@gomusdev/web-components 3.7.0 → 3.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/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.8.0 (2026-06-22)
4
+
5
+ ### Features
6
+
7
+ * **cart:** Wertgutschein value-voucher cart support
8
+
3
9
  ## 3.7.0 (2026-06-16)
4
10
 
5
11
  ### Features
@@ -12203,7 +12203,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12203
12203
  if (lsItems.length === 0) cart.clearItems();
12204
12204
  else cart.items = lsItems.map(generateCartItem).filter(defined);
12205
12205
  cart.clearCoupons();
12206
- lsCoupons.forEach((coupon) => cart.addCoupon(coupon));
12206
+ lsCoupons.forEach((coupon) => cart.addCoupon(typeof coupon === "string" ? {
12207
+ code: coupon,
12208
+ kind: "actionToken"
12209
+ } : coupon));
12207
12210
  return cart.items;
12208
12211
  } catch (e) {
12209
12212
  console.error(e);
@@ -12263,6 +12266,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12263
12266
  get totalQuantity() {
12264
12267
  return sum(this.items, (item) => item.quantity);
12265
12268
  },
12269
+ get valueVoucherCents() {
12270
+ return sum(this.coupons.filter((c) => c.kind === "valueVoucher"), (c) => c.valueCents ?? 0);
12271
+ },
12272
+ get amountToPayCents() {
12273
+ return Math.max(0, this.totalPriceCents - this.valueVoucherCents);
12274
+ },
12266
12275
  /**
12267
12276
  * Generates a formatted string representation of the current object.
12268
12277
  */
@@ -12279,10 +12288,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12279
12288
  comment: null,
12280
12289
  reference: null,
12281
12290
  payment_mode_id: this.paymentModeId ?? shop.settings?.defaultPaymentModeId,
12282
- coupons: this.coupons,
12291
+ coupons: this.coupons.map((c) => c.code),
12283
12292
  donations: [],
12284
12293
  affiliate: {},
12285
- total: this.totalPriceCents
12294
+ total: this.amountToPayCents
12286
12295
  };
12287
12296
  },
12288
12297
  get totalFormatted() {
@@ -12301,11 +12310,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12301
12310
  addItems(items) {
12302
12311
  items.forEach((item) => this.addItem(item));
12303
12312
  },
12304
- addCoupon(token) {
12305
- if (!this.coupons.includes(token)) this.coupons.push(token);
12313
+ addCoupon(item) {
12314
+ const coupon = {
12315
+ ...item,
12316
+ code: item.code.toUpperCase()
12317
+ };
12318
+ if (!this.coupons.some((c) => c.code === coupon.code)) this.coupons.push(coupon);
12306
12319
  },
12307
- removeCoupon(token) {
12308
- const index = this.coupons.indexOf(token);
12320
+ removeCoupon(code) {
12321
+ const upper = code.toUpperCase();
12322
+ const index = this.coupons.findIndex((c) => c.code === upper);
12309
12323
  if (index > -1) this.coupons.splice(index, 1);
12310
12324
  },
12311
12325
  clearCoupons() {
@@ -14924,8 +14938,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14924
14938
  }
14925
14939
  function createDisplayCart(baseCart, apiItems) {
14926
14940
  const displayCart = createCart();
14927
- const appliedCoupons = /* @__PURE__ */ new Set();
14928
- baseCart.coupons.forEach((coupon) => displayCart.addCoupon(coupon));
14941
+ const echoed = new Set(apiItems.map((i) => i.attributes.coupon).filter(Boolean).map((c) => c.toUpperCase()));
14942
+ baseCart.coupons.forEach((coupon) => displayCart.addCoupon({
14943
+ ...coupon,
14944
+ applied: coupon.kind !== "actionToken" || echoed.has(coupon.code)
14945
+ }));
14929
14946
  apiItems.forEach((apiItem) => {
14930
14947
  const attrs = apiItem.attributes;
14931
14948
  const scalePriceId = getScalePriceId(attrs);
@@ -14937,16 +14954,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14937
14954
  });
14938
14955
  return;
14939
14956
  }
14940
- if (attrs.coupon) {
14941
- displayCart.addCoupon(attrs.coupon);
14942
- appliedCoupons.add(attrs.coupon);
14943
- }
14944
14957
  displayCart.addItem(createDisplayCartItem(itemInBaseCart, attrs));
14945
14958
  });
14946
- return {
14947
- cart: displayCart,
14948
- appliedCoupons
14949
- };
14959
+ return displayCart;
14950
14960
  }
