swell-js 5.4.1 → 5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.mjs +1 -1
- package/dist/payment.mjs +438 -51
- package/dist/swell.cjs +439 -52
- package/dist/swell.cjs.map +1 -1
- package/dist/swell.umd.min.js +439 -52
- package/dist/swell.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/types/index.d.ts +17 -17
- package/types/payment/camel.ts +1 -35
- package/types/payment/index.ts +118 -73
- package/types/payment/snake.ts +0 -121
- package/types/product/camel.ts +42 -0
- package/types/product/index.ts +18 -6
- package/types/product/snake.ts +50 -3
package/dist/api.mjs
CHANGED
package/dist/payment.mjs
CHANGED
|
@@ -21,6 +21,7 @@ const SCRIPT_HANDLERS = {
|
|
|
21
21
|
'braintree-google-payment': loadBraintreeGoogle,
|
|
22
22
|
'braintree-apple-payment': loadBraintreeApple,
|
|
23
23
|
'amazon-checkout': loadAmazonCheckout,
|
|
24
|
+
'convesiopay-js': loadConvesioPay,
|
|
24
25
|
'sezzle-sdk': loadSezzleCheckout,
|
|
25
26
|
};
|
|
26
27
|
|
|
@@ -189,6 +190,16 @@ async function loadAmazonCheckout() {
|
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
|
|
193
|
+
async function loadConvesioPay() {
|
|
194
|
+
if (!window.ConvesioPay) {
|
|
195
|
+
await loadScript('convesiopay-js', 'https://js.convesiopay.com/v1/');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!window.ConvesioPay) {
|
|
199
|
+
console.error('Warning: ConvesioPay was not loaded');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
192
203
|
async function loadSezzleCheckout() {
|
|
193
204
|
if (!window.Checkout) {
|
|
194
205
|
await loadScript(
|
|
@@ -560,6 +571,8 @@ class Payment {
|
|
|
560
571
|
/** @typedef {import('@stripe/stripe-js').StripeCardNumberElement} StripeCardNumberElement */
|
|
561
572
|
/** @typedef {import('@stripe/stripe-js').CreateSourceData} CreateSourceData */
|
|
562
573
|
|
|
574
|
+
/** @typedef {import('../../types').Cart} Cart */
|
|
575
|
+
|
|
563
576
|
// https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts
|
|
564
577
|
const MINIMUM_CHARGE_AMOUNT = {
|
|
565
578
|
USD: 0.5,
|
|
@@ -614,6 +627,10 @@ function mapValues(fieldsMap, data) {
|
|
|
614
627
|
return result;
|
|
615
628
|
}
|
|
616
629
|
|
|
630
|
+
/**
|
|
631
|
+
* @param {Cart} cart
|
|
632
|
+
* @returns {object}
|
|
633
|
+
*/
|
|
617
634
|
function getBillingDetails(cart) {
|
|
618
635
|
const details = {
|
|
619
636
|
...mapValues(billingFieldsMap, cart.billing),
|
|
@@ -658,7 +675,7 @@ function createElement(type, elements, params) {
|
|
|
658
675
|
/**
|
|
659
676
|
* @param {Stripe} stripe
|
|
660
677
|
* @param {StripeCardElement | StripeCardNumberElement} cardElement
|
|
661
|
-
* @param {
|
|
678
|
+
* @param {Cart} cart
|
|
662
679
|
*/
|
|
663
680
|
async function createPaymentMethod(stripe, cardElement, cart) {
|
|
664
681
|
const billingDetails = getBillingDetails(cart);
|
|
@@ -686,7 +703,7 @@ async function createPaymentMethod(stripe, cardElement, cart) {
|
|
|
686
703
|
/**
|
|
687
704
|
* @param {Stripe} stripe
|
|
688
705
|
* @param {import('@stripe/stripe-js').StripeIdealBankElement} element
|
|
689
|
-
* @param {
|
|
706
|
+
* @param {Cart} cart
|
|
690
707
|
*/
|
|
691
708
|
async function createIDealPaymentMethod(stripe, element, cart) {
|
|
692
709
|
const billingDetails = getBillingDetails(cart);
|
|
@@ -697,6 +714,10 @@ async function createIDealPaymentMethod(stripe, element, cart) {
|
|
|
697
714
|
});
|
|
698
715
|
}
|
|
699
716
|
|
|
717
|
+
/**
|
|
718
|
+
* @param {Cart} cart
|
|
719
|
+
* @returns {object}
|
|
720
|
+
*/
|
|
700
721
|
function getKlarnaIntentDetails(cart) {
|
|
701
722
|
const { account, currency, capture_total } = cart;
|
|
702
723
|
const stripeCustomer = account && account.stripe_customer;
|
|
@@ -717,7 +738,7 @@ function getKlarnaIntentDetails(cart) {
|
|
|
717
738
|
}
|
|
718
739
|
|
|
719
740
|
/**
|
|
720
|
-
* @param {
|
|
741
|
+
* @param {Cart} cart
|
|
721
742
|
* @returns {import('@stripe/stripe-js').ConfirmKlarnaPaymentData}
|
|
722
743
|
*/
|
|
723
744
|
function getKlarnaConfirmationDetails(cart) {
|
|
@@ -737,7 +758,7 @@ function getKlarnaConfirmationDetails(cart) {
|
|
|
737
758
|
/**
|
|
738
759
|
* Returns Bancontact Setup Intent confirmation details.
|
|
739
760
|
*
|
|
740
|
-
* @param {
|
|
761
|
+
* @param {Cart} cart
|
|
741
762
|
* @returns {import('@stripe/stripe-js').ConfirmBancontactPaymentData}
|
|
742
763
|
*/
|
|
743
764
|
function getBancontactConfirmationDetails(cart) {
|
|
@@ -755,7 +776,7 @@ function getBancontactConfirmationDetails(cart) {
|
|
|
755
776
|
}
|
|
756
777
|
|
|
757
778
|
/**
|
|
758
|
-
* @param {
|
|
779
|
+
* @param {Cart} cart
|
|
759
780
|
* @param {object} params
|
|
760
781
|
* @returns {import('@stripe/stripe-js').PaymentRequestOptions}
|
|
761
782
|
*/
|
|
@@ -839,6 +860,11 @@ const zeroDecimalCurrencies = new Set([
|
|
|
839
860
|
'XOF', // West African Cfa Franc
|
|
840
861
|
]);
|
|
841
862
|
|
|
863
|
+
/**
|
|
864
|
+
* @param {string} currency
|
|
865
|
+
* @param {number} amount
|
|
866
|
+
* @returns {number}
|
|
867
|
+
*/
|
|
842
868
|
function stripeAmountByCurrency(currency, amount) {
|
|
843
869
|
if (zeroDecimalCurrencies.has(currency.toUpperCase())) {
|
|
844
870
|
return amount;
|
|
@@ -847,6 +873,11 @@ function stripeAmountByCurrency(currency, amount) {
|
|
|
847
873
|
return Math.round(amount * 100);
|
|
848
874
|
}
|
|
849
875
|
|
|
876
|
+
/**
|
|
877
|
+
* @param {number} amount
|
|
878
|
+
* @param {string} currency
|
|
879
|
+
* @returns {boolean}
|
|
880
|
+
*/
|
|
850
881
|
function isStripeChargeableAmount(amount, currency) {
|
|
851
882
|
const minAmount = MINIMUM_CHARGE_AMOUNT[currency];
|
|
852
883
|
return !minAmount || amount >= minAmount;
|
|
@@ -2075,6 +2106,44 @@ function getDiscountLabel(discount, cart) {
|
|
|
2075
2106
|
return discount.id;
|
|
2076
2107
|
}
|
|
2077
2108
|
|
|
2109
|
+
/** @type {Map<string, number>} */
|
|
2110
|
+
const CURRENCIES_CENTS = new Map();
|
|
2111
|
+
|
|
2112
|
+
/**
|
|
2113
|
+
* @param {string} currency
|
|
2114
|
+
* @returns {number}
|
|
2115
|
+
*/
|
|
2116
|
+
function getCurrencyCents(currency) {
|
|
2117
|
+
let cents = CURRENCIES_CENTS.get(currency);
|
|
2118
|
+
|
|
2119
|
+
if (cents !== undefined) {
|
|
2120
|
+
return cents;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
const formatter = new Intl.NumberFormat('en-US', {
|
|
2124
|
+
style: 'currency',
|
|
2125
|
+
currency,
|
|
2126
|
+
});
|
|
2127
|
+
|
|
2128
|
+
const options = formatter.resolvedOptions();
|
|
2129
|
+
const decimals = options.maximumFractionDigits ?? 2;
|
|
2130
|
+
|
|
2131
|
+
cents = 10 ** decimals;
|
|
2132
|
+
|
|
2133
|
+
CURRENCIES_CENTS.set(currency, cents);
|
|
2134
|
+
|
|
2135
|
+
return cents;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
/**
|
|
2139
|
+
* @param {string} currency
|
|
2140
|
+
* @param {number} amount
|
|
2141
|
+
* @returns {number}
|
|
2142
|
+
*/
|
|
2143
|
+
function amountInCents$1(currency, amount) {
|
|
2144
|
+
return Math.round(amount * getCurrencyCents(currency));
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2078
2147
|
/** @typedef {import('./payment').default} Payment */
|
|
2079
2148
|
/** @typedef {import('../../types').Cart} Cart */
|
|
2080
2149
|
/** @typedef {import('../../types').Address} Address */
|
|
@@ -2646,29 +2715,16 @@ class BraintreeGooglePayment extends Payment {
|
|
|
2646
2715
|
/** @typedef {import('../../types').Address} Address */
|
|
2647
2716
|
|
|
2648
2717
|
/**
|
|
2649
|
-
* Handles Apple Pay shipping contact selection event
|
|
2650
|
-
*
|
|
2651
|
-
* IMPORTANT: This event fires automatically when the Apple Pay sheet opens
|
|
2652
|
-
* with the user's default address. This is expected Apple Pay behavior.
|
|
2653
|
-
*
|
|
2654
|
-
* The flow:
|
|
2655
|
-
* 1. Apple Pay sheet opens → This event fires with default address
|
|
2656
|
-
* 2. User changes address → This event fires again with new address
|
|
2657
|
-
* 3. Each time, we:
|
|
2658
|
-
* - Send the address to Swell to calculate shipping/tax
|
|
2659
|
-
* - Return updated totals and available shipping methods
|
|
2660
|
-
*
|
|
2661
2718
|
* @this {Payment}
|
|
2662
|
-
* @param {
|
|
2663
|
-
* @
|
|
2664
|
-
* @returns {void}
|
|
2719
|
+
* @param {ApplePayJS.ApplePayPaymentContact} shippingContact
|
|
2720
|
+
* @returns {Promise<ApplePayJS.ApplePayShippingContactUpdate>}
|
|
2665
2721
|
*/
|
|
2666
|
-
async function
|
|
2722
|
+
async function onShippingAddressChange(shippingContact) {
|
|
2667
2723
|
try {
|
|
2668
2724
|
// Update cart with Apple Pay shipping address to get shipping options and tax
|
|
2669
2725
|
// This happens immediately when the sheet opens with the default address
|
|
2670
2726
|
const cart = await this.updateCart({
|
|
2671
|
-
shipping: convertToSwellAddress$1(
|
|
2727
|
+
shipping: convertToSwellAddress$1(shippingContact),
|
|
2672
2728
|
});
|
|
2673
2729
|
|
|
2674
2730
|
if (!cart.shipment_rating?.services?.length) {
|
|
@@ -2676,69 +2732,104 @@ async function onShippingContactSelected(session, event) {
|
|
|
2676
2732
|
cart.shipment_rating?.errors?.find(Boolean)?.message ??
|
|
2677
2733
|
'Shipping is not available for the provided address.';
|
|
2678
2734
|
|
|
2679
|
-
return
|
|
2735
|
+
return {
|
|
2680
2736
|
newTotal: getTotal(cart),
|
|
2681
|
-
newLineItems: getLineItems(cart),
|
|
2737
|
+
newLineItems: getLineItems$1(cart),
|
|
2682
2738
|
newShippingMethods: [], // REQUIRED: Must always provide this, even as empty array
|
|
2683
2739
|
errors: [
|
|
2684
2740
|
new ApplePayError('addressUnserviceable', 'postalAddress', message),
|
|
2685
2741
|
],
|
|
2686
|
-
}
|
|
2742
|
+
};
|
|
2687
2743
|
}
|
|
2688
2744
|
|
|
2689
2745
|
// Success: Return updated totals and shipping methods
|
|
2690
|
-
|
|
2746
|
+
return {
|
|
2691
2747
|
newTotal: getTotal(cart),
|
|
2692
|
-
newLineItems: getLineItems(cart),
|
|
2693
|
-
newShippingMethods: getShippingMethods(cart),
|
|
2694
|
-
}
|
|
2748
|
+
newLineItems: getLineItems$1(cart),
|
|
2749
|
+
newShippingMethods: getShippingMethods$1(cart),
|
|
2750
|
+
};
|
|
2695
2751
|
} catch (err) {
|
|
2696
2752
|
const cartData = await this.getCart();
|
|
2697
2753
|
|
|
2698
|
-
|
|
2754
|
+
return {
|
|
2699
2755
|
newTotal: getTotal(cartData),
|
|
2700
|
-
newLineItems: getLineItems(cartData),
|
|
2756
|
+
newLineItems: getLineItems$1(cartData),
|
|
2701
2757
|
newShippingMethods: [], // REQUIRED: Must always provide this, even as empty array
|
|
2702
2758
|
errors: [new ApplePayError('unknown', undefined, err.message)],
|
|
2703
|
-
}
|
|
2759
|
+
};
|
|
2704
2760
|
}
|
|
2705
2761
|
}
|
|
2706
2762
|
|
|
2707
2763
|
/**
|
|
2708
|
-
* Handles Apple Pay shipping
|
|
2764
|
+
* Handles Apple Pay shipping contact selection event
|
|
2709
2765
|
*
|
|
2710
|
-
*
|
|
2711
|
-
*
|
|
2712
|
-
* total and line items (which now include the shipping cost).
|
|
2766
|
+
* IMPORTANT: This event fires automatically when the Apple Pay sheet opens
|
|
2767
|
+
* with the user's default address. This is expected Apple Pay behavior.
|
|
2713
2768
|
*
|
|
2714
|
-
*
|
|
2715
|
-
*
|
|
2769
|
+
* The flow:
|
|
2770
|
+
* 1. Apple Pay sheet opens → This event fires with default address
|
|
2771
|
+
* 2. User changes address → This event fires again with new address
|
|
2772
|
+
* 3. Each time, we:
|
|
2773
|
+
* - Send the address to Swell to calculate shipping/tax
|
|
2774
|
+
* - Return updated totals and available shipping methods
|
|
2716
2775
|
*
|
|
2717
2776
|
* @this {Payment}
|
|
2718
2777
|
* @param {ApplePaySession} session
|
|
2719
|
-
* @param {ApplePayJS.
|
|
2778
|
+
* @param {ApplePayJS.ApplePayShippingContactSelectedEvent} event
|
|
2720
2779
|
* @returns {void}
|
|
2721
2780
|
*/
|
|
2722
|
-
async function
|
|
2781
|
+
async function onShippingContactSelected(session, event) {
|
|
2782
|
+
session.completeShippingContactSelection(
|
|
2783
|
+
await onShippingAddressChange.call(this, event.shippingContact),
|
|
2784
|
+
);
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
/**
|
|
2788
|
+
* @this {Payment}
|
|
2789
|
+
* @param {ApplePayJS.ApplePayShippingMethod} shippingMethod
|
|
2790
|
+
* @returns {Promise<ApplePayJS.ApplePayShippingMethodUpdate>}
|
|
2791
|
+
*/
|
|
2792
|
+
async function onShippingMethodChange(shippingMethod) {
|
|
2723
2793
|
try {
|
|
2724
2794
|
const cart = await this.updateCart({
|
|
2725
2795
|
shipping: {
|
|
2726
|
-
service:
|
|
2796
|
+
service: shippingMethod.identifier,
|
|
2727
2797
|
},
|
|
2728
2798
|
});
|
|
2729
2799
|
|
|
2730
|
-
|
|
2800
|
+
return {
|
|
2731
2801
|
newTotal: getTotal(cart),
|
|
2732
|
-
newLineItems: getLineItems(cart),
|
|
2733
|
-
}
|
|
2802
|
+
newLineItems: getLineItems$1(cart),
|
|
2803
|
+
};
|
|
2734
2804
|
} catch (err) {
|
|
2735
|
-
|
|
2805
|
+
return {
|
|
2736
2806
|
newTotal: getTotal(await this.getCart()),
|
|
2737
2807
|
errors: [new ApplePayError('unknown', undefined, err.message)],
|
|
2738
|
-
}
|
|
2808
|
+
};
|
|
2739
2809
|
}
|
|
2740
2810
|
}
|
|
2741
2811
|
|
|
2812
|
+
/**
|
|
2813
|
+
* Handles Apple Pay shipping method selection
|
|
2814
|
+
*
|
|
2815
|
+
* Triggered when the user selects a shipping method from the available options.
|
|
2816
|
+
* We update the cart with the selected shipping service and return the updated
|
|
2817
|
+
* total and line items (which now include the shipping cost).
|
|
2818
|
+
*
|
|
2819
|
+
* After this event, the total changes from type 'pending' to 'final' and shows
|
|
2820
|
+
* the actual final amount to the user.
|
|
2821
|
+
*
|
|
2822
|
+
* @this {Payment}
|
|
2823
|
+
* @param {ApplePaySession} session
|
|
2824
|
+
* @param {ApplePayJS.ApplePayShippingMethodSelectedEvent} event
|
|
2825
|
+
* @returns {void}
|
|
2826
|
+
*/
|
|
2827
|
+
async function onShippingMethodSelected(session, event) {
|
|
2828
|
+
session.completeShippingMethodSelection(
|
|
2829
|
+
await onShippingMethodChange.call(this, event.shippingMethod),
|
|
2830
|
+
);
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2742
2833
|
/**
|
|
2743
2834
|
* Handles Apple Pay coupon code changes
|
|
2744
2835
|
*
|
|
@@ -2759,7 +2850,7 @@ async function onCouponCodeChanged(session, event) {
|
|
|
2759
2850
|
// Valid coupon applied successfully
|
|
2760
2851
|
session.completeCouponCodeChange({
|
|
2761
2852
|
newTotal: getTotal(cart),
|
|
2762
|
-
newLineItems: getLineItems(cart),
|
|
2853
|
+
newLineItems: getLineItems$1(cart),
|
|
2763
2854
|
});
|
|
2764
2855
|
} catch (err) {
|
|
2765
2856
|
// HTTP 400 error from invalid coupon - get fresh cart state
|
|
@@ -2767,7 +2858,7 @@ async function onCouponCodeChanged(session, event) {
|
|
|
2767
2858
|
|
|
2768
2859
|
session.completeCouponCodeChange({
|
|
2769
2860
|
newTotal: getTotal(currentCart),
|
|
2770
|
-
newLineItems: getLineItems(currentCart),
|
|
2861
|
+
newLineItems: getLineItems$1(currentCart),
|
|
2771
2862
|
errors: [new ApplePayError('couponCodeInvalid', undefined, err.message)],
|
|
2772
2863
|
});
|
|
2773
2864
|
}
|
|
@@ -2821,7 +2912,7 @@ function getTotal(cart) {
|
|
|
2821
2912
|
* @param {Cart} cart
|
|
2822
2913
|
* @returns {ApplePayJS.ApplePayLineItem[]}
|
|
2823
2914
|
*/
|
|
2824
|
-
function getLineItems(cart) {
|
|
2915
|
+
function getLineItems$1(cart) {
|
|
2825
2916
|
const { sub_total, shipment_price, discount_total, tax_total } = cart;
|
|
2826
2917
|
|
|
2827
2918
|
/** @type {ApplePayJS.ApplePayLineItem[]} */
|
|
@@ -2867,7 +2958,7 @@ function getLineItems(cart) {
|
|
|
2867
2958
|
* @param {Cart} cart
|
|
2868
2959
|
* @returns {ApplePayJS.ApplePayShippingMethod[]}
|
|
2869
2960
|
*/
|
|
2870
|
-
function getShippingMethods(cart) {
|
|
2961
|
+
function getShippingMethods$1(cart) {
|
|
2871
2962
|
const { shipment_delivery, shipment_rating } = cart;
|
|
2872
2963
|
|
|
2873
2964
|
if (!shipment_delivery) {
|
|
@@ -3520,7 +3611,7 @@ class AuthorizeNetApplePayment extends Payment {
|
|
|
3520
3611
|
requiredShippingContactFields,
|
|
3521
3612
|
requiredBillingContactFields,
|
|
3522
3613
|
supportsCouponCode: true,
|
|
3523
|
-
lineItems: getLineItems(cart),
|
|
3614
|
+
lineItems: getLineItems$1(cart),
|
|
3524
3615
|
};
|
|
3525
3616
|
}
|
|
3526
3617
|
|
|
@@ -3780,6 +3871,298 @@ class QuickpayCardPayment extends Payment {
|
|
|
3780
3871
|
}
|
|
3781
3872
|
}
|
|
3782
3873
|
|
|
3874
|
+
class ConvesioCardPayment extends Payment {
|
|
3875
|
+
static convesioPay = null;
|
|
3876
|
+
static convesioPayComponent = null;
|
|
3877
|
+
|
|
3878
|
+
constructor(api, options, params, methods) {
|
|
3879
|
+
super(api, options, params, methods.card);
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3882
|
+
get scripts() {
|
|
3883
|
+
return ['convesiopay-js'];
|
|
3884
|
+
}
|
|
3885
|
+
|
|
3886
|
+
get convesioPay() {
|
|
3887
|
+
if (ConvesioCardPayment.convesioPay === null) {
|
|
3888
|
+
if (window.ConvesioPay) {
|
|
3889
|
+
this.convesioPay = window.ConvesioPay(this.method.public_key);
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3892
|
+
if (!ConvesioCardPayment.convesioPay) {
|
|
3893
|
+
throw new LibraryNotLoadedError('ConvesioPay');
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
return ConvesioCardPayment.convesioPay;
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3900
|
+
set convesioPay(convesioPay) {
|
|
3901
|
+
ConvesioCardPayment.convesioPay = convesioPay;
|
|
3902
|
+
}
|
|
3903
|
+
|
|
3904
|
+
get convesioPayComponent() {
|
|
3905
|
+
return ConvesioCardPayment.convesioPayComponent;
|
|
3906
|
+
}
|
|
3907
|
+
|
|
3908
|
+
set convesioPayComponent(convesioPayComponent) {
|
|
3909
|
+
ConvesioCardPayment.convesioPayComponent = convesioPayComponent;
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
async createElements(cart) {
|
|
3913
|
+
await this.loadScripts(this.scripts);
|
|
3914
|
+
|
|
3915
|
+
const component = this.convesioPay.component({
|
|
3916
|
+
environment: isLiveMode(this.method.mode) ? 'live' : 'test',
|
|
3917
|
+
integration: this.method.integration,
|
|
3918
|
+
customerEmail: cart.account?.email,
|
|
3919
|
+
express: false,
|
|
3920
|
+
disabledPaymentMethods: {
|
|
3921
|
+
btcpay: true,
|
|
3922
|
+
applePay: true,
|
|
3923
|
+
googlePay: true,
|
|
3924
|
+
},
|
|
3925
|
+
});
|
|
3926
|
+
|
|
3927
|
+
this.convesioPayComponent = component;
|
|
3928
|
+
|
|
3929
|
+
component.mount(`#${this.params.elementId || 'card-element'}`);
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
async tokenize() {
|
|
3933
|
+
if (!this.convesioPayComponent) {
|
|
3934
|
+
throw new Error('ConvesioPay element is not defined');
|
|
3935
|
+
}
|
|
3936
|
+
|
|
3937
|
+
const token = await this.convesioPayComponent.createToken();
|
|
3938
|
+
|
|
3939
|
+
await this.updateCart({
|
|
3940
|
+
billing: {
|
|
3941
|
+
method: 'card',
|
|
3942
|
+
account_card_id: null,
|
|
3943
|
+
card: {
|
|
3944
|
+
gateway: 'convesiopay',
|
|
3945
|
+
token,
|
|
3946
|
+
last4: '????',
|
|
3947
|
+
brand: null,
|
|
3948
|
+
exp_month: null,
|
|
3949
|
+
exp_year: null,
|
|
3950
|
+
},
|
|
3951
|
+
convesiopay: {
|
|
3952
|
+
return_url: this.params.returnUrl,
|
|
3953
|
+
},
|
|
3954
|
+
},
|
|
3955
|
+
});
|
|
3956
|
+
|
|
3957
|
+
return this.onSuccess();
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
/** @typedef {import('../../../types').Cart} Cart */
|
|
3962
|
+
|
|
3963
|
+
class ConvesioPayApplePayment extends Payment {
|
|
3964
|
+
static convesioPay = null;
|
|
3965
|
+
static convesioPayComponent = null;
|
|
3966
|
+
|
|
3967
|
+
constructor(api, options, params, methods) {
|
|
3968
|
+
if (!methods.card) {
|
|
3969
|
+
throw new PaymentMethodDisabledError('Credit cards');
|
|
3970
|
+
}
|
|
3971
|
+
|
|
3972
|
+
super(api, options, params, methods.apple);
|
|
3973
|
+
|
|
3974
|
+
this.convesiopay = methods.card;
|
|
3975
|
+
}
|
|
3976
|
+
|
|
3977
|
+
get scripts() {
|
|
3978
|
+
return ['convesiopay-js'];
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
get convesioPay() {
|
|
3982
|
+
if (ConvesioPayApplePayment.convesioPay === null) {
|
|
3983
|
+
if (window.ConvesioPay) {
|
|
3984
|
+
this.convesioPay = window.ConvesioPay(this.convesiopay.public_key);
|
|
3985
|
+
}
|
|
3986
|
+
|
|
3987
|
+
if (!ConvesioPayApplePayment.convesioPay) {
|
|
3988
|
+
throw new LibraryNotLoadedError('ConvesioPay');
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
|
|
3992
|
+
return ConvesioPayApplePayment.convesioPay;
|
|
3993
|
+
}
|
|
3994
|
+
|
|
3995
|
+
set convesioPay(convesioPay) {
|
|
3996
|
+
ConvesioPayApplePayment.convesioPay = convesioPay;
|
|
3997
|
+
}
|
|
3998
|
+
|
|
3999
|
+
get convesioPayComponent() {
|
|
4000
|
+
return ConvesioPayApplePayment.convesioPayComponent;
|
|
4001
|
+
}
|
|
4002
|
+
|
|
4003
|
+
set convesioPayComponent(convesioPayComponent) {
|
|
4004
|
+
ConvesioPayApplePayment.convesioPayComponent = convesioPayComponent;
|
|
4005
|
+
}
|
|
4006
|
+
|
|
4007
|
+
/**
|
|
4008
|
+
* Creates the Apple Pay button element
|
|
4009
|
+
*
|
|
4010
|
+
* @param {Cart} cart
|
|
4011
|
+
*/
|
|
4012
|
+
async createElements(cart) {
|
|
4013
|
+
const { elementId = 'applepay-button' } = this.params;
|
|
4014
|
+
|
|
4015
|
+
this.setElementContainer(elementId);
|
|
4016
|
+
await this.loadScripts(this.scripts);
|
|
4017
|
+
|
|
4018
|
+
this.convesioPayComponent = this.convesioPay.component({
|
|
4019
|
+
environment: isLiveMode(this.method.mode) ? 'live' : 'test',
|
|
4020
|
+
integration: this.convesiopay.integration,
|
|
4021
|
+
customerEmail: cart.account?.email,
|
|
4022
|
+
express: true,
|
|
4023
|
+
disabledPaymentMethods: {
|
|
4024
|
+
cards: true,
|
|
4025
|
+
btcpay: true,
|
|
4026
|
+
googlePay: true,
|
|
4027
|
+
},
|
|
4028
|
+
});
|
|
4029
|
+
|
|
4030
|
+
// When initiating a payment request,
|
|
4031
|
+
// we should not display the shipping cost, as it will be calculated later.
|
|
4032
|
+
cart = { ...cart };
|
|
4033
|
+
cart.shipment_price = 0;
|
|
4034
|
+
cart.shipping = {};
|
|
4035
|
+
|
|
4036
|
+
this.sessionOptions = {
|
|
4037
|
+
integration: this.convesiopay.integration,
|
|
4038
|
+
returnUrl: this.params.returnUrl,
|
|
4039
|
+
amount: amountInCents$1(cart.currency, cart.capture_total),
|
|
4040
|
+
currency: cart.currency,
|
|
4041
|
+
shippingMethods: getShippingMethods(cart),
|
|
4042
|
+
lineItems: getLineItems(cart),
|
|
4043
|
+
};
|
|
4044
|
+
}
|
|
4045
|
+
|
|
4046
|
+
/**
|
|
4047
|
+
* Mounts the Apple Pay button to the DOM
|
|
4048
|
+
*/
|
|
4049
|
+
mountElements() {
|
|
4050
|
+
const { classes = {} } = this.params;
|
|
4051
|
+
const container = this.elementContainer;
|
|
4052
|
+
|
|
4053
|
+
this.convesioPayComponent.mount(`#${container.id}`);
|
|
4054
|
+
|
|
4055
|
+
if (classes.base) {
|
|
4056
|
+
container.classList.add(classes.base);
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
this.convesioPayComponent.createApplePaySession({
|
|
4060
|
+
...this.sessionOptions,
|
|
4061
|
+
onShippingAddressChange: onShippingAddressChange.bind(this),
|
|
4062
|
+
onShippingMethodChange: onShippingMethodChange.bind(this),
|
|
4063
|
+
onPaymentMethodChange: async (_paymentMethod) => {
|
|
4064
|
+
const currentCart = await this.getCart();
|
|
4065
|
+
|
|
4066
|
+
return {
|
|
4067
|
+
newTotal: getTotal(currentCart),
|
|
4068
|
+
newLineItems: getLineItems$1(currentCart),
|
|
4069
|
+
};
|
|
4070
|
+
},
|
|
4071
|
+
});
|
|
4072
|
+
|
|
4073
|
+
this.convesioPayComponent.on('change', async (event) => {
|
|
4074
|
+
if (event.type === 'applepay') {
|
|
4075
|
+
if (event.isSuccessful) {
|
|
4076
|
+
const { token, shippingContact, billingContact } = event;
|
|
4077
|
+
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
4078
|
+
|
|
4079
|
+
await this.updateCart({
|
|
4080
|
+
account: {
|
|
4081
|
+
email: shippingContact.emailAddress,
|
|
4082
|
+
},
|
|
4083
|
+
billing: {
|
|
4084
|
+
method: 'apple',
|
|
4085
|
+
account_card_id: null,
|
|
4086
|
+
card: null,
|
|
4087
|
+
apple: {
|
|
4088
|
+
token,
|
|
4089
|
+
gateway: 'convesiopay',
|
|
4090
|
+
},
|
|
4091
|
+
...convertToSwellAddress$1(billingContact),
|
|
4092
|
+
},
|
|
4093
|
+
...(requireShipping && {
|
|
4094
|
+
shipping: convertToSwellAddress$1(shippingContact),
|
|
4095
|
+
}),
|
|
4096
|
+
});
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
});
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
|
|
4103
|
+
/**
|
|
4104
|
+
* @param {Cart} cart
|
|
4105
|
+
* @returns {object[]}
|
|
4106
|
+
*/
|
|
4107
|
+
function getLineItems(cart) {
|
|
4108
|
+
const { sub_total, shipment_price, discount_total, tax_total, currency } =
|
|
4109
|
+
cart;
|
|
4110
|
+
|
|
4111
|
+
/** @type {ApplePayJS.ApplePayLineItem[]} */
|
|
4112
|
+
const lineItems = [
|
|
4113
|
+
{
|
|
4114
|
+
label: 'Subtotal',
|
|
4115
|
+
amount: amountInCents$1(currency, sub_total || 0),
|
|
4116
|
+
},
|
|
4117
|
+
];
|
|
4118
|
+
|
|
4119
|
+
if (shipment_price) {
|
|
4120
|
+
lineItems.push({
|
|
4121
|
+
label: 'Shipping',
|
|
4122
|
+
amount: amountInCents$1(currency, shipment_price),
|
|
4123
|
+
});
|
|
4124
|
+
}
|
|
4125
|
+
|
|
4126
|
+
if (discount_total) {
|
|
4127
|
+
lineItems.push({
|
|
4128
|
+
label: 'Discount',
|
|
4129
|
+
amount: amountInCents$1(currency, -discount_total),
|
|
4130
|
+
});
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
if (tax_total) {
|
|
4134
|
+
lineItems.push({
|
|
4135
|
+
label: 'Taxes',
|
|
4136
|
+
amount: amountInCents$1(currency, tax_total),
|
|
4137
|
+
});
|
|
4138
|
+
}
|
|
4139
|
+
|
|
4140
|
+
return lineItems;
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
/**
|
|
4144
|
+
* @param {Cart} cart
|
|
4145
|
+
* @returns {object[]}
|
|
4146
|
+
*/
|
|
4147
|
+
function getShippingMethods(cart) {
|
|
4148
|
+
const { shipment_delivery, shipment_rating, currency } = cart;
|
|
4149
|
+
|
|
4150
|
+
if (!shipment_delivery) {
|
|
4151
|
+
return [];
|
|
4152
|
+
}
|
|
4153
|
+
|
|
4154
|
+
if (!shipment_rating?.services?.length) {
|
|
4155
|
+
return [];
|
|
4156
|
+
}
|
|
4157
|
+
|
|
4158
|
+
return shipment_rating.services.map((service, index) => ({
|
|
4159
|
+
label: service.name || `Shipping ${index + 1}`,
|
|
4160
|
+
detail: service.description || '',
|
|
4161
|
+
amount: amountInCents$1(currency, service.price || 0),
|
|
4162
|
+
identifier: service.id,
|
|
4163
|
+
}));
|
|
4164
|
+
}
|
|
4165
|
+
|
|
3783
4166
|
function createPaysafecardPaymentData(cart) {
|
|
3784
4167
|
const returnUrl = window.location.origin + window.location.pathname;
|
|
3785
4168
|
const url = `${returnUrl}?gateway=paysafecard`;
|
|
@@ -5156,6 +5539,8 @@ class PaymentController {
|
|
|
5156
5539
|
return StripeCardPayment;
|
|
5157
5540
|
case 'quickpay':
|
|
5158
5541
|
return QuickpayCardPayment;
|
|
5542
|
+
case 'convesiopay':
|
|
5543
|
+
return ConvesioCardPayment;
|
|
5159
5544
|
default:
|
|
5160
5545
|
return null;
|
|
5161
5546
|
}
|
|
@@ -5227,6 +5612,8 @@ class PaymentController {
|
|
|
5227
5612
|
return BraintreeApplePayment;
|
|
5228
5613
|
case 'authorizenet':
|
|
5229
5614
|
return AuthorizeNetApplePayment;
|
|
5615
|
+
case 'convesiopay':
|
|
5616
|
+
return ConvesioPayApplePayment;
|
|
5230
5617
|
default:
|
|
5231
5618
|
return null;
|
|
5232
5619
|
}
|