@aglyn/plugins-commerce 1.0.0-beta.217 → 1.0.0-beta.219

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.
Files changed (100) hide show
  1. package/README.md +1 -0
  2. package/package.json +15 -15
  3. package/src/index.d.ts +1 -0
  4. package/src/index.js +1 -19
  5. package/src/index.js.map +1 -1
  6. package/src/lib/components/cart.js +2 -1
  7. package/src/lib/components/cart.js.map +1 -1
  8. package/src/lib/components/console/catalog-organization-card.component.js +44 -18
  9. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
  10. package/src/lib/components/console/host-orders-card.component.js +2 -1
  11. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  12. package/src/lib/components/console/member-posts-card.component.js +1 -1
  13. package/src/lib/components/console/member-posts-card.component.js.map +1 -1
  14. package/src/lib/components/console/order-detail-dialog.component.js +8 -7
  15. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  16. package/src/lib/components/console/payments-settings-card.component.js +1 -1
  17. package/src/lib/components/console/payments-settings-card.component.js.map +1 -1
  18. package/src/lib/components/console/product-editor-dialog.component.js +114 -63
  19. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  20. package/src/lib/components/console/product-zones.d.ts +184 -0
  21. package/src/lib/components/console/product-zones.js +54 -0
  22. package/src/lib/components/console/product-zones.js.map +1 -0
  23. package/src/lib/components/console/products-hub-card.component.js +3 -2
  24. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  25. package/src/lib/components/console/products-hub-zone.component.d.ts +1 -1
  26. package/src/lib/components/console/products-hub-zone.component.js +2 -1
  27. package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
  28. package/src/lib/components/console/store-settings-card.component.js +2 -2
  29. package/src/lib/components/console/store-settings-card.component.js.map +1 -1
  30. package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -1
  31. package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
  32. package/src/lib/components/product-detail.js +2 -1
  33. package/src/lib/components/product-detail.js.map +1 -1
  34. package/src/lib/components/product-grid.js +1 -1
  35. package/src/lib/components/product-grid.js.map +1 -1
  36. package/src/lib/components/storefront-payment-element.js +36 -5
  37. package/src/lib/components/storefront-payment-element.js.map +1 -1
  38. package/src/lib/constants/storefront-payments.d.ts +33 -0
  39. package/src/lib/constants/storefront-payments.js +35 -0
  40. package/src/lib/constants/storefront-payments.js.map +1 -0
  41. package/src/lib/declarations.server.d.ts +3 -1
  42. package/src/lib/declarations.server.js +19 -1
  43. package/src/lib/declarations.server.js.map +1 -1
  44. package/src/lib/model/commerce-record-routes.d.ts +27 -0
  45. package/src/lib/model/commerce-record-routes.js +72 -0
  46. package/src/lib/model/commerce-record-routes.js.map +1 -0
  47. package/src/lib/model/commerce-search-sources.d.ts +21 -0
  48. package/src/lib/model/commerce-search-sources.js +40 -0
  49. package/src/lib/model/commerce-search-sources.js.map +1 -0
  50. package/src/lib/model/storefront-tax-summary.d.ts +121 -0
  51. package/src/lib/model/storefront-tax-summary.js +148 -0
  52. package/src/lib/model/storefront-tax-summary.js.map +1 -0
  53. package/src/lib/plan-entitlements.d.ts +35 -0
  54. package/src/lib/plan-entitlements.js +54 -0
  55. package/src/lib/plan-entitlements.js.map +1 -0
  56. package/src/lib/plugin.js +9 -0
  57. package/src/lib/plugin.js.map +1 -1
  58. package/src/lib/server/billing-webhook.js +135 -168
  59. package/src/lib/server/billing-webhook.js.map +1 -1
  60. package/src/lib/server/cart-checkout.js +2 -2
  61. package/src/lib/server/cart-checkout.js.map +1 -1
  62. package/src/lib/server/checkout.js +2 -2
  63. package/src/lib/server/checkout.js.map +1 -1
  64. package/src/lib/server/connect.js +5 -5
  65. package/src/lib/server/connect.js.map +1 -1
  66. package/src/lib/server/draft-order.js +2 -2
  67. package/src/lib/server/draft-order.js.map +1 -1
  68. package/src/lib/server/membership-content.js +1 -1
  69. package/src/lib/server/membership-content.js.map +1 -1
  70. package/src/lib/server/native-checkout.d.ts +20 -5
  71. package/src/lib/server/native-checkout.js +27 -6
  72. package/src/lib/server/native-checkout.js.map +1 -1
  73. package/src/lib/server/pos-order.js +2 -2
  74. package/src/lib/server/pos-order.js.map +1 -1
  75. package/src/lib/server/product-record-index.d.ts +19 -0
  76. package/src/lib/server/product-record-index.js +115 -0
  77. package/src/lib/server/product-record-index.js.map +1 -0
  78. package/src/lib/server/reserve.js +2 -2
  79. package/src/lib/server/reserve.js.map +1 -1
  80. package/src/lib/server/revenue-source.d.ts +130 -0
  81. package/src/lib/server/revenue-source.js +286 -0
  82. package/src/lib/server/revenue-source.js.map +1 -0
  83. package/src/lib/server/tax-profile.d.ts +8 -5
  84. package/src/lib/server/tax-profile.js +22 -5
  85. package/src/lib/server/tax-profile.js.map +1 -1
  86. package/src/lib/server/tax-return-source.d.ts +125 -0
  87. package/src/lib/server/tax-return-source.js +524 -0
  88. package/src/lib/server/tax-return-source.js.map +1 -0
  89. package/src/lib/server/tax-summary.d.ts +92 -0
  90. package/src/lib/server/tax-summary.js +258 -0
  91. package/src/lib/server/tax-summary.js.map +1 -0
  92. package/src/lib/server.d.ts +1 -0
  93. package/src/lib/server.js +23 -0
  94. package/src/lib/server.js.map +1 -1
  95. package/src/lib/tenant-emails.d.ts +33 -0
  96. package/src/lib/tenant-emails.js +511 -0
  97. package/src/lib/tenant-emails.js.map +1 -0
  98. package/src/lib/testing/stand-in-crm-record-routes.d.ts +25 -0
  99. package/src/lib/testing/stand-in-crm-record-routes.js +46 -0
  100. package/src/lib/testing/stand-in-crm-record-routes.js.map +1 -0
@@ -15,7 +15,8 @@
15
15
  * limitations under the License.
16
16
  */ import { _ as _extends } from "@swc/helpers/_/_extends";
17
17
  import * as Aglyn from "@aglyn/aglyn/server";
18
- import { findUserByUidAcrossPools, firebaseAdmin, getOrgForHost, meterHostEmail, notifyHostManagers, notifyRiskEvent, raiseOperatorAlert, renderHostEmailWithTokens, clearConnectPayoutFailure, recordConnectPayoutFailure, syncConnectAccountStatus, updateExisting, hostSendingIdentity } from "@aglyn/tenant-data-admin";
18
+ import { findUserByUidAcrossPools, firebaseAdmin, getOrgForHost, meterHostEmail, notifyHostManagers, notifyRiskEvent, raiseOperatorAlert, renderHostEmailWithTokens, updateExisting, hostSendingIdentity } from "@aglyn/tenant-data-admin";
19
+ import { paymentProvider } from "@aglyn/tenant-data-admin/server/payment-provider";
19
20
  import { captureHostContact } from "@aglyn/tenant-runtime";
20
21
  import { formatOperatorAlertAmount } from "@aglyn/aglyn/app-utils/operator-alerts";
21
22
  import { COMMERCE_CHARGEBACK_UNROUTABLE, COMMERCE_FEE_REPRICE_REFUSED, COMMERCE_SELLER_SHARE_NOT_REVERSED, COMMERCE_TAX_NOT_REVERSED } from "../constants/operator-alerts.js";