14951
14961
  function createDisplayCartItem(cartItem, attrs) {
14952
14962
  const quantity = resolveApiQuantity(attrs);
@@ -14976,13 +14986,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14976
14986
  set displayCart(value) {
14977
14987
  set(this.#displayCart, value, true);
14978
14988
  }
14979
- #appliedCoupons = /* @__PURE__ */ state(proxy(/* @__PURE__ */ new Set()));
14980
- get appliedCoupons() {
14981
- return get$2(this.#appliedCoupons);
14982
- }
14983
- set appliedCoupons(value) {
14984
- set(this.#appliedCoupons, value, true);
14985
- }
14986
14989
  #preview = /* @__PURE__ */ state(false);
14987
14990
  get preview() {
14988
14991
  return get$2(this.#preview);
@@ -14991,7 +14994,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14991
14994
  set(this.#preview, value, true);
14992
14995
  }
14993
14996
  get totalPriceCents() {
14994
- return this.displayCart?.totalPriceCents ?? 0;
14997
+ return this.displayCart?.amountToPayCents ?? 0;
14995
14998
  }
14996
14999
  get subtotalPriceCents() {
14997
15000
  return shop.cart?.totalPriceCents ?? 0;
@@ -15011,14 +15014,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15011
15014
  items,
15012
15015
  coupons
15013
15016
  });
15014
- if (!response || "error" in response) {
15015
- if (response && "error" in response) console.error("(go-cart) Unable to fetch discounted cart data", response.error);
15016
- this.displayCart = mc;
15017
+ if (response?.data) {
15018
+ this.displayCart = createDisplayCart(mc, response.data.items ?? []);
15017
15019
  return;
15018
15020
  }
15019
- const result = createDisplayCart(mc, response.data.items ?? []);
15020
- this.displayCart = result.cart;
15021
- this.appliedCoupons = result.appliedCoupons;
15021
+ console.error("(go-cart) Unable to fetch discounted cart data", response?.error);
15022
+ this.displayCart = mc;
15022
15023
  } catch (error) {
15023
15024
  console.error("(go-cart) Unable to fetch discounted cart data", error);
15024
15025
  this.displayCart = mc;
@@ -15448,7 +15449,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15448
15449
  var node = first_child(fragment);
15449
15450
  var consequent_1 = ($$anchor) => {
15450
15451
  var ol = root_2$8();
15451
- each(ol, 20, () => get$2(details).displayCart.coupons, (coupon) => coupon, ($$anchor, coupon) => {
15452
+ each(ol, 21, () => get$2(details).displayCart.coupons, (coupon) => coupon.code, ($$anchor, coupon) => {
15452
15453
  var li = root_1$12();
15453
15454
  let classes;
15454
15455
  var article = child(li);
@@ -15462,7 +15463,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15462
15463
  var button = child(li_2);
15463
15464
  reset(li_2);
15464
15465
  template_effect(($0) => set_attribute(button, "aria-label", $0), [() => shop.t("cart.coupons.remove")]);
15465
- delegated("click", button, () => shop.cart?.removeCoupon(coupon));
15466
+ delegated("click", button, () => shop.cart?.removeCoupon(get$2(coupon).code));
15466
15467
  append($$anchor, li_2);
15467
15468
  };
15468
15469
  if_block(node_1, ($$render) => {
@@ -15471,10 +15472,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15471
15472
  reset(ul);
15472
15473
  reset(article);
15473
15474
  reset(li);
15474
- template_effect(($0) => {
15475
- classes = set_class(li, 1, "go-cart-coupon", null, classes, $0);
15476
- set_text(text, coupon);
15477
- }, [() => ({ "go-cart-coupon-inactive": !get$2(details).appliedCoupons.has(coupon) })]);
15475
+ template_effect(() => {
15476
+ classes = set_class(li, 1, "go-cart-coupon", null, classes, { "go-cart-coupon-inactive": !get$2(coupon).applied });
15477
+ set_text(text, get$2(coupon).code);
15478
+ });
15478
15479
  append($$anchor, li);
15479
15480
  });
15480
15481
  reset(ol);
@@ -15524,7 +15525,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15524
15525
  user_effect(() => {
15525
15526
  if (!shop.cart) return;
15526
15527
  shop.cart.items.map((i) => i.uuid + ":" + i.quantity + ":" + i.time);
15527
- shop.cart.coupons.join("|");
15528
+ shop.cart.coupons.map((c) => c.code).join("|");
15528
15529
  untrack(() => details.calculateDisplayCart());
15529
15530
  });
15530
15531
  async function flushCoupons() {
@@ -15542,6 +15543,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15542
15543
  const innerForm = submit.closest("go-form");
15543
15544
  if (innerForm && $$props.$$host.contains(innerForm)) return;
15544
15545
  const ok = await flushCoupons();
15546
+ if (!ok) return;
15545
15547
  $$props.$$host.dispatchEvent(new CustomEvent("go-submit", {
15546
15548
  detail: { ok },
15547
15549
  bubbles: true,
@@ -15705,13 +15707,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15705
15707
  var APPLY_ORDER_DISCOUNT = "TokenActions::ApplyOrderDiscount";
15706
15708
  async function redeem(token) {
15707
15709
  if (!shop.cart) throw new Error("(go-coupon-redemption): cart not found");
15710
+ const cart = shop.cart;
15708
15711
  const couponSale = await shop.asyncFetch(() => shop.getCouponSaleByBarcode(token));
15709
15712
  if (!couponSale?.is_valid) return fail([shop.t("cart.coupon.form.errors.notValid")]);
15710
15713
  if (couponSale.value_action === APPLY_ORDER_DISCOUNT) {
15711
- shop.cart.addCoupon(token);
15714
+ cart.addCoupon({
15715
+ code: token,
15716
+ kind: "actionToken"
15717
+ });
15712
15718
  return { success: true };
15713
- } else if (couponSale.is_voucher_for) return applyVoucher(token, couponSale);
15714
- else return fail([shop.t("cart.coupon.form.errors.notValid")]);
15719
+ }
15720
+ if (couponSale.is_voucher_for) return applyVoucher(token, couponSale);
15721
+ if (couponSale.value_cents && couponSale.value_cents > 0) return applyValueCoupon(token, couponSale.value_cents);
15722
+ return fail([shop.t("cart.coupon.form.errors.notValid")]);
15723
+ }
15724
+ function applyValueCoupon(token, valueCents) {
15725
+ shop.cart.addCoupon({
15726
+ code: token,
15727
+ kind: "valueVoucher",
15728
+ valueCents
15729
+ });
15730
+ return { success: true };
15715
15731
  }
15716
15732
  async function applyVoucher(token, couponSale) {
15717
15733
  const ticket = (await shop.asyncFetch(() => shop.tickets({ "by_ticket_ids[]": [couponSale.is_voucher_for] }))).find((t) => t.id === couponSale.is_voucher_for);
@@ -15721,7 +15737,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15721
15737
  price_cents: 0
15722
15738
  };
15723
15739
  shop.cart.addItem(createCartItem(createUITicket(voucherTicket), { quantity: 1 }));
15724
- shop.cart.addCoupon(token);
15740
+ shop.cart.addCoupon({
15741
+ code: token,
15742
+ kind: "serviceVoucher"
15743
+ });
15725
15744
  return { success: true };
15726
15745
  }
15727
15746
  function fail(errors) {
@@ -12202,7 +12202,10 @@ function loadFromLocalStorage(cart) {
12202
12202
  if (lsItems.length === 0) cart.clearItems();
12203
12203
  else cart.items = lsItems.map(generateCartItem).filter(defined);
12204
12204
  cart.clearCoupons();
12205
- lsCoupons.forEach((coupon) => cart.addCoupon(coupon));
12205
+ lsCoupons.forEach((coupon) => cart.addCoupon(typeof coupon === "string" ? {
12206
+ code: coupon,
12207
+ kind: "actionToken"
12208
+ } : coupon));
12206
12209
  return cart.items;
12207
12210
  } catch (e) {
12208
12211
  console.error(e);
@@ -12262,6 +12265,12 @@ function createCart(products, contingent = 20) {
12262
12265
  get totalQuantity() {
12263
12266
  return sum(this.items, (item) => item.quantity);
12264
12267
  },
12268
+ get valueVoucherCents() {
12269
+ return sum(this.coupons.filter((c) => c.kind === "valueVoucher"), (c) => c.valueCents ?? 0);
12270
+ },
12271
+ get amountToPayCents() {
12272
+ return Math.max(0, this.totalPriceCents - this.valueVoucherCents);
12273
+ },
12265
12274
  /**
12266
12275
  * Generates a formatted string representation of the current object.
12267
12276
  */
@@ -12278,10 +12287,10 @@ function createCart(products, contingent = 20) {
12278
12287
  comment: null,
12279
12288
  reference: null,
12280
12289
  payment_mode_id: this.paymentModeId ?? shop.settings?.defaultPaymentModeId,
12281
- coupons: this.coupons,
12290
+ coupons: this.coupons.map((c) => c.code),
12282
12291
  donations: [],
12283
12292
  affiliate: {},
12284
- total: this.totalPriceCents
12293
+ total: this.amountToPayCents
12285
12294
  };
12286
12295
  },
12287
12296
  get totalFormatted() {
@@ -12300,11 +12309,16 @@ function createCart(products, contingent = 20) {
12300
12309
  addItems(items) {
12301
12310
  items.forEach((item) => this.addItem(item));
12302
12311
  },
12303
- addCoupon(token) {
12304
- if (!this.coupons.includes(token)) this.coupons.push(token);
12312
+ addCoupon(item) {
12313
+ const coupon = {
12314
+ ...item,
12315
+ code: item.code.toUpperCase()
12316
+ };
12317
+ if (!this.coupons.some((c) => c.code === coupon.code)) this.coupons.push(coupon);
12305
12318
  },
12306
- removeCoupon(token) {
12307
- const index = this.coupons.indexOf(token);
12319
+ removeCoupon(code) {
12320
+ const upper = code.toUpperCase();
12321
+ const index = this.coupons.findIndex((c) => c.code === upper);
12308
12322
  if (index > -1) this.coupons.splice(index, 1);
12309
12323
  },
12310
12324
  clearCoupons() {
@@ -14923,8 +14937,11 @@ function getScalePriceId(attrs) {
14923
14937
  }
14924
14938
  function createDisplayCart(baseCart, apiItems) {
14925
14939
  const displayCart = createCart();
14926
- const appliedCoupons = /* @__PURE__ */ new Set();
14927
- baseCart.coupons.forEach((coupon) => displayCart.addCoupon(coupon));
14940
+ const echoed = new Set(apiItems.map((i) => i.attributes.coupon).filter(Boolean).map((c) => c.toUpperCase()));
14941
+ baseCart.coupons.forEach((coupon) => displayCart.addCoupon({
14942
+ ...coupon,
14943
+ applied: coupon.kind !== "actionToken" || echoed.has(coupon.code)
14944
+ }));
14928
14945
  apiItems.forEach((apiItem) => {
14929
14946
  const attrs = apiItem.attributes;
14930
14947
  const scalePriceId = getScalePriceId(attrs);
@@ -14936,16 +14953,9 @@ function createDisplayCart(baseCart, apiItems) {
14936
14953
  });
14937
14954
  return;
14938
14955
  }
14939
- if (attrs.coupon) {
14940
- displayCart.addCoupon(attrs.coupon);
14941
- appliedCoupons.add(attrs.coupon);
14942
- }
14943
14956
  displayCart.addItem(createDisplayCartItem(itemInBaseCart, attrs));
14944
14957
  });
14945
- return {
14946
- cart: displayCart,
14947
- appliedCoupons
14948
- };
14958
+ return displayCart;
14949
14959
  }
14950
14960
  function createDisplayCartItem(cartItem, attrs) {
14951
14961
  const quantity = resolveApiQuantity(attrs);
@@ -14975,13 +14985,6 @@ var CartDetails = class {
14975
14985
  set displayCart(value) {
14976
14986
  set(this.#displayCart, value, true);
14977
14987
  }
14978
- #appliedCoupons = /* @__PURE__ */ state(proxy(/* @__PURE__ */ new Set()));
14979
- get appliedCoupons() {
14980
- return get$2(this.#appliedCoupons);
14981
- }
14982
- set appliedCoupons(value) {
14983
- set(this.#appliedCoupons, value, true);
14984
- }
14985
14988
  #preview = /* @__PURE__ */ state(false);
14986
14989
  get preview() {
14987
14990
  return get$2(this.#preview);
@@ -14990,7 +14993,7 @@ var CartDetails = class {
14990
14993
  set(this.#preview, value, true);
14991
14994
  }
14992
14995
  get totalPriceCents() {
14993
- return this.displayCart?.totalPriceCents ?? 0;
14996
+ return this.displayCart?.amountToPayCents ?? 0;
14994
14997
  }
14995
14998
  get subtotalPriceCents() {
14996
14999
  return shop.cart?.totalPriceCents ?? 0;
@@ -15010,14 +15013,12 @@ var CartDetails = class {
15010
15013
  items,
15011
15014
  coupons
15012
15015
  });
15013
- if (!response || "error" in response) {
15014
- if (response && "error" in response) console.error("(go-cart) Unable to fetch discounted cart data", response.error);
15015
- this.displayCart = mc;
15016
+ if (response?.data) {
15017
+ this.displayCart = createDisplayCart(mc, response.data.items ?? []);
15016
15018
  return;
15017
15019
  }
15018
- const result = createDisplayCart(mc, response.data.items ?? []);
15019
- this.displayCart = result.cart;
15020
- this.appliedCoupons = result.appliedCoupons;
15020
+ console.error("(go-cart) Unable to fetch discounted cart data", response?.error);
15021
+ this.displayCart = mc;
15021
15022
  } catch (error) {
15022
15023
  console.error("(go-cart) Unable to fetch discounted cart data", error);
15023
15024
  this.displayCart = mc;
@@ -15447,7 +15448,7 @@ function CartCoupons($$anchor, $$props) {
15447
15448
  var node = first_child(fragment);
15448
15449
  var consequent_1 = ($$anchor) => {
15449
15450
  var ol = root_2$8();
15450
- each(ol, 20, () => get$2(details).displayCart.coupons, (coupon) => coupon, ($$anchor, coupon) => {
15451
+ each(ol, 21, () => get$2(details).displayCart.coupons, (coupon) => coupon.code, ($$anchor, coupon) => {
15451
15452
  var li = root_1$12();
15452
15453
  let classes;
15453
15454
  var article = child(li);
@@ -15461,7 +15462,7 @@ function CartCoupons($$anchor, $$props) {
15461
15462
  var button = child(li_2);
15462
15463
  reset(li_2);
15463
15464
  template_effect(($0) => set_attribute(button, "aria-label", $0), [() => shop.t("cart.coupons.remove")]);
15464
- delegated("click", button, () => shop.cart?.removeCoupon(coupon));
15465
+ delegated("click", button, () => shop.cart?.removeCoupon(get$2(coupon).code));
15465
15466
  append($$anchor, li_2);
15466
15467
  };
15467
15468
  if_block(node_1, ($$render) => {
@@ -15470,10 +15471,10 @@ function CartCoupons($$anchor, $$props) {
15470
15471
  reset(ul);
15471
15472
  reset(article);
15472
15473
  reset(li);
15473
- template_effect(($0) => {
15474
- classes = set_class(li, 1, "go-cart-coupon", null, classes, $0);
15475
- set_text(text, coupon);
15476
- }, [() => ({ "go-cart-coupon-inactive": !get$2(details).appliedCoupons.has(coupon) })]);
15474
+ template_effect(() => {
15475
+ classes = set_class(li, 1, "go-cart-coupon", null, classes, { "go-cart-coupon-inactive": !get$2(coupon).applied });
15476
+ set_text(text, get$2(coupon).code);
15477
+ });
15477
15478
  append($$anchor, li);
15478
15479
  });
15479
15480
  reset(ol);
@@ -15523,7 +15524,7 @@ function Cart($$anchor, $$props) {
15523
15524
  user_effect(() => {
15524
15525
  if (!shop.cart) return;
15525
15526
  shop.cart.items.map((i) => i.uuid + ":" + i.quantity + ":" + i.time);
15526
- shop.cart.coupons.join("|");
15527
+ shop.cart.coupons.map((c) => c.code).join("|");
15527
15528
  untrack(() => details.calculateDisplayCart());
15528
15529
  });
15529
15530
  async function flushCoupons() {
@@ -15541,6 +15542,7 @@ function Cart($$anchor, $$props) {
15541
15542
  const innerForm = submit.closest("go-form");
15542
15543
  if (innerForm && $$props.$$host.contains(innerForm)) return;
15543
15544
  const ok = await flushCoupons();
15545
+ if (!ok) return;
15544
15546
  $$props.$$host.dispatchEvent(new CustomEvent("go-submit", {
15545
15547
  detail: { ok },
15546
15548
  bubbles: true,
@@ -15704,13 +15706,27 @@ customElements.define("go-checkout-form", create_custom_element(CheckoutForm, {
15704
15706
  var APPLY_ORDER_DISCOUNT = "TokenActions::ApplyOrderDiscount";
15705
15707
  async function redeem(token) {
15706
15708
  if (!shop.cart) throw new Error("(go-coupon-redemption): cart not found");
15709
+ const cart = shop.cart;
15707
15710
  const couponSale = await shop.asyncFetch(() => shop.getCouponSaleByBarcode(token));
15708
15711
  if (!couponSale?.is_valid) return fail([shop.t("cart.coupon.form.errors.notValid")]);
15709
15712
  if (couponSale.value_action === APPLY_ORDER_DISCOUNT) {
15710
- shop.cart.addCoupon(token);
15713
+ cart.addCoupon({
15714
+ code: token,
15715
+ kind: "actionToken"
15716
+ });
15711
15717
  return { success: true };
15712
- } else if (couponSale.is_voucher_for) return applyVoucher(token, couponSale);
15713
- else return fail([shop.t("cart.coupon.form.errors.notValid")]);
15718
+ }
15719
+ if (couponSale.is_voucher_for) return applyVoucher(token, couponSale);
15720
+ if (couponSale.value_cents && couponSale.value_cents > 0) return applyValueCoupon(token, couponSale.value_cents);
15721
+ return fail([shop.t("cart.coupon.form.errors.notValid")]);
15722
+ }
15723
+ function applyValueCoupon(token, valueCents) {
15724
+ shop.cart.addCoupon({
15725
+ code: token,
15726
+ kind: "valueVoucher",
15727
+ valueCents
15728
+ });
15729
+ return { success: true };
15714
15730
  }
15715
15731
  async function applyVoucher(token, couponSale) {
15716
15732
  const ticket = (await shop.asyncFetch(() => shop.tickets({ "by_ticket_ids[]": [couponSale.is_voucher_for] }))).find((t) => t.id === couponSale.is_voucher_for);
@@ -15720,7 +15736,10 @@ async function applyVoucher(token, couponSale) {
15720
15736
  price_cents: 0
15721
15737
  };
15722
15738
  shop.cart.addItem(createCartItem(createUITicket(voucherTicket), { quantity: 1 }));
15723
- shop.cart.addCoupon(token);
15739
+ shop.cart.addCoupon({
15740
+ code: token,
15741
+ kind: "serviceVoucher"
15742
+ });
15724
15743
  return { success: true };
15725
15744
  }
15726
15745
  function fail(errors) {