swell-js 5.7.0 → 5.8.0
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 +397 -239
- package/dist/swell.cjs +398 -240
- package/dist/swell.cjs.map +1 -1
- package/dist/swell.umd.min.js +398 -240
- package/dist/swell.umd.min.js.map +1 -1
- package/package.json +2 -1
package/dist/swell.umd.min.js
CHANGED
|
@@ -12845,13 +12845,13 @@
|
|
|
12845
12845
|
tax_included_total,
|
|
12846
12846
|
settings,
|
|
12847
12847
|
} = cart;
|
|
12848
|
-
const { price: shippingPrice, service_name } = shipping || {};
|
|
12848
|
+
const { price: shippingPrice, service, service_name } = shipping || {};
|
|
12849
12849
|
const { country, name } = settings || {};
|
|
12850
12850
|
const { require: { shipping: requireShipping } = {} } = params;
|
|
12851
12851
|
|
|
12852
12852
|
const stripeCurrency = currency.toLowerCase();
|
|
12853
12853
|
const displayItems = items.map((item) => ({
|
|
12854
|
-
label:
|
|
12854
|
+
label: item.product_name || item.product?.name || 'Unknown product',
|
|
12855
12855
|
amount: stripeAmountByCurrency(
|
|
12856
12856
|
currency,
|
|
12857
12857
|
item.price_total - item.discount_total,
|
|
@@ -12873,14 +12873,21 @@
|
|
|
12873
12873
|
}
|
|
12874
12874
|
|
|
12875
12875
|
let shippingOptions;
|
|
12876
|
-
const services =
|
|
12877
|
-
if (Array.isArray(services) && services.length > 0) {
|
|
12876
|
+
const services = shipment_rating?.services;
|
|
12877
|
+
if (requireShipping && Array.isArray(services) && services.length > 0) {
|
|
12878
12878
|
shippingOptions = services.map((service) => ({
|
|
12879
12879
|
id: service.id,
|
|
12880
12880
|
label: service.name,
|
|
12881
12881
|
detail: service.description,
|
|
12882
12882
|
amount: stripeAmountByCurrency(currency, service.price),
|
|
12883
12883
|
}));
|
|
12884
|
+
|
|
12885
|
+
const index = shippingOptions.findIndex((item) => item.id === service);
|
|
12886
|
+
|
|
12887
|
+
if (index > 0) {
|
|
12888
|
+
// Move selected shipping option to the top
|
|
12889
|
+
shippingOptions.unshift(...shippingOptions.splice(index, 1));
|
|
12890
|
+
}
|
|
12884
12891
|
}
|
|
12885
12892
|
|
|
12886
12893
|
return {
|
|
@@ -12892,7 +12899,7 @@
|
|
|
12892
12899
|
pending: true,
|
|
12893
12900
|
},
|
|
12894
12901
|
displayItems,
|
|
12895
|
-
...(
|
|
12902
|
+
...(shippingOptions && { shippingOptions }),
|
|
12896
12903
|
};
|
|
12897
12904
|
}
|
|
12898
12905
|
|
|
@@ -13440,6 +13447,7 @@
|
|
|
13440
13447
|
|
|
13441
13448
|
/** @typedef {import('@stripe/stripe-js').Stripe} Stripe */
|
|
13442
13449
|
/** @typedef {import('@stripe/stripe-js').PaymentRequestPaymentMethodEvent} PaymentRequestPaymentMethodEvent */
|
|
13450
|
+
/** @typedef {import('../../../types').Cart} Cart */
|
|
13443
13451
|
|
|
13444
13452
|
class StripeGooglePayment extends Payment {
|
|
13445
13453
|
constructor(api, options, params, methods) {
|
|
@@ -13507,6 +13515,7 @@
|
|
|
13507
13515
|
this.element.mount(`#${this.elementContainer.id}`);
|
|
13508
13516
|
}
|
|
13509
13517
|
|
|
13518
|
+
/** @param {Cart} cart */
|
|
13510
13519
|
_createPaymentRequest(cart) {
|
|
13511
13520
|
const { require: { name, email, shipping, phone } = {} } = this.params;
|
|
13512
13521
|
|
|
@@ -13519,15 +13528,10 @@
|
|
|
13519
13528
|
...getPaymentRequestData(cart, this.params),
|
|
13520
13529
|
});
|
|
13521
13530
|
|
|
13522
|
-
paymentRequest
|
|
13523
|
-
'shippingaddresschange',
|
|
13524
|
-
this.
|
|
13525
|
-
|
|
13526
|
-
paymentRequest.on(
|
|
13527
|
-
'shippingoptionchange',
|
|
13528
|
-
this._onShippingOptionChange.bind(this),
|
|
13529
|
-
);
|
|
13530
|
-
paymentRequest.on('paymentmethod', this._onPaymentMethod.bind(this));
|
|
13531
|
+
paymentRequest
|
|
13532
|
+
.on('shippingaddresschange', this._onShippingAddressChange.bind(this))
|
|
13533
|
+
.on('shippingoptionchange', this._onShippingOptionChange.bind(this))
|
|
13534
|
+
.on('paymentmethod', this._onPaymentMethod.bind(this));
|
|
13531
13535
|
|
|
13532
13536
|
return paymentRequest;
|
|
13533
13537
|
}
|
|
@@ -13535,9 +13539,9 @@
|
|
|
13535
13539
|
/** @param {import('@stripe/stripe-js').PaymentRequestShippingAddressEvent} event */
|
|
13536
13540
|
async _onShippingAddressChange(event) {
|
|
13537
13541
|
const { shippingAddress, updateWith } = event;
|
|
13538
|
-
|
|
13542
|
+
|
|
13539
13543
|
const cart = await this.updateCart({
|
|
13540
|
-
shipping:
|
|
13544
|
+
shipping: this._mapShippingAddress(shippingAddress),
|
|
13541
13545
|
shipment_rating: null,
|
|
13542
13546
|
});
|
|
13543
13547
|
|
|
@@ -13577,16 +13581,15 @@
|
|
|
13577
13581
|
shippingOption,
|
|
13578
13582
|
complete,
|
|
13579
13583
|
} = event;
|
|
13580
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
13581
13584
|
|
|
13582
13585
|
await this.updateCart({
|
|
13583
13586
|
account: {
|
|
13584
|
-
email: payerEmail,
|
|
13587
|
+
email: payerEmail || billing_details?.email,
|
|
13585
13588
|
},
|
|
13586
|
-
...(
|
|
13589
|
+
...(shippingAddress && {
|
|
13587
13590
|
shipping: {
|
|
13588
13591
|
...this._mapShippingAddress(shippingAddress),
|
|
13589
|
-
service: shippingOption
|
|
13592
|
+
service: shippingOption?.id || undefined,
|
|
13590
13593
|
},
|
|
13591
13594
|
}),
|
|
13592
13595
|
billing: {
|
|
@@ -13600,9 +13603,9 @@
|
|
|
13600
13603
|
exp_month: card.exp_month,
|
|
13601
13604
|
exp_year: card.exp_year,
|
|
13602
13605
|
last4: card.last4,
|
|
13603
|
-
address_check: card.checks
|
|
13604
|
-
zip_check: card.checks
|
|
13605
|
-
cvc_check: card.checks
|
|
13606
|
+
address_check: card.checks?.address_line1_check,
|
|
13607
|
+
zip_check: card.checks?.address_postal_code_check,
|
|
13608
|
+
cvc_check: card.checks?.cvc_check,
|
|
13606
13609
|
},
|
|
13607
13610
|
},
|
|
13608
13611
|
});
|
|
@@ -13650,8 +13653,8 @@
|
|
|
13650
13653
|
_mapShippingAddress(address = {}) {
|
|
13651
13654
|
return {
|
|
13652
13655
|
name: address.recipient,
|
|
13653
|
-
address1: address.addressLine[0],
|
|
13654
|
-
address2: address.addressLine[1],
|
|
13656
|
+
address1: address.addressLine?.[0],
|
|
13657
|
+
address2: address.addressLine?.[1],
|
|
13655
13658
|
city: address.city,
|
|
13656
13659
|
state: address.region,
|
|
13657
13660
|
zip: address.postalCode,
|
|
@@ -13665,18 +13668,19 @@
|
|
|
13665
13668
|
return {
|
|
13666
13669
|
name: address.name,
|
|
13667
13670
|
phone: address.phone,
|
|
13668
|
-
address1: address.address
|
|
13669
|
-
address2: address.address
|
|
13670
|
-
city: address.address
|
|
13671
|
-
state: address.address
|
|
13672
|
-
zip: address.address
|
|
13673
|
-
country: address.address
|
|
13671
|
+
address1: address.address?.line1,
|
|
13672
|
+
address2: address.address?.line2,
|
|
13673
|
+
city: address.address?.city,
|
|
13674
|
+
state: address.address?.state,
|
|
13675
|
+
zip: address.address?.postal_code,
|
|
13676
|
+
country: address.address?.country,
|
|
13674
13677
|
};
|
|
13675
13678
|
}
|
|
13676
13679
|
}
|
|
13677
13680
|
|
|
13678
13681
|
/** @typedef {import('@stripe/stripe-js').Stripe} Stripe */
|
|
13679
13682
|
/** @typedef {import('@stripe/stripe-js').PaymentRequestPaymentMethodEvent} PaymentRequestPaymentMethodEvent */
|
|
13683
|
+
/** @typedef {import('../../../types').Cart} Cart */
|
|
13680
13684
|
|
|
13681
13685
|
class StripeApplePayment extends Payment {
|
|
13682
13686
|
constructor(api, options, params, methods) {
|
|
@@ -13730,7 +13734,7 @@
|
|
|
13730
13734
|
const paymentRequest = this._createPaymentRequest(cart);
|
|
13731
13735
|
const canMakePayment = await paymentRequest.canMakePayment();
|
|
13732
13736
|
|
|
13733
|
-
if (!canMakePayment
|
|
13737
|
+
if (!canMakePayment?.applePay) {
|
|
13734
13738
|
throw new Error(
|
|
13735
13739
|
'This device is not capable of making Apple Pay payments',
|
|
13736
13740
|
);
|
|
@@ -13767,6 +13771,7 @@
|
|
|
13767
13771
|
}
|
|
13768
13772
|
}
|
|
13769
13773
|
|
|
13774
|
+
/** @param {Cart} cart */
|
|
13770
13775
|
_createPaymentRequest(cart) {
|
|
13771
13776
|
const { require: { name, email, shipping, phone } = {} } = this.params;
|
|
13772
13777
|
|
|
@@ -13779,15 +13784,10 @@
|
|
|
13779
13784
|
...getPaymentRequestData(cart, this.params),
|
|
13780
13785
|
});
|
|
13781
13786
|
|
|
13782
|
-
paymentRequest
|
|
13783
|
-
'shippingaddresschange',
|
|
13784
|
-
this.
|
|
13785
|
-
|
|
13786
|
-
paymentRequest.on(
|
|
13787
|
-
'shippingoptionchange',
|
|
13788
|
-
this._onShippingOptionChange.bind(this),
|
|
13789
|
-
);
|
|
13790
|
-
paymentRequest.on('paymentmethod', this._onPaymentMethod.bind(this));
|
|
13787
|
+
paymentRequest
|
|
13788
|
+
.on('shippingaddresschange', this._onShippingAddressChange.bind(this))
|
|
13789
|
+
.on('shippingoptionchange', this._onShippingOptionChange.bind(this))
|
|
13790
|
+
.on('paymentmethod', this._onPaymentMethod.bind(this));
|
|
13791
13791
|
|
|
13792
13792
|
return paymentRequest;
|
|
13793
13793
|
}
|
|
@@ -13795,9 +13795,9 @@
|
|
|
13795
13795
|
/** @param {import('@stripe/stripe-js').PaymentRequestShippingAddressEvent} event */
|
|
13796
13796
|
async _onShippingAddressChange(event) {
|
|
13797
13797
|
const { shippingAddress, updateWith } = event;
|
|
13798
|
-
|
|
13798
|
+
|
|
13799
13799
|
const cart = await this.updateCart({
|
|
13800
|
-
shipping:
|
|
13800
|
+
shipping: this._mapShippingAddress(shippingAddress),
|
|
13801
13801
|
shipment_rating: null,
|
|
13802
13802
|
});
|
|
13803
13803
|
|
|
@@ -13837,16 +13837,15 @@
|
|
|
13837
13837
|
shippingOption,
|
|
13838
13838
|
complete,
|
|
13839
13839
|
} = event;
|
|
13840
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
13841
13840
|
|
|
13842
13841
|
await this.updateCart({
|
|
13843
13842
|
account: {
|
|
13844
|
-
email: payerEmail,
|
|
13843
|
+
email: payerEmail || billing_details?.email,
|
|
13845
13844
|
},
|
|
13846
|
-
...(
|
|
13845
|
+
...(shippingAddress && {
|
|
13847
13846
|
shipping: {
|
|
13848
13847
|
...this._mapShippingAddress(shippingAddress),
|
|
13849
|
-
service: shippingOption
|
|
13848
|
+
service: shippingOption?.id || undefined,
|
|
13850
13849
|
},
|
|
13851
13850
|
}),
|
|
13852
13851
|
billing: {
|
|
@@ -13860,9 +13859,9 @@
|
|
|
13860
13859
|
exp_month: card.exp_month,
|
|
13861
13860
|
exp_year: card.exp_year,
|
|
13862
13861
|
last4: card.last4,
|
|
13863
|
-
address_check: card.checks
|
|
13864
|
-
zip_check: card.checks
|
|
13865
|
-
cvc_check: card.checks
|
|
13862
|
+
address_check: card.checks?.address_line1_check,
|
|
13863
|
+
zip_check: card.checks?.address_postal_code_check,
|
|
13864
|
+
cvc_check: card.checks?.cvc_check,
|
|
13866
13865
|
},
|
|
13867
13866
|
},
|
|
13868
13867
|
});
|
|
@@ -13876,8 +13875,8 @@
|
|
|
13876
13875
|
_mapShippingAddress(address = {}) {
|
|
13877
13876
|
return {
|
|
13878
13877
|
name: address.recipient,
|
|
13879
|
-
address1: address.addressLine[0],
|
|
13880
|
-
address2: address.addressLine[1],
|
|
13878
|
+
address1: address.addressLine?.[0],
|
|
13879
|
+
address2: address.addressLine?.[1],
|
|
13881
13880
|
city: address.city,
|
|
13882
13881
|
state: address.region,
|
|
13883
13882
|
zip: address.postalCode,
|
|
@@ -13891,12 +13890,12 @@
|
|
|
13891
13890
|
return {
|
|
13892
13891
|
name: address.name,
|
|
13893
13892
|
phone: address.phone,
|
|
13894
|
-
address1: address.address
|
|
13895
|
-
address2: address.address
|
|
13896
|
-
city: address.address
|
|
13897
|
-
state: address.address
|
|
13898
|
-
zip: address.address
|
|
13899
|
-
country: address.address
|
|
13893
|
+
address1: address.address?.line1,
|
|
13894
|
+
address2: address.address?.line2,
|
|
13895
|
+
city: address.address?.city,
|
|
13896
|
+
state: address.address?.state,
|
|
13897
|
+
zip: address.address?.postal_code,
|
|
13898
|
+
country: address.address?.country,
|
|
13900
13899
|
};
|
|
13901
13900
|
}
|
|
13902
13901
|
}
|
|
@@ -14164,6 +14163,44 @@
|
|
|
14164
14163
|
return discount.id;
|
|
14165
14164
|
}
|
|
14166
14165
|
|
|
14166
|
+
/** @type {Map<string, number>} */
|
|
14167
|
+
const CURRENCIES_CENTS = new Map();
|
|
14168
|
+
|
|
14169
|
+
/**
|
|
14170
|
+
* @param {string} currency
|
|
14171
|
+
* @returns {number}
|
|
14172
|
+
*/
|
|
14173
|
+
function getCurrencyCents(currency) {
|
|
14174
|
+
let cents = CURRENCIES_CENTS.get(currency);
|
|
14175
|
+
|
|
14176
|
+
if (cents !== undefined) {
|
|
14177
|
+
return cents;
|
|
14178
|
+
}
|
|
14179
|
+
|
|
14180
|
+
const formatter = new Intl.NumberFormat('en-US', {
|
|
14181
|
+
style: 'currency',
|
|
14182
|
+
currency,
|
|
14183
|
+
});
|
|
14184
|
+
|
|
14185
|
+
const options = formatter.resolvedOptions();
|
|
14186
|
+
const decimals = options.maximumFractionDigits ?? 2;
|
|
14187
|
+
|
|
14188
|
+
cents = 10 ** decimals;
|
|
14189
|
+
|
|
14190
|
+
CURRENCIES_CENTS.set(currency, cents);
|
|
14191
|
+
|
|
14192
|
+
return cents;
|
|
14193
|
+
}
|
|
14194
|
+
|
|
14195
|
+
/**
|
|
14196
|
+
* @param {string} currency
|
|
14197
|
+
* @param {number} amount
|
|
14198
|
+
* @returns {number}
|
|
14199
|
+
*/
|
|
14200
|
+
function amountInCents(currency, amount) {
|
|
14201
|
+
return Math.round(amount * getCurrencyCents(currency));
|
|
14202
|
+
}
|
|
14203
|
+
|
|
14167
14204
|
/** @typedef {import('./payment').default} Payment */
|
|
14168
14205
|
/** @typedef {import('../../types').Cart} Cart */
|
|
14169
14206
|
/** @typedef {import('../../types').Address} Address */
|
|
@@ -14251,7 +14288,7 @@
|
|
|
14251
14288
|
this,
|
|
14252
14289
|
cart,
|
|
14253
14290
|
),
|
|
14254
|
-
newTransactionInfo: getTransactionInfo(cart),
|
|
14291
|
+
newTransactionInfo: getTransactionInfo.call(this, cart),
|
|
14255
14292
|
};
|
|
14256
14293
|
}
|
|
14257
14294
|
|
|
@@ -14264,7 +14301,7 @@
|
|
|
14264
14301
|
},
|
|
14265
14302
|
});
|
|
14266
14303
|
|
|
14267
|
-
return { newTransactionInfo: getTransactionInfo(cart) };
|
|
14304
|
+
return { newTransactionInfo: getTransactionInfo.call(this, cart) };
|
|
14268
14305
|
} catch (err) {
|
|
14269
14306
|
return createError(
|
|
14270
14307
|
intermediatePaymentData.callbackTrigger,
|
|
@@ -14286,7 +14323,7 @@
|
|
|
14286
14323
|
|
|
14287
14324
|
return {
|
|
14288
14325
|
newOfferInfo: getOfferInfo(cart),
|
|
14289
|
-
newTransactionInfo: getTransactionInfo(cart),
|
|
14326
|
+
newTransactionInfo: getTransactionInfo.call(this, cart),
|
|
14290
14327
|
};
|
|
14291
14328
|
} catch (err) {
|
|
14292
14329
|
return createError(
|
|
@@ -14386,12 +14423,13 @@
|
|
|
14386
14423
|
|
|
14387
14424
|
/**
|
|
14388
14425
|
* Converts cart data to Google Pay transaction information.
|
|
14426
|
+
* @this {Payment}
|
|
14389
14427
|
* @param {Cart} cart - The current cart data
|
|
14390
14428
|
* @returns {google.payments.api.TransactionInfo} Transaction info for Google Pay
|
|
14391
14429
|
*/
|
|
14392
14430
|
function getTransactionInfo(cart) {
|
|
14393
|
-
const {
|
|
14394
|
-
|
|
14431
|
+
const { require: { shipping: shipmentDelivery = false } = {} } = this.params;
|
|
14432
|
+
const { settings, capture_total, currency, shipping } = cart;
|
|
14395
14433
|
|
|
14396
14434
|
return {
|
|
14397
14435
|
countryCode: settings?.country || 'US',
|
|
@@ -14399,7 +14437,7 @@
|
|
|
14399
14437
|
totalPrice: String(capture_total ?? 0),
|
|
14400
14438
|
// Set status to FINAL if shipping has been selected, otherwise ESTIMATED
|
|
14401
14439
|
totalPriceStatus:
|
|
14402
|
-
!
|
|
14440
|
+
!shipmentDelivery || shipping?.service ? 'FINAL' : 'ESTIMATED',
|
|
14403
14441
|
totalPriceLabel: 'Total',
|
|
14404
14442
|
displayItems: getDisplayItems(cart),
|
|
14405
14443
|
};
|
|
@@ -14412,12 +14450,14 @@
|
|
|
14412
14450
|
* @returns {google.payments.api.ShippingOptionParameters | undefined} Shipping options for Google Pay
|
|
14413
14451
|
*/
|
|
14414
14452
|
function getShippingOptionParameters(cart) {
|
|
14415
|
-
const {
|
|
14453
|
+
const { require: { shipping: shipmentDelivery = false } = {} } = this.params;
|
|
14416
14454
|
|
|
14417
|
-
if (!
|
|
14455
|
+
if (!shipmentDelivery) {
|
|
14418
14456
|
return undefined;
|
|
14419
14457
|
}
|
|
14420
14458
|
|
|
14459
|
+
const { shipment_rating, shipping } = cart;
|
|
14460
|
+
|
|
14421
14461
|
if (!shipment_rating?.services?.length) {
|
|
14422
14462
|
// Return placeholder when no shipping services are available
|
|
14423
14463
|
return {
|
|
@@ -14498,20 +14538,11 @@
|
|
|
14498
14538
|
};
|
|
14499
14539
|
}
|
|
14500
14540
|
|
|
14541
|
+
/** @typedef {import('../../../types').Cart} Cart */
|
|
14542
|
+
|
|
14501
14543
|
const API_VERSION$1 = 2;
|
|
14502
14544
|
const API_MINOR_VERSION$1 = 0;
|
|
14503
14545
|
|
|
14504
|
-
const ALLOWED_CARD_AUTH_METHODS = ['PAN_ONLY', 'CRYPTOGRAM_3DS'];
|
|
14505
|
-
|
|
14506
|
-
const ALLOWED_CARD_NETWORKS = [
|
|
14507
|
-
'AMEX',
|
|
14508
|
-
'DISCOVER',
|
|
14509
|
-
'INTERAC',
|
|
14510
|
-
'JCB',
|
|
14511
|
-
'MASTERCARD',
|
|
14512
|
-
'VISA',
|
|
14513
|
-
];
|
|
14514
|
-
|
|
14515
14546
|
class BraintreeGooglePayment extends Payment {
|
|
14516
14547
|
constructor(api, options, params, methods) {
|
|
14517
14548
|
if (!methods.card) {
|
|
@@ -14547,6 +14578,9 @@
|
|
|
14547
14578
|
if (this.google) {
|
|
14548
14579
|
this.googleClient = new this.google.payments.api.PaymentsClient({
|
|
14549
14580
|
environment: isLiveMode(this.method.mode) ? 'PRODUCTION' : 'TEST',
|
|
14581
|
+
paymentDataCallbacks: {
|
|
14582
|
+
onPaymentDataChanged: onPaymentDataChanged.bind(this),
|
|
14583
|
+
},
|
|
14550
14584
|
});
|
|
14551
14585
|
}
|
|
14552
14586
|
|
|
@@ -14562,31 +14596,12 @@
|
|
|
14562
14596
|
BraintreeGooglePayment.googleClient = googleClient;
|
|
14563
14597
|
}
|
|
14564
14598
|
|
|
14565
|
-
/** @
|
|
14566
|
-
get cardPaymentMethod() {
|
|
14567
|
-
return {
|
|
14568
|
-
type: 'CARD',
|
|
14569
|
-
parameters: {
|
|
14570
|
-
allowedAuthMethods: ALLOWED_CARD_AUTH_METHODS,
|
|
14571
|
-
allowedCardNetworks: ALLOWED_CARD_NETWORKS,
|
|
14572
|
-
billingAddressRequired: true,
|
|
14573
|
-
billingAddressParameters: {
|
|
14574
|
-
format: 'FULL',
|
|
14575
|
-
phoneNumberRequired: true,
|
|
14576
|
-
},
|
|
14577
|
-
},
|
|
14578
|
-
};
|
|
14579
|
-
}
|
|
14580
|
-
|
|
14581
|
-
/** @returns {google.payments.api.PaymentMethodSpecification[]} */
|
|
14582
|
-
get allowedPaymentMethods() {
|
|
14583
|
-
return [this.cardPaymentMethod];
|
|
14584
|
-
}
|
|
14585
|
-
|
|
14599
|
+
/** @param {Cart} cart */
|
|
14586
14600
|
async createElements(cart) {
|
|
14587
14601
|
const {
|
|
14588
14602
|
elementId = 'googlepay-button',
|
|
14589
14603
|
locale = 'en',
|
|
14604
|
+
require: { phone } = {},
|
|
14590
14605
|
style: { color = 'black', type = 'plain', sizeMode = 'fill' } = {},
|
|
14591
14606
|
} = this.params;
|
|
14592
14607
|
|
|
@@ -14597,10 +14612,35 @@
|
|
|
14597
14612
|
this.setElementContainer(elementId);
|
|
14598
14613
|
await this.loadScripts(this.scripts);
|
|
14599
14614
|
|
|
14615
|
+
const braintreeClient = await this._createBraintreeClient();
|
|
14616
|
+
|
|
14617
|
+
const googlePayment = await this.braintree.googlePayment.create({
|
|
14618
|
+
client: braintreeClient,
|
|
14619
|
+
googleMerchantId: this.method.merchant_id,
|
|
14620
|
+
googlePayVersion: API_VERSION$1,
|
|
14621
|
+
});
|
|
14622
|
+
|
|
14623
|
+
const paymentDataRequest = googlePayment.createPaymentDataRequest(
|
|
14624
|
+
this._createPaymentRequestData(cart),
|
|
14625
|
+
);
|
|
14626
|
+
|
|
14627
|
+
const cardPaymentMethod = paymentDataRequest.allowedPaymentMethods.find(
|
|
14628
|
+
(method) => method.type === 'CARD',
|
|
14629
|
+
);
|
|
14630
|
+
|
|
14631
|
+
if (cardPaymentMethod !== undefined) {
|
|
14632
|
+
cardPaymentMethod.parameters.billingAddressRequired = true;
|
|
14633
|
+
|
|
14634
|
+
cardPaymentMethod.parameters.billingAddressParameters = {
|
|
14635
|
+
format: 'FULL',
|
|
14636
|
+
phoneNumberRequired: Boolean(phone),
|
|
14637
|
+
};
|
|
14638
|
+
}
|
|
14639
|
+
|
|
14600
14640
|
const isReadyToPay = await this.googleClient.isReadyToPay({
|
|
14601
14641
|
apiVersion: API_VERSION$1,
|
|
14602
14642
|
apiVersionMinor: API_MINOR_VERSION$1,
|
|
14603
|
-
allowedPaymentMethods:
|
|
14643
|
+
allowedPaymentMethods: paymentDataRequest.allowedPaymentMethods,
|
|
14604
14644
|
existingPaymentMethodRequired: true,
|
|
14605
14645
|
});
|
|
14606
14646
|
|
|
@@ -14610,16 +14650,6 @@
|
|
|
14610
14650
|
);
|
|
14611
14651
|
}
|
|
14612
14652
|
|
|
14613
|
-
const braintreeClient = await this._createBraintreeClient();
|
|
14614
|
-
const googlePayment = await this.braintree.googlePayment.create({
|
|
14615
|
-
client: braintreeClient,
|
|
14616
|
-
googleMerchantId: this.method.merchant_id,
|
|
14617
|
-
googlePayVersion: API_VERSION$1,
|
|
14618
|
-
});
|
|
14619
|
-
const paymentRequestData = this._createPaymentRequestData(cart);
|
|
14620
|
-
const paymentDataRequest =
|
|
14621
|
-
googlePayment.createPaymentDataRequest(paymentRequestData);
|
|
14622
|
-
|
|
14623
14653
|
this.element = this.googleClient.createButton({
|
|
14624
14654
|
buttonColor: color,
|
|
14625
14655
|
buttonType: type,
|
|
@@ -14646,6 +14676,7 @@
|
|
|
14646
14676
|
}
|
|
14647
14677
|
}
|
|
14648
14678
|
|
|
14679
|
+
/** @returns {Promise<braintree.Client>} */
|
|
14649
14680
|
async _createBraintreeClient() {
|
|
14650
14681
|
const authorization = await this.authorizeGateway({
|
|
14651
14682
|
gateway: 'braintree',
|
|
@@ -14660,39 +14691,51 @@
|
|
|
14660
14691
|
});
|
|
14661
14692
|
}
|
|
14662
14693
|
|
|
14663
|
-
/**
|
|
14694
|
+
/**
|
|
14695
|
+
* @param {Cart} cart
|
|
14696
|
+
* @returns {google.payments.api.PaymentDataRequest}
|
|
14697
|
+
*/
|
|
14664
14698
|
_createPaymentRequestData(cart) {
|
|
14665
14699
|
const {
|
|
14666
|
-
settings: { name
|
|
14667
|
-
capture_total,
|
|
14668
|
-
currency,
|
|
14700
|
+
settings: { name },
|
|
14669
14701
|
} = cart;
|
|
14702
|
+
|
|
14670
14703
|
const { require: { email, shipping, phone } = {} } = this.params;
|
|
14671
14704
|
|
|
14705
|
+
/** @type {google.payments.api.CallbackIntent[]} */
|
|
14706
|
+
const callbackIntents = ['OFFER'];
|
|
14707
|
+
|
|
14708
|
+
if (shipping) {
|
|
14709
|
+
callbackIntents.push('SHIPPING_ADDRESS', 'SHIPPING_OPTION');
|
|
14710
|
+
}
|
|
14711
|
+
|
|
14672
14712
|
return {
|
|
14673
14713
|
apiVersion: API_VERSION$1,
|
|
14674
14714
|
apiVersionMinor: API_MINOR_VERSION$1,
|
|
14675
|
-
transactionInfo:
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
allowedPaymentMethods: this.allowedPaymentMethods,
|
|
14715
|
+
transactionInfo: getTransactionInfo.call(this, cart),
|
|
14716
|
+
/**
|
|
14717
|
+
* @see {@link https://developer.paypal.com/braintree/docs/guides/google-pay/client-side/javascript/v3/#requesting-a-payment}
|
|
14718
|
+
*
|
|
14719
|
+
* Braintree automatically populates the `allowedPaymentMethods` property.
|
|
14720
|
+
*/
|
|
14682
14721
|
emailRequired: Boolean(email),
|
|
14683
14722
|
shippingAddressRequired: Boolean(shipping),
|
|
14684
14723
|
shippingAddressParameters: {
|
|
14685
14724
|
phoneNumberRequired: Boolean(phone),
|
|
14686
14725
|
},
|
|
14726
|
+
shippingOptionRequired: Boolean(shipping),
|
|
14727
|
+
shippingOptionParameters: getShippingOptionParameters.call(this, cart),
|
|
14728
|
+
offerInfo: getOfferInfo(cart),
|
|
14687
14729
|
merchantInfo: {
|
|
14688
14730
|
merchantName: name,
|
|
14689
14731
|
merchantId: this.method.merchant_id,
|
|
14690
14732
|
},
|
|
14733
|
+
callbackIntents,
|
|
14691
14734
|
};
|
|
14692
14735
|
}
|
|
14693
14736
|
|
|
14694
14737
|
/**
|
|
14695
|
-
* @param {
|
|
14738
|
+
* @param {braintree.GooglePayment} googlePayment
|
|
14696
14739
|
* @param {google.payments.api.PaymentDataRequest} paymentDataRequest
|
|
14697
14740
|
*/
|
|
14698
14741
|
async _onClick(googlePayment, paymentDataRequest) {
|
|
@@ -14709,34 +14752,59 @@
|
|
|
14709
14752
|
}
|
|
14710
14753
|
|
|
14711
14754
|
/**
|
|
14712
|
-
* @param {
|
|
14755
|
+
* @param {braintree.GooglePayment} googlePayment
|
|
14713
14756
|
* @param {google.payments.api.PaymentData} paymentData
|
|
14714
14757
|
*/
|
|
14715
14758
|
async _submitPayment(googlePayment, paymentData) {
|
|
14716
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
14717
14759
|
const { nonce } = await googlePayment.parseResponse(paymentData);
|
|
14718
|
-
const { email, shippingAddress, paymentMethodData } =
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
} = paymentMethodData;
|
|
14760
|
+
const { email, shippingAddress, shippingOptionData, paymentMethodData } =
|
|
14761
|
+
paymentData;
|
|
14762
|
+
const { info: { billingAddress } = {} } = paymentMethodData;
|
|
14722
14763
|
|
|
14723
|
-
await this.updateCart({
|
|
14764
|
+
const cart = await this.updateCart({
|
|
14724
14765
|
account: {
|
|
14725
14766
|
email,
|
|
14726
14767
|
},
|
|
14727
14768
|
billing: {
|
|
14728
14769
|
method: 'google',
|
|
14770
|
+
account_card_id: null,
|
|
14771
|
+
card: null,
|
|
14729
14772
|
google: {
|
|
14730
14773
|
nonce,
|
|
14731
14774
|
gateway: 'braintree',
|
|
14732
14775
|
},
|
|
14733
14776
|
...convertToSwellAddress$2(billingAddress),
|
|
14734
14777
|
},
|
|
14735
|
-
...(
|
|
14736
|
-
shipping:
|
|
14778
|
+
...(shippingAddress && {
|
|
14779
|
+
shipping: {
|
|
14780
|
+
...convertToSwellAddress$2(shippingAddress),
|
|
14781
|
+
service: shippingOptionData?.id || undefined,
|
|
14782
|
+
},
|
|
14737
14783
|
}),
|
|
14738
14784
|
});
|
|
14739
14785
|
|
|
14786
|
+
if (cart.subscription_delivery) {
|
|
14787
|
+
try {
|
|
14788
|
+
const card = await cardApi.createToken({
|
|
14789
|
+
gateway: 'braintree',
|
|
14790
|
+
account_id: cart.account_id,
|
|
14791
|
+
nonce,
|
|
14792
|
+
});
|
|
14793
|
+
|
|
14794
|
+
delete card.nonce;
|
|
14795
|
+
|
|
14796
|
+
await this.updateCart({
|
|
14797
|
+
billing: {
|
|
14798
|
+
method: 'card',
|
|
14799
|
+
card,
|
|
14800
|
+
google: null,
|
|
14801
|
+
},
|
|
14802
|
+
});
|
|
14803
|
+
} catch (error) {
|
|
14804
|
+
console.warn('Failed to extract card data from google token', error);
|
|
14805
|
+
}
|
|
14806
|
+
}
|
|
14807
|
+
|
|
14740
14808
|
this.onSuccess();
|
|
14741
14809
|
}
|
|
14742
14810
|
}
|
|
@@ -14766,7 +14834,7 @@
|
|
|
14766
14834
|
'Shipping is not available for the provided address.';
|
|
14767
14835
|
|
|
14768
14836
|
return {
|
|
14769
|
-
newTotal: getTotal(cart, this.merchantInfo),
|
|
14837
|
+
newTotal: getTotal.call(this, cart, this.merchantInfo),
|
|
14770
14838
|
newLineItems: getLineItems(cart),
|
|
14771
14839
|
newShippingMethods: [], // REQUIRED: Must always provide this, even as empty array
|
|
14772
14840
|
errors: [
|
|
@@ -14777,15 +14845,15 @@
|
|
|
14777
14845
|
|
|
14778
14846
|
// Success: Return updated totals and shipping methods
|
|
14779
14847
|
return {
|
|
14780
|
-
newTotal: getTotal(cart, this.merchantInfo),
|
|
14848
|
+
newTotal: getTotal.call(this, cart, this.merchantInfo),
|
|
14781
14849
|
newLineItems: getLineItems(cart),
|
|
14782
|
-
newShippingMethods: getShippingMethods(cart),
|
|
14850
|
+
newShippingMethods: getShippingMethods.call(this, cart),
|
|
14783
14851
|
};
|
|
14784
14852
|
} catch (err) {
|
|
14785
14853
|
const cartData = await this.getCart();
|
|
14786
14854
|
|
|
14787
14855
|
return {
|
|
14788
|
-
newTotal: getTotal(cartData, this.merchantInfo),
|
|
14856
|
+
newTotal: getTotal.call(this, cartData, this.merchantInfo),
|
|
14789
14857
|
newLineItems: getLineItems(cartData),
|
|
14790
14858
|
newShippingMethods: [], // REQUIRED: Must always provide this, even as empty array
|
|
14791
14859
|
errors: [new ApplePayError('unknown', undefined, err.message)],
|
|
@@ -14831,12 +14899,12 @@
|
|
|
14831
14899
|
});
|
|
14832
14900
|
|
|
14833
14901
|
return {
|
|
14834
|
-
newTotal: getTotal(cart, this.merchantInfo),
|
|
14902
|
+
newTotal: getTotal.call(this, cart, this.merchantInfo),
|
|
14835
14903
|
newLineItems: getLineItems(cart),
|
|
14836
14904
|
};
|
|
14837
14905
|
} catch (err) {
|
|
14838
14906
|
return {
|
|
14839
|
-
newTotal: getTotal(await this.getCart(), this.merchantInfo),
|
|
14907
|
+
newTotal: getTotal.call(this, await this.getCart(), this.merchantInfo),
|
|
14840
14908
|
errors: [new ApplePayError('unknown', undefined, err.message)],
|
|
14841
14909
|
};
|
|
14842
14910
|
}
|
|
@@ -14876,7 +14944,7 @@
|
|
|
14876
14944
|
|
|
14877
14945
|
// Valid coupon applied successfully
|
|
14878
14946
|
return {
|
|
14879
|
-
newTotal: getTotal(cart, this.merchantInfo),
|
|
14947
|
+
newTotal: getTotal.call(this, cart, this.merchantInfo),
|
|
14880
14948
|
newLineItems: getLineItems(cart),
|
|
14881
14949
|
};
|
|
14882
14950
|
} catch (err) {
|
|
@@ -14884,7 +14952,7 @@
|
|
|
14884
14952
|
const currentCart = await this.getCart();
|
|
14885
14953
|
|
|
14886
14954
|
return {
|
|
14887
|
-
newTotal: getTotal(currentCart, this.merchantInfo),
|
|
14955
|
+
newTotal: getTotal.call(this, currentCart, this.merchantInfo),
|
|
14888
14956
|
newLineItems: getLineItems(currentCart),
|
|
14889
14957
|
errors: [new ApplePayError('couponCodeInvalid', undefined, err.message)],
|
|
14890
14958
|
};
|
|
@@ -14918,15 +14986,17 @@
|
|
|
14918
14986
|
* This ensures the user sees "pending" until they've selected shipping,
|
|
14919
14987
|
* then sees the final amount once everything is calculated.
|
|
14920
14988
|
*
|
|
14989
|
+
* @this {Payment}
|
|
14921
14990
|
* @param {Cart} cart
|
|
14922
14991
|
* @param {object} [merchantInfo]
|
|
14923
14992
|
* @returns {ApplePayJS.ApplePayLineItem}
|
|
14924
14993
|
*/
|
|
14925
14994
|
function getTotal(cart, merchantInfo) {
|
|
14926
|
-
const {
|
|
14995
|
+
const { require: { shipping: shipmentDelivery = false } = {} } = this.params;
|
|
14996
|
+
const { capture_total, shipping } = cart;
|
|
14927
14997
|
|
|
14928
14998
|
// Use 'final' only after shipping method is selected or not needed, otherwise 'pending'
|
|
14929
|
-
const isFinalPrice = !
|
|
14999
|
+
const isFinalPrice = !shipmentDelivery || shipping?.service;
|
|
14930
15000
|
const type = isFinalPrice ? 'final' : 'pending';
|
|
14931
15001
|
|
|
14932
15002
|
return {
|
|
@@ -14995,16 +15065,19 @@
|
|
|
14995
15065
|
*
|
|
14996
15066
|
* IMPORTANT: Amounts must be formatted as strings with 2 decimals.
|
|
14997
15067
|
*
|
|
15068
|
+
* @this {Payment}
|
|
14998
15069
|
* @param {Cart} cart
|
|
14999
15070
|
* @returns {ApplePayJS.ApplePayShippingMethod[]}
|
|
15000
15071
|
*/
|
|
15001
15072
|
function getShippingMethods(cart) {
|
|
15002
|
-
const {
|
|
15073
|
+
const { require: { shipping: shipmentDelivery = false } = {} } = this.params;
|
|
15003
15074
|
|
|
15004
|
-
if (!
|
|
15075
|
+
if (!shipmentDelivery) {
|
|
15005
15076
|
return [];
|
|
15006
15077
|
}
|
|
15007
15078
|
|
|
15079
|
+
const { shipment_rating } = cart;
|
|
15080
|
+
|
|
15008
15081
|
if (!shipment_rating?.services?.length) {
|
|
15009
15082
|
return [];
|
|
15010
15083
|
}
|
|
@@ -15055,13 +15128,38 @@
|
|
|
15055
15128
|
};
|
|
15056
15129
|
}
|
|
15057
15130
|
|
|
15058
|
-
|
|
15131
|
+
/** @param {object} params */
|
|
15132
|
+
function getRequiredContactFields(params) {
|
|
15133
|
+
const { require = {} } = params;
|
|
15134
|
+
/** @type {ApplePayJS.ApplePayContactField[]} */
|
|
15135
|
+
const requiredFields = [];
|
|
15136
|
+
|
|
15137
|
+
if (require.email) {
|
|
15138
|
+
requiredFields.push('email');
|
|
15139
|
+
}
|
|
15140
|
+
|
|
15141
|
+
if (require.name) {
|
|
15142
|
+
requiredFields.push('name');
|
|
15143
|
+
}
|
|
15144
|
+
|
|
15145
|
+
if (require.phone) {
|
|
15146
|
+
requiredFields.push('phone');
|
|
15147
|
+
}
|
|
15148
|
+
|
|
15149
|
+
/** @type {ApplePayJS.ApplePayContactField[]} */
|
|
15150
|
+
const requiredShippingContactFields = require.shipping
|
|
15151
|
+
? [...requiredFields, 'postalAddress']
|
|
15152
|
+
: [];
|
|
15153
|
+
|
|
15154
|
+
/** @type {ApplePayJS.ApplePayContactField[]} */
|
|
15155
|
+
const requiredBillingContactFields = [...requiredFields, 'postalAddress'];
|
|
15156
|
+
|
|
15157
|
+
return { requiredBillingContactFields, requiredShippingContactFields };
|
|
15158
|
+
}
|
|
15159
|
+
|
|
15160
|
+
/** @typedef {import('../../../types').Cart} Cart */
|
|
15059
15161
|
|
|
15060
|
-
const
|
|
15061
|
-
'supports3DS',
|
|
15062
|
-
'supportsDebit',
|
|
15063
|
-
'supportsCredit',
|
|
15064
|
-
];
|
|
15162
|
+
const VERSION$1 = 14;
|
|
15065
15163
|
|
|
15066
15164
|
class BraintreeApplePayment extends Payment {
|
|
15067
15165
|
constructor(api, options, params, methods) {
|
|
@@ -15093,6 +15191,7 @@
|
|
|
15093
15191
|
return window.ApplePaySession;
|
|
15094
15192
|
}
|
|
15095
15193
|
|
|
15194
|
+
/** @param {Cart} cart */
|
|
15096
15195
|
async createElements(cart) {
|
|
15097
15196
|
const { elementId = 'applepay-button' } = this.params;
|
|
15098
15197
|
|
|
@@ -15106,10 +15205,12 @@
|
|
|
15106
15205
|
}
|
|
15107
15206
|
|
|
15108
15207
|
const braintreeClient = await this._createBraintreeClient();
|
|
15208
|
+
|
|
15109
15209
|
const applePayment = await this.braintree.applePay.create({
|
|
15110
15210
|
client: braintreeClient,
|
|
15111
15211
|
});
|
|
15112
|
-
|
|
15212
|
+
|
|
15213
|
+
const paymentRequest = this._createPaymentRequest(cart, applePayment);
|
|
15113
15214
|
|
|
15114
15215
|
this.element = this._createButton(applePayment, paymentRequest);
|
|
15115
15216
|
}
|
|
@@ -15126,8 +15227,9 @@
|
|
|
15126
15227
|
}
|
|
15127
15228
|
|
|
15128
15229
|
/**
|
|
15129
|
-
* @param {
|
|
15230
|
+
* @param {braintree.ApplePay} applePayment
|
|
15130
15231
|
* @param {ApplePayJS.ApplePayPaymentRequest} paymentRequest
|
|
15232
|
+
* @returns {HTMLDivElement}
|
|
15131
15233
|
*/
|
|
15132
15234
|
_createButton(applePayment, paymentRequest) {
|
|
15133
15235
|
const { style: { type = 'plain', theme = 'black', height = '40px' } = {} } =
|
|
@@ -15148,6 +15250,7 @@
|
|
|
15148
15250
|
return button;
|
|
15149
15251
|
}
|
|
15150
15252
|
|
|
15253
|
+
/** @returns {Promise<braintree.Client>} */
|
|
15151
15254
|
async _createBraintreeClient() {
|
|
15152
15255
|
const authorization = await this.authorizeGateway({
|
|
15153
15256
|
gateway: 'braintree',
|
|
@@ -15162,47 +15265,43 @@
|
|
|
15162
15265
|
});
|
|
15163
15266
|
}
|
|
15164
15267
|
|
|
15165
|
-
/**
|
|
15268
|
+
/**
|
|
15269
|
+
* @param {Cart} cart
|
|
15270
|
+
* @param {braintree.ApplePay} applePayment
|
|
15271
|
+
* @returns {ApplePayJS.ApplePayPaymentRequest}
|
|
15272
|
+
*/
|
|
15166
15273
|
_createPaymentRequest(cart, applePayment) {
|
|
15167
|
-
const { require = {} } = this.params;
|
|
15168
15274
|
const {
|
|
15169
15275
|
settings: { name, country },
|
|
15170
15276
|
capture_total,
|
|
15171
15277
|
currency,
|
|
15172
15278
|
} = cart;
|
|
15173
15279
|
|
|
15174
|
-
const requiredShippingContactFields =
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
if (require.name) {
|
|
15178
|
-
requiredShippingContactFields.push('name');
|
|
15179
|
-
}
|
|
15180
|
-
if (require.email) {
|
|
15181
|
-
requiredShippingContactFields.push('email');
|
|
15182
|
-
}
|
|
15183
|
-
if (require.phone) {
|
|
15184
|
-
requiredShippingContactFields.push('phone');
|
|
15185
|
-
}
|
|
15186
|
-
if (require.shipping) {
|
|
15187
|
-
requiredShippingContactFields.push('postalAddress');
|
|
15188
|
-
}
|
|
15280
|
+
const { requiredBillingContactFields, requiredShippingContactFields } =
|
|
15281
|
+
getRequiredContactFields(this.params);
|
|
15189
15282
|
|
|
15190
15283
|
return applePayment.createPaymentRequest({
|
|
15191
15284
|
total: {
|
|
15192
15285
|
label: name,
|
|
15193
15286
|
type: 'pending',
|
|
15194
|
-
amount: capture_total.
|
|
15287
|
+
amount: (capture_total || 0).toFixed(2),
|
|
15195
15288
|
},
|
|
15196
15289
|
countryCode: country,
|
|
15197
15290
|
currencyCode: currency,
|
|
15198
|
-
|
|
15291
|
+
/**
|
|
15292
|
+
* @see {@link https://developer.paypal.com/braintree/docs/guides/apple-pay/client-side/javascript/v3/#create-anapplepaysession}
|
|
15293
|
+
*
|
|
15294
|
+
* Braintree automatically fills in `supportedNetworks` and `merchantCapabilities`.
|
|
15295
|
+
*/
|
|
15199
15296
|
requiredShippingContactFields,
|
|
15200
15297
|
requiredBillingContactFields,
|
|
15298
|
+
supportsCouponCode: true,
|
|
15299
|
+
lineItems: getLineItems(cart),
|
|
15201
15300
|
});
|
|
15202
15301
|
}
|
|
15203
15302
|
|
|
15204
15303
|
/**
|
|
15205
|
-
* @param {
|
|
15304
|
+
* @param {braintree.ApplePay} applePayment
|
|
15206
15305
|
* @param {ApplePayJS.ApplePayPaymentRequest} paymentRequest
|
|
15207
15306
|
*/
|
|
15208
15307
|
_createPaymentSession(applePayment, paymentRequest) {
|
|
@@ -15223,11 +15322,23 @@
|
|
|
15223
15322
|
}
|
|
15224
15323
|
};
|
|
15225
15324
|
|
|
15325
|
+
session.onshippingcontactselected = onShippingContactSelected.bind(
|
|
15326
|
+
this,
|
|
15327
|
+
session,
|
|
15328
|
+
);
|
|
15329
|
+
|
|
15330
|
+
session.onshippingmethodselected = onShippingMethodSelected.bind(
|
|
15331
|
+
this,
|
|
15332
|
+
session,
|
|
15333
|
+
);
|
|
15334
|
+
|
|
15335
|
+
session.oncouponcodechanged = onCouponCodeChanged.bind(this, session);
|
|
15336
|
+
|
|
15226
15337
|
session.onpaymentauthorized = async (event) => {
|
|
15227
15338
|
const {
|
|
15228
15339
|
payment: { token, shippingContact, billingContact },
|
|
15229
15340
|
} = event;
|
|
15230
|
-
|
|
15341
|
+
|
|
15231
15342
|
const payload = await applePayment
|
|
15232
15343
|
.tokenize({ token })
|
|
15233
15344
|
.catch(this.onError.bind(this));
|
|
@@ -15236,23 +15347,47 @@
|
|
|
15236
15347
|
return session.completePayment(this.ApplePaySession.STATUS_FAILURE);
|
|
15237
15348
|
}
|
|
15238
15349
|
|
|
15239
|
-
await this.updateCart({
|
|
15350
|
+
const cart = await this.updateCart({
|
|
15240
15351
|
account: {
|
|
15241
|
-
email: shippingContact
|
|
15352
|
+
email: shippingContact?.emailAddress || billingContact?.emailAddress,
|
|
15242
15353
|
},
|
|
15243
15354
|
billing: {
|
|
15244
15355
|
method: 'apple',
|
|
15356
|
+
account_card_id: null,
|
|
15357
|
+
card: null,
|
|
15245
15358
|
apple: {
|
|
15246
15359
|
nonce: payload.nonce,
|
|
15247
15360
|
gateway: 'braintree',
|
|
15248
15361
|
},
|
|
15249
15362
|
...convertToSwellAddress$1(billingContact),
|
|
15250
15363
|
},
|
|
15251
|
-
...(
|
|
15364
|
+
...(shippingContact && {
|
|
15252
15365
|
shipping: convertToSwellAddress$1(shippingContact),
|
|
15253
15366
|
}),
|
|
15254
15367
|
});
|
|
15255
15368
|
|
|
15369
|
+
if (cart.subscription_delivery) {
|
|
15370
|
+
try {
|
|
15371
|
+
const card = await cardApi.createToken({
|
|
15372
|
+
gateway: 'braintree',
|
|
15373
|
+
account_id: cart.account_id,
|
|
15374
|
+
nonce: payload.nonce,
|
|
15375
|
+
});
|
|
15376
|
+
|
|
15377
|
+
delete card.nonce;
|
|
15378
|
+
|
|
15379
|
+
await this.updateCart({
|
|
15380
|
+
billing: {
|
|
15381
|
+
method: 'card',
|
|
15382
|
+
card,
|
|
15383
|
+
apple: null,
|
|
15384
|
+
},
|
|
15385
|
+
});
|
|
15386
|
+
} catch (error) {
|
|
15387
|
+
console.warn('Failed to extract card data from apple token', error);
|
|
15388
|
+
}
|
|
15389
|
+
}
|
|
15390
|
+
|
|
15256
15391
|
this.onSuccess();
|
|
15257
15392
|
|
|
15258
15393
|
return session.completePayment(this.ApplePaySession.STATUS_SUCCESS);
|
|
@@ -15358,6 +15493,8 @@
|
|
|
15358
15493
|
* @returns {google.payments.api.PaymentMethodSpecification}
|
|
15359
15494
|
*/
|
|
15360
15495
|
_getCardPaymentMethod(submit = false) {
|
|
15496
|
+
const { require: { phone } = {} } = this.params;
|
|
15497
|
+
|
|
15361
15498
|
return {
|
|
15362
15499
|
type: 'CARD',
|
|
15363
15500
|
parameters: {
|
|
@@ -15366,7 +15503,7 @@
|
|
|
15366
15503
|
billingAddressRequired: true,
|
|
15367
15504
|
billingAddressParameters: {
|
|
15368
15505
|
format: 'FULL',
|
|
15369
|
-
phoneNumberRequired:
|
|
15506
|
+
phoneNumberRequired: Boolean(phone),
|
|
15370
15507
|
},
|
|
15371
15508
|
},
|
|
15372
15509
|
...(submit && {
|
|
@@ -15399,29 +15536,30 @@
|
|
|
15399
15536
|
cart.shipment_price = 0;
|
|
15400
15537
|
cart.shipping = {};
|
|
15401
15538
|
|
|
15402
|
-
const { shipment_delivery } = cart;
|
|
15403
15539
|
const { require: { email, shipping, phone } = {} } = this.params;
|
|
15404
15540
|
|
|
15541
|
+
/** @type {google.payments.api.CallbackIntent[]} */
|
|
15542
|
+
const callbackIntents = ['OFFER', 'PAYMENT_AUTHORIZATION'];
|
|
15543
|
+
|
|
15544
|
+
if (shipping) {
|
|
15545
|
+
callbackIntents.push('SHIPPING_ADDRESS', 'SHIPPING_OPTION');
|
|
15546
|
+
}
|
|
15547
|
+
|
|
15405
15548
|
return {
|
|
15406
15549
|
apiVersion: API_VERSION,
|
|
15407
15550
|
apiVersionMinor: API_MINOR_VERSION,
|
|
15408
|
-
transactionInfo: getTransactionInfo(cart),
|
|
15551
|
+
transactionInfo: getTransactionInfo.call(this, cart),
|
|
15409
15552
|
allowedPaymentMethods: this._getAllowedPaymentMethods(true),
|
|
15410
15553
|
emailRequired: Boolean(email),
|
|
15411
15554
|
shippingAddressRequired: Boolean(shipping),
|
|
15412
15555
|
shippingAddressParameters: {
|
|
15413
15556
|
phoneNumberRequired: Boolean(phone),
|
|
15414
15557
|
},
|
|
15415
|
-
shippingOptionRequired: Boolean(
|
|
15558
|
+
shippingOptionRequired: Boolean(shipping),
|
|
15416
15559
|
shippingOptionParameters: getShippingOptionParameters.call(this, cart),
|
|
15417
15560
|
offerInfo: getOfferInfo(cart),
|
|
15418
15561
|
merchantInfo,
|
|
15419
|
-
callbackIntents
|
|
15420
|
-
'OFFER',
|
|
15421
|
-
'SHIPPING_ADDRESS',
|
|
15422
|
-
'SHIPPING_OPTION',
|
|
15423
|
-
'PAYMENT_AUTHORIZATION',
|
|
15424
|
-
],
|
|
15562
|
+
callbackIntents,
|
|
15425
15563
|
};
|
|
15426
15564
|
}
|
|
15427
15565
|
|
|
@@ -15545,6 +15683,22 @@
|
|
|
15545
15683
|
/** @typedef {import('../../../types').Cart} Cart */
|
|
15546
15684
|
|
|
15547
15685
|
class AuthorizeNetGooglePayment extends AbstractGooglePayment {
|
|
15686
|
+
/**
|
|
15687
|
+
* @override
|
|
15688
|
+
* @returns {google.payments.api.CardNetwork[]}
|
|
15689
|
+
*/
|
|
15690
|
+
getAllowedCardNetworks() {
|
|
15691
|
+
return ['AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'];
|
|
15692
|
+
}
|
|
15693
|
+
|
|
15694
|
+
/**
|
|
15695
|
+
* @override
|
|
15696
|
+
* @returns {google.payments.api.CardAuthMethod[]}
|
|
15697
|
+
*/
|
|
15698
|
+
getAllowedCardAuthMethods() {
|
|
15699
|
+
return ['PAN_ONLY', 'CRYPTOGRAM_3DS'];
|
|
15700
|
+
}
|
|
15701
|
+
|
|
15548
15702
|
/**
|
|
15549
15703
|
* @override
|
|
15550
15704
|
* @returns {google.payments.api.PaymentGatewayTokenizationParameters}
|
|
@@ -15562,7 +15716,6 @@
|
|
|
15562
15716
|
* @returns {Promise<object>}
|
|
15563
15717
|
*/
|
|
15564
15718
|
async preparePaymentDataForCartUpdate(paymentData) {
|
|
15565
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
15566
15719
|
const { email, shippingAddress, shippingOptionData, paymentMethodData } =
|
|
15567
15720
|
paymentData;
|
|
15568
15721
|
|
|
@@ -15583,7 +15736,7 @@
|
|
|
15583
15736
|
},
|
|
15584
15737
|
...convertToSwellAddress$2(billingAddress),
|
|
15585
15738
|
},
|
|
15586
|
-
...(
|
|
15739
|
+
...(shippingAddress && {
|
|
15587
15740
|
shipping: {
|
|
15588
15741
|
...convertToSwellAddress$2(shippingAddress),
|
|
15589
15742
|
service: shippingOptionData?.id || undefined,
|
|
@@ -15650,9 +15803,15 @@
|
|
|
15650
15803
|
return window.ApplePaySession;
|
|
15651
15804
|
}
|
|
15652
15805
|
|
|
15653
|
-
/**
|
|
15806
|
+
/**
|
|
15807
|
+
* We should specify the payment methods in the order preferred by the gateway.
|
|
15808
|
+
*
|
|
15809
|
+
* @see {@link https://developer.apple.com/documentation/applepayontheweb/applepaypaymentrequest/supportednetworks}
|
|
15810
|
+
*
|
|
15811
|
+
* @returns {string[]}
|
|
15812
|
+
*/
|
|
15654
15813
|
getSupportedCardNetworks() {
|
|
15655
|
-
return ['
|
|
15814
|
+
return ['visa', 'masterCard', 'amex', 'discover', 'interac', 'jcb'];
|
|
15656
15815
|
}
|
|
15657
15816
|
|
|
15658
15817
|
/** @returns {ApplePayJS.ApplePayMerchantCapability[]} */
|
|
@@ -15663,12 +15822,12 @@
|
|
|
15663
15822
|
/**
|
|
15664
15823
|
* Creates the Apple Pay payment request object
|
|
15665
15824
|
*
|
|
15666
|
-
* IMPORTANT: countryCode here is the MERCHANT's country (where your business is located),
|
|
15667
|
-
* NOT the customer's country. Customer country comes from shippingContact.countryCode
|
|
15825
|
+
* IMPORTANT: `countryCode` here is the MERCHANT's country (where your business is located),
|
|
15826
|
+
* NOT the customer's country. Customer country comes from `shippingContact.countryCode`.
|
|
15668
15827
|
*
|
|
15669
|
-
* NOTE: We do NOT pass shippingMethods in the initial request. Shipping methods
|
|
15828
|
+
* NOTE: We do NOT pass `shippingMethods` in the initial request. Shipping methods
|
|
15670
15829
|
* are provided dynamically after the user selects/confirms their address in the
|
|
15671
|
-
* 'shippingcontactselected' event handler.
|
|
15830
|
+
* `'shippingcontactselected'` event handler.
|
|
15672
15831
|
*
|
|
15673
15832
|
* @param {Cart} cart
|
|
15674
15833
|
* @returns {ApplePayJS.ApplePayPaymentRequest}
|
|
@@ -15676,38 +15835,21 @@
|
|
|
15676
15835
|
_createPaymentRequest(cart) {
|
|
15677
15836
|
cart = { ...cart };
|
|
15678
15837
|
|
|
15679
|
-
const { require = {} } = this.params;
|
|
15680
15838
|
const {
|
|
15681
15839
|
settings: { country },
|
|
15682
15840
|
currency,
|
|
15683
15841
|
} = cart;
|
|
15684
15842
|
|
|
15685
|
-
const requiredShippingContactFields = [];
|
|
15686
|
-
const requiredBillingContactFields = ['postalAddress'];
|
|
15687
|
-
|
|
15688
|
-
if (require.name) {
|
|
15689
|
-
requiredShippingContactFields.push('name');
|
|
15690
|
-
}
|
|
15691
|
-
|
|
15692
|
-
if (require.email) {
|
|
15693
|
-
requiredShippingContactFields.push('email');
|
|
15694
|
-
}
|
|
15695
|
-
|
|
15696
|
-
if (require.phone) {
|
|
15697
|
-
requiredShippingContactFields.push('phone');
|
|
15698
|
-
}
|
|
15699
|
-
|
|
15700
|
-
if (require.shipping) {
|
|
15701
|
-
requiredShippingContactFields.push('postalAddress');
|
|
15702
|
-
}
|
|
15703
|
-
|
|
15704
15843
|
// When initiating a payment request,
|
|
15705
15844
|
// we should not display the shipping cost, as it will be calculated later.
|
|
15706
15845
|
cart.shipment_price = 0;
|
|
15707
15846
|
cart.shipping = {};
|
|
15708
15847
|
|
|
15848
|
+
const { requiredBillingContactFields, requiredShippingContactFields } =
|
|
15849
|
+
getRequiredContactFields(this.params);
|
|
15850
|
+
|
|
15709
15851
|
return {
|
|
15710
|
-
total: getTotal(cart, this.merchantInfo),
|
|
15852
|
+
total: getTotal.call(this, cart, this.merchantInfo),
|
|
15711
15853
|
countryCode: country, // Merchant's country
|
|
15712
15854
|
currencyCode: currency,
|
|
15713
15855
|
supportedNetworks: this.getSupportedCardNetworks(),
|
|
@@ -15889,6 +16031,22 @@
|
|
|
15889
16031
|
}
|
|
15890
16032
|
|
|
15891
16033
|
class AuthorizeNetApplePayment extends AbstractApplePayment {
|
|
16034
|
+
/**
|
|
16035
|
+
* @override
|
|
16036
|
+
* @returns {string[]}
|
|
16037
|
+
*/
|
|
16038
|
+
getSupportedCardNetworks() {
|
|
16039
|
+
return ['visa', 'masterCard', 'amex', 'discover'];
|
|
16040
|
+
}
|
|
16041
|
+
|
|
16042
|
+
/**
|
|
16043
|
+
* @override
|
|
16044
|
+
* @returns {ApplePayJS.ApplePayMerchantCapability[]}
|
|
16045
|
+
*/
|
|
16046
|
+
getMerchantCapabilities() {
|
|
16047
|
+
return ['supports3DS', 'supportsDebit', 'supportsCredit'];
|
|
16048
|
+
}
|
|
16049
|
+
|
|
15892
16050
|
/**
|
|
15893
16051
|
* @override
|
|
15894
16052
|
* @param {ApplePayJS.ApplePayValidateMerchantEvent} event
|
|
@@ -15922,11 +16080,9 @@
|
|
|
15922
16080
|
payment: { token, shippingContact, billingContact },
|
|
15923
16081
|
} = event;
|
|
15924
16082
|
|
|
15925
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
15926
|
-
|
|
15927
16083
|
return {
|
|
15928
16084
|
account: {
|
|
15929
|
-
email: shippingContact
|
|
16085
|
+
email: shippingContact?.emailAddress || billingContact?.emailAddress,
|
|
15930
16086
|
},
|
|
15931
16087
|
billing: {
|
|
15932
16088
|
method: 'apple',
|
|
@@ -15938,7 +16094,7 @@
|
|
|
15938
16094
|
},
|
|
15939
16095
|
...convertToSwellAddress$1(billingContact),
|
|
15940
16096
|
},
|
|
15941
|
-
...(
|
|
16097
|
+
...(shippingContact && {
|
|
15942
16098
|
shipping: convertToSwellAddress$1(shippingContact),
|
|
15943
16099
|
}),
|
|
15944
16100
|
};
|
|
@@ -16058,7 +16214,7 @@
|
|
|
16058
16214
|
merchantAccount: false,
|
|
16059
16215
|
countryCode: country || 'US',
|
|
16060
16216
|
shopperLocale: 'en-US',
|
|
16061
|
-
// shopperReference: email ? md5(email) : undefined,
|
|
16217
|
+
// shopperReference: email ? md5(email.toLowerCase()) : undefined,
|
|
16062
16218
|
}),
|
|
16063
16219
|
},
|
|
16064
16220
|
).then((res) => res.json());
|
|
@@ -16186,15 +16342,20 @@
|
|
|
16186
16342
|
}
|
|
16187
16343
|
}
|
|
16188
16344
|
|
|
16345
|
+
function getBaseConvesioVaultUrl(mode) {
|
|
16346
|
+
return isLiveMode(mode)
|
|
16347
|
+
? 'https://vault.convesiopay.com'
|
|
16348
|
+
: 'https://qa-vault.convesiopay.com';
|
|
16349
|
+
}
|
|
16350
|
+
|
|
16189
16351
|
function createConvesioCardPaymentToken(settings, data) {
|
|
16190
|
-
const baseUrl =
|
|
16352
|
+
const baseUrl = getBaseConvesioVaultUrl(settings.mode);
|
|
16191
16353
|
|
|
16192
16354
|
return fetch(`${baseUrl}/v1/create-token`, {
|
|
16193
16355
|
method: 'POST',
|
|
16194
16356
|
headers: {
|
|
16195
16357
|
Accept: 'application/json',
|
|
16196
16358
|
'Content-Type': 'application/json',
|
|
16197
|
-
'X-Requested-With': 'convesio-pay-dashboard',
|
|
16198
16359
|
'X-Api-Key': settings.public_key,
|
|
16199
16360
|
},
|
|
16200
16361
|
body: JSON.stringify(data),
|
|
@@ -16309,8 +16470,6 @@
|
|
|
16309
16470
|
payment: { token, shippingContact, billingContact },
|
|
16310
16471
|
} = event;
|
|
16311
16472
|
|
|
16312
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
16313
|
-
|
|
16314
16473
|
const payment = await createConvesioApplePaymentToken(
|
|
16315
16474
|
this.method.mode,
|
|
16316
16475
|
this.convesiopay,
|
|
@@ -16332,7 +16491,7 @@
|
|
|
16332
16491
|
|
|
16333
16492
|
return {
|
|
16334
16493
|
account: {
|
|
16335
|
-
email: shippingContact
|
|
16494
|
+
email: shippingContact?.emailAddress || billingContact?.emailAddress,
|
|
16336
16495
|
},
|
|
16337
16496
|
billing: {
|
|
16338
16497
|
method: 'apple',
|
|
@@ -16347,7 +16506,7 @@
|
|
|
16347
16506
|
},
|
|
16348
16507
|
...convertToSwellAddress$1(billingContact),
|
|
16349
16508
|
},
|
|
16350
|
-
...(
|
|
16509
|
+
...(shippingContact && {
|
|
16351
16510
|
shipping: convertToSwellAddress$1(shippingContact),
|
|
16352
16511
|
}),
|
|
16353
16512
|
};
|
|
@@ -16477,7 +16636,6 @@
|
|
|
16477
16636
|
* @returns {Promise<object>}
|
|
16478
16637
|
*/
|
|
16479
16638
|
async preparePaymentDataForCartUpdate(paymentData) {
|
|
16480
|
-
const { require: { shipping: requireShipping } = {} } = this.params;
|
|
16481
16639
|
const { email, shippingAddress, shippingOptionData, paymentMethodData } =
|
|
16482
16640
|
paymentData;
|
|
16483
16641
|
|
|
@@ -16520,7 +16678,7 @@
|
|
|
16520
16678
|
},
|
|
16521
16679
|
...convertToSwellAddress$2(billingAddress),
|
|
16522
16680
|
},
|
|
16523
|
-
...(
|
|
16681
|
+
...(shippingAddress && {
|
|
16524
16682
|
shipping: {
|
|
16525
16683
|
...convertToSwellAddress$2(shippingAddress),
|
|
16526
16684
|
service: shippingOptionData?.id || undefined,
|
|
@@ -17416,20 +17574,29 @@
|
|
|
17416
17574
|
settings: { name },
|
|
17417
17575
|
} = cart;
|
|
17418
17576
|
|
|
17419
|
-
const
|
|
17577
|
+
const { require: { shipping } = {} } = this.params;
|
|
17420
17578
|
const cartCurrency = getCartCurrency(cart);
|
|
17421
17579
|
|
|
17422
17580
|
return {
|
|
17423
17581
|
checkout_payload: {
|
|
17424
|
-
express_checkout_type:
|
|
17582
|
+
express_checkout_type: shipping ? 'multi-step' : 'no-shipping',
|
|
17583
|
+
customer: {
|
|
17584
|
+
email: cart.account?.email,
|
|
17585
|
+
first_name: cart.account?.first_name,
|
|
17586
|
+
last_name: cart.account?.last_name,
|
|
17587
|
+
phone: cart.account?.phone,
|
|
17588
|
+
// TODO: recurring payments https://docs.sezzle.com/docs/api/tokenization/intro
|
|
17589
|
+
// tokenize: cart.subscription_delivery,
|
|
17590
|
+
// recurring: cart.subscription_delivery,
|
|
17591
|
+
},
|
|
17425
17592
|
order: {
|
|
17426
17593
|
intent: 'AUTH',
|
|
17427
17594
|
reference_id: cart.checkout_id,
|
|
17428
17595
|
description: `${name} #${cart.number}`,
|
|
17429
|
-
requires_shipping_info:
|
|
17596
|
+
requires_shipping_info: shipping,
|
|
17430
17597
|
items: getItems(cart),
|
|
17431
17598
|
discounts: getDiscounts(cart),
|
|
17432
|
-
tax_amount:
|
|
17599
|
+
tax_amount: shipping
|
|
17433
17600
|
? undefined
|
|
17434
17601
|
: getAmountInCents(cartCurrency, cart.tax_total),
|
|
17435
17602
|
order_amount: getAmountInCents(cartCurrency, cart.capture_total),
|
|
@@ -17689,15 +17856,6 @@
|
|
|
17689
17856
|
};
|
|
17690
17857
|
}
|
|
17691
17858
|
|
|
17692
|
-
/**
|
|
17693
|
-
* @param {string} currency
|
|
17694
|
-
* @param {number} amount
|
|
17695
|
-
* @returns {number}
|
|
17696
|
-
*/
|
|
17697
|
-
function amountInCents(currency, amount) {
|
|
17698
|
-
return Math.round(amount * 100);
|
|
17699
|
-
}
|
|
17700
|
-
|
|
17701
17859
|
class PaymentController {
|
|
17702
17860
|
constructor(api, options) {
|
|
17703
17861
|
this.api = api;
|
|
@@ -18400,7 +18558,7 @@
|
|
|
18400
18558
|
const api = {};
|
|
18401
18559
|
|
|
18402
18560
|
Object.assign(api, {
|
|
18403
|
-
version: '5.
|
|
18561
|
+
version: '5.8.0',
|
|
18404
18562
|
options,
|
|
18405
18563
|
request,
|
|
18406
18564
|
|