swell-js 5.1.2 → 5.2.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/swell.cjs CHANGED
@@ -6312,6 +6312,7 @@ const SCRIPT_HANDLERS = {
6312
6312
  'braintree-google-payment': loadBraintreeGoogle,
6313
6313
  'braintree-apple-payment': loadBraintreeApple,
6314
6314
  'amazon-checkout': loadAmazonCheckout,
6315
+ 'sezzle-sdk': loadSezzleCheckout,
6315
6316
  };
6316
6317
 
6317
6318
  const BRAINTREE_VERSION = '3.91.0';
@@ -6479,6 +6480,19 @@ async function loadAmazonCheckout() {
6479
6480
  }
6480
6481
  }
6481
6482
 
6483
+ async function loadSezzleCheckout() {
6484
+ if (!window.Checkout) {
6485
+ await loadScript(
6486
+ 'sezzle-sdk',
6487
+ 'https://checkout-sdk.sezzle.com/express_checkout.min.js',
6488
+ );
6489
+ }
6490
+
6491
+ if (!window.Checkout) {
6492
+ console.error('Warning: Sezzle Checkout was not loaded');
6493
+ }
6494
+ }
6495
+
6482
6496
  async function loadScripts(scripts) {
6483
6497
  if (!scripts) {
6484
6498
  return;
@@ -6732,8 +6746,8 @@ class Payment {
6732
6746
  /**
6733
6747
  * Calls the onSuccess handler.
6734
6748
  *
6735
- * @param {object | undefined} data
6736
- * @returns {any}
6749
+ * @param {unknown} [data]
6750
+ * @returns {unknown}
6737
6751
  */
6738
6752
  onSuccess(data) {
6739
6753
  const successHandler = get(this.params, 'onSuccess');
@@ -6746,7 +6760,7 @@ class Payment {
6746
6760
  /**
6747
6761
  * Calls the onCancel handler.
6748
6762
  *
6749
- * @returns {any}
6763
+ * @returns {unknown}
6750
6764
  */
6751
6765
  onCancel() {
6752
6766
  const cancelHandler = get(this.params, 'onCancel');
@@ -6760,7 +6774,7 @@ class Payment {
6760
6774
  * Calls the onError handler.
6761
6775
  *
6762
6776
  * @param {Error} error
6763
- * @returns {any}
6777
+ * @returns {unknown}
6764
6778
  */
6765
6779
  onError(error) {
6766
6780
  const errorHandler = get(this.params, 'onError');
@@ -8274,6 +8288,107 @@ class BraintreePaypalPayment extends Payment {
8274
8288
  }
8275
8289
  }
8276
8290
 
8291
+ /** @typedef {import('../../types').Cart} Cart */
8292
+ /** @typedef {import('../../types').Discount} Discount */
8293
+
8294
+ function adjustConfig(params) {
8295
+ if (!params.config) {
8296
+ return;
8297
+ }
8298
+
8299
+ if (params.card) {
8300
+ console.warn('Please move the "config" field to the "card.config"');
8301
+
8302
+ params.card.config = params.config;
8303
+ }
8304
+
8305
+ if (params.ideal) {
8306
+ console.warn('Please move the "config" field to the "ideal.config"');
8307
+
8308
+ params.ideal.config = params.config;
8309
+ }
8310
+
8311
+ delete params.config;
8312
+ }
8313
+
8314
+ function adjustElementId(methodParams) {
8315
+ if (methodParams.cardNumber) {
8316
+ adjustElementId(methodParams.cardNumber);
8317
+ }
8318
+
8319
+ if (methodParams.cardExpiry) {
8320
+ adjustElementId(methodParams.cardExpiry);
8321
+ }
8322
+
8323
+ if (methodParams.cardCvc) {
8324
+ adjustElementId(methodParams.cardCvc);
8325
+ }
8326
+
8327
+ if (!methodParams.elementId) {
8328
+ return;
8329
+ }
8330
+
8331
+ if (methodParams.elementId.startsWith('#')) {
8332
+ console.warn(
8333
+ `Please remove the "#" sign from the "${methodParams.elementId}" element ID`,
8334
+ );
8335
+
8336
+ methodParams.elementId = methodParams.elementId.substring(1);
8337
+ }
8338
+ }
8339
+
8340
+ function adjustParams(_params) {
8341
+ const params = { ..._params };
8342
+
8343
+ adjustConfig(params);
8344
+
8345
+ return params;
8346
+ }
8347
+
8348
+ function adjustMethodParams(_methodParams) {
8349
+ const methodParams = { ..._methodParams };
8350
+
8351
+ adjustElementId(methodParams);
8352
+
8353
+ return methodParams;
8354
+ }
8355
+
8356
+ /**
8357
+ * @param {Discount} discount
8358
+ * @param {Cart} cart
8359
+ */
8360
+ function getDiscountLabel(discount, cart) {
8361
+ switch (discount.type) {
8362
+ case 'coupon': {
8363
+ const { coupon } = cart;
8364
+
8365
+ if (coupon?.name) {
8366
+ return coupon.name;
8367
+ }
8368
+
8369
+ break;
8370
+ }
8371
+
8372
+ case 'promo': {
8373
+ const { promotions } = cart;
8374
+
8375
+ if (Array.isArray(promotions?.results)) {
8376
+ const promo = promotions.results.find(
8377
+ (promo) => promo.id === discount.source_id,
8378
+ );
8379
+
8380
+ if (promo?.name) {
8381
+ return promo?.name;
8382
+ }
8383
+ }
8384
+
8385
+ break;
8386
+ }
8387
+ }
8388
+
8389
+ return discount.id;
8390
+ }
8391
+
8277
8392
  /** @typedef {import('./payment').default} Payment */
8278
8393
  /** @typedef {import('../../types').Cart} Cart */
8279
8394
  /** @typedef {import('../../types').Address} Address */
@@ -8316,7 +8431,7 @@ async function onPaymentDataChanged(intermediatePaymentData) {
8316
8431
 
8317
8432
  // Update cart with new shipping address and force tax recalculation
8318
8433
  let cart = await this.updateCart({
8319
- shipping: convertToSwellAddress$1(
8434
+ shipping: convertToSwellAddress$2(
8320
8435
  intermediatePaymentData.shippingAddress,
8321
8436
  ),
8322
8437
  });
@@ -8409,42 +8524,6 @@ async function onPaymentDataChanged(intermediatePaymentData) {
8409
8524
  return {};
8410
8525
  }
8411
8526
 
8412
- /**
8413
- * @param {Discount} discount
8414
- * @param {Cart} cart
8415
- */
8416
- function getDiscountLabel(discount, cart) {
8417
- switch (discount.type) {
8418
- case 'coupon': {
8419
- const { coupon } = cart;
8420
-
8421
- if (coupon?.name) {
8422
- return coupon.name;
8423
- }
8424
-
8425
- break;
8426
- }
8427
-
8428
- case 'promo': {
8429
- const { promotions } = cart;
8430
-
8431
- if (Array.isArray(promotions?.results)) {
8432
- const promo = promotions.results.find(
8433
- (promo) => promo.id === discount.source_id,
8434
- );
8435
-
8436
- if (promo?.name) {
8437
- return promo?.name;
8438
- }
8439
- }
8440
-
8441
- break;
8442
- }
8443
- }
8444
-
8445
- return discount.id;
8446
- }
8447
-
8448
8527
  /**
8449
8528
  * Converts cart data to Google Pay display items for the payment sheet.
8450
8529
  * Only works when payment callbacks are properly configured.
@@ -8602,7 +8681,7 @@ function getOfferInfo(cart) {
8602
8681
  * @param {google.payments.api.Address} address
8603
8682
  * @returns {Address}
8604
8683
  */
8605
- function convertToSwellAddress$1(address) {
8684
+ function convertToSwellAddress$2(address) {
8606
8685
  return {
8607
8686
  name: address.name,
8608
8687
  address1: address.address1,
@@ -8863,10 +8942,10 @@ class BraintreeGooglePayment extends Payment {
8863
8942
  nonce,
8864
8943
  gateway: 'braintree',
8865
8944
  },
8866
- ...convertToSwellAddress$1(billingAddress),
8945
+ ...convertToSwellAddress$2(billingAddress),
8867
8946
  },
8868
8947
  ...(requireShipping && {
8869
- shipping: convertToSwellAddress$1(shippingAddress),
8948
+ shipping: convertToSwellAddress$2(shippingAddress),
8870
8949
  }),
8871
8950
  });
8872
8951
 
@@ -8903,7 +8982,7 @@ async function onShippingContactSelected(session, event) {
8903
8982
  // Update cart with Apple Pay shipping address to get shipping options and tax
8904
8983
  // This happens immediately when the sheet opens with the default address
8905
8984
  const cart = await this.updateCart({
8906
- shipping: convertToSwellAddress(event.shippingContact),
8985
+ shipping: convertToSwellAddress$1(event.shippingContact),
8907
8986
  });
8908
8987
 
8909
8988
  if (!cart.shipment_rating?.services?.length) {
@@ -9145,7 +9224,7 @@ function getShippingMethods(cart) {
9145
9224
  * @param {ApplePayJS.ApplePayPaymentContact} [address]
9146
9225
  * @returns {Address}
9147
9226
  */
9148
- function convertToSwellAddress(address = {}) {
9227
+ function convertToSwellAddress$1(address = {}) {
9149
9228
  return {
9150
9229
  first_name: address.givenName,
9151
9230
  last_name: address.familyName,
@@ -9350,10 +9429,10 @@ class BraintreeApplePayment extends Payment {
9350
9429
  nonce: payload.nonce,
9351
9430
  gateway: 'braintree',
9352
9431
  },
9353
- ...convertToSwellAddress(billingContact),
9432
+ ...convertToSwellAddress$1(billingContact),
9354
9433
  },
9355
9434
  ...(requireShipping && {
9356
- shipping: convertToSwellAddress(shippingContact),
9435
+ shipping: convertToSwellAddress$1(shippingContact),
9357
9436
  }),
9358
9437
  });
9359
9438
 
@@ -9531,7 +9610,7 @@ class AuthorizeNetGooglePayment extends Payment {
9531
9610
  throw new Error('Payment token is missing');
9532
9611
  }
9533
9612
 
9534
- const cart = await this.updateCart({
9613
+ await this.updateCart({
9535
9614
  account: {
9536
9615
  email,
9537
9616
  },
@@ -9543,14 +9622,14 @@ class AuthorizeNetGooglePayment extends Payment {
9543
9622
  gateway: 'authorizenet',
9544
9623
  token: base64Encode(token),
9545
9624
  },
9546
- ...convertToSwellAddress$1(billingAddress),
9625
+ ...convertToSwellAddress$2(billingAddress),
9547
9626
  },
9548
9627
  ...(requireShipping && {
9549
- shipping: convertToSwellAddress$1(shippingAddress),
9628
+ shipping: convertToSwellAddress$2(shippingAddress),
9550
9629
  }),
9551
9630
  });
9552
9631
 
9553
- this.onSuccess(cart);
9632
+ this.onSuccess();
9554
9633
  }
9555
9634
 
9556
9635
  /**
@@ -9832,7 +9911,7 @@ class AuthorizeNetApplePayment extends Payment {
9832
9911
  //
9833
9912
  // We store the payment token but DO NOT process the order yet.
9834
9913
  // The user must manually click "Place Order" to complete the transaction.
9835
- const cart = await this.updateCart({
9914
+ await this.updateCart({
9836
9915
  account: {
9837
9916
  email: shippingContact.emailAddress,
9838
9917
  },
@@ -9844,10 +9923,10 @@ class AuthorizeNetApplePayment extends Payment {
9844
9923
  token: base64Encode(JSON.stringify(token.paymentData)),
9845
9924
  gateway: 'authorizenet',
9846
9925
  },
9847
- ...convertToSwellAddress(billingContact),
9926
+ ...convertToSwellAddress$1(billingContact),
9848
9927
  },
9849
9928
  ...(requireShipping && {
9850
- shipping: convertToSwellAddress(shippingContact),
9929
+ shipping: convertToSwellAddress$1(shippingContact),
9851
9930
  }),
9852
9931
  });
9853
9932
 
@@ -9860,7 +9939,7 @@ class AuthorizeNetApplePayment extends Payment {
9860
9939
  // Notify that Apple Pay authorization is complete
9861
9940
  // The cart now has the payment token and is ready for submission
9862
9941
  // NOTE: This does NOT submit the order - user must click "Place Order"
9863
- this.onSuccess(cart);
9942
+ this.onSuccess();
9864
9943
  } catch (err) {
9865
9944
  session.completePayment({
9866
9945
  status: this.ApplePaySession.STATUS_FAILURE,
@@ -10686,66 +10765,438 @@ class AmazonDirectPayment extends Payment {
10686
10765
  }
10687
10766
  }
10688
10767
 
10689
- function adjustConfig(params) {
10690
- if (!params.config) {
10691
- return;
10768
+ /** @typedef {import('../../../types').Cart} Cart */
10769
+ /** @typedef {import('../../../types').Address} Address */
10770
+
10771
+ /**
10772
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderAmount
10773
+ * @prop {number} amount_in_cents
10774
+ * @prop {string} currency
10775
+ */
10776
+
10777
+ /**
10778
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderItem
10779
+ * @prop {string} name
10780
+ * @prop {string} sku
10781
+ * @prop {number} quantity
10782
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} price
10783
+ */
10784
+
10785
+ /**
10786
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderDiscount
10787
+ * @prop {string} name
10788
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} amount
10789
+ */
10790
+
10791
+ /**
10792
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrder
10793
+ * @prop {'AUTH' | 'CAPTURE'} intent
10794
+ * @prop {string} reference_id
10795
+ * @prop {string} description
10796
+ * @prop {boolean} requires_shipping_info
10797
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderItem[]} items
10798
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderDiscount[]} discounts
10799
+ * @prop {Record<string, string>} [metadata]
10800
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} tax_amount
10801
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} order_amount
10802
+ */
10803
+
10804
+ /**
10805
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadData
10806
+ * @prop {'single-step' | 'multi-step' | 'no-shipping'} express_checkout_type
10807
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrder} order
10808
+ */
10809
+
10810
+ /**
10811
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayload
10812
+ * @prop {SezzleCheckoutSdkCheckoutPayloadData} checkout_payload
10813
+ */
10814
+
10815
+ /**
10816
+ * @typedef {object} SezzleCheckoutSdkCheckoutUrl
10817
+ * @prop {string} checkout_url
10818
+ */
10819
+
10820
+ /**
10821
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingAddress
10822
+ * @prop {string} uuid
10823
+ * @prop {string} name
10824
+ * @prop {string} street
10825
+ * @prop {string} street2
10826
+ * @prop {string} city
10827
+ * @prop {string} state
10828
+ * @prop {string} postal_code
10829
+ * @prop {string} country_code
10830
+ * @prop {string} phone
10831
+ */
10832
+
10833
+ /**
10834
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingError
10835
+ * @prop {'merchant_unsupported_shipping_address' | 'merchant_error'} code
10836
+ */
10837
+
10838
+ /**
10839
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingResult
10840
+ * @prop {boolean} ok
10841
+ * @prop {SezzleCheckoutSdkCheckoutShippingError} [error]
10842
+ */
10843
+
10844
+ /**
10845
+ * @typedef {object} SezzleCheckoutSdkInit
10846
+ * @prop {(event: MouseEvent) => void} onClick
10847
+ * @prop {(event: CustomEvent) => void} onComplete
10848
+ * @prop {() => void} onCancel
10849
+ * @prop {() => void} onFailure
10850
+ * @prop {(shippingAddress: SezzleCheckoutSdkCheckoutShippingAddress, orderUuid: string) => Promise<SezzleCheckoutSdkCheckoutShippingResult>} onCalculateAddressRelatedCosts
10851
+ */
10852
+
10853
+ /**
10854
+ * @typedef {object} SezzleCheckoutSdk
10855
+ * @prop {(containerId: string) => void} renderSezzleButton
10856
+ * @prop {(options: SezzleCheckoutSdkInit) => void} init
10857
+ * @prop {(options: SezzleCheckoutSdkCheckoutPayload | SezzleCheckoutSdkCheckoutUrl) => void} startCheckout
10858
+ */
10859
+
10860
+ /**
10861
+ * @typedef {object} SezzleCheckoutOptions
10862
+ * @prop {'popup' | 'iframe' | 'redirect'} [mode='popup']
10863
+ * @prop {string} publicKey
10864
+ * @prop {'live' | 'sandbox'} [apiMode='live']
10865
+ * @prop {'v2'} [apiVersion='v2']
10866
+ */
10867
+
10868
+ /** @typedef {new (options: SezzleCheckoutOptions) => SezzleCheckoutSdk} SezzleCheckout */
10869
+
10870
+ const SEZZLE_BUTTON_ID = 'sezzle-smart-button-container';
10871
+
10872
+ class SezzleDirectPayment extends Payment {
10873
+ constructor(api, options, params, methods) {
10874
+ super(api, options, params, methods.sezzle);
10875
+
10876
+ /** @type {SezzleCheckoutSdkCheckoutPayload | null} */
10877
+ this._paymentRequest = null;
10692
10878
  }
10693
10879
 
10694
- if (params.card) {
10695
- console.warn('Please move the "config" field to the "card.config"');
10880
+ get scripts() {
10881
+ return ['sezzle-sdk'];
10882
+ }
10696
10883
 
10697
- params.card.config = params.config;
10884
+ /** @returns {SezzleCheckout} */
10885
+ get SezzleCheckout() {
10886
+ if (!window.Checkout) {
10887
+ throw new LibraryNotLoadedError('Sezzle');
10888
+ }
10889
+
10890
+ return window.Checkout;
10698
10891
  }
10699
10892
 
10700
- if (params.ideal) {
10701
- console.warn('Please move the "config" field to the "ideal.config"');
10893
+ /** @returns {SezzleCheckoutSdk} */
10894
+ get SezzleSdk() {
10895
+ if (!this._sezzleSdk) {
10896
+ this._sezzleSdk = new this.SezzleCheckout({
10897
+ mode: 'popup',
10898
+ publicKey: this.method.public_key,
10899
+ apiMode: isLiveMode(this.method.mode) ? 'live' : 'sandbox',
10900
+ apiVersion: 'v2',
10901
+ });
10702
10902
 
10703
- params.ideal.config = params.config;
10903
+ if (!this._sezzleSdk) {
10904
+ throw new LibraryNotLoadedError('Sezzle sdk client');
10905
+ }
10906
+ }
10907
+
10908
+ return this._sezzleSdk;
10704
10909
  }
10705
10910
 
10706
- delete params.config;
10707
- }
10911
+ /**
10912
+ * @param {Cart} cart
10913
+ * @returns {SezzleCheckoutSdkCheckoutPayload}
10914
+ */
10915
+ _createPaymentRequest(cart) {
10916
+ const {
10917
+ settings: { name },
10918
+ } = cart;
10708
10919
 
10709
- function adjustElementId(methodParams) {
10710
- if (methodParams.cardNumber) {
10711
- adjustElementId(methodParams.cardNumber);
10920
+ const shipmentDelivery = Boolean(cart.shipment_delivery);
10921
+ const cartCurrency = getCartCurrency(cart);
10922
+
10923
+ return {
10924
+ checkout_payload: {
10925
+ express_checkout_type: shipmentDelivery ? 'multi-step' : 'no-shipping',
10926
+ order: {
10927
+ intent: 'AUTH',
10928
+ reference_id: cart.checkout_id,
10929
+ description: `${name} #${cart.number}`,
10930
+ requires_shipping_info: shipmentDelivery,
10931
+ items: getItems(cart),
10932
+ discounts: getDiscounts(cart),
10933
+ tax_amount: shipmentDelivery
10934
+ ? undefined
10935
+ : getAmountInCents(cartCurrency, cart.tax_total),
10936
+ order_amount: getAmountInCents(cartCurrency, cart.capture_total),
10937
+ },
10938
+ },
10939
+ };
10712
10940
  }
10713
10941
 
10714
- if (methodParams.cardExpiry) {
10715
- adjustElementId(methodParams.cardExpiry);
10942
+ _createButton() {
10943
+ const { style = {} } = this.params;
10944
+
10945
+ if (!style.templateText) {
10946
+ style.templateText = '%%logo%%';
10947
+ }
10948
+
10949
+ if (!style.borderType) {
10950
+ style.borderType = 'square';
10951
+ }
10952
+
10953
+ if (!style.width) {
10954
+ style.width = '100%';
10955
+ }
10956
+
10957
+ if (!style.height) {
10958
+ style.height = '45px';
10959
+ }
10960
+
10961
+ const button = document.createElement('div');
10962
+
10963
+ for (const attrId of Object.keys(style)) {
10964
+ button.setAttribute(attrId, style[attrId]);
10965
+ }
10966
+
10967
+ button.setAttribute('id', SEZZLE_BUTTON_ID);
10968
+ button.style.textAlign = 'center';
10969
+
10970
+ return button;
10716
10971
  }
10717
10972
 
10718
- if (methodParams.cardCvc) {
10719
- adjustElementId(methodParams.cardCvc);
10973
+ _initSezzleSdk() {
10974
+ let shippingServices = [];
10975
+
10976
+ this.SezzleSdk.init({
10977
+ onClick: (event) => {
10978
+ event.preventDefault();
10979
+
10980
+ this.SezzleSdk.startCheckout(this._paymentRequest);
10981
+ },
10982
+ onComplete: async (event) => {
10983
+ try {
10984
+ const { order_uuid } = event.data;
10985
+
10986
+ const details = await this.authorizeGateway({
10987
+ gateway: 'sezzle',
10988
+ params: {
10989
+ action: 'details',
10990
+ order_uuid,
10991
+ },
10992
+ });
10993
+
10994
+ let shippingService = null;
10995
+
10996
+ if (details.service_name) {
10997
+ shippingService =
10998
+ shippingServices.find(
10999
+ (service) => service.name === details.service_name,
11000
+ )?.id ?? null;
11001
+ }
11002
+
11003
+ await this.updateCart({
11004
+ account: details.account,
11005
+ shipping: {
11006
+ ...details.shipping,
11007
+ service: shippingService,
11008
+ },
11009
+ billing: {
11010
+ method: 'sezzle',
11011
+ account_card_id: null,
11012
+ card: null,
11013
+ sezzle: { order_uuid },
11014
+ ...details.billing,
11015
+ },
11016
+ });
11017
+
11018
+ this.onSuccess();
11019
+ } catch (err) {
11020
+ this.onError(err);
11021
+ }
11022
+ },
11023
+ onCancel(_event) {},
11024
+ onFailure: (event) => {
11025
+ this.onError(event.data);
11026
+ },
11027
+ onCalculateAddressRelatedCosts: async (address, orderUuid) => {
11028
+ const cart = await this.updateCart({
11029
+ shipping: convertToSwellAddress(address),
11030
+ });
11031
+
11032
+ if (!cart.shipment_rating?.services?.length) {
11033
+ return {
11034
+ ok: false,
11035
+ error: { code: 'merchant_unsupported_shipping_address' },
11036
+ };
11037
+ }
11038
+
11039
+ shippingServices = cart.shipment_rating.services;
11040
+
11041
+ const result = await this.authorizeGateway({
11042
+ gateway: 'sezzle',
11043
+ params: {
11044
+ action: 'shipping',
11045
+ order_uuid: orderUuid,
11046
+ currency_code: cart.currency,
11047
+ address_uuid: address.uuid,
11048
+ shipping_options: cart.shipment_rating.services.map((service) => ({
11049
+ name: service.name,
11050
+ description: service.description,
11051
+ shipping_amount_in_cents: amountInCents(
11052
+ cart.currency,
11053
+ service.price || 0,
11054
+ ),
11055
+ tax_amount_in_cents: amountInCents(
11056
+ cart.currency,
11057
+ cart.tax_total || 0,
11058
+ ),
11059
+ final_order_amount_in_cents: amountInCents(
11060
+ cart.currency,
11061
+ (cart.sub_total || 0) +
11062
+ (cart.tax_total || 0) +
11063
+ (service.price || 0),
11064
+ ),
11065
+ })),
11066
+ },
11067
+ });
11068
+
11069
+ if (result?.error) {
11070
+ console.error(
11071
+ '[Sezzle] Update checkout by order error:',
11072
+ result.error,
11073
+ );
11074
+
11075
+ return {
11076
+ ok: false,
11077
+ error: { code: 'merchant_error' },
11078
+ };
11079
+ }
11080
+
11081
+ return { ok: true };
11082
+ },
11083
+ });
10720
11084
  }
10721
11085
 
10722
- if (!methodParams.elementId) {
10723
- return;
11086
+ /**
11087
+ * Creates the Sezzle button element
11088
+ *
11089
+ * @param {Cart} cart
11090
+ */
11091
+ async createElements(cart) {
11092
+ const { elementId = 'sezzle-button' } = this.params;
11093
+
11094
+ this.setElementContainer(elementId);
11095
+ await this.loadScripts(this.scripts);
11096
+
11097
+ this._paymentRequest = this._createPaymentRequest(cart);
11098
+
11099
+ this.element = this._createButton();
10724
11100
  }
10725
11101
 
10726
- if (methodParams.elementId.startsWith('#')) {
10727
- console.warn(
10728
- `Please remove the "#" sign from the "${methodParams.elementId}" element ID`,
10729
- );
11102
+ /**
11103
+ * Mounts the Sezzle button to the DOM
11104
+ */
11105
+ mountElements() {
11106
+ const { classes = {} } = this.params;
11107
+ const container = this.elementContainer;
10730
11108
 
10731
- methodParams.elementId = methodParams.elementId.substring(1);
11109
+ container.appendChild(this.element);
11110
+
11111
+ this.SezzleSdk.renderSezzleButton(SEZZLE_BUTTON_ID);
11112
+
11113
+ if (classes.base) {
11114
+ container.classList.add(classes.base);
11115
+ }
11116
+
11117
+ this._initSezzleSdk();
10732
11118
  }
10733
11119
  }
10734
11120
 
10735
- function adjustParams(_params) {
10736
- const params = { ..._params };
11121
+ /**
11122
+ * @param {Cart} cart
11123
+ * @returns {string}
11124
+ */
11125
+ function getCartCurrency(cart) {
11126
+ const {
11127
+ settings: { currency },
11128
+ } = cart;
10737
11129
 
10738
- adjustConfig(params);
11130
+ return cart.currency || currency || 'USD';
11131
+ }
10739
11132
 
10740
- return params;
11133
+ /**
11134
+ * @param {string} currency
11135
+ * @param {number} amount
11136
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderAmount}
11137
+ */
11138
+ function getAmountInCents(currency, amount) {
11139
+ return {
11140
+ amount_in_cents: amountInCents(currency, amount),
11141
+ currency,
11142
+ };
10741
11143
  }
10742
11144
 
10743
- function adjustMethodParams(_methodParams) {
10744
- const methodParams = { ..._methodParams };
11145
+ /**
11146
+ * @param {Cart} cart
11147
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderItem[]}
11148
+ */
11149
+ function getItems(cart) {
11150
+ const currency = getCartCurrency(cart);
10745
11151
 
10746
- adjustElementId(methodParams);
11152
+ /** @type {SezzleCheckoutSdkCheckoutPayloadOrderItem[]} */
11153
+ const items = cart.items.map((item, index) => ({
11154
+ name: item.product?.name || `Product ${index + 1}`,
11155
+ sku: item.product?.sku || `Product SKU ${index + 1}`,
11156
+ quantity: item.quantity || 1,
11157
+ price: getAmountInCents(currency, item.price || 0),
11158
+ }));
10747
11159
 
10748
- return methodParams;
11160
+ return items;
11161
+ }
11162
+
11163
+ /**
11164
+ * @param {Cart} cart
11165
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderDiscount[]}
11166
+ */
11167
+ function getDiscounts(cart) {
11168
+ const currency = getCartCurrency(cart);
11169
+
11170
+ return (cart.discounts || []).map((discount) => ({
11171
+ name: getDiscountLabel(discount, cart),
11172
+ amount: getAmountInCents(currency, discount.amount || 0),
11173
+ }));
11174
+ }
11175
+
11176
+ /**
11177
+ * @param {SezzleCheckoutSdkCheckoutShippingAddress} address
11178
+ * @returns {Address}
11179
+ */
11180
+ function convertToSwellAddress(address) {
11181
+ return {
11182
+ name: address.name || null,
11183
+ address1: address.street || null,
11184
+ address2: address.street2 || null,
11185
+ city: address.city || null,
11186
+ state: address.state || null,
11187
+ zip: address.postal_code || null,
11188
+ country: address.country_code || null,
11189
+ phone: address.phone || null,
11190
+ };
11191
+ }
11192
+
11193
+ /**
11194
+ * @param {string} currency
11195
+ * @param {number} amount
11196
+ * @returns {number}
11197
+ */
11198
+ function amountInCents(currency, amount) {
11199
+ return Math.round(amount * 100);
10749
11200
  }
10750
11201
 
10751
11202
  class PaymentController {
@@ -10914,6 +11365,9 @@ class PaymentController {
10914
11365
  return response;
10915
11366
  }
10916
11367
 
11368
+ /**
11369
+ * @returns {Promise<Payment[]>}
11370
+ */
10917
11371
  async _createPaymentInstances() {
10918
11372
  const paymentMethods = await this._getPaymentMethods();
10919
11373
  const params = adjustParams(this.params);
@@ -10959,6 +11413,12 @@ class PaymentController {
10959
11413
  }, []);
10960
11414
  }
10961
11415
 
11416
+ /**
11417
+ * @param {Payment[]} paymentInstances
11418
+ * @param {string} action
11419
+ * @param {...unknown} args
11420
+ * @returns {Promise<Payment[]>}
11421
+ */
10962
11422
  async _performPaymentAction(paymentInstances, action, ...args) {
10963
11423
  const actions = paymentInstances.reduce((acc, instance) => {
10964
11424
  const paymentAction = instance[action];
@@ -10979,9 +11439,7 @@ class PaymentController {
10979
11439
  await resultPromise;
10980
11440
  nextPaymentInstances.push(instance);
10981
11441
  } catch (error) {
10982
- const onPaymentError = instance.onError.bind(instance);
10983
-
10984
- onPaymentError(error);
11442
+ instance.onError(error);
10985
11443
  }
10986
11444
  }
10987
11445
 
@@ -11008,6 +11466,8 @@ class PaymentController {
11008
11466
  return this._getApplePaymentClass(gateway);
11009
11467
  case 'amazon':
11010
11468
  return this._getAmazonPaymentClass(gateway);
11469
+ case 'sezzle':
11470
+ return this._getSezzlePaymentClass(gateway);
11011
11471
  default:
11012
11472
  return null;
11013
11473
  }
@@ -11101,6 +11561,13 @@ class PaymentController {
11101
11561
  return AmazonDirectPayment;
11102
11562
  }
11103
11563
  }
11564
+
11565
+ _getSezzlePaymentClass(gateway) {
11566
+ switch (gateway) {
11567
+ default:
11568
+ return SezzleDirectPayment;
11569
+ }
11570
+ }
11104
11571
  }
11105
11572
 
11106
11573
  function methods$2(api, opt) {
@@ -11437,7 +11904,7 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
11437
11904
  const api = {};
11438
11905
 
11439
11906
  Object.assign(api, {
11440
- version: '5.1.2',
11907
+ version: '5.2.0',
11441
11908
  options,
11442
11909
  request,
11443
11910