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.
@@ -11757,6 +11757,7 @@
11757
11757
  'braintree-google-payment': loadBraintreeGoogle,
11758
11758
  'braintree-apple-payment': loadBraintreeApple,
11759
11759
  'amazon-checkout': loadAmazonCheckout,
11760
+ 'sezzle-sdk': loadSezzleCheckout,
11760
11761
  };
11761
11762
 
11762
11763
  const BRAINTREE_VERSION = '3.91.0';
@@ -11924,6 +11925,19 @@
11924
11925
  }
11925
11926
  }
11926
11927
 
11928
+ async function loadSezzleCheckout() {
11929
+ if (!window.Checkout) {
11930
+ await loadScript(
11931
+ 'sezzle-sdk',
11932
+ 'https://checkout-sdk.sezzle.com/express_checkout.min.js',
11933
+ );
11934
+ }
11935
+
11936
+ if (!window.Checkout) {
11937
+ console.error('Warning: Sezzle Checkout was not loaded');
11938
+ }
11939
+ }
11940
+
11927
11941
  async function loadScripts(scripts) {
11928
11942
  if (!scripts) {
11929
11943
  return;
@@ -12177,8 +12191,8 @@
12177
12191
  /**
12178
12192
  * Calls the onSuccess handler.
12179
12193
  *
12180
- * @param {object | undefined} data
12181
- * @returns {any}
12194
+ * @param {unknown} [data]
12195
+ * @returns {unknown}
12182
12196
  */
12183
12197
  onSuccess(data) {
12184
12198
  const successHandler = get(this.params, 'onSuccess');
@@ -12191,7 +12205,7 @@
12191
12205
  /**
12192
12206
  * Calls the onCancel handler.
12193
12207
  *
12194
- * @returns {any}
12208
+ * @returns {unknown}
12195
12209
  */
12196
12210
  onCancel() {
12197
12211
  const cancelHandler = get(this.params, 'onCancel');
@@ -12205,7 +12219,7 @@
12205
12219
  * Calls the onError handler.
12206
12220
  *
12207
12221
  * @param {Error} error
12208
- * @returns {any}
12222
+ * @returns {unknown}
12209
12223
  */
12210
12224
  onError(error) {
12211
12225
  const errorHandler = get(this.params, 'onError');
@@ -13719,6 +13733,107 @@
13719
13733
  }
13720
13734
  }
13721
13735
 
13736
+ /** @typedef {import('../../types').Cart} Cart */
13737
+ /** @typedef {import('../../types').Discount} Discount */
13738
+
13739
+ function adjustConfig(params) {
13740
+ if (!params.config) {
13741
+ return;
13742
+ }
13743
+
13744
+ if (params.card) {
13745
+ console.warn('Please move the "config" field to the "card.config"');
13746
+
13747
+ params.card.config = params.config;
13748
+ }
13749
+
13750
+ if (params.ideal) {
13751
+ console.warn('Please move the "config" field to the "ideal.config"');
13752
+
13753
+ params.ideal.config = params.config;
13754
+ }
13755
+
13756
+ delete params.config;
13757
+ }
13758
+
13759
+ function adjustElementId(methodParams) {
13760
+ if (methodParams.cardNumber) {
13761
+ adjustElementId(methodParams.cardNumber);
13762
+ }
13763
+
13764
+ if (methodParams.cardExpiry) {
13765
+ adjustElementId(methodParams.cardExpiry);
13766
+ }
13767
+
13768
+ if (methodParams.cardCvc) {
13769
+ adjustElementId(methodParams.cardCvc);
13770
+ }
13771
+
13772
+ if (!methodParams.elementId) {
13773
+ return;
13774
+ }
13775
+
13776
+ if (methodParams.elementId.startsWith('#')) {
13777
+ console.warn(
13778
+ `Please remove the "#" sign from the "${methodParams.elementId}" element ID`,
13779
+ );
13780
+
13781
+ methodParams.elementId = methodParams.elementId.substring(1);
13782
+ }
13783
+ }
13784
+
13785
+ function adjustParams(_params) {
13786
+ const params = { ..._params };
13787
+
13788
+ adjustConfig(params);
13789
+
13790
+ return params;
13791
+ }
13792
+
13793
+ function adjustMethodParams(_methodParams) {
13794
+ const methodParams = { ..._methodParams };
13795
+
13796
+ adjustElementId(methodParams);
13797
+
13798
+ return methodParams;
13799
+ }
13800
+
13801
+ /**
13802
+ * @param {Discount} discount
13803
+ * @param {Cart} cart
13804
+ */
13805
+ function getDiscountLabel(discount, cart) {
13806
+ switch (discount.type) {
13807
+ case 'coupon': {
13808
+ const { coupon } = cart;
13809
+
13810
+ if (coupon?.name) {
13811
+ return coupon.name;
13812
+ }
13813
+
13814
+ break;
13815
+ }
13816
+
13817
+ case 'promo': {
13818
+ const { promotions } = cart;
13819
+
13820
+ if (Array.isArray(promotions?.results)) {
13821
+ const promo = promotions.results.find(
13822
+ (promo) => promo.id === discount.source_id,
13823
+ );
13824
+
13825
+ if (promo?.name) {
13826
+ return promo?.name;
13827
+ }
13828
+ }
13829
+
13830
+ break;
13831
+ }
13832
+ }
13833
+
13834
+ return discount.id;
13835
+ }
13836
+
13722
13837
  /** @typedef {import('./payment').default} Payment */
13723
13838
  /** @typedef {import('../../types').Cart} Cart */
13724
13839
  /** @typedef {import('../../types').Address} Address */
@@ -13761,7 +13876,7 @@
13761
13876
 
13762
13877
  // Update cart with new shipping address and force tax recalculation
13763
13878
  let cart = await this.updateCart({
13764
- shipping: convertToSwellAddress$1(
13879
+ shipping: convertToSwellAddress$2(
13765
13880
  intermediatePaymentData.shippingAddress,
13766
13881
  ),
13767
13882
  });
@@ -13854,42 +13969,6 @@
13854
13969
  return {};
13855
13970
  }
13856
13971
 
13857
- /**
13858
- * @param {Discount} discount
13859
- * @param {Cart} cart
13860
- */
13861
- function getDiscountLabel(discount, cart) {
13862
- switch (discount.type) {
13863
- case 'coupon': {
13864
- const { coupon } = cart;
13865
-
13866
- if (coupon?.name) {
13867
- return coupon.name;
13868
- }
13869
-
13870
- break;
13871
- }
13872
-
13873
- case 'promo': {
13874
- const { promotions } = cart;
13875
-
13876
- if (Array.isArray(promotions?.results)) {
13877
- const promo = promotions.results.find(
13878
- (promo) => promo.id === discount.source_id,
13879
- );
13880
-
13881
- if (promo?.name) {
13882
- return promo?.name;
13883
- }
13884
- }
13885
-
13886
- break;
13887
- }
13888
- }
13889
-
13890
- return discount.id;
13891
- }
13892
-
13893
13972
  /**
13894
13973
  * Converts cart data to Google Pay display items for the payment sheet.
13895
13974
  * Only works when payment callbacks are properly configured.
@@ -14047,7 +14126,7 @@
14047
14126
  * @param {google.payments.api.Address} address
14048
14127
  * @returns {Address}
14049
14128
  */
14050
- function convertToSwellAddress$1(address) {
14129
+ function convertToSwellAddress$2(address) {
14051
14130
  return {
14052
14131
  name: address.name,
14053
14132
  address1: address.address1,
@@ -14308,10 +14387,10 @@
14308
14387
  nonce,
14309
14388
  gateway: 'braintree',
14310
14389
  },
14311
- ...convertToSwellAddress$1(billingAddress),
14390
+ ...convertToSwellAddress$2(billingAddress),
14312
14391
  },
14313
14392
  ...(requireShipping && {
14314
- shipping: convertToSwellAddress$1(shippingAddress),
14393
+ shipping: convertToSwellAddress$2(shippingAddress),
14315
14394
  }),
14316
14395
  });
14317
14396
 
@@ -14348,7 +14427,7 @@
14348
14427
  // Update cart with Apple Pay shipping address to get shipping options and tax
14349
14428
  // This happens immediately when the sheet opens with the default address
14350
14429
  const cart = await this.updateCart({
14351
- shipping: convertToSwellAddress(event.shippingContact),
14430
+ shipping: convertToSwellAddress$1(event.shippingContact),
14352
14431
  });
14353
14432
 
14354
14433
  if (!cart.shipment_rating?.services?.length) {
@@ -14590,7 +14669,7 @@
14590
14669
  * @param {ApplePayJS.ApplePayPaymentContact} [address]
14591
14670
  * @returns {Address}
14592
14671
  */
14593
- function convertToSwellAddress(address = {}) {
14672
+ function convertToSwellAddress$1(address = {}) {
14594
14673
  return {
14595
14674
  first_name: address.givenName,
14596
14675
  last_name: address.familyName,
@@ -14795,10 +14874,10 @@
14795
14874
  nonce: payload.nonce,
14796
14875
  gateway: 'braintree',
14797
14876
  },
14798
- ...convertToSwellAddress(billingContact),
14877
+ ...convertToSwellAddress$1(billingContact),
14799
14878
  },
14800
14879
  ...(requireShipping && {
14801
- shipping: convertToSwellAddress(shippingContact),
14880
+ shipping: convertToSwellAddress$1(shippingContact),
14802
14881
  }),
14803
14882
  });
14804
14883
 
@@ -14976,7 +15055,7 @@
14976
15055
  throw new Error('Payment token is missing');
14977
15056
  }
14978
15057
 
14979
- const cart = await this.updateCart({
15058
+ await this.updateCart({
14980
15059
  account: {
14981
15060
  email,
14982
15061
  },
@@ -14988,14 +15067,14 @@
14988
15067
  gateway: 'authorizenet',
14989
15068
  token: base64Encode(token),
14990
15069
  },
14991
- ...convertToSwellAddress$1(billingAddress),
15070
+ ...convertToSwellAddress$2(billingAddress),
14992
15071
  },
14993
15072
  ...(requireShipping && {
14994
- shipping: convertToSwellAddress$1(shippingAddress),
15073
+ shipping: convertToSwellAddress$2(shippingAddress),
14995
15074
  }),
14996
15075
  });
14997
15076
 
14998
- this.onSuccess(cart);
15077
+ this.onSuccess();
14999
15078
  }
