PaymentRequest.h (10274B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_PaymentRequest_h 8 #define mozilla_dom_PaymentRequest_h 9 10 #include "PaymentRequestUpdateEvent.h" 11 #include "mozilla/DOMEventTargetHelper.h" 12 #include "mozilla/ErrorResult.h" 13 #include "mozilla/dom/PaymentRequestBinding.h" 14 #include "mozilla/dom/Promise.h" 15 #include "mozilla/dom/PromiseNativeHandler.h" 16 #include "nsIDocumentActivity.h" 17 #include "nsWrapperCache.h" 18 19 namespace mozilla::dom { 20 21 class PaymentAddress; 22 class PaymentRequestChild; 23 class PaymentResponse; 24 class ResponseData; 25 26 class GeneralDetails final { 27 public: 28 GeneralDetails() = default; 29 ~GeneralDetails() = default; 30 nsString details; 31 }; 32 33 class BasicCardDetails final { 34 public: 35 struct Address { 36 nsString country; 37 CopyableTArray<nsString> addressLine; 38 nsString region; 39 nsString regionCode; 40 nsString city; 41 nsString dependentLocality; 42 nsString postalCode; 43 nsString sortingCode; 44 nsString organization; 45 nsString recipient; 46 nsString phone; 47 }; 48 BasicCardDetails() = default; 49 ~BasicCardDetails() = default; 50 51 Address billingAddress; 52 }; 53 54 class ChangeDetails final { 55 public: 56 enum Type { Unknown = 0, GeneralMethodDetails = 1, BasicCardMethodDetails }; 57 ChangeDetails() : mType(ChangeDetails::Unknown) {} 58 explicit ChangeDetails(const GeneralDetails& aGeneralDetails) 59 : mType(GeneralMethodDetails), mGeneralDetails(aGeneralDetails) {} 60 explicit ChangeDetails(const BasicCardDetails& aBasicCardDetails) 61 : mType(BasicCardMethodDetails), mBasicCardDetails(aBasicCardDetails) {} 62 ChangeDetails& operator=(const GeneralDetails& aGeneralDetails) { 63 mType = GeneralMethodDetails; 64 mGeneralDetails = aGeneralDetails; 65 mBasicCardDetails = BasicCardDetails(); 66 return *this; 67 } 68 ChangeDetails& operator=(const BasicCardDetails& aBasicCardDetails) { 69 mType = BasicCardMethodDetails; 70 mGeneralDetails = GeneralDetails(); 71 mBasicCardDetails = aBasicCardDetails; 72 return *this; 73 } 74 ~ChangeDetails() = default; 75 76 const Type& type() const { return mType; } 77 const GeneralDetails& generalDetails() const { return mGeneralDetails; } 78 const BasicCardDetails& basicCardDetails() const { return mBasicCardDetails; } 79 80 private: 81 Type mType; 82 GeneralDetails mGeneralDetails; 83 BasicCardDetails mBasicCardDetails; 84 }; 85 86 class PaymentRequest final : public DOMEventTargetHelper, 87 public PromiseNativeHandler, 88 public nsIDocumentActivity { 89 public: 90 NS_DECL_ISUPPORTS_INHERITED 91 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PaymentRequest, 92 DOMEventTargetHelper) 93 NS_DECL_NSIDOCUMENTACTIVITY 94 95 virtual JSObject* WrapObject(JSContext* aCx, 96 JS::Handle<JSObject*> aGivenProto) override; 97 98 static already_AddRefed<PaymentRequest> CreatePaymentRequest( 99 nsPIDOMWindowInner* aWindow, ErrorResult& aRv); 100 101 static bool PrefEnabled(JSContext* aCx, JSObject* aObj); 102 103 // Parameter validation methods 104 static void IsValidStandardizedPMI(const nsAString& aIdentifier, 105 ErrorResult& aRv); 106 107 static void IsValidPaymentMethodIdentifier(const nsAString& aIdentifier, 108 ErrorResult& aRv); 109 110 static void IsValidMethodData(JSContext* aCx, 111 const Sequence<PaymentMethodData>& aMethodData, 112 ErrorResult& aRv); 113 114 static void IsValidNumber(const nsAString& aItem, const nsAString& aStr, 115 ErrorResult& aRv); 116 117 static void IsNonNegativeNumber(const nsAString& aItem, const nsAString& aStr, 118 ErrorResult& aRv); 119 120 static void IsValidCurrencyAmount(const nsAString& aItem, 121 const PaymentCurrencyAmount& aAmount, 122 const bool aIsTotalItem, ErrorResult& aRv); 123 124 static void IsValidCurrency(const nsAString& aItem, 125 const nsAString& aCurrency, ErrorResult& aRv); 126 127 static void IsValidDetailsInit(const PaymentDetailsInit& aDetails, 128 const bool aRequestShipping, ErrorResult& aRv); 129 130 static void IsValidDetailsUpdate(const PaymentDetailsUpdate& aDetails, 131 const bool aRequestShipping, 132 ErrorResult& aRv); 133 134 static void IsValidDetailsBase(const PaymentDetailsBase& aDetails, 135 const bool aRequestShipping, ErrorResult& aRv); 136 137 // Webidl implementation 138 static already_AddRefed<PaymentRequest> Constructor( 139 const GlobalObject& aGlobal, 140 const Sequence<PaymentMethodData>& aMethodData, 141 const PaymentDetailsInit& aDetails, const PaymentOptions& aOptions, 142 ErrorResult& aRv); 143 144 already_AddRefed<Promise> CanMakePayment(ErrorResult& aRv); 145 void RespondCanMakePayment(bool aResult); 146 147 already_AddRefed<Promise> Show( 148 const Optional<OwningNonNull<Promise>>& detailsPromise, ErrorResult& aRv); 149 void RespondShowPayment(const nsAString& aMethodName, 150 const ResponseData& aData, 151 const nsAString& aPayerName, 152 const nsAString& aPayerEmail, 153 const nsAString& aPayerPhone, ErrorResult&& aResult); 154 void RejectShowPayment(ErrorResult&& aRejectReason); 155 void RespondComplete(); 156 157 already_AddRefed<Promise> Abort(ErrorResult& aRv); 158 void RespondAbortPayment(bool aResult); 159 160 void RetryPayment(JSContext* aCx, const PaymentValidationErrors& aErrors, 161 ErrorResult& aRv); 162 163 void GetId(nsAString& aRetVal) const; 164 void GetInternalId(nsAString& aRetVal); 165 void SetId(const nsAString& aId); 166 167 bool Equals(const nsAString& aInternalId) const; 168 169 bool ReadyForUpdate(); 170 bool IsUpdating() const { return mUpdating; } 171 void SetUpdating(bool aUpdating); 172 173 already_AddRefed<PaymentResponse> GetResponse() const; 174 175 already_AddRefed<PaymentAddress> GetShippingAddress() const; 176 // Update mShippingAddress and fire shippingaddresschange event 177 nsresult UpdateShippingAddress( 178 const nsAString& aCountry, const nsTArray<nsString>& aAddressLine, 179 const nsAString& aRegion, const nsAString& aRegionCode, 180 const nsAString& aCity, const nsAString& aDependentLocality, 181 const nsAString& aPostalCode, const nsAString& aSortingCode, 182 const nsAString& aOrganization, const nsAString& aRecipient, 183 const nsAString& aPhone); 184 185 void SetShippingOption(const nsAString& aShippingOption); 186 void GetShippingOption(nsAString& aRetVal) const; 187 void GetOptions(PaymentOptions& aRetVal) const; 188 void SetOptions(const PaymentOptions& aOptions); 189 nsresult UpdateShippingOption(const nsAString& aShippingOption); 190 191 void UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails, 192 ErrorResult& aRv); 193 void AbortUpdate(ErrorResult& aReason); 194 195 void SetShippingType(const Nullable<PaymentShippingType>& aShippingType); 196 Nullable<PaymentShippingType> GetShippingType() const; 197 198 inline void ShippingWasRequested() { mRequestShipping = true; } 199 200 nsresult UpdatePaymentMethod(const nsAString& aMethodName, 201 const ChangeDetails& aMethodDetails); 202 203 void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue, 204 ErrorResult& aRv) override; 205 void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue, 206 ErrorResult& aRv) override; 207 208 bool InFullyActiveDocument(); 209 210 IMPL_EVENT_HANDLER(merchantvalidation); 211 IMPL_EVENT_HANDLER(shippingaddresschange); 212 IMPL_EVENT_HANDLER(shippingoptionchange); 213 IMPL_EVENT_HANDLER(paymentmethodchange); 214 215 void SetIPC(PaymentRequestChild* aChild) { mIPC = aChild; } 216 217 PaymentRequestChild* GetIPC() const { return mIPC; } 218 219 private: 220 PaymentOptions mOptions; 221 222 protected: 223 ~PaymentRequest(); 224 225 void RegisterActivityObserver(); 226 void UnregisterActivityObserver(); 227 228 nsresult DispatchUpdateEvent(const nsAString& aType); 229 230 nsresult DispatchMerchantValidationEvent(const nsAString& aType); 231 232 nsresult DispatchPaymentMethodChangeEvent(const nsAString& aMethodName, 233 const ChangeDetails& aMethodDatils); 234 235 PaymentRequest(nsPIDOMWindowInner* aWindow, const nsAString& aInternalId); 236 237 // Id for internal identification 238 nsString mInternalId; 239 // Id for communicating with merchant side 240 // mId is initialized to details.id if it exists 241 // otherwise, mId has the same value as mInternalId. 242 nsString mId; 243 // Promise for "PaymentRequest::CanMakePayment" 244 RefPtr<Promise> mResultPromise; 245 // Promise for "PaymentRequest::Show" 246 RefPtr<Promise> mAcceptPromise; 247 // Promise for "PaymentRequest::Abort" 248 RefPtr<Promise> mAbortPromise; 249 // Resolve mAcceptPromise with mResponse if user accepts the request. 250 RefPtr<PaymentResponse> mResponse; 251 // The redacted shipping address. 252 RefPtr<PaymentAddress> mShippingAddress; 253 // The full shipping address to be used in the response upon payment. 254 RefPtr<PaymentAddress> mFullShippingAddress; 255 // Hold a reference to the document to allow unregistering the activity 256 // observer. 257 RefPtr<Document> mDocument; 258 // It is populated when the user chooses a shipping option. 259 nsString mShippingOption; 260 261 Nullable<PaymentShippingType> mShippingType; 262 263 // "true" when there is a pending updateWith() call to update the payment 264 // request and "false" otherwise. 265 bool mUpdating; 266 267 // Whether shipping was requested. This models [[options]].requestShipping, 268 // but we don't actually store the full [[options]] internal slot. 269 bool mRequestShipping; 270 271 // The error is set in AbortUpdate(). The value is not-failed by default. 272 ErrorResult mUpdateError; 273 274 enum { eUnknown, eCreated, eInteractive, eClosed } mState; 275 276 PaymentRequestChild* mIPC; 277 }; 278 } // namespace mozilla::dom 279 280 #endif // mozilla_dom_PaymentRequest_h