UNPKG

react-native-moyasar-sdk

Version:

Official React Native Moyasar SDK - Integrate Credit Cards, Apple Pay, Samsung Pay, and STC Pay with simple interfaces for a seamless payment experience in your React Native app

176 lines (145 loc) 8.05 kB
"use strict"; import { Platform } from 'react-native'; import { MODULE_SCOPING, SHIPPING_ADDRESS_CHANGE_EVENT, SHIPPING_OPTION_CHANGE_EVENT, INTERNAL_SHIPPING_ADDRESS_CHANGE_EVENT, INTERNAL_SHIPPING_OPTION_CHANGE_EVENT, USER_DISMISS_EVENT, USER_ACCEPT_EVENT, SUPPORTED_METHOD_NAME } from "./constants.js"; const noop = () => {}; import PaymentRequest from "./index.js"; import NativePayments from "../NativeBridge/index.js"; // Helpers import { validateTotal, validateDisplayItems, validateShippingOptions, convertDetailAmountsToString } from "./helpers/index.js"; // Errors import { DOMException } from "./errors/index.js"; export default class PaymentRequestUpdateEvent { constructor(name, target) { if (name !== SHIPPING_ADDRESS_CHANGE_EVENT && name !== SHIPPING_OPTION_CHANGE_EVENT) { throw new Error(`Only "${SHIPPING_ADDRESS_CHANGE_EVENT}" and "${SHIPPING_OPTION_CHANGE_EVENT}" event listeners are supported.`); } this.name = name; this.target = target; this._waitForUpdate = false; this._handleDetailsChange = this._handleDetailsChange.bind(this); this._resetEvent = this._resetEvent.bind(this); } _handleDetailsChange(value) { const target = this.target; validateTotal(value.total, DOMException); validateDisplayItems(value.displayItems, DOMException); validateShippingOptions(value.shippingOptions, DOMException); // 1. Let details be the result of converting value to a PaymentDetailsUpdate dictionary. If this throws an exception, abort the update with the thrown exception. const details = Object.assign(target._details, value); // 2. Let serializedModifierData be an empty list. let serializedModifierData = []; // 3. Let selectedShippingOption be null. let selectedShippingOption = null; // 4. Let shippingOptions be an empty sequence<PaymentShippingOption>. let shippingOptions = []; // 5. Validate and canonicalize the details: // TODO: implmentation // 6. Update the PaymentRequest using the new details: target._details = details; // 6.1 If the total member of details is present, then: // if (details.total) { // target._details = Object.assign({}, target._details, { total: details.total }); // } // // 6.2 If the displayItems member of details is present, then: // if (details.displayItems) { // target._details = Object.assign({}, target._details, { displayItems: details.displayItems }); // } // // 6.3 If the shippingOptions member of details is present, and target.[[options]].requestShipping is true, then: // if (details.shippingOptions && target._options.requestShipping === true) { // // 6.3.1 Set target.[[details]].shippingOptions to shippingOptions. // shippingOptions = details.shippingOptions; // target._details = Object.assign({}, target._details, { shippingOptions }); // // 6.3.2 Set the value of target's shippingOption attribute to selectedShippingOption. // selectedShippingOption = target.shippingOption; // } // // 6.4 If the modifiers member of details is present, then: // if (details.modifiers) { // // 6.4.1 Set target.[[details]].modifiers to details.modifiers. // target._details = Object.assign({}, target._details, { modifiers: details.modifiers }); // // 6.4.2 Set target.[[serializedModifierData]] to serializedModifierData. // target._serializedModifierData = serializedModifierData; // } // 6.5 If target.[[options]].requestShipping is true, and target.[[details]].shippingOptions is empty, // then the developer has signified that there are no valid shipping options for the currently-chosen shipping address (given by target's shippingAddress). // In this case, the user agent should display an error indicating this, and may indicate that that the currently-chosen shipping address is invalid in some way. // The user agent should use the error member of details, if it is present, to give more information about why there are no valid shipping options for that address. // React Native Payments specific 👇 // --------------------------------- const normalizedDetails = convertDetailAmountsToString(target._details); return NativePayments.handleDetailsUpdate(normalizedDetails, DOMException) // 14. Upon fulfillment of detailsPromise with value value .then(this._resetEvent()) // On iOS the `selectedShippingMethod` defaults back to the first option // when updating shippingMethods. So we call the `_handleShippingOptionChange` // method with the first shippingOption id so that JS is in sync with Apple Pay. .then(() => { if (Platform.OS !== 'ios') { return; } if (target._details.shippingOptions && target._details.shippingOptions.length > 0 && value.shippingOptions && ((value.shippingOptions.find(op => op.selected) || {}).id || null) !== target._shippingOption) { target._handleShippingOptionChange({ selectedShippingOptionId: target._details.shippingOptions[0].id }); } }) // 13. Upon rejection of detailsPromise: .catch(e => { this._resetEvent(); throw new Error('AbortError'); }); } _resetEvent() { // 1. Set event.[[waitForUpdate]] to false. this._waitForUpdate = false; // 2. Set target.[[updating]] to false. this.target._updating = false; // 3. The user agent should update the user interface based on any changed values in target. // The user agent should re-enable user interface elements that might have been disabled in the steps above if appropriate. noop(); } async updateWith(PaymentDetailsModifierOrPromise) { // 1. Let event be this PaymentRequestUpdateEvent instance. let event = this; // 2. Let target be the value of event's target attribute. let target = this.target; // 3. If target is not a PaymentRequest object, then throw a TypeError. if (!(target instanceof PaymentRequest)) { throw new Error('TypeError'); } // 5. If event.[[waitForUpdate]] is true, then throw an "InvalidStateError" DOMException. if (event._waitForUpdate === true) { throw new Error('InvalidStateError'); } // 6. If target.[[state]] is not " interactive", then throw an " InvalidStateError" DOMException. if (target._state !== 'interactive') { throw new Error('InvalidStateError'); } // 7. If target.[[updating]] is true, then throw an "InvalidStateError" DOMException. if (target._updating === true) { throw new Error('InvalidStateError'); } // 8. Set event's stop propagation flag and stop immediate propagation flag. noop(); // 9. Set event.[[waitForUpdate]] to true. event._waitForUpdate = true; // 10. Set target.[[updating]] to true. target._updating = true; // 11. The user agent should disable the user interface that allows the user to accept the payment request. // This is to ensure that the payment is not accepted until the web page has made changes required by the change. // The web page must settle the detailsPromise to indicate that the payment request is valid again. // The user agent should disable any part of the user interface that could cause another update event to be fired. // Only one update may be processed at a time. noop(); // NativePayments does this for us (iOS does at the time of this comment) // 12. Return from the method and perform the remaining steps in parallel. if (typeof PaymentDetailsModifierOrPromise === 'object') { const paymentDetailsModifier = PaymentDetailsModifierOrPromise; return this._handleDetailsChange(paymentDetailsModifier); } if (typeof PaymentDetailsModifierOrPromise === 'function') { const detailsFromPromise = await PaymentDetailsModifierOrPromise(); this._handleDetailsChange(detailsFromPromise); } // 13 & 14 happen in `this._handleDetailsChange`. } } //# sourceMappingURL=PaymentRequestUpdateEvent.js.map