15000
15079
 
15001
15080
  /**
@@ -15277,7 +15356,7 @@
15277
15356
  //
15278
15357
  // We store the payment token but DO NOT process the order yet.
15279
15358
  // The user must manually click "Place Order" to complete the transaction.
15280
- const cart = await this.updateCart({
15359
+ await this.updateCart({
15281
15360
  account: {
15282
15361
  email: shippingContact.emailAddress,
15283
15362
  },
@@ -15289,10 +15368,10 @@
15289
15368
  token: base64Encode(JSON.stringify(token.paymentData)),
15290
15369
  gateway: 'authorizenet',
15291
15370
  },
15292
- ...convertToSwellAddress(billingContact),
15371
+ ...convertToSwellAddress$1(billingContact),
15293
15372
  },
15294
15373
  ...(requireShipping && {
15295
- shipping: convertToSwellAddress(shippingContact),
15374
+ shipping: convertToSwellAddress$1(shippingContact),
15296
15375
  }),
15297
15376
  });
15298
15377
 
@@ -15305,7 +15384,7 @@
15305
15384
  // Notify that Apple Pay authorization is complete
15306
15385
  // The cart now has the payment token and is ready for submission
15307
15386
  // NOTE: This does NOT submit the order - user must click "Place Order"
15308
- this.onSuccess(cart);
15387
+ this.onSuccess();
15309
15388
  } catch (err) {
15310
15389
  session.completePayment({
15311
15390
  status: this.ApplePaySession.STATUS_FAILURE,
@@ -16131,66 +16210,438 @@
16131
16210
  }
16132
16211
  }
16133
16212
 
16134
- function adjustConfig(params) {
16135
- if (!params.config) {
16136
- return;
16213
+ /** @typedef {import('../../../types').Cart} Cart */
16214
+ /** @typedef {import('../../../types').Address} Address */
16215
+
16216
+ /**
16217
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderAmount
16218
+ * @prop {number} amount_in_cents
16219
+ * @prop {string} currency
16220
+ */
16221
+
16222
+ /**
16223
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderItem
16224
+ * @prop {string} name
16225
+ * @prop {string} sku
16226
+ * @prop {number} quantity
16227
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} price
16228
+ */
16229
+
16230
+ /**
16231
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrderDiscount
16232
+ * @prop {string} name
16233
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} amount
16234
+ */
16235
+
16236
+ /**
16237
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadOrder
16238
+ * @prop {'AUTH' | 'CAPTURE'} intent
16239
+ * @prop {string} reference_id
16240
+ * @prop {string} description
16241
+ * @prop {boolean} requires_shipping_info
16242
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderItem[]} items
16243
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderDiscount[]} discounts
16244
+ * @prop {Record<string, string>} [metadata]
16245
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} tax_amount
16246
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrderAmount} order_amount
16247
+ */
16248
+
16249
+ /**
16250
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayloadData
16251
+ * @prop {'single-step' | 'multi-step' | 'no-shipping'} express_checkout_type
16252
+ * @prop {SezzleCheckoutSdkCheckoutPayloadOrder} order
16253
+ */
16254
+
16255
+ /**
16256
+ * @typedef {object} SezzleCheckoutSdkCheckoutPayload
16257
+ * @prop {SezzleCheckoutSdkCheckoutPayloadData} checkout_payload
16258
+ */
16259
+
16260
+ /**
16261
+ * @typedef {object} SezzleCheckoutSdkCheckoutUrl
16262
+ * @prop {string} checkout_url
16263
+ */
16264
+
16265
+ /**
16266
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingAddress
16267
+ * @prop {string} uuid
16268
+ * @prop {string} name
16269
+ * @prop {string} street
16270
+ * @prop {string} street2
16271
+ * @prop {string} city
16272
+ * @prop {string} state
16273
+ * @prop {string} postal_code
16274
+ * @prop {string} country_code
16275
+ * @prop {string} phone
16276
+ */
16277
+
16278
+ /**
16279
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingError
16280
+ * @prop {'merchant_unsupported_shipping_address' | 'merchant_error'} code
16281
+ */
16282
+
16283
+ /**
16284
+ * @typedef {object} SezzleCheckoutSdkCheckoutShippingResult
16285
+ * @prop {boolean} ok
16286
+ * @prop {SezzleCheckoutSdkCheckoutShippingError} [error]
16287
+ */
16288
+
16289
+ /**
16290
+ * @typedef {object} SezzleCheckoutSdkInit
16291
+ * @prop {(event: MouseEvent) => void} onClick
16292
+ * @prop {(event: CustomEvent) => void} onComplete
16293
+ * @prop {() => void} onCancel
16294
+ * @prop {() => void} onFailure
16295
+ * @prop {(shippingAddress: SezzleCheckoutSdkCheckoutShippingAddress, orderUuid: string) => Promise<SezzleCheckoutSdkCheckoutShippingResult>} onCalculateAddressRelatedCosts
16296
+ */
16297
+
16298
+ /**
16299
+ * @typedef {object} SezzleCheckoutSdk
16300
+ * @prop {(containerId: string) => void} renderSezzleButton
16301
+ * @prop {(options: SezzleCheckoutSdkInit) => void} init
16302
+ * @prop {(options: SezzleCheckoutSdkCheckoutPayload | SezzleCheckoutSdkCheckoutUrl) => void} startCheckout
16303
+ */
16304
+
16305
+ /**
16306
+ * @typedef {object} SezzleCheckoutOptions
16307
+ * @prop {'popup' | 'iframe' | 'redirect'} [mode='popup']
16308
+ * @prop {string} publicKey
16309
+ * @prop {'live' | 'sandbox'} [apiMode='live']
16310
+ * @prop {'v2'} [apiVersion='v2']
16311
+ */
16312
+
16313
+ /** @typedef {new (options: SezzleCheckoutOptions) => SezzleCheckoutSdk} SezzleCheckout */
16314
+
16315
+ const SEZZLE_BUTTON_ID = 'sezzle-smart-button-container';
16316
+
16317
+ class SezzleDirectPayment extends Payment {
16318
+ constructor(api, options, params, methods) {
16319
+ super(api, options, params, methods.sezzle);
16320
+
16321
+ /** @type {SezzleCheckoutSdkCheckoutPayload | null} */
16322
+ this._paymentRequest = null;
16137
16323
  }
16138
16324
 
16139
- if (params.card) {
16140
- console.warn('Please move the "config" field to the "card.config"');
16325
+ get scripts() {
16326
+ return ['sezzle-sdk'];
16327
+ }
16141
16328
 
16142
- params.card.config = params.config;
16329
+ /** @returns {SezzleCheckout} */
16330
+ get SezzleCheckout() {
16331
+ if (!window.Checkout) {
16332
+ throw new LibraryNotLoadedError('Sezzle');
16333
+ }
16334
+
16335
+ return window.Checkout;
16143
16336
  }
16144
16337
 
16145
- if (params.ideal) {
16146
- console.warn('Please move the "config" field to the "ideal.config"');
16338
+ /** @returns {SezzleCheckoutSdk} */
16339
+ get SezzleSdk() {
16340
+ if (!this._sezzleSdk) {
16341
+ this._sezzleSdk = new this.SezzleCheckout({
16342
+ mode: 'popup',
16343
+ publicKey: this.method.public_key,
16344
+ apiMode: isLiveMode(this.method.mode) ? 'live' : 'sandbox',
16345
+ apiVersion: 'v2',
16346
+ });
16147
16347
 
16148
- params.ideal.config = params.config;
16348
+ if (!this._sezzleSdk) {
16349
+ throw new LibraryNotLoadedError('Sezzle sdk client');
16350
+ }
16351
+ }
16352
+
16353
+ return this._sezzleSdk;
16149
16354
  }
16150
16355
 
16151
- delete params.config;
16152
- }
16356
+ /**
16357
+ * @param {Cart} cart
16358
+ * @returns {SezzleCheckoutSdkCheckoutPayload}
16359
+ */
16360
+ _createPaymentRequest(cart) {
16361
+ const {
16362
+ settings: { name },
16363
+ } = cart;
16153
16364
 
16154
- function adjustElementId(methodParams) {
16155
- if (methodParams.cardNumber) {
16156
- adjustElementId(methodParams.cardNumber);
16365
+ const shipmentDelivery = Boolean(cart.shipment_delivery);
16366
+ const cartCurrency = getCartCurrency(cart);
16367
+
16368
+ return {
16369
+ checkout_payload: {
16370
+ express_checkout_type: shipmentDelivery ? 'multi-step' : 'no-shipping',
16371
+ order: {
16372
+ intent: 'AUTH',
16373
+ reference_id: cart.checkout_id,
16374
+ description: `${name} #${cart.number}`,
16375
+ requires_shipping_info: shipmentDelivery,
16376
+ items: getItems(cart),
16377
+ discounts: getDiscounts(cart),
16378
+ tax_amount: shipmentDelivery
16379
+ ? undefined
16380
+ : getAmountInCents(cartCurrency, cart.tax_total),
16381
+ order_amount: getAmountInCents(cartCurrency, cart.capture_total),
16382
+ },
16383
+ },
16384
+ };
16157
16385
  }
16158
16386
 
16159
- if (methodParams.cardExpiry) {
16160
- adjustElementId(methodParams.cardExpiry);
16387
+ _createButton() {
16388
+ const { style = {} } = this.params;
16389
+
16390
+ if (!style.templateText) {
16391
+ style.templateText = '%%logo%%';
16392
+ }
16393
+
16394
+ if (!style.borderType) {
16395
+ style.borderType = 'square';
16396
+ }
16397
+
16398
+ if (!style.width) {
16399
+ style.width = '100%';
16400
+ }
16401
+
16402
+ if (!style.height) {
16403
+ style.height = '45px';
16404
+ }
16405
+
16406
+ const button = document.createElement('div');
16407
+
16408
+ for (const attrId of Object.keys(style)) {
16409
+ button.setAttribute(attrId, style[attrId]);
16410
+ }
16411
+
16412
+ button.setAttribute('id', SEZZLE_BUTTON_ID);
16413
+ button.style.textAlign = 'center';
16414
+
16415
+ return button;
16161
16416
  }
16162
16417
 
16163
- if (methodParams.cardCvc) {
16164
- adjustElementId(methodParams.cardCvc);
16418
+ _initSezzleSdk() {
16419
+ let shippingServices = [];
16420
+
16421
+ this.SezzleSdk.init({
16422
+ onClick: (event) => {
16423
+ event.preventDefault();
16424
+
16425
+ this.SezzleSdk.startCheckout(this._paymentRequest);
16426
+ },
16427
+ onComplete: async (event) => {
16428
+ try {
16429
+ const { order_uuid } = event.data;
16430
+
16431
+ const details = await this.authorizeGateway({
16432
+ gateway: 'sezzle',
16433
+ params: {
16434
+ action: 'details',
16435
+ order_uuid,
16436
+ },
16437
+ });
16438
+
16439
+ let shippingService = null;
16440
+
16441
+ if (details.service_name) {
16442
+ shippingService =
16443
+ shippingServices.find(
16444
+ (service) => service.name === details.service_name,
16445
+ )?.id ?? null;
16446
+ }
16447
+
16448
+ await this.updateCart({
16449
+ account: details.account,
16450
+ shipping: {
16451
+ ...details.shipping,
16452
+ service: shippingService,
16453
+ },
16454
+ billing: {
16455
+ method: 'sezzle',
16456
+ account_card_id: null,
16457
+ card: null,
16458
+ sezzle: { order_uuid },
16459
+ ...details.billing,
16460
+ },
16461
+ });
16462
+
16463
+ this.onSuccess();
16464
+ } catch (err) {
16465
+ this.onError(err);
16466
+ }
16467
+ },
16468
+ onCancel(_event) {},
16469
+ onFailure: (event) => {
16470
+ this.onError(event.data);
16471
+ },
16472
+ onCalculateAddressRelatedCosts: async (address, orderUuid) => {
16473
+ const cart = await this.updateCart({
16474
+ shipping: convertToSwellAddress(address),
16475
+ });
16476
+
16477
+ if (!cart.shipment_rating?.services?.length) {
16478
+ return {
16479
+ ok: false,
16480
+ error: { code: 'merchant_unsupported_shipping_address' },
16481
+ };
16482
+ }
16483
+
16484
+ shippingServices = cart.shipment_rating.services;
16485
+
16486
+ const result = await this.authorizeGateway({
16487
+ gateway: 'sezzle',
16488
+ params: {
16489
+ action: 'shipping',
16490
+ order_uuid: orderUuid,
16491
+ currency_code: cart.currency,
16492
+ address_uuid: address.uuid,
16493
+ shipping_options: cart.shipment_rating.services.map((service) => ({
16494
+ name: service.name,
16495
+ description: service.description,
16496
+ shipping_amount_in_cents: amountInCents(
16497
+ cart.currency,
16498
+ service.price || 0,
16499
+ ),
16500
+ tax_amount_in_cents: amountInCents(
16501
+ cart.currency,
16502
+ cart.tax_total || 0,
16503
+ ),
16504
+ final_order_amount_in_cents: amountInCents(
16505
+ cart.currency,
16506
+ (cart.sub_total || 0) +
16507
+ (cart.tax_total || 0) +
16508
+ (service.price || 0),
16509
+ ),
16510
+ })),
16511
+ },
16512
+ });
16513
+
16514
+ if (result?.error) {
16515
+ console.error(
16516
+ '[Sezzle] Update checkout by order error:',
16517
+ result.error,
16518
+ );
16519
+
16520
+ return {
16521
+ ok: false,
16522
+ error: { code: 'merchant_error' },
16523
+ };
16524
+ }
16525
+
16526
+ return { ok: true };
16527
+ },
16528
+ });
16165
16529
  }
16166
16530
 
16167
- if (!methodParams.elementId) {
16168
- return;
16531
+ /**
16532
+ * Creates the Sezzle button element
16533
+ *
16534
+ * @param {Cart} cart
16535
+ */
16536
+ async createElements(cart) {
16537
+ const { elementId = 'sezzle-button' } = this.params;
16538
+
16539
+ this.setElementContainer(elementId);
16540
+ await this.loadScripts(this.scripts);
16541
+
16542
+ this._paymentRequest = this._createPaymentRequest(cart);
16543
+
16544
+ this.element = this._createButton();
16169
16545
  }
16170
16546
 
16171
- if (methodParams.elementId.startsWith('#')) {
16172
- console.warn(
16173
- `Please remove the "#" sign from the "${methodParams.elementId}" element ID`,
16174
- );
16547
+ /**
16548
+ * Mounts the Sezzle button to the DOM
16549
+ */
16550
+ mountElements() {
16551
+ const { classes = {} } = this.params;
16552
+ const container = this.elementContainer;
16175
16553
 
16176
- methodParams.elementId = methodParams.elementId.substring(1);
16554
+ container.appendChild(this.element);
16555
+
16556
+ this.SezzleSdk.renderSezzleButton(SEZZLE_BUTTON_ID);
16557
+
16558
+ if (classes.base) {
16559
+ container.classList.add(classes.base);
16560
+ }
16561
+
16562
+ this._initSezzleSdk();
16177
16563
  }
16178
16564
  }
16179
16565
 
16180
- function adjustParams(_params) {
16181
- const params = { ..._params };
16566
+ /**
16567
+ * @param {Cart} cart
16568
+ * @returns {string}
16569
+ */
16570
+ function getCartCurrency(cart) {
16571
+ const {
16572
+ settings: { currency },
16573
+ } = cart;
16182
16574
 
16183
- adjustConfig(params);
16575
+ return cart.currency || currency || 'USD';
16576
+ }
16184
16577
 
16185
- return params;
16578
+ /**
16579
+ * @param {string} currency
16580
+ * @param {number} amount
16581
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderAmount}
16582
+ */
16583
+ function getAmountInCents(currency, amount) {
16584
+ return {
16585
+ amount_in_cents: amountInCents(currency, amount),
16586
+ currency,
16587
+ };
16186
16588
  }
16187
16589
 
16188
- function adjustMethodParams(_methodParams) {
16189
- const methodParams = { ..._methodParams };
16590
+ /**
16591
+ * @param {Cart} cart
16592
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderItem[]}
16593
+ */
16594
+ function getItems(cart) {
16595
+ const currency = getCartCurrency(cart);
16596
+
16597
+ /** @type {SezzleCheckoutSdkCheckoutPayloadOrderItem[]} */
16598
+ const items = cart.items.map((item, index) => ({
16599
+ name: item.product?.name || `Product ${index + 1}`,
16600
+ sku: item.product?.sku || `Product SKU ${index + 1}`,
16601
+ quantity: item.quantity || 1,
16602
+ price: getAmountInCents(currency, item.price || 0),
16603
+ }));
16190
16604
 
16191
- adjustElementId(methodParams);
16605
+ return items;
16606
+ }
16192
16607
 
16193
- return methodParams;
16608
+ /**
16609
+ * @param {Cart} cart
16610
+ * @returns {SezzleCheckoutSdkCheckoutPayloadOrderDiscount[]}
16611
+ */
16612
+ function getDiscounts(cart) {
16613
+ const currency = getCartCurrency(cart);
16614
+
16615
+ return (cart.discounts || []).map((discount) => ({
16616
+ name: getDiscountLabel(discount, cart),
16617
+ amount: getAmountInCents(currency, discount.amount || 0),
16618
+ }));
16619
+ }
16620
+
16621
+ /**
16622
+ * @param {SezzleCheckoutSdkCheckoutShippingAddress} address
16623
+ * @returns {Address}
16624
+ */
16625
+ function convertToSwellAddress(address) {
16626
+ return {
16627
+ name: address.name || null,
16628
+ address1: address.street || null,
16629
+ address2: address.street2 || null,
16630
+ city: address.city || null,
16631
+ state: address.state || null,
16632
+ zip: address.postal_code || null,
16633
+ country: address.country_code || null,
16634
+ phone: address.phone || null,
16635
+ };
16636
+ }
16637
+
16638
+ /**
16639
+ * @param {string} currency
16640
+ * @param {number} amount
16641
+ * @returns {number}
16642
+ */
16643
+ function amountInCents(currency, amount) {
16644
+ return Math.round(amount * 100);
16194
16645
  }
16195
16646
 
16196
16647
  class PaymentController {
@@ -16359,6 +16810,9 @@
16359
16810
  return response;
16360
16811
  }
16361
16812
 
16813
+ /**
16814
+ * @returns {Promise<Payment[]>}
16815
+ */
16362
16816
  async _createPaymentInstances() {
16363
16817
  const paymentMethods = await this._getPaymentMethods();
16364
16818
  const params = adjustParams(this.params);
@@ -16404,6 +16858,12 @@
16404
16858
  }, []);
16405
16859
  }
16406
16860
 
16861
+ /**
16862
+ * @param {Payment[]} paymentInstances
16863
+ * @param {string} action
16864
+ * @param {...unknown} args
16865
+ * @returns {Promise<Payment[]>}
16866
+ */
16407
16867
  async _performPaymentAction(paymentInstances, action, ...args) {
16408
16868
  const actions = paymentInstances.reduce((acc, instance) => {
16409
16869
  const paymentAction = instance[action];
@@ -16424,9 +16884,7 @@
16424
16884
  await resultPromise;
16425
16885
  nextPaymentInstances.push(instance);
16426
16886
  } catch (error) {
16427
- const onPaymentError = instance.onError.bind(instance);
16428
-
16429
- onPaymentError(error);
16887
+ instance.onError(error);
16430
16888
  }
16431
16889
  }
16432
16890
 
@@ -16453,6 +16911,8 @@
16453
16911
  return this._getApplePaymentClass(gateway);
16454
16912
  case 'amazon':
16455
16913
  return this._getAmazonPaymentClass(gateway);
16914
+ case 'sezzle':
16915
+ return this._getSezzlePaymentClass(gateway);
16456
16916
  default:
16457
16917
  return null;
16458
16918
  }
@@ -16546,6 +17006,13 @@
16546
17006
  return AmazonDirectPayment;
16547
17007
  }
16548
17008
  }
17009
+
17010
+ _getSezzlePaymentClass(gateway) {
17011
+ switch (gateway) {
17012
+ default:
17013
+ return SezzleDirectPayment;
17014
+ }
17015
+ }
16549
17016
  }
16550
17017
 
16551
17018
  function methods$2(api, opt) {
@@ -16882,7 +17349,7 @@
16882
17349
  const api = {};
16883
17350
 
16884
17351
  Object.assign(api, {
16885
- version: '5.1.2',
17352
+ version: '5.2.0',
16886
17353
  options,
16887
17354
  request,
16888
17355