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/. */
7 #ifndef mozilla_dom_PaymentRequest_h
8 #define mozilla_dom_PaymentRequest_h
10 #include "mozilla/DOMEventTargetHelper.h"
11 #include "mozilla/dom/PaymentRequestBinding.h"
12 #include "mozilla/dom/Promise.h"
13 #include "mozilla/dom/PromiseNativeHandler.h"
14 #include "mozilla/ErrorResult.h"
15 #include "nsIDocumentActivity.h"
16 #include "nsWrapperCache.h"
17 #include "PaymentRequestUpdateEvent.h"
23 class PaymentRequestChild
;
24 class PaymentResponse
;
27 class GeneralDetails final
{
29 GeneralDetails() = default;
30 ~GeneralDetails() = default;
34 class BasicCardDetails final
{
38 nsTArray
<nsString
> addressLine
;
42 nsString dependentLocality
;
45 nsString organization
;
49 BasicCardDetails() = default;
50 ~BasicCardDetails() = default;
52 Address billingAddress
;
55 class ChangeDetails final
{
57 enum Type
{ Unknown
= 0, GeneralMethodDetails
= 1, BasicCardMethodDetails
};
58 ChangeDetails() : mType(ChangeDetails::Unknown
) {}
59 explicit ChangeDetails(const GeneralDetails
& aGeneralDetails
)
60 : mType(GeneralMethodDetails
), mGeneralDetails(aGeneralDetails
) {}
61 explicit ChangeDetails(const BasicCardDetails
& aBasicCardDetails
)
62 : mType(BasicCardMethodDetails
), mBasicCardDetails(aBasicCardDetails
) {}
63 ChangeDetails
& operator=(const GeneralDetails
& aGeneralDetails
) {
64 mType
= GeneralMethodDetails
;
65 mGeneralDetails
= aGeneralDetails
;
66 mBasicCardDetails
= BasicCardDetails();
69 ChangeDetails
& operator=(const BasicCardDetails
& aBasicCardDetails
) {
70 mType
= BasicCardMethodDetails
;
71 mGeneralDetails
= GeneralDetails();
72 mBasicCardDetails
= aBasicCardDetails
;
75 ~ChangeDetails() = default;
77 const Type
& type() const { return mType
; }
78 const GeneralDetails
& generalDetails() const { return mGeneralDetails
; }
79 const BasicCardDetails
& basicCardDetails() const { return mBasicCardDetails
; }
83 GeneralDetails mGeneralDetails
;
84 BasicCardDetails mBasicCardDetails
;
87 class PaymentRequest final
: public DOMEventTargetHelper
,
88 public PromiseNativeHandler
,
89 public nsIDocumentActivity
{
91 NS_DECL_ISUPPORTS_INHERITED
92 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PaymentRequest
,
94 NS_DECL_NSIDOCUMENTACTIVITY
96 virtual JSObject
* WrapObject(JSContext
* aCx
,
97 JS::Handle
<JSObject
*> aGivenProto
) override
;
99 static already_AddRefed
<PaymentRequest
> CreatePaymentRequest(
100 nsPIDOMWindowInner
* aWindow
, nsresult
& aRv
);
102 static bool PrefEnabled(JSContext
* aCx
, JSObject
* aObj
);
104 static nsresult
IsValidStandardizedPMI(const nsAString
& aIdentifier
,
105 nsAString
& aErrorMsg
);
107 static nsresult
IsValidPaymentMethodIdentifier(const nsAString
& aIdentifier
,
108 nsAString
& aErrorMsg
);
110 static nsresult
IsValidMethodData(
111 JSContext
* aCx
, const Sequence
<PaymentMethodData
>& aMethodData
,
112 nsAString
& aErrorMsg
);
114 static nsresult
IsValidNumber(const nsAString
& aItem
, const nsAString
& aStr
,
115 nsAString
& aErrorMsg
);
116 static nsresult
IsNonNegativeNumber(const nsAString
& aItem
,
117 const nsAString
& aStr
,
118 nsAString
& aErrorMsg
);
120 static nsresult
IsValidCurrencyAmount(const nsAString
& aItem
,
121 const PaymentCurrencyAmount
& aAmount
,
122 const bool aIsTotalItem
,
123 nsAString
& aErrorMsg
);
125 static nsresult
IsValidCurrency(const nsAString
& aItem
,
126 const nsAString
& aCurrency
,
127 nsAString
& aErrorMsg
);
129 static nsresult
IsValidDetailsInit(const PaymentDetailsInit
& aDetails
,
130 const bool aRequestShipping
,
131 nsAString
& aErrorMsg
);
133 static nsresult
IsValidDetailsUpdate(const PaymentDetailsUpdate
& aDetails
,
134 const bool aRequestShipping
);
136 static nsresult
IsValidDetailsBase(const PaymentDetailsBase
& aDetails
,
137 const bool aRequestShipping
,
138 nsAString
& aErrorMsg
);
140 static already_AddRefed
<PaymentRequest
> Constructor(
141 const GlobalObject
& aGlobal
,
142 const Sequence
<PaymentMethodData
>& aMethodData
,
143 const PaymentDetailsInit
& aDetails
, const PaymentOptions
& aOptions
,
146 already_AddRefed
<Promise
> CanMakePayment(ErrorResult
& aRv
);
147 void RespondCanMakePayment(bool aResult
);
149 already_AddRefed
<Promise
> Show(
150 const Optional
<OwningNonNull
<Promise
>>& detailsPromise
, ErrorResult
& aRv
);
151 void RespondShowPayment(const nsAString
& aMethodName
,
152 const ResponseData
& aData
,
153 const nsAString
& aPayerName
,
154 const nsAString
& aPayerEmail
,
155 const nsAString
& aPayerPhone
, nsresult aRv
);
156 void RejectShowPayment(nsresult aRejectReason
);
157 void RespondComplete();
159 already_AddRefed
<Promise
> Abort(ErrorResult
& aRv
);
160 void RespondAbortPayment(bool aResult
);
162 nsresult
RetryPayment(JSContext
* aCx
, const PaymentValidationErrors
& aErrors
);
164 void GetId(nsAString
& aRetVal
) const;
165 void GetInternalId(nsAString
& aRetVal
);
166 void SetId(const nsAString
& aId
);
168 bool Equals(const nsAString
& aInternalId
) const;
170 bool ReadyForUpdate();
171 bool IsUpdating() const { return mUpdating
; }
172 void SetUpdating(bool aUpdating
);
174 already_AddRefed
<PaymentResponse
> GetResponse() const;
176 already_AddRefed
<PaymentAddress
> GetShippingAddress() const;
177 // Update mShippingAddress and fire shippingaddresschange event
178 nsresult
UpdateShippingAddress(
179 const nsAString
& aCountry
, const nsTArray
<nsString
>& aAddressLine
,
180 const nsAString
& aRegion
, const nsAString
& aRegionCode
,
181 const nsAString
& aCity
, const nsAString
& aDependentLocality
,
182 const nsAString
& aPostalCode
, const nsAString
& aSortingCode
,
183 const nsAString
& aOrganization
, const nsAString
& aRecipient
,
184 const nsAString
& aPhone
);
186 void SetShippingOption(const nsAString
& aShippingOption
);
187 void GetShippingOption(nsAString
& aRetVal
) const;
188 void GetOptions(PaymentOptions
& aRetVal
) const;
189 void SetOptions(const PaymentOptions
& aOptions
);
190 nsresult
UpdateShippingOption(const nsAString
& aShippingOption
);
192 nsresult
UpdatePayment(JSContext
* aCx
, const PaymentDetailsUpdate
& aDetails
);
193 void AbortUpdate(nsresult aRv
);
195 void SetShippingType(const Nullable
<PaymentShippingType
>& aShippingType
);
196 Nullable
<PaymentShippingType
> GetShippingType() const;
198 inline void ShippingWasRequested() { mRequestShipping
= true; }
200 nsresult
UpdatePaymentMethod(const nsAString
& aMethodName
,
201 const ChangeDetails
& aMethodDetails
);
203 void ResolvedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
) override
;
204 void RejectedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
) override
;
206 bool InFullyActiveDocument();
208 IMPL_EVENT_HANDLER(merchantvalidation
);
209 IMPL_EVENT_HANDLER(shippingaddresschange
);
210 IMPL_EVENT_HANDLER(shippingoptionchange
);
211 IMPL_EVENT_HANDLER(paymentmethodchange
);
213 void SetIPC(PaymentRequestChild
* aChild
) { mIPC
= aChild
; }
215 PaymentRequestChild
* GetIPC() const { return mIPC
; }
218 PaymentOptions mOptions
;
223 void RegisterActivityObserver();
224 void UnregisterActivityObserver();
226 nsresult
DispatchUpdateEvent(const nsAString
& aType
);
228 nsresult
DispatchMerchantValidationEvent(const nsAString
& aType
);
230 nsresult
DispatchPaymentMethodChangeEvent(const nsAString
& aMethodName
,
231 const ChangeDetails
& aMethodDatils
);
233 PaymentRequest(nsPIDOMWindowInner
* aWindow
, const nsAString
& aInternalId
);
235 // Id for internal identification
236 nsString mInternalId
;
237 // Id for communicating with merchant side
238 // mId is initialized to details.id if it exists
239 // otherwise, mId has the same value as mInternalId.
241 // Promise for "PaymentRequest::CanMakePayment"
242 RefPtr
<Promise
> mResultPromise
;
243 // Promise for "PaymentRequest::Show"
244 RefPtr
<Promise
> mAcceptPromise
;
245 // Promise for "PaymentRequest::Abort"
246 RefPtr
<Promise
> mAbortPromise
;
247 // Resolve mAcceptPromise with mResponse if user accepts the request.
248 RefPtr
<PaymentResponse
> mResponse
;
249 // The redacted shipping address.
250 RefPtr
<PaymentAddress
> mShippingAddress
;
251 // The full shipping address to be used in the response upon payment.
252 RefPtr
<PaymentAddress
> mFullShippingAddress
;
253 // Hold a reference to the document to allow unregistering the activity
255 RefPtr
<Document
> mDocument
;
256 // It is populated when the user chooses a shipping option.
257 nsString mShippingOption
;
259 Nullable
<PaymentShippingType
> mShippingType
;
261 // "true" when there is a pending updateWith() call to update the payment
262 // request and "false" otherwise.
265 // Whether shipping was requested. This models [[options]].requestShipping,
266 // but we don't actually store the full [[options]] internal slot.
267 bool mRequestShipping
;
269 // The error is set in AbortUpdate(). The value is NS_OK by default.
270 nsresult mUpdateError
;
272 enum { eUnknown
, eCreated
, eInteractive
, eClosed
} mState
;
274 PaymentRequestChild
* mIPC
;
277 } // namespace mozilla
279 #endif // mozilla_dom_PaymentRequest_h