@@ -1633,59 +1634,25 @@ async function findOrderForDispute(paymentIntentId) {
1633
1634
  * `object.metadata.type`, exactly as the inline route sections did.
1634
1635
  */ export const commerceBillingWebhookHandler = async ({ type, object, event, requestHost })=>{
1635
1636
  var _object_metadata, _object_metadata1, _object_metadata2, _object_metadata3, _object_metadata4;
1636
- // Connect readiness, kept fresh (AGL-1997). Every commerce money route —
1637
+ // THE MERCHANT'S PAYMENT ACCOUNT CHANGED. Every commerce money route —
1637
1638
  // checkout, cart checkout, draft orders, reservations, POS — gates the sale
1638
- // on the CACHED `stripeChargesEnabled` written by the connect route. Nothing
1639
- // refreshed it but the merchant reopening that route, so a merchant Stripe
1640
- // later restricted kept selling on a stale `true` and the shopper met the
1641
- // failure at payment time.
1639
+ // on the readiness the connect route CACHED on the merchant's profile
1640
+ // (AGL-1997), and nothing refreshed it but the merchant reopening that
1641
+ // route: a merchant the provider later restricted kept selling on a stale
1642
+ // `true`, and the shopper met the failure at payment time. A payout or
1643
+ // transfer that never landed is recorded against the same profile, and a
1644
+ // later one that did retires the warning.
1642
1645
  //
1643
- // FIRST and with an early return: this event shares nothing with the order
1644
- // sections below, and returning here keeps it out of every `metadata.type`
1645
- // test. `syncConnectAccountStatus` mirrors current state, so a redelivery is
1646
- // harmless.
1647
- // `event.livemode`, not `object.livemode` (AGL-2471): the Stripe Account
1648
- // object carries no `livemode` field, but the event announcing it does, and
1649
- // that is what lets a linkage whose mode was never recorded heal itself
1650
- // instead of staying refused forever.
1651
- if (type === 'account.updated') {
1652
- await syncConnectAccountStatus('profiles', object, event == null ? void 0 : event.livemode);
1653
- return;
1654
- }
1655
- // A PAYOUT OR TRANSFER THAT NEVER LANDED.
1656
- //
1657
- // Placed beside `account.updated` because it is the same kind of event —
1658
- // account-level, nothing to do with the `metadata.type` order sections
1659
- // below — and returns for the same reason.
1660
- //
1661
- // `payout.failed` is the CONNECTED account's balance failing to reach its
1662
- // bank, so the account id is `event.account`: the Payout object's own
1663
- // `destination` names the bank, not the Connect account. `transfer.failed`
1664
- // is the platform's balance failing to reach the connected account, a
1665
- // platform event whose `destination` IS the account.
1666
- //
1667
- // Recorded and surfaced, never retried: Stripe runs its own retry schedule
1668
- // and a second transfer against an account that just refused one is how a
1669
- // duplicate lands.
1670
- if (type === 'payout.failed' || type === 'transfer.failed') {
1671
- var _ref, _ref1, _ref2;
1672
- var _object_destination;
1673
- const failedAccountId = type === 'payout.failed' ? String((_ref = event == null ? void 0 : event.account) != null ? _ref : '') : String((_ref1 = (_ref2 = object == null ? void 0 : (_object_destination = object.destination) == null ? void 0 : _object_destination.id) != null ? _ref2 : object == null ? void 0 : object.destination) != null ? _ref1 : '');
1674
- await recordConnectPayoutFailure('profiles', {
1675
- kind: type === 'payout.failed' ? 'payout' : 'transfer',
1676
- object,
1677
- accountId: failedAccountId,
1678
- livemode: event == null ? void 0 : event.livemode
1679
- });
1680
- return;
1681
- }
1682
- // A later success retires the warning the card shows. The history in
1683
- // `connectPayoutFailures` is kept — "has this account failed before" is what
1684
- // that record exists to answer — but a stale warning on a resolved problem
1685
- // trains people to ignore the surface.
1686
- if (type === 'payout.paid') {
1687
- var _ref3;
1688
- await clearConnectPayoutFailure('profiles', String((_ref3 = event == null ? void 0 : event.account) != null ? _ref3 : ''));
1646
+ // The payment provider reads the event — which ones describe an account,
1647
+ // and where each keeps its id — and mirrors current state, so a redelivery
1648
+ // is harmless. FIRST and with an early return: these events share nothing
1649
+ // with the order sections below, and returning here keeps them out of
1650
+ // every `metadata.type` test.
1651
+ if (await paymentProvider().applyAccountEvent('profiles', {
1652
+ type,
1653
+ object,
1654
+ event
1655
+ })) {
1689
1656
  return;
1690
1657
  }
1691
1658
  // A DEAD SESSION GIVES ITS RESERVATIONS BACK (AGL-2453).
@@ -1706,9 +1673,9 @@ async function findOrderForDispute(paymentIntentId) {
1706
1673
  // Same early return as `account.updated`: this event carries no order and
1707
1674
  // shares nothing with the `checkout.session.completed` sections below.
1708
1675
  if (type === 'checkout.session.expired') {
1709
- var _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref10, _ref11;
1676
+ var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
1710
1677
  var _object_metadata5, _object_metadata6, _object_metadata7, _object_metadata8, _object_metadata9, _object_metadata10, _object_metadata11, _object_metadata12;
1711
- const expiredHostId = String((_ref4 = object == null ? void 0 : (_object_metadata5 = object.metadata) == null ? void 0 : _object_metadata5.hostId) != null ? _ref4 : '');
1678
+ const expiredHostId = String((_ref = object == null ? void 0 : (_object_metadata5 = object.metadata) == null ? void 0 : _object_metadata5.hostId) != null ? _ref : '');
1712
1679
  if (!expiredHostId) return;
1713
1680
  const expiredHostRef = firebaseAdmin.app().firestore().collection('hosts').doc(expiredHostId);
1714
1681
  // THE UNITS COME BACK FIRST (AGL-2356), because they are the reservation a
@@ -1722,14 +1689,14 @@ async function findOrderForDispute(paymentIntentId) {
1722
1689
  // fire at all unless the endpoint subscribes to the event. What it buys is
1723
1690
  // that the shelf and the storefront agree PROMPTLY, which is the difference
1724
1691
  // between a hold a merchant can reason about and one they cannot.
1725
- await releaseStockHold(expiredHostRef, String((_ref5 = object == null ? void 0 : (_object_metadata6 = object.metadata) == null ? void 0 : _object_metadata6.stockHoldKey) != null ? _ref5 : ''));
1726
- const couponHoldKey = String((_ref6 = object == null ? void 0 : (_object_metadata7 = object.metadata) == null ? void 0 : _object_metadata7.couponHoldKey) != null ? _ref6 : '');
1727
- const couponCode = String((_ref7 = object == null ? void 0 : (_object_metadata8 = object.metadata) == null ? void 0 : _object_metadata8.couponCode) != null ? _ref7 : '');
1692
+ await releaseStockHold(expiredHostRef, String((_ref1 = object == null ? void 0 : (_object_metadata6 = object.metadata) == null ? void 0 : _object_metadata6.stockHoldKey) != null ? _ref1 : ''));
1693
+ const couponHoldKey = String((_ref2 = object == null ? void 0 : (_object_metadata7 = object.metadata) == null ? void 0 : _object_metadata7.couponHoldKey) != null ? _ref2 : '');
1694
+ const couponCode = String((_ref3 = object == null ? void 0 : (_object_metadata8 = object.metadata) == null ? void 0 : _object_metadata8.couponCode) != null ? _ref3 : '');
1728
1695
  if (couponHoldKey && couponCode) {
1729
1696
  await releasePromotionHold(expiredHostRef.collection('coupons').doc(couponCode), couponHoldKey);
1730
1697
  }
1731
- const discountHoldKey = String((_ref8 = object == null ? void 0 : (_object_metadata9 = object.metadata) == null ? void 0 : _object_metadata9.discountHoldKey) != null ? _ref8 : '');
1732
- const discountId = String((_ref9 = object == null ? void 0 : (_object_metadata10 = object.metadata) == null ? void 0 : _object_metadata10.discountId) != null ? _ref9 : '');
1698
+ const discountHoldKey = String((_ref4 = object == null ? void 0 : (_object_metadata9 = object.metadata) == null ? void 0 : _object_metadata9.discountHoldKey) != null ? _ref4 : '');
1699
+ const discountId = String((_ref5 = object == null ? void 0 : (_object_metadata10 = object.metadata) == null ? void 0 : _object_metadata10.discountId) != null ? _ref5 : '');
1733
1700
  if (discountHoldKey && discountId) {
1734
1701
  await releasePromotionHold(expiredHostRef.collection('discounts').doc(discountId), discountHoldKey);
1735
1702
  }
@@ -1737,8 +1704,8 @@ async function findOrderForDispute(paymentIntentId) {
1737
1704
  // event and AGL-2449 left it to the TTL alone. A shopper whose abandoned
1738
1705
  // checkout stands their own balance off for a day cannot be told why
1739
1706
  // either, and the release is the identical delete sentinel.
1740
- const giftCardHoldKey = String((_ref10 = object == null ? void 0 : (_object_metadata11 = object.metadata) == null ? void 0 : _object_metadata11.giftCardHoldKey) != null ? _ref10 : '');
1741
- const giftCardCode = String((_ref11 = object == null ? void 0 : (_object_metadata12 = object.metadata) == null ? void 0 : _object_metadata12.giftCardCode) != null ? _ref11 : '');
1707
+ const giftCardHoldKey = String((_ref6 = object == null ? void 0 : (_object_metadata11 = object.metadata) == null ? void 0 : _object_metadata11.giftCardHoldKey) != null ? _ref6 : '');
1708
+ const giftCardCode = String((_ref7 = object == null ? void 0 : (_object_metadata12 = object.metadata) == null ? void 0 : _object_metadata12.giftCardCode) != null ? _ref7 : '');
1742
1709
  if (giftCardHoldKey && giftCardCode) {
1743
1710
  await expiredHostRef.collection('giftCards').doc(giftCardCode).set({
1744
1711
  holds: {
@@ -1791,9 +1758,9 @@ async function findOrderForDispute(paymentIntentId) {
1791
1758
  var _object_metadata14;
1792
1759
  const subHostId = object == null ? void 0 : (_object_metadata14 = object.metadata) == null ? void 0 : _object_metadata14.hostId;
1793
1760
  if (subHostId) {
1794
- var _ref12;
1761
+ var _ref8;
1795
1762
  await firebaseAdmin.app().firestore().collection('hosts').doc(String(subHostId)).collection('subscriptions').doc(String(object.id)).set({
1796
- status: type === 'customer.subscription.deleted' ? 'canceled' : String((_ref12 = object == null ? void 0 : object.status) != null ? _ref12 : 'active'),
1763
+ status: type === 'customer.subscription.deleted' ? 'canceled' : String((_ref8 = object == null ? void 0 : object.status) != null ? _ref8 : 'active'),
1797
1764
  currentPeriodEndMs: (object == null ? void 0 : object.current_period_end) ? object.current_period_end * 1000 : null
1798
1765
  }, {
1799
1766
  merge: true
@@ -1807,7 +1774,7 @@ async function findOrderForDispute(paymentIntentId) {
1807
1774
  var _object_metadata15;
1808
1775
  const { hostId, productId } = (_object_metadata15 = object.metadata) != null ? _object_metadata15 : {};
1809
1776
  if (hostId && productId) {
1810
- var _productForSnapshot_data, _ref13, _productForSnapshot_get, _subTotals_totalCents, _ref14;
1777
+ var _productForSnapshot_data, _ref9, _productForSnapshot_get, _subTotals_totalCents, _ref10;
1811
1778
  var _object_metadata16, _liftedForSnapshot_subscription, _object_customer_details, _object_customer_details1, _object_customer_details2;
1812
1779
  const firestore = firebaseAdmin.app().firestore();
1813
1780
  const hostRef = firestore.collection('hosts').doc(String(hostId));
@@ -1838,7 +1805,7 @@ async function findOrderForDispute(paymentIntentId) {
1838
1805
  name: 'Product'
1839
1806
  });
1840
1807
  const soldVariant = ((_object_metadata16 = object.metadata) == null ? void 0 : _object_metadata16.variantId) ? liftedForSnapshot.variants.find((item)=>item.id === String(object.metadata.variantId)) : liftedForSnapshot.variants[0];
1841
- const variantOptions = Object.values((_ref13 = soldVariant == null ? void 0 : soldVariant.options) != null ? _ref13 : {});
1808
+ const variantOptions = Object.values((_ref9 = soldVariant == null ? void 0 : soldVariant.options) != null ? _ref9 : {});
1842
1809
  const { lineItems: subLineItems, totals: subTotals } = CommerceModel.computeBuyNowOrder(object, _extends({
1843
1810
  name: String((_productForSnapshot_get = productForSnapshot.get('name')) != null ? _productForSnapshot_get : 'Product')
1844
1811
  }, variantOptions.length ? {
@@ -1944,7 +1911,7 @@ async function findOrderForDispute(paymentIntentId) {
1944
1911
  await captureHostContact(_extends({
1945
1912
  hostId: String(hostId),
1946
1913
  email: object == null ? void 0 : (_object_customer_details1 = object.customer_details) == null ? void 0 : _object_customer_details1.email,
1947
- name: (_ref14 = object == null ? void 0 : (_object_customer_details2 = object.customer_details) == null ? void 0 : _object_customer_details2.name) != null ? _ref14 : undefined,
1914
+ name: (_ref10 = object == null ? void 0 : (_object_customer_details2 = object.customer_details) == null ? void 0 : _object_customer_details2.name) != null ? _ref10 : undefined,
1948
1915
  source: 'order',
1949
1916
  // Every order door names `customer` (AGL-2612): a floor, so the
1950
1917
  // stage fills or advances and never moves anybody back.
@@ -1993,23 +1960,23 @@ async function findOrderForDispute(paymentIntentId) {
1993
1960
  // is enabled). Handling both means the branch fires whichever is on; the
1994
1961
  // invoice-id guard means having both on records the cycle once.
1995
1962
  if (type === 'invoice.payment_succeeded' || type === 'invoice.paid') {
1996
- var _ref15, _ref16, _ref17, _ref18, _ref19, _ref20;
1963
+ var _ref11, _ref12, _ref13, _ref14, _ref15, _ref16;
1997
1964
  var _object_subscription_details, _object_parent_subscription_details, _object_parent, _object_parent_subscription_details1, _object_parent1;
1998
1965
  // The SUBSCRIPTION's metadata, which is what `checkout.ts` sets
1999
1966
  // (`subscription_data[metadata]`) — the invoice's own `metadata` is a
2000
1967
  // different, empty bag. `parent.subscription_details` is where newer API
2001
1968
  // versions moved it; both are read because the endpoint's version is not
2002
1969
  // visible from here.
2003
- const subscriptionMeta = (_ref15 = (_ref16 = object == null ? void 0 : (_object_subscription_details = object.subscription_details) == null ? void 0 : _object_subscription_details.metadata) != null ? _ref16 : object == null ? void 0 : (_object_parent = object.parent) == null ? void 0 : (_object_parent_subscription_details = _object_parent.subscription_details) == null ? void 0 : _object_parent_subscription_details.metadata) != null ? _ref15 : null;
2004
- const invoiceId = String((_ref17 = object == null ? void 0 : object.id) != null ? _ref17 : '');
2005
- const subscriptionId = String((_ref18 = (_ref19 = object == null ? void 0 : object.subscription) != null ? _ref19 : object == null ? void 0 : (_object_parent1 = object.parent) == null ? void 0 : (_object_parent_subscription_details1 = _object_parent1.subscription_details) == null ? void 0 : _object_parent_subscription_details1.subscription) != null ? _ref18 : '');
2006
- const invoiceHostId = String((_ref20 = subscriptionMeta == null ? void 0 : subscriptionMeta.hostId) != null ? _ref20 : '');
1970
+ const subscriptionMeta = (_ref11 = (_ref12 = object == null ? void 0 : (_object_subscription_details = object.subscription_details) == null ? void 0 : _object_subscription_details.metadata) != null ? _ref12 : object == null ? void 0 : (_object_parent = object.parent) == null ? void 0 : (_object_parent_subscription_details = _object_parent.subscription_details) == null ? void 0 : _object_parent_subscription_details.metadata) != null ? _ref11 : null;
1971
+ const invoiceId = String((_ref13 = object == null ? void 0 : object.id) != null ? _ref13 : '');
1972
+ const subscriptionId = String((_ref14 = (_ref15 = object == null ? void 0 : object.subscription) != null ? _ref15 : object == null ? void 0 : (_object_parent1 = object.parent) == null ? void 0 : (_object_parent_subscription_details1 = _object_parent1.subscription_details) == null ? void 0 : _object_parent_subscription_details1.subscription) != null ? _ref14 : '');
1973
+ const invoiceHostId = String((_ref16 = subscriptionMeta == null ? void 0 : subscriptionMeta.hostId) != null ? _ref16 : '');
2007
1974
  // Platform billing — Aglyn charging its own customers — runs through the
2008
1975
  // same endpoint and the same fan-out, and its invoices carry `orgId`
2009
1976
  // instead. Self-selection is on the same discriminator every other
2010
1977
  // section of this file uses.
2011
1978
  if ((subscriptionMeta == null ? void 0 : subscriptionMeta.type) === 'commerce-subscription' && invoiceHostId && subscriptionId && invoiceId) {
2012
- var _soldSnapshot_get, _ref21, _ref22, _ref23, _ref24, _ref25;
1979
+ var _soldSnapshot_get, _ref17, _ref18, _ref19, _ref20, _ref21;
2013
1980
  var _this, _this1, _object_status_transitions, _object_customer_shipping;
2014
1981
  const firestore = firebaseAdmin.app().firestore();
2015
1982
  const hostRef = firestore.collection('hosts').doc(invoiceHostId);
@@ -2060,7 +2027,7 @@ async function findOrderForDispute(paymentIntentId) {
2060
2027
  // and only for them.
2061
2028
  const soldSnapshot = await subscriptionRef.get();
2062
2029
  const soldLine = (_this1 = (_soldSnapshot_get = soldSnapshot.get('lineItems')) != null ? _soldSnapshot_get : []) == null ? void 0 : _this1[0];
2063
- const productId = String((_ref21 = (_ref22 = (_ref23 = soldLine == null ? void 0 : soldLine.productId) != null ? _ref23 : soldSnapshot.get('productId')) != null ? _ref22 : subscriptionMeta == null ? void 0 : subscriptionMeta.productId) != null ? _ref21 : '');
2030
+ const productId = String((_ref17 = (_ref18 = (_ref19 = soldLine == null ? void 0 : soldLine.productId) != null ? _ref19 : soldSnapshot.get('productId')) != null ? _ref18 : subscriptionMeta == null ? void 0 : subscriptionMeta.productId) != null ? _ref17 : '');
2064
2031
  let snapshot;
2065
2032
  if (soldLine) {
2066
2033
  snapshot = _extends({
@@ -2077,7 +2044,7 @@ async function findOrderForDispute(paymentIntentId) {
2077
2044
  productType: soldLine.productType
2078
2045
  } : {});
2079
2046
  } else {
2080
- var _ref26, _soldSnapshot_get1, _ref27, _ref28;
2047
+ var _ref22, _soldSnapshot_get1, _ref23, _ref24;
2081
2048
  // AGL-1763: no product id, no read. `doc('__missing__')` was a
2082
2049
  // deliberate miss that Firestore does not permit — a document id
2083
2050
  // matching `__.*__` is RESERVED, so the backend rejects the path with
@@ -2090,18 +2057,18 @@ async function findOrderForDispute(paymentIntentId) {
2090
2057
  // exactly the population this branch now serves: a subscription
2091
2058
  // Aglyn has no record of, whose metadata nothing of ours wrote.
2092
2059
  const productSnapshot = productId ? await hostRef.collection('products').doc(productId).get() : null;
2093
- const lifted = CommerceModel.liftLegacyProduct((_ref26 = productSnapshot == null ? void 0 : productSnapshot.data()) != null ? _ref26 : {
2060
+ const lifted = CommerceModel.liftLegacyProduct((_ref22 = productSnapshot == null ? void 0 : productSnapshot.data()) != null ? _ref22 : {
2094
2061
  name: 'Subscription'
2095
2062
  });
2096
2063
  const variantId = String((_soldSnapshot_get1 = soldSnapshot.get('variantId')) != null ? _soldSnapshot_get1 : '');
2097
2064
  const variant = variantId ? lifted.variants.find((item)=>item.id === variantId) : lifted.variants[0];
2098
- const variantOptions = Object.values((_ref27 = variant == null ? void 0 : variant.options) != null ? _ref27 : {});
2065
+ const variantOptions = Object.values((_ref23 = variant == null ? void 0 : variant.options) != null ? _ref23 : {});
2099
2066
  snapshot = _extends({
2100
2067
  productId
2101
2068
  }, variantId ? {
2102
2069
  variantId
2103
2070
  } : {}, {
2104
- name: String((_ref28 = productSnapshot == null ? void 0 : productSnapshot.get('name')) != null ? _ref28 : 'Subscription')
2071
+ name: String((_ref24 = productSnapshot == null ? void 0 : productSnapshot.get('name')) != null ? _ref24 : 'Subscription')
2105
2072
  }, variantOptions.length ? {
2106
2073
  variantLabel: variantOptions.join(' / ')
2107
2074
  } : {}, (variant == null ? void 0 : variant.sku) ? {
@@ -2123,8 +2090,8 @@ async function findOrderForDispute(paymentIntentId) {
2123
2090
  const invoiceTotals = _extends({}, computedInvoiceTotals, {
2124
2091
  feeCents: feeCentsInForce
2125
2092
  });
2126
- const paidCents = Math.max(0, Math.round(Number((_ref24 = object == null ? void 0 : object.amount_paid) != null ? _ref24 : 0)));
2127
- const billingReason = String((_ref25 = object == null ? void 0 : object.billing_reason) != null ? _ref25 : '');
2093
+ const paidCents = Math.max(0, Math.round(Number((_ref20 = object == null ? void 0 : object.amount_paid) != null ? _ref20 : 0)));
2094
+ const billingReason = String((_ref21 = object == null ? void 0 : object.billing_reason) != null ? _ref21 : '');
2128
2095
  // The subscription's FIRST invoice is also a paid invoice, and
2129
2096
  // `checkout.session.completed` has already counted that money into the
2130
2097
  // contact's lifetime value and already told the managers about it
@@ -2444,8 +2411,8 @@ async function findOrderForDispute(paymentIntentId) {
2444
2411
  const stockVariantId = (_snapshot_variantId = snapshot.variantId) != null ? _snapshot_variantId : (_stocked_variants_ = stocked.variants[0]) == null ? void 0 : _stocked_variants_.id;
2445
2412
  const tracked = stocked.variants.some((variant)=>variant.id === stockVariantId && variant.inventory != null);
2446
2413
  if (stockVariantId && tracked) {
2447
- var _ref29;
2448
- const cycleQuantity = (_ref29 = cycleLine == null ? void 0 : cycleLine.quantity) != null ? _ref29 : 1;
2414
+ var _ref25;
2415
+ const cycleQuantity = (_ref25 = cycleLine == null ? void 0 : cycleLine.quantity) != null ? _ref25 : 1;
2449
2416
  // Atomic since AGL-2320, like every other decrement: a renewal
2450
2417
  // batch bills many subscribers at once, so two cycles of the same
2451
2418
  // physical box are exactly the concurrent pair that lost a
@@ -2470,8 +2437,8 @@ async function findOrderForDispute(paymentIntentId) {
2470
2437
  }
2471
2438
  }
2472
2439
  if (!isOpeningInvoice && paidCents > 0) {
2473
- var _ref30, _ref31;
2474
- const renewalEmail = (_ref30 = (_ref31 = object == null ? void 0 : object.customer_email) != null ? _ref31 : soldSnapshot.get('customerEmail')) != null ? _ref30 : null;
2440
+ var _ref26, _ref27;
2441
+ const renewalEmail = (_ref26 = (_ref27 = object == null ? void 0 : object.customer_email) != null ? _ref27 : soldSnapshot.get('customerEmail')) != null ? _ref26 : null;
2475
2442
  // A physical cycle now lands in Orders (AGL-1750), but the console
2476
2443
  // still has no Subscriptions tab, so for a digital or service
2477
2444
  // subscription this notification remains the only place a merchant
@@ -2510,7 +2477,7 @@ async function findOrderForDispute(paymentIntentId) {
2510
2477
  var _object_metadata17;
2511
2478
  const { hostId, reservationId } = (_object_metadata17 = object.metadata) != null ? _object_metadata17 : {};
2512
2479
  if (hostId && reservationId) {
2513
- var _ref32, _ref33;
2480
+ var _ref28, _ref29;
2514
2481
  var _object_metadata18;
2515
2482
  const firestore = firebaseAdmin.app().firestore();
2516
2483
  const reservationRef = firestore.collection('hosts').doc(String(hostId)).collection('reservations').doc(String(reservationId));
@@ -2523,7 +2490,7 @@ async function findOrderForDispute(paymentIntentId) {
2523
2490
  // `amount_total` is stay-plus-tax and Stripe's own tax fields read
2524
2491
  // zero; the session's metadata is the only witness, exactly as it is
2525
2492
  // for a buy-now sale.
2526
- const taxCents = Math.max(0, Math.round(Number((_ref32 = object == null ? void 0 : (_object_metadata18 = object.metadata) == null ? void 0 : _object_metadata18.taxCents) != null ? _ref32 : 0)));
2493
+ const taxCents = Math.max(0, Math.round(Number((_ref28 = object == null ? void 0 : (_object_metadata18 = object.metadata) == null ? void 0 : _object_metadata18.taxCents) != null ? _ref28 : 0)));
2527
2494
  // What the guest actually handed over, MINUS that tax. This is the
2528
2495
  // DEPOSIT when the resource has one (`reserve.ts` charges
2529
2496
  // `depositCents || totalCents`), never the stay's `totalCents` — see
@@ -2537,7 +2504,7 @@ async function findOrderForDispute(paymentIntentId) {
2537
2504
  // are and under-state what the merchant collects at the register. The
2538
2505
  // same figure feeds the guest's lifetime value, which tax is no part
2539
2506
  // of either (AGL-1755).
2540
- const paidCents = Math.max(0, Math.round(Number((_ref33 = object == null ? void 0 : object.amount_total) != null ? _ref33 : 0)) - taxCents);
2507
+ const paidCents = Math.max(0, Math.round(Number((_ref29 = object == null ? void 0 : object.amount_total) != null ? _ref29 : 0)) - taxCents);
2541
2508
  // Redelivery guard (AGL-1755), the AGL-1748 shape. The `pending` ->
2542
2509
  // `confirmed` transition was always the guard, but it was a
2543
2510
  // read-then-write with every side effect hanging off it, so two
@@ -2608,7 +2575,7 @@ async function findOrderForDispute(paymentIntentId) {
2608
2575
  return true;
2609
2576
  });
2610
2577
  if (confirmedNow) {
2611
- var _ref34, _ref35;
2578
+ var _ref30, _ref31;
2612
2579
  var _object_customer_details3, _object_customer_details4, _object_customer_details5;
2613
2580
  const reservation = reserved != null ? reserved : {};
2614
2581
  void notifyHostManagers(String(hostId), _extends({
@@ -2648,14 +2615,14 @@ async function findOrderForDispute(paymentIntentId) {
2648
2615
  // exactly once. Taking `totalCents` here is what WOULD double-count:
2649
2616
  // it would claim money the guest has not paid yet and will pay again
2650
2617
  // through the register.
2651
- const guestContactEmail = (_ref34 = (_ref35 = object == null ? void 0 : (_object_customer_details4 = object.customer_details) == null ? void 0 : _object_customer_details4.email) != null ? _ref35 : reservation['guestEmail']) != null ? _ref34 : null;
2618
+ const guestContactEmail = (_ref30 = (_ref31 = object == null ? void 0 : (_object_customer_details4 = object.customer_details) == null ? void 0 : _object_customer_details4.email) != null ? _ref31 : reservation['guestEmail']) != null ? _ref30 : null;
2652
2619
  if (guestContactEmail) {
2653
- var _ref36, _ref37;
2620
+ var _ref32, _ref33;
2654
2621
  var _object_customer_details6;
2655
2622
  await captureHostContact(_extends({
2656
2623
  hostId: String(hostId),
2657
2624
  email: guestContactEmail,
2658
- name: (_ref36 = (_ref37 = object == null ? void 0 : (_object_customer_details6 = object.customer_details) == null ? void 0 : _object_customer_details6.name) != null ? _ref37 : reservation['guestName']) != null ? _ref36 : undefined,
2625
+ name: (_ref32 = (_ref33 = object == null ? void 0 : (_object_customer_details6 = object.customer_details) == null ? void 0 : _object_customer_details6.name) != null ? _ref33 : reservation['guestName']) != null ? _ref32 : undefined,
2659
2626
  source: 'booking',
2660
2627
  // A paid stay is a sale (AGL-2612), whatever the source says
2661
2628
  // about the kind of thing that was bought.
@@ -2671,7 +2638,7 @@ async function findOrderForDispute(paymentIntentId) {
2671
2638
  }
2672
2639
  const guestEmail = object == null ? void 0 : (_object_customer_details5 = object.customer_details) == null ? void 0 : _object_customer_details5.email;
2673
2640
  if (guestEmail) {
2674
- var _reservation_nights, _ref38;
2641
+ var _reservation_nights, _ref34;
2675
2642
  const checkIn = new Date(Number(reservation['checkInDayMs'])).toUTCString();
2676
2643
  const paid = `$${(paidCents / 100).toFixed(2)}`;
2677
2644
  const checkInShort = checkIn.slice(0, 16);
@@ -2685,7 +2652,7 @@ async function findOrderForDispute(paymentIntentId) {
2685
2652
  });
2686
2653
  await sendEmail(_extends({
2687
2654
  to: guestEmail,
2688
- subject: (_ref38 = designed == null ? void 0 : designed.subject) != null ? _ref38 : 'Reservation confirmed',
2655
+ subject: (_ref34 = designed == null ? void 0 : designed.subject) != null ? _ref34 : 'Reservation confirmed',
2689
2656
  text: (designed == null ? void 0 : designed.text) || fallbackText
2690
2657
  }, (designed == null ? void 0 : designed.html) ? {
2691
2658
  html: designed.html
@@ -2711,7 +2678,7 @@ async function findOrderForDispute(paymentIntentId) {
2711
2678
  var _object_metadata19;
2712
2679
  const { hostId, cartId, feeCents, couponCode } = (_object_metadata19 = object.metadata) != null ? _object_metadata19 : {};
2713
2680
  if (hostId && cartId) {
2714
- var _cartSnapshot_data, _ref39, _ref40, _ref41, _ref42, _ref43, _ref44;
2681
+ var _cartSnapshot_data, _ref35, _ref36, _ref37, _ref38, _ref39, _ref40;
2715
2682
  var _object_customer_details7, _object_metadata20, _object_customer_details8, _object_customer_details9, _object_customer_details10, _object_metadata21, _this2, _object_metadata22;
2716
2683
  const firestore = firebaseAdmin.app().firestore();
2717
2684
  const hostRef = firestore.collection('hosts').doc(String(hostId));
@@ -2777,7 +2744,7 @@ async function findOrderForDispute(paymentIntentId) {
2777
2744
  unitAmountCents: Math.round(Number((_ref = variant == null ? void 0 : variant.priceUsd) != null ? _ref : 0) * 100)
2778
2745
  });
2779
2746
  }).filter(Boolean);
2780
- const shipping = (_ref39 = object == null ? void 0 : object.shipping_details) != null ? _ref39 : object == null ? void 0 : object.customer_details;
2747
+ const shipping = (_ref35 = object == null ? void 0 : object.shipping_details) != null ? _ref35 : object == null ? void 0 : object.customer_details;
2781
2748
  const created = await firestore.runTransaction(async (transaction)=>{
2782
2749
  var _counter_get, _ref, _ref1, _ref2, _ref3, _ref4, _shipping_address_line1, _shipping_address_line2, _shipping_address_city, _shipping_address_state, _shipping_address_postal_code, _shipping_address_country, _ref5;
2783
2750
  var _object_metadata, _object_customer_details, _object_customer_details1;
@@ -2915,10 +2882,10 @@ async function findOrderForDispute(paymentIntentId) {
2915
2882
  // matters, and the order carries the buyer identity anyway.
2916
2883
  const licenseKeysByProduct = {};
2917
2884
  for (const line of lineItems){
2918
- var _ref45;
2885
+ var _ref41;
2919
2886
  var _object_customer_details11;
2920
2887
  if (line.productType !== 'digital') continue;
2921
- const keys = await assignLicenseKeys(firestore, hostRef, String(hostId), line.productId, String(object.id), (_ref45 = object == null ? void 0 : (_object_customer_details11 = object.customer_details) == null ? void 0 : _object_customer_details11.email) != null ? _ref45 : null, line.quantity);
2888
+ const keys = await assignLicenseKeys(firestore, hostRef, String(hostId), line.productId, String(object.id), (_ref41 = object == null ? void 0 : (_object_customer_details11 = object.customer_details) == null ? void 0 : _object_customer_details11.email) != null ? _ref41 : null, line.quantity);
2922
2889
  if (keys.length) licenseKeysByProduct[line.productId] = keys;
2923
2890
  }
2924
2891
  if (Object.keys(licenseKeysByProduct).length) {
@@ -2931,9 +2898,9 @@ async function findOrderForDispute(paymentIntentId) {
2931
2898
  // Branded receipt (AGL-296): env-gated like every outbound email.
2932
2899
  const buyerEmailForReceipt = object == null ? void 0 : (_object_customer_details7 = object.customer_details) == null ? void 0 : _object_customer_details7.email;
2933
2900
  if (isEmailConfigured() && buyerEmailForReceipt) {
2934
- var _ref46, _ref47, _ref48, _ref49;
2901
+ var _ref42, _ref43, _ref44, _ref45;
2935
2902
  const receiptSettings = await hostRef.collection('settings').doc('store').get().catch(()=>null);
2936
- const receiptFooter = String((_ref46 = receiptSettings == null ? void 0 : receiptSettings.get('receiptFooter')) != null ? _ref46 : '');
2903
+ const receiptFooter = String((_ref42 = receiptSettings == null ? void 0 : receiptSettings.get('receiptFooter')) != null ? _ref42 : '');
2937
2904
  const linesText = lineItems.map((line)=>`${line.quantity}× ${line.name}${line.variantLabel ? ` (${line.variantLabel})` : ''} — $${(line.unitAmountCents * line.quantity / 100).toFixed(2)}`).join('\n');
2938
2905
  // The keys assigned above the gate (AGL-2149); the receipt only
2939
2906
  // reports them.
@@ -2947,9 +2914,9 @@ async function findOrderForDispute(paymentIntentId) {
2947
2914
  // Digital delivery links (AGL-302); reuse the canonical mint the
2948
2915
  // tenant download endpoint verifies so the secret can never drift.
2949
2916
  const downloadToken = mintDownloadToken(hostId, String(object.id));
2950
- const siteOrigin = String((_ref47 = object == null ? void 0 : object.success_url) != null ? _ref47 : '').replace(/\/\?.*$|\?.*$/, '');
2917
+ const siteOrigin = String((_ref43 = object == null ? void 0 : object.success_url) != null ? _ref43 : '').replace(/\/\?.*$|\?.*$/, '');
2951
2918
  const downloadLines = lineItems.filter((line)=>line.productType === 'digital').map((line)=>`Download ${line.name}: ${siteOrigin}/api/commerce/download` + `?hostId=${hostId}&orderId=${object.id}` + `&productId=${line.productId}&token=${downloadToken}`).join('\n');
2952
- const orderTotal = `$${(Number((_ref48 = object == null ? void 0 : object.amount_total) != null ? _ref48 : 0) / 100).toFixed(2)}`;
2919
+ const orderTotal = `$${(Number((_ref44 = object == null ? void 0 : object.amount_total) != null ? _ref44 : 0) / 100).toFixed(2)}`;
2953
2920
  const orderSummary = [
2954
2921
  linesText,
2955
2922
  licenseText,
@@ -2965,7 +2932,7 @@ async function findOrderForDispute(paymentIntentId) {
2965
2932
  });
2966
2933
  await sendEmail(_extends({
2967
2934
  to: buyerEmailForReceipt,
2968
- subject: (_ref49 = designed == null ? void 0 : designed.subject) != null ? _ref49 : `Receipt for your order`,
2935
+ subject: (_ref45 = designed == null ? void 0 : designed.subject) != null ? _ref45 : `Receipt for your order`,
2969
2936
  text: (designed == null ? void 0 : designed.text) || fallbackText
2970
2937
  }, (designed == null ? void 0 : designed.html) ? {
2971
2938
  html: designed.html
@@ -3042,10 +3009,10 @@ async function findOrderForDispute(paymentIntentId) {
3042
3009
  // is byte-identical to what it was before this issue for exactly that
3043
3010
  // reason. The hold refuses the SECOND shopper; it never gates the
3044
3011
  // first one's goods.
3045
- await releaseStockHold(hostRef, String((_ref40 = (_object_metadata20 = object.metadata) == null ? void 0 : _object_metadata20.stockHoldKey) != null ? _ref40 : ''));
3012
+ await releaseStockHold(hostRef, String((_ref36 = (_object_metadata20 = object.metadata) == null ? void 0 : _object_metadata20.stockHoldKey) != null ? _ref36 : ''));
3046
3013
  void notifyHostManagers(String(hostId), _extends({
3047
3014
  type: 'content.order',
3048
- title: `New order — $${(Number((_ref41 = object == null ? void 0 : object.amount_total) != null ? _ref41 : 0) / 100).toFixed(2)}`
3015
+ title: `New order — $${(Number((_ref37 = object == null ? void 0 : object.amount_total) != null ? _ref37 : 0) / 100).toFixed(2)}`
3049
3016
  }, (object == null ? void 0 : (_object_customer_details8 = object.customer_details) == null ? void 0 : _object_customer_details8.email) ? {
3050
3017
  body: `From ${object.customer_details.email}`
3051
3018
  } : {}, {
@@ -3054,25 +3021,25 @@ async function findOrderForDispute(paymentIntentId) {
3054
3021
  await captureHostContact(_extends({
3055
3022
  hostId: String(hostId),
3056
3023
  email: object == null ? void 0 : (_object_customer_details9 = object.customer_details) == null ? void 0 : _object_customer_details9.email,
3057
- name: (_ref42 = object == null ? void 0 : (_object_customer_details10 = object.customer_details) == null ? void 0 : _object_customer_details10.name) != null ? _ref42 : undefined,
3024
+ name: (_ref38 = object == null ? void 0 : (_object_customer_details10 = object.customer_details) == null ? void 0 : _object_customer_details10.name) != null ? _ref38 : undefined,
3058
3025
  source: 'order',
3059
3026
  initialLifecycleStage: 'customer'
3060
3027
  }, marketingOptIn ? {
3061
3028
  marketingConsent: true
3062
3029
  } : {}, {
3063
- purchaseCents: Number((_ref43 = object == null ? void 0 : object.amount_total) != null ? _ref43 : 0),
3030
+ purchaseCents: Number((_ref39 = object == null ? void 0 : object.amount_total) != null ? _ref39 : 0),
3064
3031
  interaction: {
3065
3032
  refId: String(object.id),
3066
- summary: `Placed an order ($${(Number((_ref44 = object == null ? void 0 : object.amount_total) != null ? _ref44 : 0) / 100).toFixed(2)})`
3033
+ summary: `Placed an order ($${(Number((_ref40 = object == null ? void 0 : object.amount_total) != null ? _ref40 : 0) / 100).toFixed(2)})`
3067
3034
  }
3068
3035
  }));
3069
3036
  if (couponCode) {
3070
- var _ref50;
3037
+ var _ref46;
3071
3038
  var _object_metadata23;
3072
3039
  await settleRedemption({
3073
3040
  firestore,
3074
3041
  ref: hostRef.collection('coupons').doc(String(couponCode)),
3075
- holdKey: String((_ref50 = (_object_metadata23 = object.metadata) == null ? void 0 : _object_metadata23.couponHoldKey) != null ? _ref50 : ''),
3042
+ holdKey: String((_ref46 = (_object_metadata23 = object.metadata) == null ? void 0 : _object_metadata23.couponHoldKey) != null ? _ref46 : ''),
3076
3043
  orderRef,
3077
3044
  label: `coupon ${couponCode}`,
3078
3045
  detail: `Coupon ${couponCode} was applied to this order but no longer ` + 'exists, so the redemption is uncounted against its limit.'
@@ -3080,10 +3047,10 @@ async function findOrderForDispute(paymentIntentId) {
3080
3047
  }
3081
3048
  // Gift card balance settlement (AGL-322, made a settlement by AGL-2449).
3082
3049
  if ((_object_metadata21 = object.metadata) == null ? void 0 : _object_metadata21.giftCardCode) {
3083
- var _ref51, _ref52;
3050
+ var _ref47, _ref48;
3084
3051
  var _object_metadata24, _object_metadata25;
3085
- const giftCardCents = Number((_ref51 = (_object_metadata24 = object.metadata) == null ? void 0 : _object_metadata24.giftCardCents) != null ? _ref51 : 0);
3086
- const holdKey = String((_ref52 = (_object_metadata25 = object.metadata) == null ? void 0 : _object_metadata25.giftCardHoldKey) != null ? _ref52 : '');
3052
+ const giftCardCents = Number((_ref47 = (_object_metadata24 = object.metadata) == null ? void 0 : _object_metadata24.giftCardCents) != null ? _ref47 : 0);
3053
+ const holdKey = String((_ref48 = (_object_metadata25 = object.metadata) == null ? void 0 : _object_metadata25.giftCardHoldKey) != null ? _ref48 : '');
3087
3054
  const cardRef = hostRef.collection('giftCards').doc(String(object.metadata.giftCardCode));
3088
3055
  const orphanNote = `$${(giftCardCents / 100).toFixed(2)} was applied from gift card ` + `${object.metadata.giftCardCode}, which no longer exists. The ` + 'balance was not deducted from any card.';
3089
3056
  if (!holdKey) {
@@ -3163,7 +3130,7 @@ async function findOrderForDispute(paymentIntentId) {
3163
3130
  const lineProduct = productsById.get(line.productId);
3164
3131
  if (!(lineProduct == null ? void 0 : lineProduct.giftCard)) continue;
3165
3132
  for(let unit = 0; unit < line.quantity; unit += 1){
3166
- var _ref53, _ref54;
3133
+ var _ref49, _ref50;
3167
3134
  var _object_customer_details12, _object_customer_details13, _object_customer_details14;
3168
3135
  const code = `GC-${createHmac('sha256', String(object.id)).update(`${line.productId}:${unit}:${Date.now()}`).digest('hex').slice(0, 12).toUpperCase()}`;
3169
3136
  // THE EMAIL IS GATED ON THE WRITE (AGL-2161). This `.set()` used
@@ -3182,13 +3149,13 @@ async function findOrderForDispute(paymentIntentId) {
3182
3149
  const issued = await hostRef.collection('giftCards').doc(code).set({
3183
3150
  initialCents: line.unitAmountCents,
3184
3151
  balanceCents: line.unitAmountCents,
3185
- recipientEmail: (_ref53 = object == null ? void 0 : (_object_customer_details12 = object.customer_details) == null ? void 0 : _object_customer_details12.email) != null ? _ref53 : null,
3152
+ recipientEmail: (_ref49 = object == null ? void 0 : (_object_customer_details12 = object.customer_details) == null ? void 0 : _object_customer_details12.email) != null ? _ref49 : null,
3186
3153
  orderId: String(object.id),
3187
3154
  // Which line bought it, so a refund that withdraws that line
3188
3155
  // voids this card and no other (AGL-3363).
3189
3156
  productId: line.productId,
3190
3157
  // What the console's Gift cards search asks (AGL-3321).
3191
- searchTokens: giftCardSearchTokens(code, (_ref54 = object == null ? void 0 : (_object_customer_details13 = object.customer_details) == null ? void 0 : _object_customer_details13.email) != null ? _ref54 : null),
3158
+ searchTokens: giftCardSearchTokens(code, (_ref50 = object == null ? void 0 : (_object_customer_details13 = object.customer_details) == null ? void 0 : _object_customer_details13.email) != null ? _ref50 : null),
3192
3159
  createdAtMs: Date.now()
3193
3160
  }).then(()=>true).catch((error)=>{
3194
3161
  console.error('Gift card issuance failed', hostId, code, error);
@@ -3216,7 +3183,7 @@ async function findOrderForDispute(paymentIntentId) {
3216
3183
  }
3217
3184
  const giftTo = object == null ? void 0 : (_object_customer_details14 = object.customer_details) == null ? void 0 : _object_customer_details14.email;
3218
3185
  if (giftTo) {
3219
- var _ref55;
3186
+ var _ref51;
3220
3187
  const giftValue = `$${(line.unitAmountCents / 100).toFixed(2)}`;
3221
3188
  const fallbackText = `Gift card code: ${code}\n` + `Value: ${giftValue}\n\n` + 'Enter it at checkout to apply the balance.';
3222
3189
  // Site-owner-designed template when published (AGL-771).
@@ -3226,7 +3193,7 @@ async function findOrderForDispute(paymentIntentId) {
3226
3193
  });
3227
3194
  await sendEmail(_extends({
3228
3195
  to: giftTo,
3229
- subject: (_ref55 = designed == null ? void 0 : designed.subject) != null ? _ref55 : 'Your gift card',
3196
+ subject: (_ref51 = designed == null ? void 0 : designed.subject) != null ? _ref51 : 'Your gift card',
3230
3197
  text: (designed == null ? void 0 : designed.text) || fallbackText
3231
3198
  }, (designed == null ? void 0 : designed.html) ? {
3232
3199
  html: designed.html
@@ -3247,12 +3214,12 @@ async function findOrderForDispute(paymentIntentId) {
3247
3214
  }
3248
3215
  // Discounts engine redemptions (AGL-305).
3249
3216
  if ((_object_metadata22 = object.metadata) == null ? void 0 : _object_metadata22.discountId) {
3250
- var _ref56;
3217
+ var _ref52;
3251
3218
  var _object_metadata26;
3252
3219
  await settleRedemption({
3253
3220
  firestore,
3254
3221
  ref: hostRef.collection('discounts').doc(String(object.metadata.discountId)),
3255
- holdKey: String((_ref56 = (_object_metadata26 = object.metadata) == null ? void 0 : _object_metadata26.discountHoldKey) != null ? _ref56 : ''),
3222
+ holdKey: String((_ref52 = (_object_metadata26 = object.metadata) == null ? void 0 : _object_metadata26.discountHoldKey) != null ? _ref52 : ''),
3256
3223
  orderRef,
3257
3224
  label: `discount ${object.metadata.discountId}`,
3258
3225
  detail: `Discount ${object.metadata.discountId} was applied to this ` + 'order but no longer exists, so the redemption is uncounted ' + 'against its limit.'
@@ -3266,7 +3233,7 @@ async function findOrderForDispute(paymentIntentId) {
3266
3233
  var _object_metadata27;
3267
3234
  const { hostId, orderId, productId } = (_object_metadata27 = object.metadata) != null ? _object_metadata27 : {};
3268
3235
  if (hostId && orderId) {
3269
- var _ref57, _ref58, _ref59;
3236
+ var _ref53, _ref54, _ref55;
3270
3237
  var _object_total_details, _object_total_details1;
3271
3238
  const firestore = firebaseAdmin.app().firestore();
3272
3239
  const hostRef = firestore.collection('hosts').doc(String(hostId));
@@ -3305,7 +3272,7 @@ async function findOrderForDispute(paymentIntentId) {
3305
3272
  //
3306
3273
  // The whole map is written rather than one field of it, so a
3307
3274
  // `merge`-set's nested-map merge and a plain replace agree.
3308
- const shippingCents = Math.max(0, Math.round(Number((_ref57 = object == null ? void 0 : (_object_total_details = object.total_details) == null ? void 0 : _object_total_details.amount_shipping) != null ? _ref57 : 0) || 0));
3275
+ const shippingCents = Math.max(0, Math.round(Number((_ref53 = object == null ? void 0 : (_object_total_details = object.total_details) == null ? void 0 : _object_total_details.amount_shipping) != null ? _ref53 : 0) || 0));
3309
3276
  // Tax joins shipping in the fold (AGL-1953). `draft-order.ts` now
3310
3277
  // declares tax — a Stripe Tax Rate for a `manual` store, whose figure
3311
3278
  // it already froze into `totals`, or `automatic_tax` for a `stripe`
@@ -3318,8 +3285,8 @@ async function findOrderForDispute(paymentIntentId) {
3318
3285
  // `amount_tax` 0 here (its own figure stays on the order, and its
3319
3286
  // AGL-1953 witness is metadata, not this field), and a draft composed
3320
3287
  // by a store with no tax reports 0 too.
3321
- const stripeTaxCents = Math.max(0, Math.round(Number((_ref58 = object == null ? void 0 : (_object_total_details1 = object.total_details) == null ? void 0 : _object_total_details1.amount_tax) != null ? _ref58 : 0) || 0));
3322
- const chargedTotalCents = Number((_ref59 = object == null ? void 0 : object.amount_total) != null ? _ref59 : NaN);
3288
+ const stripeTaxCents = Math.max(0, Math.round(Number((_ref54 = object == null ? void 0 : (_object_total_details1 = object.total_details) == null ? void 0 : _object_total_details1.amount_tax) != null ? _ref54 : 0) || 0));
3289
+ const chargedTotalCents = Number((_ref55 = object == null ? void 0 : object.amount_total) != null ? _ref55 : NaN);
3323
3290
  // `shipping_details` ONLY, unlike the cart branch's
3324
3291
  // `?? customer_details` fallback: that address is the BILLING one, and
3325
3292
  // a card sale rung up at a register completes here too — it must not
@@ -3433,7 +3400,7 @@ async function findOrderForDispute(paymentIntentId) {
3433
3400
  });
3434
3401
  }
3435
3402
  if (flipped) {
3436
- var _ref60, _ref61;
3403
+ var _ref56, _ref57;
3437
3404
  var _object_metadata28, _object_customer_details15;
3438
3405
  const order = paidOrder;
3439
3406
  // Discounts engine redemptions (AGL-305), for this branch's BOTH
@@ -3449,12 +3416,12 @@ async function findOrderForDispute(paymentIntentId) {
3449
3416
  // the hold existed, which Stripe's at-least-once delivery would run
3450
3417
  // twice. The transition is what makes it once.
3451
3418
  if ((_object_metadata28 = object.metadata) == null ? void 0 : _object_metadata28.discountId) {
3452
- var _ref62;
3419
+ var _ref58;
3453
3420
  var _object_metadata29;
3454
3421
  await settleRedemption({
3455
3422
  firestore,
3456
3423
  ref: hostRef.collection('discounts').doc(String(object.metadata.discountId)),
3457
- holdKey: String((_ref62 = (_object_metadata29 = object.metadata) == null ? void 0 : _object_metadata29.discountHoldKey) != null ? _ref62 : ''),
3424
+ holdKey: String((_ref58 = (_object_metadata29 = object.metadata) == null ? void 0 : _object_metadata29.discountHoldKey) != null ? _ref58 : ''),
3458
3425
  orderRef,
3459
3426
  label: `discount ${object.metadata.discountId}`,
3460
3427
  detail: `Discount ${object.metadata.discountId} was applied to this ` + 'order but no longer exists, so the redemption is uncounted ' + 'against its limit.'
@@ -3477,15 +3444,15 @@ async function findOrderForDispute(paymentIntentId) {
3477
3444
  // figure the draft was priced at, and the two agree by construction,
3478
3445
  // but only one of them is the money that moved. Stored totals remain
3479
3446
  // the fallback for a session shape that reports no total.
3480
- const draftEmail = (_ref60 = (_ref61 = object == null ? void 0 : (_object_customer_details15 = object.customer_details) == null ? void 0 : _object_customer_details15.email) != null ? _ref61 : order.customerEmail) != null ? _ref60 : null;
3447
+ const draftEmail = (_ref56 = (_ref57 = object == null ? void 0 : (_object_customer_details15 = object.customer_details) == null ? void 0 : _object_customer_details15.email) != null ? _ref57 : order.customerEmail) != null ? _ref56 : null;
3481
3448
  if (draftEmail) {
3482
- var _ref63, _ref64, _ref65;
3449
+ var _ref59, _ref60, _ref61;
3483
3450
  var _order_totals, _object_customer_details16;
3484
- const chargedCents = Number((_ref63 = object == null ? void 0 : object.amount_total) != null ? _ref63 : 0) || Number((_ref64 = (_order_totals = order.totals) == null ? void 0 : _order_totals.totalCents) != null ? _ref64 : 0);
3451
+ const chargedCents = Number((_ref59 = object == null ? void 0 : object.amount_total) != null ? _ref59 : 0) || Number((_ref60 = (_order_totals = order.totals) == null ? void 0 : _order_totals.totalCents) != null ? _ref60 : 0);
3485
3452
  await captureHostContact(_extends({
3486
3453
  hostId: String(hostId),
3487
3454
  email: draftEmail,
3488
- name: (_ref65 = object == null ? void 0 : (_object_customer_details16 = object.customer_details) == null ? void 0 : _object_customer_details16.name) != null ? _ref65 : undefined,
3455
+ name: (_ref61 = object == null ? void 0 : (_object_customer_details16 = object.customer_details) == null ? void 0 : _object_customer_details16.name) != null ? _ref61 : undefined,
3489
3456
  source: 'order',
3490
3457
  initialLifecycleStage: 'customer'
3491
3458
  }, chargedCents > 0 ? {
@@ -3498,15 +3465,15 @@ async function findOrderForDispute(paymentIntentId) {
3498
3465
  }));
3499
3466
  }
3500
3467
  if (productId) {
3501
- var _productSnapshot_data, _ref66, _ref67;
3468
+ var _productSnapshot_data, _ref62, _ref63;
3502
3469
  var _object_metadata30, _lifted_variants_, _order_lineItems_, _order_lineItems;
3503
3470
  const productRef = hostRef.collection('products').doc(String(productId));
3504
3471
  const productSnapshot = await productRef.get();
3505
3472
  const lifted = CommerceModel.liftLegacyProduct((_productSnapshot_data = productSnapshot.data()) != null ? _productSnapshot_data : {
3506
3473
  name: 'Product'
3507
3474
  });
3508
- const soldVariantId = String((_ref66 = (_object_metadata30 = object.metadata) == null ? void 0 : _object_metadata30.variantId) != null ? _ref66 : '') || ((_lifted_variants_ = lifted.variants[0]) == null ? void 0 : _lifted_variants_.id);
3509
- const quantity = (_ref67 = (_order_lineItems = order.lineItems) == null ? void 0 : (_order_lineItems_ = _order_lineItems[0]) == null ? void 0 : _order_lineItems_.quantity) != null ? _ref67 : 1;
3475
+ const soldVariantId = String((_ref62 = (_object_metadata30 = object.metadata) == null ? void 0 : _object_metadata30.variantId) != null ? _ref62 : '') || ((_lifted_variants_ = lifted.variants[0]) == null ? void 0 : _lifted_variants_.id);
3476
+ const quantity = (_ref63 = (_order_lineItems = order.lineItems) == null ? void 0 : (_order_lineItems_ = _order_lineItems[0]) == null ? void 0 : _order_lineItems_.quantity) != null ? _ref63 : 1;
3510
3477
  if (soldVariantId) {
3511
3478
  // Atomic since AGL-2320.
3512
3479
  const moved = await decrementVariantStock({
@@ -3558,10 +3525,10 @@ async function findOrderForDispute(paymentIntentId) {
3558
3525
  // would decrement it twice.
3559
3526
  const paidProducts = new Map();
3560
3527
  for (const line of (_order_lineItems1 = order.lineItems) != null ? _order_lineItems1 : []){
3561
- var _ref68, _ref69, _line_variantId1;
3528
+ var _ref64, _ref65, _line_variantId1;
3562
3529
  var _lineProduct_variants_;
3563
- const lineProductId = String((_ref68 = line == null ? void 0 : line.productId) != null ? _ref68 : '');
3564
- const soldQty = Math.round(Number((_ref69 = line == null ? void 0 : line.quantity) != null ? _ref69 : 0));
3530
+ const lineProductId = String((_ref64 = line == null ? void 0 : line.productId) != null ? _ref64 : '');
3531
+ const soldQty = Math.round(Number((_ref65 = line == null ? void 0 : line.quantity) != null ? _ref65 : 0));
3565
3532
  if (!lineProductId || !(soldQty > 0)) continue;
3566
3533
  // Firestore reserves `__…__` ids and `.doc()` throws
3567
3534
  // synchronously on one; a corrupt line must not fail the
@@ -3624,7 +3591,7 @@ async function findOrderForDispute(paymentIntentId) {
3624
3591
  var _object_metadata31;
3625
3592
  const { hostId, productId, feeCents, couponCode } = (_object_metadata31 = object.metadata) != null ? _object_metadata31 : {};
3626
3593
  if (hostId && productId) {
3627
- var _ref70, _productForSnapshot_get1, _productForSnapshot_data1, _ref71, _ref72, _ref73, _ref74, _ref75, _ref76, _ref77;
3594
+ var _ref66, _productForSnapshot_get1, _productForSnapshot_data1, _ref67, _ref68, _ref69, _ref70, _ref71, _ref72, _ref73;
3628
3595
  var _object_metadata32, _buyNowLineItems_, _object_customer_details17, _object_customer_details18, _object_customer_details19, _object_metadata33;
3629
3596
  const firestore = firebaseAdmin.app().firestore();
3630
3597
  const hostRef = firestore.collection('hosts').doc(String(hostId));
@@ -3635,7 +3602,7 @@ async function findOrderForDispute(paymentIntentId) {
3635
3602
  // is bounded to Stripe's at-least-once edge).
3636
3603
  const orderRef = hostRef.collection('orders').doc(String(object.id));
3637
3604
  const counterRef = hostRef.collection('counters').doc('orders');
3638
- const amountCents = Number((_ref70 = object == null ? void 0 : object.amount_total) != null ? _ref70 : 0);
3605
+ const amountCents = Number((_ref66 = object == null ? void 0 : object.amount_total) != null ? _ref66 : 0);
3639
3606
  const productForSnapshot = await hostRef.collection('products').doc(String(productId)).get();
3640
3607
  const snapshotName = String((_productForSnapshot_get1 = productForSnapshot.get('name')) != null ? _productForSnapshot_get1 : 'Product');
3641
3608
  // AGL-1711: the line item and totals used to be fabricated from
@@ -3648,7 +3615,7 @@ async function findOrderForDispute(paymentIntentId) {
3648
3615
  name: snapshotName
3649
3616
  });
3650
3617
  const soldVariant = ((_object_metadata32 = object.metadata) == null ? void 0 : _object_metadata32.variantId) ? liftedForSnapshot.variants.find((item)=>item.id === String(object.metadata.variantId)) : liftedForSnapshot.variants[0];
3651
- const variantOptions = Object.values((_ref71 = soldVariant == null ? void 0 : soldVariant.options) != null ? _ref71 : {});
3618
+ const variantOptions = Object.values((_ref67 = soldVariant == null ? void 0 : soldVariant.options) != null ? _ref67 : {});
3652
3619
  const { lineItems: buyNowLineItems, totals: buyNowTotals } = CommerceModel.computeBuyNowOrder(object, _extends({
3653
3620
  name: snapshotName
3654
3621
  }, variantOptions.length ? {
@@ -3660,7 +3627,7 @@ async function findOrderForDispute(paymentIntentId) {
3660
3627
  } : {}, liftedForSnapshot.supplierId ? {
3661
3628
  supplierId: liftedForSnapshot.supplierId
3662
3629
  } : {}));
3663
- const soldQuantity = (_ref72 = (_buyNowLineItems_ = buyNowLineItems[0]) == null ? void 0 : _buyNowLineItems_.quantity) != null ? _ref72 : 1;
3630
+ const soldQuantity = (_ref68 = (_buyNowLineItems_ = buyNowLineItems[0]) == null ? void 0 : _buyNowLineItems_.quantity) != null ? _ref68 : 1;
3664
3631
  const created = await firestore.runTransaction(async (transaction)=>{
3665
3632
  var _counter_get, _ref, _ref1, _ref2, _ref3;
3666
3633
  var _object_metadata, _object_customer_details, _object_customer_details1;
@@ -3720,7 +3687,7 @@ async function findOrderForDispute(paymentIntentId) {
3720
3687
  // in the bell, not just the owner's email.
3721
3688
  void notifyHostManagers(String(hostId), _extends({
3722
3689
  type: 'content.order',
3723
- title: `New order — $${(Number((_ref73 = object == null ? void 0 : object.amount_total) != null ? _ref73 : 0) / 100).toFixed(2)}`
3690
+ title: `New order — $${(Number((_ref69 = object == null ? void 0 : object.amount_total) != null ? _ref69 : 0) / 100).toFixed(2)}`
3724
3691
  }, (object == null ? void 0 : (_object_customer_details17 = object.customer_details) == null ? void 0 : _object_customer_details17.email) ? {
3725
3692
  body: `From ${object.customer_details.email}`
3726
3693
  } : {}, {
@@ -3829,13 +3796,13 @@ async function findOrderForDispute(paymentIntentId) {
3829
3796
  await captureHostContact({
3830
3797
  hostId: String(hostId),
3831
3798
  email: object == null ? void 0 : (_object_customer_details18 = object.customer_details) == null ? void 0 : _object_customer_details18.email,
3832
- name: (_ref74 = object == null ? void 0 : (_object_customer_details19 = object.customer_details) == null ? void 0 : _object_customer_details19.name) != null ? _ref74 : undefined,
3799
+ name: (_ref70 = object == null ? void 0 : (_object_customer_details19 = object.customer_details) == null ? void 0 : _object_customer_details19.name) != null ? _ref70 : undefined,
3833
3800
  source: 'order',
3834
3801
  initialLifecycleStage: 'customer',
3835
- purchaseCents: Number((_ref75 = object == null ? void 0 : object.amount_total) != null ? _ref75 : 0),
3802
+ purchaseCents: Number((_ref71 = object == null ? void 0 : object.amount_total) != null ? _ref71 : 0),
3836
3803
  interaction: {
3837
3804
  refId: String(object.id),
3838
- summary: `Placed an order ($${(Number((_ref76 = object == null ? void 0 : object.amount_total) != null ? _ref76 : 0) / 100).toFixed(2)})`
3805
+ summary: `Placed an order ($${(Number((_ref72 = object == null ? void 0 : object.amount_total) != null ? _ref72 : 0) / 100).toFixed(2)})`
3839
3806
  }
3840
3807
  });
3841
3808
  const productRef = hostRef.collection('products').doc(String(productId));
@@ -3853,12 +3820,12 @@ async function findOrderForDispute(paymentIntentId) {
3853
3820
  // serialize; the snapshot above is still read, for the product NAME on
3854
3821
  // the receipt below, and no longer decides any count.
3855
3822
  {
3856
- var _productSnapshot_data2, _ref78;
3823
+ var _productSnapshot_data2, _ref74;
3857
3824
  var _object_metadata34, _lifted_variants_1;
3858
3825
  const lifted = CommerceModel.liftLegacyProduct((_productSnapshot_data2 = productSnapshot.data()) != null ? _productSnapshot_data2 : {
3859
3826
  name: 'Product'
3860
3827
  });
3861
- const soldVariantId = String((_ref78 = (_object_metadata34 = object.metadata) == null ? void 0 : _object_metadata34.variantId) != null ? _ref78 : '') || ((_lifted_variants_1 = lifted.variants[0]) == null ? void 0 : _lifted_variants_1.id);
3828
+ const soldVariantId = String((_ref74 = (_object_metadata34 = object.metadata) == null ? void 0 : _object_metadata34.variantId) != null ? _ref74 : '') || ((_lifted_variants_1 = lifted.variants[0]) == null ? void 0 : _lifted_variants_1.id);
3862
3829
  if (soldVariantId) {
3863
3830
  // AGL-1711: `-1` regardless of how many units were bought, so a
3864
3831
  // 3-unit buy-now sale decremented stock by one and the difference
@@ -3889,14 +3856,14 @@ async function findOrderForDispute(paymentIntentId) {
3889
3856
  // Settlement, the same way round and for the same reason as the cart
3890
3857
  // branch above (AGL-2356): the decrement lands first, then the
3891
3858
  // reservation is dropped.
3892
- await releaseStockHold(hostRef, String((_ref77 = (_object_metadata33 = object.metadata) == null ? void 0 : _object_metadata33.stockHoldKey) != null ? _ref77 : ''));
3859
+ await releaseStockHold(hostRef, String((_ref73 = (_object_metadata33 = object.metadata) == null ? void 0 : _object_metadata33.stockHoldKey) != null ? _ref73 : ''));
3893
3860
  if (couponCode) {
3894
- var _ref79;
3861
+ var _ref75;
3895
3862
  var _object_metadata35;
3896
3863
  await settleRedemption({
3897
3864
  firestore,
3898
3865
  ref: hostRef.collection('coupons').doc(String(couponCode)),
3899
- holdKey: String((_ref79 = (_object_metadata35 = object.metadata) == null ? void 0 : _object_metadata35.couponHoldKey) != null ? _ref79 : ''),
3866
+ holdKey: String((_ref75 = (_object_metadata35 = object.metadata) == null ? void 0 : _object_metadata35.couponHoldKey) != null ? _ref75 : ''),
3900
3867
  orderRef,
3901
3868
  label: `coupon ${couponCode}`,
3902
3869
  detail: `Coupon ${couponCode} was applied to this order but no longer ` + 'exists, so the redemption is uncounted against its limit.'
@@ -3905,14 +3872,14 @@ async function findOrderForDispute(paymentIntentId) {
3905
3872
  // Receipt + seller notification (AGL-96): env-gated like every
3906
3873
  // other outbound email; failures never fail the webhook.
3907
3874
  if (isEmailConfigured()) {
3908
- var _productSnapshot_get, _ref80;
3875
+ var _productSnapshot_get, _ref76;
3909
3876
  var _object_customer_details20, _org, _this3;
3910
3877
  const productName = String((_productSnapshot_get = productSnapshot.get('name')) != null ? _productSnapshot_get : 'your purchase');
3911
- const amount = (Number((_ref80 = object == null ? void 0 : object.amount_total) != null ? _ref80 : 0) / 100).toFixed(2);
3878
+ const amount = (Number((_ref76 = object == null ? void 0 : object.amount_total) != null ? _ref76 : 0) / 100).toFixed(2);
3912
3879
  const buyerEmail = object == null ? void 0 : (_object_customer_details20 = object.customer_details) == null ? void 0 : _object_customer_details20.email;
3913
3880
  const orderTotal = `$${amount}`;
3914
3881
  if (buyerEmail) {
3915
- var _ref81;
3882
+ var _ref77;
3916
3883
  const fallbackText = `Thanks for your purchase!\n\n${productName} — $${amount}` + `\nOrder reference: ${object.id}`;
3917
3884
  // Site-owner-designed template when published (AGL-771).
3918
3885
  const designed = await renderHostEmailWithTokens(firebaseAdmin.app().firestore(), String(hostId), 'order-receipt', {
@@ -3922,7 +3889,7 @@ async function findOrderForDispute(paymentIntentId) {
3922
3889
  });
3923
3890
  await sendEmail(_extends({
3924
3891
  to: String(buyerEmail),
3925
- subject: (_ref81 = designed == null ? void 0 : designed.subject) != null ? _ref81 : `Receipt: ${productName}`,
3892
+ subject: (_ref77 = designed == null ? void 0 : designed.subject) != null ? _ref77 : `Receipt: ${productName}`,
3926
3893
  text: (designed == null ? void 0 : designed.text) || fallbackText
3927
3894
  }, (designed == null ? void 0 : designed.html) ? {
3928
3895
  html: designed.html
@@ -3956,7 +3923,7 @@ async function findOrderForDispute(paymentIntentId) {
3956
3923
  // SSO.
3957
3924
  const seller = (_this4 = await findUserByUidAcrossPools(sellerUid).catch(()=>null)) == null ? void 0 : _this4.record;
3958
3925
  if (seller == null ? void 0 : seller.email) {
3959
- var _hostSnapshot_get, _ref82;
3926
+ var _hostSnapshot_get, _ref78;
3960
3927
  const siteName = String((_hostSnapshot_get = hostSnapshot.get('displayName')) != null ? _hostSnapshot_get : hostId);
3961
3928
  const fallbackText = `You made a sale on ${siteName}!\n\n${productName} — $${amount}` + (buyerEmail ? `\nBuyer: ${buyerEmail}` : '') + `\nOrder reference: ${object.id}`;
3962
3929
  // Site-owner-designed template when published (AGL-771).
@@ -3969,7 +3936,7 @@ async function findOrderForDispute(paymentIntentId) {
3969
3936
  });
3970
3937
  await sendEmail(_extends({
3971
3938
  to: seller.email,
3972
- subject: (_ref82 = designed == null ? void 0 : designed.subject) != null ? _ref82 : `New order: ${productName}`,
3939
+ subject: (_ref78 = designed == null ? void 0 : designed.subject) != null ? _ref78 : `New order: ${productName}`,
3973
3940
  text: (designed == null ? void 0 : designed.text) || fallbackText
3974
3941
  }, (designed == null ? void 0 : designed.html) ? {
3975
3942
  html: designed.html
@@ -3999,15 +3966,15 @@ async function findOrderForDispute(paymentIntentId) {
3999
3966
  // the refund is written on the order's timeline. Nothing else is moved: a
4000
3967
  // Dashboard refund is staff's act, and they chose its transfer reversal.
4001
3968
  if (type === 'charge.refunded') {
4002
- var _ref83, _ref84;
3969
+ var _ref79, _ref80;
4003
3970
  var _object_payment_intent, _snapshot_ref_parent_parent;
4004
- const paymentIntentId = typeof (object == null ? void 0 : object.payment_intent) === 'string' ? object.payment_intent : String((_ref83 = object == null ? void 0 : (_object_payment_intent = object.payment_intent) == null ? void 0 : _object_payment_intent.id) != null ? _ref83 : '');
3971
+ const paymentIntentId = typeof (object == null ? void 0 : object.payment_intent) === 'string' ? object.payment_intent : String((_ref79 = object == null ? void 0 : (_object_payment_intent = object.payment_intent) == null ? void 0 : _object_payment_intent.id) != null ? _ref79 : '');
4005
3972
  const lookup = paymentIntentId ? await findOrderForDispute(paymentIntentId) : {
4006
3973
  kind: 'not-ours'
4007
3974
  };
4008
3975
  if (lookup.kind !== 'order') return;
4009
3976
  const snapshot = lookup.snapshot;
4010
- const hostId = String((_ref84 = (_snapshot_ref_parent_parent = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent.id) != null ? _ref84 : '');
3977
+ const hostId = String((_ref80 = (_snapshot_ref_parent_parent = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent.id) != null ? _ref80 : '');
4011
3978
  const external = await recordExternalRefund(snapshot.ref, object);
4012
3979
  if (external && hostId && snapshot.ref.parent.parent) {
4013
3980
  const outcome = await applyExternalRefundToGiftCards({
@@ -4045,14 +4012,14 @@ async function findOrderForDispute(paymentIntentId) {
4045
4012
  // merchant; both report the site so the seller's fraud ledger can name it.
4046
4013
  const risk = paymentRiskEventFrom(type, object);
4047
4014
  if (risk && risk.signal.kind !== 'dispute') {
4048
- var _ref85, _snapshot_data;
4015
+ var _ref81, _snapshot_data;
4049
4016
  var _snapshot_ref_parent_parent1;
4050
4017
  const lookup = risk.paymentIntentId ? await findOrderForDispute(risk.paymentIntentId) : {
4051
4018
  kind: 'not-ours'
4052
4019
  };
4053
4020
  if (lookup.kind !== 'order') return;
4054
4021
  const snapshot = lookup.snapshot;
4055
- const hostId = String((_ref85 = (_snapshot_ref_parent_parent1 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent1.id) != null ? _ref85 : '');
4022
+ const hostId = String((_ref81 = (_snapshot_ref_parent_parent1 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent1.id) != null ? _ref81 : '');
4056
4023
  const order = CommerceModel.liftLegacyOrder((_snapshot_data = snapshot.data()) != null ? _snapshot_data : {});
4057
4024
  await recordPaymentRiskOnRecord({
4058
4025
  ref: snapshot.ref,
@@ -4114,7 +4081,7 @@ async function findOrderForDispute(paymentIntentId) {
4114
4081
  // finds). AGL-1554 will add its own `closed` branch for the marketplace
4115
4082
  // side; the two coexist because each self-selects by finding its own record.
4116
4083
  if (type === 'charge.dispute.created' || type === 'charge.dispute.closed') {
4117
- var _dispute_payment_intent, _ref86;
4084
+ var _dispute_payment_intent, _ref82;
4118
4085
  var _snapshot_ref_parent_parent2;
4119
4086
  const dispute = object != null ? object : {};
4120
4087
  const paymentIntentId = String((_dispute_payment_intent = dispute.payment_intent) != null ? _dispute_payment_intent : '');
@@ -4140,9 +4107,9 @@ async function findOrderForDispute(paymentIntentId) {
4140
4107
  const claimed = lookup.kind === 'order' || lookup.kind === 'unresolved';
4141
4108
  const snapshot = lookup.kind === 'order' ? lookup.snapshot : null;
4142
4109
  if (snapshot) {
4143
- var _ref87;
4110
+ var _ref83;
4144
4111
  var _snapshot_ref_parent_parent3;
4145
- const hostId = String((_ref87 = (_snapshot_ref_parent_parent3 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent3.id) != null ? _ref87 : '');
4112
+ const hostId = String((_ref83 = (_snapshot_ref_parent_parent3 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent3.id) != null ? _ref83 : '');
4146
4113
  if (type === 'charge.dispute.created') {
4147
4114
  // A chargeback's gift cards are frozen while it is open (AGL-3363).
4148
4115
  await notifyGiftCardHold({
@@ -4158,7 +4125,7 @@ async function findOrderForDispute(paymentIntentId) {
4158
4125
  }, notifyRiskEvent);
4159
4126
  const { opened, record } = await recordDisputeOpened(snapshot, dispute);
4160
4127
  if (opened && hostId) {
4161
- var _snapshot_data1, _record_evidenceDueByMs, _ref88;
4128
+ var _snapshot_data1, _record_evidenceDueByMs, _ref84;
4162
4129
  // Time-critical — Stripe's evidence window is days, not weeks — so
4163
4130
  // this is awaited rather than fired off with `void`: the handler is
4164
4131
  // serverless and work left running past the response is work the
@@ -4177,16 +4144,16 @@ async function findOrderForDispute(paymentIntentId) {
4177
4144
  },
4178
4145
  amount: `$${(record.amountCents / 100).toFixed(2)}`,
4179
4146
  evidenceDueByMs: (_record_evidenceDueByMs = record.evidenceDueByMs) != null ? _record_evidenceDueByMs : null,
4180
- dedupeKey: `sale:${String((_ref88 = dispute == null ? void 0 : dispute.id) != null ? _ref88 : snapshot.id)}`,
4147
+ dedupeKey: `sale:${String((_ref84 = dispute == null ? void 0 : dispute.id) != null ? _ref84 : snapshot.id)}`,
4181
4148
  staffEvidence: record.reason ? `Reason: ${record.reason.replace(/_/g, ' ')}.` : null
4182
4149
  });
4183
4150
  }
4184
4151
  } else {
4185
- var _ref89, _ref90;
4152
+ var _ref85, _ref86;
4186
4153
  // Lost: the money went back, so the cards it bought are voided. Won
4187
4154
  // (or closed on a warning): the dispute's freeze lifts; a freeze a
4188
4155
  // fraud warning or review put on stays for the merchant (AGL-3363).
4189
- await applyOrderGiftCardRisk(snapshot, String((_ref89 = dispute == null ? void 0 : dispute.status) != null ? _ref89 : '') === 'lost' ? {
4156
+ await applyOrderGiftCardRisk(snapshot, String((_ref85 = dispute == null ? void 0 : dispute.status) != null ? _ref85 : '') === 'lost' ? {
4190
4157
  kind: 'void',
4191
4158
  reason: 'dispute-lost'
4192
4159
  } : {
@@ -4250,7 +4217,7 @@ async function findOrderForDispute(paymentIntentId) {
4250
4217
  // transiently-failed reversal gets its retry — and gated inside on
4251
4218
  // the order's own `reversedTransferCents` marker, so it runs at most
4252
4219
  // once per dispute however many times Stripe delivers.
4253
- if (String((_ref90 = dispute == null ? void 0 : dispute.status) != null ? _ref90 : '') === 'lost') {
4220
+ if (String((_ref86 = dispute == null ? void 0 : dispute.status) != null ? _ref86 : '') === 'lost') {
4254
4221
  const pulledBackCents = await reverseSellerShare(snapshot.ref, dispute);
4255
4222
  // The merchant-experience half of the AGL-1794 decision, and not an
4256
4223
  // optional extra: the reversal takes money out of the connected
@@ -4280,7 +4247,7 @@ async function findOrderForDispute(paymentIntentId) {
4280
4247
  return _extends({
4281
4248
  claimed
4282
4249
  }, snapshot ? {
4283
- hostId: String((_ref86 = (_snapshot_ref_parent_parent2 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent2.id) != null ? _ref86 : '')
4250
+ hostId: String((_ref82 = (_snapshot_ref_parent_parent2 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent2.id) != null ? _ref82 : '')
4284
4251
  } : {});
4285
4252
  }
4286
4253
  };