@aglyn/plugins-commerce 1.0.0-beta.232 → 1.0.0-beta.233
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/package.json +13 -13
- package/src/lib/components/cart-extras.d.ts +6 -0
- package/src/lib/components/cart-extras.js +4 -1
- package/src/lib/components/cart-extras.js.map +1 -1
- package/src/lib/components/cart-fulfillment.d.ts +117 -0
- package/src/lib/components/cart-fulfillment.js +367 -0
- package/src/lib/components/cart-fulfillment.js.map +1 -0
- package/src/lib/components/cart.js +52 -10
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +42 -1
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +38 -10
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.js +177 -3
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +10 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
- package/src/lib/components/console/order-offline-notice.component.js +53 -0
- package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +24 -1
- package/src/lib/components/console/pos/pos-api.js +13 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
- package/src/lib/components/console/pos/use-pos-display.js +3 -2
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-devices-card.component.js +2 -2
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
- package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
- package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
- package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
- package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
- package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
- package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.js +174 -27
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +35 -10
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/stock-movements-card.component.js +48 -16
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +8 -1
- package/src/lib/components/console/store-zones.js +11 -1
- package/src/lib/components/console/store-zones.js.map +1 -1
- package/src/lib/components/order-status.js +66 -0
- package/src/lib/components/order-status.js.map +1 -1
- package/src/lib/components/product-detail.js +42 -15
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
- package/src/lib/constants/local-fulfillment-list-query.js +84 -0
- package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
- package/src/lib/constants/orders-list-query.d.ts +7 -2
- package/src/lib/constants/orders-list-query.js +89 -8
- package/src/lib/constants/orders-list-query.js.map +1 -1
- package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
- package/src/lib/constants/pos-shift-list-query.js +115 -0
- package/src/lib/constants/pos-shift-list-query.js.map +1 -0
- package/src/lib/constants/product-list-query.d.ts +6 -1
- package/src/lib/constants/product-list-query.js +77 -8
- package/src/lib/constants/product-list-query.js.map +1 -1
- package/src/lib/constants/stock-movement-query.d.ts +3 -2
- package/src/lib/constants/stock-movement-query.js +52 -8
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +5 -3
- package/src/lib/model/buyer-notifications.js +25 -4
- package/src/lib/model/buyer-notifications.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +59 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
- package/src/lib/model/commerce-pos-kiosk.js +147 -0
- package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
- package/src/lib/model/commerce-pos-offline.d.ts +234 -0
- package/src/lib/model/commerce-pos-offline.js +301 -0
- package/src/lib/model/commerce-pos-offline.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +16 -6
- package/src/lib/model/commerce-pos-ops.js +12 -4
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +13 -1
- package/src/lib/model/commerce-pos.js +5 -4
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-stock-holds.d.ts +24 -3
- package/src/lib/model/commerce-stock-holds.js +26 -8
- package/src/lib/model/commerce-stock-holds.js.map +1 -1
- package/src/lib/model/commerce.d.ts +3 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +4 -0
- package/src/lib/model/index.js +4 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
- package/src/lib/model/local-fulfillment-settings.js +361 -0
- package/src/lib/model/local-fulfillment-settings.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +10 -1
- package/src/lib/model/order-list-fields.js +1 -0
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-local-fulfillment.d.ts +131 -0
- package/src/lib/model/order-local-fulfillment.js +125 -0
- package/src/lib/model/order-local-fulfillment.js.map +1 -0
- package/src/lib/model/order-shipping-export.js +4 -0
- package/src/lib/model/order-shipping-export.js.map +1 -1
- package/src/lib/model/order-status-view.d.ts +20 -1
- package/src/lib/model/order-status-view.js +60 -6
- package/src/lib/model/order-status-view.js.map +1 -1
- package/src/lib/plugin-config.js +6 -2
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +8 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-kiosk-config.d.ts +26 -0
- package/src/lib/pos-kiosk-config.js +59 -0
- package/src/lib/pos-kiosk-config.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +8 -0
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +19 -0
- package/src/lib/server/api-v1/order-view.js +35 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -1
- package/src/lib/server/billing-webhook.js +238 -87
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +173 -13
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/checkout-extras.js +18 -4
- package/src/lib/server/checkout-extras.js.map +1 -1
- package/src/lib/server/checkout.js +71 -14
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.d.ts +86 -0
- package/src/lib/server/local-fulfillment-status.js +379 -0
- package/src/lib/server/local-fulfillment-status.js.map +1 -0
- package/src/lib/server/local-fulfillment.d.ts +190 -0
- package/src/lib/server/local-fulfillment.js +580 -0
- package/src/lib/server/local-fulfillment.js.map +1 -0
- package/src/lib/server/membership-register.js +3 -1
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/order-notifications.js +61 -0
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +27 -1
- package/src/lib/server/pos-display.js +50 -9
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
- package/src/lib/server/pos-kiosk-principal.js +42 -0
- package/src/lib/server/pos-kiosk-principal.js.map +1 -0
- package/src/lib/server/pos-kiosk.d.ts +54 -0
- package/src/lib/server/pos-kiosk.js +972 -0
- package/src/lib/server/pos-kiosk.js.map +1 -0
- package/src/lib/server/pos-offline-sync.d.ts +85 -0
- package/src/lib/server/pos-offline-sync.js +765 -0
- package/src/lib/server/pos-offline-sync.js.map +1 -0
- package/src/lib/server/pos-order.js +22 -4
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +6 -0
- package/src/lib/server/pos-payment.js +225 -6
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-print.js +5 -0
- package/src/lib/server/pos-print.js.map +1 -1
- package/src/lib/server/pos-return.js +27 -0
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.d.ts +6 -0
- package/src/lib/server/pos-sale.js +2 -0
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +8 -1
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/refund.js +3 -0
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/stock-hold.d.ts +9 -1
- package/src/lib/server/stock-hold.js +15 -7
- package/src/lib/server/stock-hold.js.map +1 -1
- package/src/lib/server.js +16 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.js +161 -0
- package/src/lib/tenant-emails.js.map +1 -1
|
@@ -36,6 +36,7 @@ import { alertLowStockCrossing } from "./low-stock.js";
|
|
|
36
36
|
import { decrementVariantStock } from "./reserve-stock.js";
|
|
37
37
|
import { giftCardSearchTokens } from "../model/gift-card-search.js";
|
|
38
38
|
import { releaseStockHold } from "./stock-hold.js";
|
|
39
|
+
import { orderLocalFulfillmentFromSession } from "./local-fulfillment.js";
|
|
39
40
|
import { releasePromotionHold, settlePromotionSlot } from "./promotion-hold.js";
|
|
40
41
|
import { flagOrderRestock } from "./restock-flag.js";
|
|
41
42
|
import { storefrontTaxModeOf } from "./storefront-tax.js";
|
|
@@ -45,6 +46,7 @@ import { enqueueSupplierDelivery } from "./supplier-outbox.js";
|
|
|
45
46
|
import { notifyOrderBuyer, onlineReceiptExtras } from "./order-notifications.js";
|
|
46
47
|
import { ORDER_PAID_EVENT, ORDER_REFUNDED_EVENT } from "../model/order-events.js";
|
|
47
48
|
import { checkoutExtrasCents, decodeCheckoutExtrasMetadata } from "@aglyn/aglyn/plugin-manager/plugin-checkout-extras";
|
|
49
|
+
import { checkoutCreditProvider, checkoutCreditSold, decodeCheckoutCreditMetadata } from "@aglyn/aglyn/plugin-manager/plugin-checkout-credits";
|
|
48
50
|
import { raiseOrderEvent } from "./order-events.js";
|
|
49
51
|
import { handlePosStripeEvent } from "./pos-terminal.js";
|
|
50
52
|
import { notifyPosSaleCompleted } from "./pos-sale.js";
|
|
@@ -1795,6 +1797,19 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
1795
1797
|
console.error('Gift card hold release failed', giftCardCode, error);
|
|
1796
1798
|
});
|
|
1797
1799
|
}
|
|
1800
|
+
// Store credit another plugin held for the checkout (AGL-3640) goes back
|
|
1801
|
+
// the same way: its provider lets the hold go.
|
|
1802
|
+
const expiredCredit = decodeCheckoutCreditMetadata(object == null ? void 0 : object.metadata);
|
|
1803
|
+
if (expiredCredit) {
|
|
1804
|
+
var _checkoutCreditProvider;
|
|
1805
|
+
await ((_checkoutCreditProvider = checkoutCreditProvider(expiredCredit.providerId)) == null ? void 0 : _checkoutCreditProvider.provider.release({
|
|
1806
|
+
hostId: expiredHostId,
|
|
1807
|
+
reference: expiredCredit.reference,
|
|
1808
|
+
holdKey: expiredCredit.holdKey
|
|
1809
|
+
}).catch((error)=>{
|
|
1810
|
+
console.error('Checkout credit hold release failed', expiredCredit.providerId, error);
|
|
1811
|
+
}));
|
|
1812
|
+
}
|
|
1798
1813
|
return;
|
|
1799
1814
|
}
|
|
1800
1815
|
// White-label brand per host (White-Label Phase 3): every storefront email
|
|
@@ -2814,8 +2829,8 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2814
2829
|
var _object_metadata19;
|
|
2815
2830
|
const { hostId, cartId, feeCents, couponCode } = (_object_metadata19 = object.metadata) != null ? _object_metadata19 : {};
|
|
2816
2831
|
if (hostId && cartId) {
|
|
2817
|
-
var _cartSnapshot_data, _ref40, _ref41, _ref42, _ref43, _ref44, _ref45;
|
|
2818
|
-
var _object_customer_details7, _object_metadata20, _object_customer_details8, _object_customer_details9, _object_customer_details10, _object_metadata21, _this2, _object_metadata22;
|
|
2832
|
+
var _cartSnapshot_data, _ref40, _object_shipping_details_address_postal_code, _object_shipping_details_address_country, _ref41, _ref42, _ref43, _ref44, _ref45;
|
|
2833
|
+
var _object_shipping_details, _object_customer_details7, _object_metadata20, _object_customer_details8, _object_customer_details9, _object_customer_details10, _object_metadata21, _this2, _object_metadata22;
|
|
2819
2834
|
const firestore = firebaseAdmin.app().firestore();
|
|
2820
2835
|
const hostRef = firestore.collection('hosts').doc(String(hostId));
|
|
2821
2836
|
const cartRef = hostRef.collection('carts').doc(String(cartId));
|
|
@@ -2888,14 +2903,68 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2888
2903
|
// The optional lines the buyer took (AGL-3635), read back off the
|
|
2889
2904
|
// session they were charged on; never re-quoted here.
|
|
2890
2905
|
const cartExtras = decodeCheckoutExtrasMetadata(object == null ? void 0 : object.metadata);
|
|
2906
|
+
// Store credit another plugin held for this checkout (AGL-3640): taken
|
|
2907
|
+
// in THIS transaction, so the redemption and the order are written
|
|
2908
|
+
// together or not at all. What Stripe discounted is the hold; what the
|
|
2909
|
+
// provider gives now is what the order records.
|
|
2910
|
+
const heldCredit = decodeCheckoutCreditMetadata(object == null ? void 0 : object.metadata);
|
|
2911
|
+
const creditEntry = heldCredit ? checkoutCreditProvider(heldCredit.providerId) : null;
|
|
2912
|
+
let creditShortCents = 0;
|
|
2913
|
+
// Picked up or brought by the store's own driver (AGL-3624): where
|
|
2914
|
+
// the buyer chose, read back off the session they paid. Never throws
|
|
2915
|
+
// past here — a failed read records the order as shipped rather than
|
|
2916
|
+
// losing it.
|
|
2917
|
+
const cartLocalFulfillment = await orderLocalFulfillmentFromSession({
|
|
2918
|
+
hostId: String(hostId),
|
|
2919
|
+
hostRef,
|
|
2920
|
+
metadata: object == null ? void 0 : object.metadata,
|
|
2921
|
+
shippingAddress: (object == null ? void 0 : (_object_shipping_details = object.shipping_details) == null ? void 0 : _object_shipping_details.address) ? {
|
|
2922
|
+
postalCode: (_object_shipping_details_address_postal_code = object.shipping_details.address.postal_code) != null ? _object_shipping_details_address_postal_code : null,
|
|
2923
|
+
country: (_object_shipping_details_address_country = object.shipping_details.address.country) != null ? _object_shipping_details_address_country : null
|
|
2924
|
+
} : null,
|
|
2925
|
+
createdAtMs: Date.now()
|
|
2926
|
+
}).catch((error)=>{
|
|
2927
|
+
console.error('commerce cart local fulfillment unreadable', String(object.id), error);
|
|
2928
|
+
return null;
|
|
2929
|
+
});
|
|
2891
2930
|
const created = await firestore.runTransaction(async (transaction)=>{
|
|
2892
|
-
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;
|
|
2931
|
+
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, _ref6;
|
|
2893
2932
|
var _object_metadata, _object_customer_details, _object_customer_details1;
|
|
2894
2933
|
const [existing, counter] = await Promise.all([
|
|
2895
2934
|
transaction.get(orderRef),
|
|
2896
2935
|
transaction.get(counterRef)
|
|
2897
2936
|
]);
|
|
2898
2937
|
if (existing.exists) return false;
|
|
2938
|
+
// The provider's reads, before this transaction writes anything.
|
|
2939
|
+
let creditStage = null;
|
|
2940
|
+
if (heldCredit && creditEntry) {
|
|
2941
|
+
creditStage = await creditEntry.provider.stage({
|
|
2942
|
+
transaction,
|
|
2943
|
+
hostId: String(hostId),
|
|
2944
|
+
reference: heldCredit.reference,
|
|
2945
|
+
orderId: orderRef.id,
|
|
2946
|
+
nowMs: Date.now(),
|
|
2947
|
+
holdKey: heldCredit.holdKey
|
|
2948
|
+
}).catch((error)=>{
|
|
2949
|
+
console.error('Checkout credit stage failed', heldCredit.providerId, error);
|
|
2950
|
+
return null;
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
const creditTaken = heldCredit && creditStage ? Math.max(0, Math.min(heldCredit.amountCents, creditStage.debit({
|
|
2954
|
+
cents: heldCredit.amountCents,
|
|
2955
|
+
key: heldCredit.holdKey,
|
|
2956
|
+
orderId: orderRef.id,
|
|
2957
|
+
channel: 'online'
|
|
2958
|
+
}))) : 0;
|
|
2959
|
+
creditShortCents = heldCredit ? heldCredit.amountCents - creditTaken : 0;
|
|
2960
|
+
const creditSold = heldCredit && creditTaken > 0 ? checkoutCreditSold({
|
|
2961
|
+
providerId: heldCredit.providerId,
|
|
2962
|
+
reference: heldCredit.reference,
|
|
2963
|
+
label: heldCredit.label,
|
|
2964
|
+
last4: heldCredit.last4,
|
|
2965
|
+
amountCents: creditTaken,
|
|
2966
|
+
appliedAs: 'discount'
|
|
2967
|
+
}) : null;
|
|
2899
2968
|
const number = Number((_counter_get = counter.get('next')) != null ? _counter_get : 1);
|
|
2900
2969
|
cartOrderNumber = number;
|
|
2901
2970
|
transaction.set(counterRef, {
|
|
@@ -2919,6 +2988,10 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2919
2988
|
totals
|
|
2920
2989
|
}, cartExtras.length ? {
|
|
2921
2990
|
extras: cartExtras
|
|
2991
|
+
} : {}, creditSold ? {
|
|
2992
|
+
credits: [
|
|
2993
|
+
creditSold
|
|
2994
|
+
]
|
|
2922
2995
|
} : {}, {
|
|
2923
2996
|
// WHICH TAX THIS SALE CARRIED (AGL-2451). `totals.taxCents` above
|
|
2924
2997
|
// says how much; this says who computed it, which is the fact that
|
|
@@ -2940,6 +3013,13 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2940
3013
|
event: 'line-unresolved',
|
|
2941
3014
|
detail: `${unresolvedLines.length} paid ${unresolvedLines.length === 1 ? 'line' : 'lines'} could not be recorded because the product was ` + 'deleted during checkout, so this order is short of ' + 'what the shopper was charged. Refund the difference ' + 'or fulfill it by hand.'
|
|
2942
3015
|
}
|
|
3016
|
+
] : [],
|
|
3017
|
+
...heldCredit && creditShortCents > 0 ? [
|
|
3018
|
+
{
|
|
3019
|
+
atMs: Date.now(),
|
|
3020
|
+
event: 'credit-short',
|
|
3021
|
+
detail: `$${(heldCredit.amountCents / 100).toFixed(2)} of ${heldCredit.label} was taken off this ` + `order, but only $${((heldCredit.amountCents - creditShortCents) / 100).toFixed(2)} was ` + 'still in the account when it was paid.'
|
|
3022
|
+
}
|
|
2943
3023
|
] : []
|
|
2944
3024
|
]
|
|
2945
3025
|
}, unresolvedLines.length ? {
|
|
@@ -2952,7 +3032,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2952
3032
|
} : {}, {
|
|
2953
3033
|
customerName: (_ref2 = object == null ? void 0 : (_object_customer_details = object.customer_details) == null ? void 0 : _object_customer_details.name) != null ? _ref2 : null,
|
|
2954
3034
|
customerEmail: (_ref3 = object == null ? void 0 : (_object_customer_details1 = object.customer_details) == null ? void 0 : _object_customer_details1.email) != null ? _ref3 : null
|
|
2955
|
-
}, (shipping == null ? void 0 : shipping.address) ? {
|
|
3035
|
+
}, (shipping == null ? void 0 : shipping.address) && (cartLocalFulfillment == null ? void 0 : cartLocalFulfillment.fields.fulfillmentMethod) !== 'pickup' ? {
|
|
2956
3036
|
shippingAddress: {
|
|
2957
3037
|
name: (_ref4 = shipping == null ? void 0 : shipping.name) != null ? _ref4 : undefined,
|
|
2958
3038
|
line1: (_shipping_address_line1 = shipping.address.line1) != null ? _shipping_address_line1 : undefined,
|
|
@@ -2962,10 +3042,10 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2962
3042
|
postalCode: (_shipping_address_postal_code = shipping.address.postal_code) != null ? _shipping_address_postal_code : undefined,
|
|
2963
3043
|
country: (_shipping_address_country = shipping.address.country) != null ? _shipping_address_country : undefined
|
|
2964
3044
|
}
|
|
2965
|
-
} : {}, couponCode ? {
|
|
3045
|
+
} : {}, (_ref5 = cartLocalFulfillment == null ? void 0 : cartLocalFulfillment.fields) != null ? _ref5 : {}, couponCode ? {
|
|
2966
3046
|
couponCode
|
|
2967
3047
|
} : {}, {
|
|
2968
|
-
amountCents: Number((
|
|
3048
|
+
amountCents: Number((_ref6 = object == null ? void 0 : object.amount_total) != null ? _ref6 : 0),
|
|
2969
3049
|
feeCents: Number(feeCents != null ? feeCents : 0),
|
|
2970
3050
|
createdAtMs: Date.now(),
|
|
2971
3051
|
createdAt: firebaseAdmin.firestore.FieldValue.serverTimestamp()
|
|
@@ -2996,6 +3076,34 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2996
3076
|
link: `/${hostId}/products`
|
|
2997
3077
|
});
|
|
2998
3078
|
}
|
|
3079
|
+
// A store-credit hold that no longer covered what Stripe discounted
|
|
3080
|
+
// (AGL-3640): the buyer kept the discount, the account gave less. Said
|
|
3081
|
+
// once, like a lost line, so the merchant can square it.
|
|
3082
|
+
if (heldCredit && creditShortCents > 0) {
|
|
3083
|
+
console.error('commerce cart order credit short', {
|
|
3084
|
+
hostId: String(hostId),
|
|
3085
|
+
orderId: String(object.id),
|
|
3086
|
+
providerId: heldCredit.providerId,
|
|
3087
|
+
shortCents: creditShortCents
|
|
3088
|
+
});
|
|
3089
|
+
void notifyHostManagers(String(hostId), {
|
|
3090
|
+
type: 'content.order',
|
|
3091
|
+
title: 'Store credit on an order came up short',
|
|
3092
|
+
body: `Order ${cartOrderLabel} on {site} was discounted ` + `$${(heldCredit.amountCents / 100).toFixed(2)} for ${heldCredit.label}, but the account ` + `had only $${((heldCredit.amountCents - creditShortCents) / 100).toFixed(2)} left when it was paid.`,
|
|
3093
|
+
link: `/${hostId}/products`
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
// The address typed at payment is outside every delivery zone the
|
|
3097
|
+
// store has (AGL-3624): the fee was charged for the postal code the
|
|
3098
|
+
// buyer declared, so the store decides — deliver, or refund.
|
|
3099
|
+
if (cartLocalFulfillment == null ? void 0 : cartLocalFulfillment.outsideZone) {
|
|
3100
|
+
void notifyHostManagers(String(hostId), {
|
|
3101
|
+
type: 'content.order',
|
|
3102
|
+
title: `Check the delivery address on order ${cartOrderLabel}`,
|
|
3103
|
+
body: `Order ${cartOrderLabel} on {site} was booked for local delivery, but the ` + 'address entered at payment is outside your delivery zones. Contact the ' + 'buyer, or refund the delivery.',
|
|
3104
|
+
link: `/${hostId}/products`
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
2999
3107
|
await cartRef.delete().catch(()=>undefined);
|
|
3000
3108
|
// Recoverable checkout closes (AGL-296) so recovery emails stop;
|
|
3001
3109
|
// the doc also carries the marketing opt-in (AGL-301).
|
|
@@ -3058,7 +3166,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3058
3166
|
// The store's receipt switch and the status link (AGL-3610).
|
|
3059
3167
|
const receiptExtras = await onlineReceiptExtras(String(hostId), String(object.id));
|
|
3060
3168
|
if (isEmailConfigured() && buyerEmailForReceipt && receiptExtras.enabled) {
|
|
3061
|
-
var _ref47, _ref48, _ref49, _ref50;
|
|
3169
|
+
var _ref47, _ref48, _ref49, _ref50, _ref51;
|
|
3062
3170
|
const receiptSettings = await hostRef.collection('settings').doc('store').get().catch(()=>null);
|
|
3063
3171
|
const receiptFooter = String((_ref47 = receiptSettings == null ? void 0 : receiptSettings.get('receiptFooter')) != null ? _ref47 : '');
|
|
3064
3172
|
const linesText = lineItems.map((line)=>`${line.quantity}× ${line.name}${line.variantLabel ? ` (${line.variantLabel})` : ''} — $${(line.unitAmountCents * line.quantity / 100).toFixed(2)}`).concat(// Optional lines the buyer took (AGL-3635), as charged.
|
|
@@ -3078,12 +3186,15 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3078
3186
|
const siteOrigin = String((_ref48 = object == null ? void 0 : object.success_url) != null ? _ref48 : '').replace(/\/\?.*$|\?.*$/, '');
|
|
3079
3187
|
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');
|
|
3080
3188
|
const orderTotal = `$${(Number((_ref49 = object == null ? void 0 : object.amount_total) != null ? _ref49 : 0) / 100).toFixed(2)}`;
|
|
3189
|
+
// Where to collect it, or when it is coming (AGL-3624).
|
|
3190
|
+
const fulfillmentText = (_ref50 = cartLocalFulfillment == null ? void 0 : cartLocalFulfillment.summary) != null ? _ref50 : '';
|
|
3081
3191
|
const orderSummary = [
|
|
3082
3192
|
linesText,
|
|
3083
3193
|
licenseText,
|
|
3084
|
-
downloadLines
|
|
3194
|
+
downloadLines,
|
|
3195
|
+
fulfillmentText
|
|
3085
3196
|
].filter(Boolean).join('\n\n');
|
|
3086
|
-
const fallbackText = `Thanks for your purchase!\n\n${linesText}\n\n` + (licenseText ? `${licenseText}\n\n` : '') + (downloadLines ? `${downloadLines}\n\n` : '') + `Total: ${orderTotal}\n` + `Order reference: ${object.id}` + (receiptFooter ? `\n\n${receiptFooter}` : '');
|
|
3197
|
+
const fallbackText = `Thanks for your purchase!\n\n${linesText}\n\n` + (licenseText ? `${licenseText}\n\n` : '') + (downloadLines ? `${downloadLines}\n\n` : '') + (fulfillmentText ? `${fulfillmentText}\n\n` : '') + `Total: ${orderTotal}\n` + `Order reference: ${object.id}` + (receiptFooter ? `\n\n${receiptFooter}` : '');
|
|
3087
3198
|
// Site-owner-designed template when published (AGL-771). The
|
|
3088
3199
|
// license keys and download links ride in {{order.summary}}.
|
|
3089
3200
|
const designed = await renderHostEmailWithTokens(firebaseAdmin.app().firestore(), String(hostId), 'order-receipt', _extends({
|
|
@@ -3097,7 +3208,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3097
3208
|
}, receiptExtras.tokens));
|
|
3098
3209
|
await sendEmail(_extends({
|
|
3099
3210
|
to: buyerEmailForReceipt,
|
|
3100
|
-
subject: (
|
|
3211
|
+
subject: (_ref51 = designed == null ? void 0 : designed.subject) != null ? _ref51 : `Receipt for your order`,
|
|
3101
3212
|
text: (designed == null ? void 0 : designed.text) || fallbackText
|
|
3102
3213
|
}, (designed == null ? void 0 : designed.html) ? {
|
|
3103
3214
|
html: designed.html
|
|
@@ -3145,7 +3256,10 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3145
3256
|
ledger: {
|
|
3146
3257
|
reason: 'sale',
|
|
3147
3258
|
orderId: String(object.id)
|
|
3148
|
-
}
|
|
3259
|
+
},
|
|
3260
|
+
// Off the pickup location's shelf, or the one deliveries leave
|
|
3261
|
+
// from (AGL-3624); `order.locationId` says so for a cancellation.
|
|
3262
|
+
locationId: (cartLocalFulfillment == null ? void 0 : cartLocalFulfillment.fields.locationId) || undefined
|
|
3149
3263
|
});
|
|
3150
3264
|
if (!moved.before || !moved.after) continue;
|
|
3151
3265
|
productsById.set(line.productId, moved.after);
|
|
@@ -3204,12 +3318,12 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3204
3318
|
}
|
|
3205
3319
|
}));
|
|
3206
3320
|
if (couponCode) {
|
|
3207
|
-
var
|
|
3321
|
+
var _ref52;
|
|
3208
3322
|
var _object_metadata23;
|
|
3209
3323
|
await settleRedemption({
|
|
3210
3324
|
firestore,
|
|
3211
3325
|
ref: hostRef.collection('coupons').doc(String(couponCode)),
|
|
3212
|
-
holdKey: String((
|
|
3326
|
+
holdKey: String((_ref52 = (_object_metadata23 = object.metadata) == null ? void 0 : _object_metadata23.couponHoldKey) != null ? _ref52 : ''),
|
|
3213
3327
|
orderRef,
|
|
3214
3328
|
label: `coupon ${couponCode}`,
|
|
3215
3329
|
detail: `Coupon ${couponCode} was applied to this order but no longer ` + 'exists, so the redemption is uncounted against its limit.'
|
|
@@ -3217,10 +3331,10 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3217
3331
|
}
|
|
3218
3332
|
// Gift card balance settlement (AGL-322, made a settlement by AGL-2449).
|
|
3219
3333
|
if ((_object_metadata21 = object.metadata) == null ? void 0 : _object_metadata21.giftCardCode) {
|
|
3220
|
-
var
|
|
3334
|
+
var _ref53, _ref54;
|
|
3221
3335
|
var _object_metadata24, _object_metadata25;
|
|
3222
|
-
const giftCardCents = Number((
|
|
3223
|
-
const holdKey = String((
|
|
3336
|
+
const giftCardCents = Number((_ref53 = (_object_metadata24 = object.metadata) == null ? void 0 : _object_metadata24.giftCardCents) != null ? _ref53 : 0);
|
|
3337
|
+
const holdKey = String((_ref54 = (_object_metadata25 = object.metadata) == null ? void 0 : _object_metadata25.giftCardHoldKey) != null ? _ref54 : '');
|
|
3224
3338
|
const cardRef = hostRef.collection('giftCards').doc(String(object.metadata.giftCardCode));
|
|
3225
3339
|
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.';
|
|
3226
3340
|
if (!holdKey) {
|
|
@@ -3300,7 +3414,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3300
3414
|
const lineProduct = productsById.get(line.productId);
|
|
3301
3415
|
if (!(lineProduct == null ? void 0 : lineProduct.giftCard)) continue;
|
|
3302
3416
|
for(let unit = 0; unit < line.quantity; unit += 1){
|
|
3303
|
-
var
|
|
3417
|
+
var _ref55, _ref56;
|
|
3304
3418
|
var _object_customer_details12, _object_customer_details13, _object_customer_details14;
|
|
3305
3419
|
const code = `GC-${createHmac('sha256', String(object.id)).update(`${line.productId}:${unit}:${Date.now()}`).digest('hex').slice(0, 12).toUpperCase()}`;
|
|
3306
3420
|
// THE EMAIL IS GATED ON THE WRITE (AGL-2161). This `.set()` used
|
|
@@ -3319,13 +3433,13 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3319
3433
|
const issued = await hostRef.collection('giftCards').doc(code).set({
|
|
3320
3434
|
initialCents: line.unitAmountCents,
|
|
3321
3435
|
balanceCents: line.unitAmountCents,
|
|
3322
|
-
recipientEmail: (
|
|
3436
|
+
recipientEmail: (_ref55 = object == null ? void 0 : (_object_customer_details12 = object.customer_details) == null ? void 0 : _object_customer_details12.email) != null ? _ref55 : null,
|
|
3323
3437
|
orderId: String(object.id),
|
|
3324
3438
|
// Which line bought it, so a refund that withdraws that line
|
|
3325
3439
|
// voids this card and no other (AGL-3363).
|
|
3326
3440
|
productId: line.productId,
|
|
3327
3441
|
// What the console's Gift cards search asks (AGL-3321).
|
|
3328
|
-
searchTokens: giftCardSearchTokens(code, (
|
|
3442
|
+
searchTokens: giftCardSearchTokens(code, (_ref56 = object == null ? void 0 : (_object_customer_details13 = object.customer_details) == null ? void 0 : _object_customer_details13.email) != null ? _ref56 : null),
|
|
3329
3443
|
createdAtMs: Date.now()
|
|
3330
3444
|
}).then(()=>true).catch((error)=>{
|
|
3331
3445
|
console.error('Gift card issuance failed', hostId, code, error);
|
|
@@ -3353,7 +3467,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3353
3467
|
}
|
|
3354
3468
|
const giftTo = object == null ? void 0 : (_object_customer_details14 = object.customer_details) == null ? void 0 : _object_customer_details14.email;
|
|
3355
3469
|
if (giftTo) {
|
|
3356
|
-
var
|
|
3470
|
+
var _ref57;
|
|
3357
3471
|
const giftValue = `$${(line.unitAmountCents / 100).toFixed(2)}`;
|
|
3358
3472
|
const fallbackText = `Gift card code: ${code}\n` + `Value: ${giftValue}\n\n` + 'Enter it at checkout to apply the balance.';
|
|
3359
3473
|
// Site-owner-designed template when published (AGL-771). A
|
|
@@ -3366,7 +3480,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3366
3480
|
});
|
|
3367
3481
|
await sendEmail(_extends({
|
|
3368
3482
|
to: giftTo,
|
|
3369
|
-
subject: (
|
|
3483
|
+
subject: (_ref57 = designed == null ? void 0 : designed.subject) != null ? _ref57 : 'Your gift card',
|
|
3370
3484
|
text: (designed == null ? void 0 : designed.text) || fallbackText
|
|
3371
3485
|
}, (designed == null ? void 0 : designed.html) ? {
|
|
3372
3486
|
html: designed.html
|
|
@@ -3387,12 +3501,12 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3387
3501
|
}
|
|
3388
3502
|
// Discounts engine redemptions (AGL-305).
|
|
3389
3503
|
if ((_object_metadata22 = object.metadata) == null ? void 0 : _object_metadata22.discountId) {
|
|
3390
|
-
var
|
|
3504
|
+
var _ref58;
|
|
3391
3505
|
var _object_metadata26;
|
|
3392
3506
|
await settleRedemption({
|
|
3393
3507
|
firestore,
|
|
3394
3508
|
ref: hostRef.collection('discounts').doc(String(object.metadata.discountId)),
|
|
3395
|
-
holdKey: String((
|
|
3509
|
+
holdKey: String((_ref58 = (_object_metadata26 = object.metadata) == null ? void 0 : _object_metadata26.discountHoldKey) != null ? _ref58 : ''),
|
|
3396
3510
|
orderRef,
|
|
3397
3511
|
label: `discount ${object.metadata.discountId}`,
|
|
3398
3512
|
detail: `Discount ${object.metadata.discountId} was applied to this ` + 'order but no longer exists, so the redemption is uncounted ' + 'against its limit.'
|
|
@@ -3406,7 +3520,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3406
3520
|
var _object_metadata27;
|
|
3407
3521
|
const { hostId, orderId, productId } = (_object_metadata27 = object.metadata) != null ? _object_metadata27 : {};
|
|
3408
3522
|
if (hostId && orderId) {
|
|
3409
|
-
var
|
|
3523
|
+
var _ref59, _ref60, _ref61;
|
|
3410
3524
|
var _object_total_details, _object_total_details1;
|
|
3411
3525
|
const firestore = firebaseAdmin.app().firestore();
|
|
3412
3526
|
const hostRef = firestore.collection('hosts').doc(String(hostId));
|
|
@@ -3445,7 +3559,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3445
3559
|
//
|
|
3446
3560
|
// The whole map is written rather than one field of it, so a
|
|
3447
3561
|
// `merge`-set's nested-map merge and a plain replace agree.
|
|
3448
|
-
const shippingCents = Math.max(0, Math.round(Number((
|
|
3562
|
+
const shippingCents = Math.max(0, Math.round(Number((_ref59 = object == null ? void 0 : (_object_total_details = object.total_details) == null ? void 0 : _object_total_details.amount_shipping) != null ? _ref59 : 0) || 0));
|
|
3449
3563
|
// Tax joins shipping in the fold (AGL-1953). `draft-order.ts` now
|
|
3450
3564
|
// declares tax — a Stripe Tax Rate for a `manual` store, whose figure
|
|
3451
3565
|
// it already froze into `totals`, or `automatic_tax` for a `stripe`
|
|
@@ -3458,8 +3572,8 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3458
3572
|
// `amount_tax` 0 here (its own figure stays on the order, and its
|
|
3459
3573
|
// AGL-1953 witness is metadata, not this field), and a draft composed
|
|
3460
3574
|
// by a store with no tax reports 0 too.
|
|
3461
|
-
const stripeTaxCents = Math.max(0, Math.round(Number((
|
|
3462
|
-
const chargedTotalCents = Number((
|
|
3575
|
+
const stripeTaxCents = Math.max(0, Math.round(Number((_ref60 = object == null ? void 0 : (_object_total_details1 = object.total_details) == null ? void 0 : _object_total_details1.amount_tax) != null ? _ref60 : 0) || 0));
|
|
3576
|
+
const chargedTotalCents = Number((_ref61 = object == null ? void 0 : object.amount_total) != null ? _ref61 : NaN);
|
|
3463
3577
|
// `shipping_details` ONLY, unlike the cart branch's
|
|
3464
3578
|
// `?? customer_details` fallback: that address is the BILLING one, and
|
|
3465
3579
|
// a card sale rung up at a register completes here too — it must not
|
|
@@ -3578,7 +3692,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3578
3692
|
});
|
|
3579
3693
|
}
|
|
3580
3694
|
if (flipped) {
|
|
3581
|
-
var
|
|
3695
|
+
var _ref62, _ref63, _ref64, _ref65, _ref66, _ref67;
|
|
3582
3696
|
var _object_metadata28, _object_customer_details15, _order_totals, _object_customer_details16;
|
|
3583
3697
|
const order = paidOrder;
|
|
3584
3698
|
// A legacy register QR sale is a register sale completing (AGL-3607).
|
|
@@ -3604,20 +3718,20 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3604
3718
|
// the hold existed, which Stripe's at-least-once delivery would run
|
|
3605
3719
|
// twice. The transition is what makes it once.
|
|
3606
3720
|
if ((_object_metadata28 = object.metadata) == null ? void 0 : _object_metadata28.discountId) {
|
|
3607
|
-
var
|
|
3721
|
+
var _ref68;
|
|
3608
3722
|
var _object_metadata29;
|
|
3609
3723
|
await settleRedemption({
|
|
3610
3724
|
firestore,
|
|
3611
3725
|
ref: hostRef.collection('discounts').doc(String(object.metadata.discountId)),
|
|
3612
|
-
holdKey: String((
|
|
3726
|
+
holdKey: String((_ref68 = (_object_metadata29 = object.metadata) == null ? void 0 : _object_metadata29.discountHoldKey) != null ? _ref68 : ''),
|
|
3613
3727
|
orderRef,
|
|
3614
3728
|
label: `discount ${object.metadata.discountId}`,
|
|
3615
3729
|
detail: `Discount ${object.metadata.discountId} was applied to this ` + 'order but no longer exists, so the redemption is uncounted ' + 'against its limit.'
|
|
3616
3730
|
});
|
|
3617
3731
|
}
|
|
3618
3732
|
const draftLabel = CommerceModel.formatOrderNumber(order, String(orderId));
|
|
3619
|
-
const draftPayer = (
|
|
3620
|
-
const draftPaidCents = Number((
|
|
3733
|
+
const draftPayer = (_ref62 = (_ref63 = object == null ? void 0 : (_object_customer_details15 = object.customer_details) == null ? void 0 : _object_customer_details15.email) != null ? _ref63 : order.customerEmail) != null ? _ref62 : null;
|
|
3734
|
+
const draftPaidCents = Number((_ref64 = object == null ? void 0 : object.amount_total) != null ? _ref64 : 0) || Number((_ref65 = (_order_totals = order.totals) == null ? void 0 : _order_totals.totalCents) != null ? _ref65 : 0);
|
|
3621
3735
|
void notifyHostManagers(String(hostId), {
|
|
3622
3736
|
type: 'content.order',
|
|
3623
3737
|
title: `Draft order paid — ${draftLabel}`,
|
|
@@ -3637,17 +3751,17 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3637
3751
|
// figure the draft was priced at, and the two agree by construction,
|
|
3638
3752
|
// but only one of them is the money that moved. Stored totals remain
|
|
3639
3753
|
// the fallback for a session shape that reports no total.
|
|
3640
|
-
const draftEmail = (
|
|
3754
|
+
const draftEmail = (_ref66 = (_ref67 = object == null ? void 0 : (_object_customer_details16 = object.customer_details) == null ? void 0 : _object_customer_details16.email) != null ? _ref67 : order.customerEmail) != null ? _ref66 : null;
|
|
3641
3755
|
if (draftEmail) {
|
|
3642
|
-
var
|
|
3756
|
+
var _ref69, _ref70, _ref71;
|
|
3643
3757
|
var _order_totals1, _object_customer_details17;
|
|
3644
|
-
const chargedCents = Number((
|
|
3758
|
+
const chargedCents = Number((_ref69 = object == null ? void 0 : object.amount_total) != null ? _ref69 : 0) || Number((_ref70 = (_order_totals1 = order.totals) == null ? void 0 : _order_totals1.totalCents) != null ? _ref70 : 0);
|
|
3645
3759
|
await recordCapturedContact(_extends({
|
|
3646
3760
|
orgId: '',
|
|
3647
3761
|
hostId: String(hostId),
|
|
3648
3762
|
identity: {
|
|
3649
3763
|
email: draftEmail,
|
|
3650
|
-
name: (
|
|
3764
|
+
name: (_ref71 = object == null ? void 0 : (_object_customer_details17 = object.customer_details) == null ? void 0 : _object_customer_details17.name) != null ? _ref71 : null
|
|
3651
3765
|
},
|
|
3652
3766
|
surface: 'relationship',
|
|
3653
3767
|
lifecycleFloor: 'customer'
|
|
@@ -3674,15 +3788,15 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3674
3788
|
key: 'paid'
|
|
3675
3789
|
});
|
|
3676
3790
|
if (productId) {
|
|
3677
|
-
var _productSnapshot_data,
|
|
3791
|
+
var _productSnapshot_data, _ref72, _ref73;
|
|
3678
3792
|
var _object_metadata30, _lifted_variants_, _order_lineItems_, _order_lineItems;
|
|
3679
3793
|
const productRef = hostRef.collection('products').doc(String(productId));
|
|
3680
3794
|
const productSnapshot = await productRef.get();
|
|
3681
3795
|
const lifted = CommerceModel.liftLegacyProduct((_productSnapshot_data = productSnapshot.data()) != null ? _productSnapshot_data : {
|
|
3682
3796
|
name: 'Product'
|
|
3683
3797
|
});
|
|
3684
|
-
const soldVariantId = String((
|
|
3685
|
-
const quantity = (
|
|
3798
|
+
const soldVariantId = String((_ref72 = (_object_metadata30 = object.metadata) == null ? void 0 : _object_metadata30.variantId) != null ? _ref72 : '') || ((_lifted_variants_ = lifted.variants[0]) == null ? void 0 : _lifted_variants_.id);
|
|
3799
|
+
const quantity = (_ref73 = (_order_lineItems = order.lineItems) == null ? void 0 : (_order_lineItems_ = _order_lineItems[0]) == null ? void 0 : _order_lineItems_.quantity) != null ? _ref73 : 1;
|
|
3686
3800
|
if (soldVariantId) {
|
|
3687
3801
|
// Atomic since AGL-2320.
|
|
3688
3802
|
const moved = await decrementVariantStock({
|
|
@@ -3734,10 +3848,10 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3734
3848
|
// would decrement it twice.
|
|
3735
3849
|
const paidProducts = new Map();
|
|
3736
3850
|
for (const line of (_order_lineItems1 = order.lineItems) != null ? _order_lineItems1 : []){
|
|
3737
|
-
var
|
|
3851
|
+
var _ref74, _ref75, _line_variantId1;
|
|
3738
3852
|
var _lineProduct_variants_;
|
|
3739
|
-
const lineProductId = String((
|
|
3740
|
-
const soldQty = Math.round(Number((
|
|
3853
|
+
const lineProductId = String((_ref74 = line == null ? void 0 : line.productId) != null ? _ref74 : '');
|
|
3854
|
+
const soldQty = Math.round(Number((_ref75 = line == null ? void 0 : line.quantity) != null ? _ref75 : 0));
|
|
3741
3855
|
if (!lineProductId || !(soldQty > 0)) continue;
|
|
3742
3856
|
// Firestore reserves `__…__` ids and `.doc()` throws
|
|
3743
3857
|
// synchronously on one; a corrupt line must not fail the
|
|
@@ -3800,8 +3914,8 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3800
3914
|
var _object_metadata31;
|
|
3801
3915
|
const { hostId, productId, feeCents, couponCode } = (_object_metadata31 = object.metadata) != null ? _object_metadata31 : {};
|
|
3802
3916
|
if (hostId && productId) {
|
|
3803
|
-
var
|
|
3804
|
-
var _object_metadata32, _buyNowLineItems_, _object_customer_details18, _object_customer_details19, _object_customer_details20, _object_metadata33;
|
|
3917
|
+
var _ref76, _productForSnapshot_get2, _productForSnapshot_data1, _ref77, _ref78, _object_shipping_details_address_postal_code1, _object_shipping_details_address_country1, _ref79, _ref80, _ref81, _ref82, _ref83;
|
|
3918
|
+
var _object_metadata32, _buyNowLineItems_, _object_shipping_details1, _object_customer_details18, _object_customer_details19, _object_customer_details20, _object_metadata33;
|
|
3805
3919
|
const firestore = firebaseAdmin.app().firestore();
|
|
3806
3920
|
const hostRef = firestore.collection('hosts').doc(String(hostId));
|
|
3807
3921
|
// Orders v1 (AGL-283): line-item snapshot + totals + timeline with
|
|
@@ -3811,7 +3925,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3811
3925
|
// is bounded to Stripe's at-least-once edge).
|
|
3812
3926
|
const orderRef = hostRef.collection('orders').doc(String(object.id));
|
|
3813
3927
|
const counterRef = hostRef.collection('counters').doc('orders');
|
|
3814
|
-
const amountCents = Number((
|
|
3928
|
+
const amountCents = Number((_ref76 = object == null ? void 0 : object.amount_total) != null ? _ref76 : 0);
|
|
3815
3929
|
const productForSnapshot = await hostRef.collection('products').doc(String(productId)).get();
|
|
3816
3930
|
const snapshotName = String((_productForSnapshot_get2 = productForSnapshot.get('name')) != null ? _productForSnapshot_get2 : 'Product');
|
|
3817
3931
|
// AGL-1711: the line item and totals used to be fabricated from
|
|
@@ -3824,7 +3938,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3824
3938
|
name: snapshotName
|
|
3825
3939
|
});
|
|
3826
3940
|
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];
|
|
3827
|
-
const variantOptions = Object.values((
|
|
3941
|
+
const variantOptions = Object.values((_ref77 = soldVariant == null ? void 0 : soldVariant.options) != null ? _ref77 : {});
|
|
3828
3942
|
const { lineItems: buyNowLineItems, totals: buyNowTotals } = CommerceModel.computeBuyNowOrder(object, _extends({
|
|
3829
3943
|
name: snapshotName
|
|
3830
3944
|
}, variantOptions.length ? {
|
|
@@ -3836,13 +3950,28 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3836
3950
|
} : {}, liftedForSnapshot.supplierId ? {
|
|
3837
3951
|
supplierId: liftedForSnapshot.supplierId
|
|
3838
3952
|
} : {}));
|
|
3839
|
-
const soldQuantity = (
|
|
3953
|
+
const soldQuantity = (_ref78 = (_buyNowLineItems_ = buyNowLineItems[0]) == null ? void 0 : _buyNowLineItems_.quantity) != null ? _ref78 : 1;
|
|
3840
3954
|
// The number the merchant knows this order by, for the notices below
|
|
3841
3955
|
// (AGL-3432).
|
|
3842
3956
|
let buyNowOrderNumber;
|
|
3957
|
+
// Picked up or brought by the store's own driver (AGL-3624), as the
|
|
3958
|
+
// cart branch reads it.
|
|
3959
|
+
const buyNowLocalFulfillment = await orderLocalFulfillmentFromSession({
|
|
3960
|
+
hostId: String(hostId),
|
|
3961
|
+
hostRef,
|
|
3962
|
+
metadata: object == null ? void 0 : object.metadata,
|
|
3963
|
+
shippingAddress: (object == null ? void 0 : (_object_shipping_details1 = object.shipping_details) == null ? void 0 : _object_shipping_details1.address) ? {
|
|
3964
|
+
postalCode: (_object_shipping_details_address_postal_code1 = object.shipping_details.address.postal_code) != null ? _object_shipping_details_address_postal_code1 : null,
|
|
3965
|
+
country: (_object_shipping_details_address_country1 = object.shipping_details.address.country) != null ? _object_shipping_details_address_country1 : null
|
|
3966
|
+
} : null,
|
|
3967
|
+
createdAtMs: Date.now()
|
|
3968
|
+
}).catch((error)=>{
|
|
3969
|
+
console.error('commerce buy-now local fulfillment unreadable', String(object.id), error);
|
|
3970
|
+
return null;
|
|
3971
|
+
});
|
|
3843
3972
|
const created = await firestore.runTransaction(async (transaction)=>{
|
|
3844
|
-
var _counter_get, _ref, _ref1, _ref2, _ref3;
|
|
3845
|
-
var _object_metadata, _object_customer_details, _object_customer_details1;
|
|
3973
|
+
var _counter_get, _ref, _ref1, _ref2, _object_shipping_details_name, _object_shipping_details_address_line1, _object_shipping_details_address_line2, _object_shipping_details_address_city, _object_shipping_details_address_state, _object_shipping_details_address_postal_code, _object_shipping_details_address_country, _ref3, _ref4;
|
|
3974
|
+
var _object_metadata, _object_customer_details, _object_shipping_details, _object_customer_details1;
|
|
3846
3975
|
const [existing, counter] = await Promise.all([
|
|
3847
3976
|
transaction.get(orderRef),
|
|
3848
3977
|
transaction.get(counterRef)
|
|
@@ -3880,13 +4009,24 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3880
4009
|
}, typeof (event == null ? void 0 : event.livemode) === 'boolean' ? {
|
|
3881
4010
|
livemode: event.livemode
|
|
3882
4011
|
} : {}, {
|
|
3883
|
-
customerName: (_ref2 = object == null ? void 0 : (_object_customer_details = object.customer_details) == null ? void 0 : _object_customer_details.name) != null ? _ref2 : null
|
|
4012
|
+
customerName: (_ref2 = object == null ? void 0 : (_object_customer_details = object.customer_details) == null ? void 0 : _object_customer_details.name) != null ? _ref2 : null
|
|
4013
|
+
}, (object == null ? void 0 : (_object_shipping_details = object.shipping_details) == null ? void 0 : _object_shipping_details.address) ? {
|
|
4014
|
+
shippingAddress: {
|
|
4015
|
+
name: (_object_shipping_details_name = object.shipping_details.name) != null ? _object_shipping_details_name : undefined,
|
|
4016
|
+
line1: (_object_shipping_details_address_line1 = object.shipping_details.address.line1) != null ? _object_shipping_details_address_line1 : undefined,
|
|
4017
|
+
line2: (_object_shipping_details_address_line2 = object.shipping_details.address.line2) != null ? _object_shipping_details_address_line2 : undefined,
|
|
4018
|
+
city: (_object_shipping_details_address_city = object.shipping_details.address.city) != null ? _object_shipping_details_address_city : undefined,
|
|
4019
|
+
state: (_object_shipping_details_address_state = object.shipping_details.address.state) != null ? _object_shipping_details_address_state : undefined,
|
|
4020
|
+
postalCode: (_object_shipping_details_address_postal_code = object.shipping_details.address.postal_code) != null ? _object_shipping_details_address_postal_code : undefined,
|
|
4021
|
+
country: (_object_shipping_details_address_country = object.shipping_details.address.country) != null ? _object_shipping_details_address_country : undefined
|
|
4022
|
+
}
|
|
4023
|
+
} : {}, (_ref3 = buyNowLocalFulfillment == null ? void 0 : buyNowLocalFulfillment.fields) != null ? _ref3 : {}, {
|
|
3884
4024
|
createdAtMs: Date.now(),
|
|
3885
4025
|
// Legacy Commerce Starter fields (AGL-90).
|
|
3886
4026
|
productId,
|
|
3887
4027
|
amountCents,
|
|
3888
4028
|
feeCents: Number(feeCents != null ? feeCents : 0),
|
|
3889
|
-
customerEmail: (
|
|
4029
|
+
customerEmail: (_ref4 = object == null ? void 0 : (_object_customer_details1 = object.customer_details) == null ? void 0 : _object_customer_details1.email) != null ? _ref4 : null
|
|
3890
4030
|
}, couponCode ? {
|
|
3891
4031
|
couponCode
|
|
3892
4032
|
} : {}, {
|
|
@@ -3900,10 +4040,18 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3900
4040
|
const buyNowOrderLabel = CommerceModel.formatOrderNumber({
|
|
3901
4041
|
number: buyNowOrderNumber
|
|
3902
4042
|
}, String(object.id));
|
|
4043
|
+
if (buyNowLocalFulfillment == null ? void 0 : buyNowLocalFulfillment.outsideZone) {
|
|
4044
|
+
void notifyHostManagers(String(hostId), {
|
|
4045
|
+
type: 'content.order',
|
|
4046
|
+
title: `Check the delivery address on order ${buyNowOrderLabel}`,
|
|
4047
|
+
body: `Order ${buyNowOrderLabel} on {site} was booked for local delivery, but the ` + 'address entered at payment is outside your delivery zones. Contact the ' + 'buyer, or refund the delivery.',
|
|
4048
|
+
link: `/${hostId}/products`
|
|
4049
|
+
});
|
|
4050
|
+
}
|
|
3903
4051
|
// In-app order notification (wave v6): host managers see sales
|
|
3904
4052
|
// in the bell, not just the owner's email: what came in, from whom
|
|
3905
4053
|
// and where (AGL-3432).
|
|
3906
|
-
const buyNowTotal = `$${(Number((
|
|
4054
|
+
const buyNowTotal = `$${(Number((_ref79 = object == null ? void 0 : object.amount_total) != null ? _ref79 : 0) / 100).toFixed(2)}`;
|
|
3907
4055
|
void notifyHostManagers(String(hostId), {
|
|
3908
4056
|
type: 'content.order',
|
|
3909
4057
|
title: `New order on {site} — ${buyNowTotal}`,
|
|
@@ -4052,15 +4200,15 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4052
4200
|
hostId: String(hostId),
|
|
4053
4201
|
identity: {
|
|
4054
4202
|
email: object == null ? void 0 : (_object_customer_details19 = object.customer_details) == null ? void 0 : _object_customer_details19.email,
|
|
4055
|
-
name: (
|
|
4203
|
+
name: (_ref80 = object == null ? void 0 : (_object_customer_details20 = object.customer_details) == null ? void 0 : _object_customer_details20.name) != null ? _ref80 : null
|
|
4056
4204
|
},
|
|
4057
4205
|
surface: 'relationship',
|
|
4058
4206
|
lifecycleFloor: 'customer',
|
|
4059
|
-
purchaseCents: Number((
|
|
4207
|
+
purchaseCents: Number((_ref81 = object == null ? void 0 : object.amount_total) != null ? _ref81 : 0),
|
|
4060
4208
|
interaction: {
|
|
4061
4209
|
source: 'order',
|
|
4062
4210
|
refId: String(object.id),
|
|
4063
|
-
summary: `Placed an order ($${(Number((
|
|
4211
|
+
summary: `Placed an order ($${(Number((_ref82 = object == null ? void 0 : object.amount_total) != null ? _ref82 : 0) / 100).toFixed(2)})`
|
|
4064
4212
|
}
|
|
4065
4213
|
});
|
|
4066
4214
|
const productRef = hostRef.collection('products').doc(String(productId));
|
|
@@ -4078,12 +4226,12 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4078
4226
|
// serialize; the snapshot above is still read, for the product NAME on
|
|
4079
4227
|
// the receipt below, and no longer decides any count.
|
|
4080
4228
|
{
|
|
4081
|
-
var _productSnapshot_data2,
|
|
4229
|
+
var _productSnapshot_data2, _ref84;
|
|
4082
4230
|
var _object_metadata34, _lifted_variants_1;
|
|
4083
4231
|
const lifted = CommerceModel.liftLegacyProduct((_productSnapshot_data2 = productSnapshot.data()) != null ? _productSnapshot_data2 : {
|
|
4084
4232
|
name: 'Product'
|
|
4085
4233
|
});
|
|
4086
|
-
const soldVariantId = String((
|
|
4234
|
+
const soldVariantId = String((_ref84 = (_object_metadata34 = object.metadata) == null ? void 0 : _object_metadata34.variantId) != null ? _ref84 : '') || ((_lifted_variants_1 = lifted.variants[0]) == null ? void 0 : _lifted_variants_1.id);
|
|
4087
4235
|
if (soldVariantId) {
|
|
4088
4236
|
// AGL-1711: `-1` regardless of how many units were bought, so a
|
|
4089
4237
|
// 3-unit buy-now sale decremented stock by one and the difference
|
|
@@ -4099,7 +4247,9 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4099
4247
|
ledger: {
|
|
4100
4248
|
reason: 'sale',
|
|
4101
4249
|
orderId: String(object.id)
|
|
4102
|
-
}
|
|
4250
|
+
},
|
|
4251
|
+
// Off the pickup or delivery location's shelf (AGL-3624).
|
|
4252
|
+
locationId: (buyNowLocalFulfillment == null ? void 0 : buyNowLocalFulfillment.fields.locationId) || undefined
|
|
4103
4253
|
});
|
|
4104
4254
|
if (moved.before && moved.after) {
|
|
4105
4255
|
// Low-stock alert (AGL-281): fires on the crossing sale only,
|
|
@@ -4114,14 +4264,14 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4114
4264
|
// Settlement, the same way round and for the same reason as the cart
|
|
4115
4265
|
// branch above (AGL-2356): the decrement lands first, then the
|
|
4116
4266
|
// reservation is dropped.
|
|
4117
|
-
await releaseStockHold(hostRef, String((
|
|
4267
|
+
await releaseStockHold(hostRef, String((_ref83 = (_object_metadata33 = object.metadata) == null ? void 0 : _object_metadata33.stockHoldKey) != null ? _ref83 : ''));
|
|
4118
4268
|
if (couponCode) {
|
|
4119
|
-
var
|
|
4269
|
+
var _ref85;
|
|
4120
4270
|
var _object_metadata35;
|
|
4121
4271
|
await settleRedemption({
|
|
4122
4272
|
firestore,
|
|
4123
4273
|
ref: hostRef.collection('coupons').doc(String(couponCode)),
|
|
4124
|
-
holdKey: String((
|
|
4274
|
+
holdKey: String((_ref85 = (_object_metadata35 = object.metadata) == null ? void 0 : _object_metadata35.couponHoldKey) != null ? _ref85 : ''),
|
|
4125
4275
|
orderRef,
|
|
4126
4276
|
label: `coupon ${couponCode}`,
|
|
4127
4277
|
detail: `Coupon ${couponCode} was applied to this order but no longer ` + 'exists, so the redemption is uncounted against its limit.'
|
|
@@ -4136,22 +4286,23 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4136
4286
|
// Receipt + seller notification (AGL-96): env-gated like every
|
|
4137
4287
|
// other outbound email; failures never fail the webhook.
|
|
4138
4288
|
if (isEmailConfigured()) {
|
|
4139
|
-
var _productSnapshot_get,
|
|
4289
|
+
var _productSnapshot_get, _ref86;
|
|
4140
4290
|
var _object_customer_details21, _org, _this3;
|
|
4141
4291
|
const productName = String((_productSnapshot_get = productSnapshot.get('name')) != null ? _productSnapshot_get : 'your purchase');
|
|
4142
|
-
const amount = (Number((
|
|
4292
|
+
const amount = (Number((_ref86 = object == null ? void 0 : object.amount_total) != null ? _ref86 : 0) / 100).toFixed(2);
|
|
4143
4293
|
const buyerEmail = object == null ? void 0 : (_object_customer_details21 = object.customer_details) == null ? void 0 : _object_customer_details21.email;
|
|
4144
4294
|
const orderTotal = `$${amount}`;
|
|
4145
4295
|
// The store's receipt switch and the status link (AGL-3610).
|
|
4146
4296
|
const receiptExtras = await onlineReceiptExtras(String(hostId), String(object.id));
|
|
4147
4297
|
if (buyerEmail && receiptExtras.enabled) {
|
|
4148
|
-
var
|
|
4298
|
+
var _ref87, _ref88;
|
|
4149
4299
|
// The store's own Receipt footer, as the cart receipt carries it
|
|
4150
4300
|
// (AGL-3432).
|
|
4151
|
-
const receiptFooter = String((
|
|
4301
|
+
const receiptFooter = String((_ref87 = await hostRef.collection('settings').doc('store').get().then((snapshot)=>snapshot.get('receiptFooter')).catch(()=>'')) != null ? _ref87 : '');
|
|
4152
4302
|
// The quantity with the name (AGL-3432), so a three-unit sale
|
|
4153
4303
|
// does not read as one item at the whole total.
|
|
4154
|
-
const receiptLine = `${soldQuantity}× ${productName}
|
|
4304
|
+
const receiptLine = `${soldQuantity}× ${productName}` + // Where to collect it, or when it is coming (AGL-3624).
|
|
4305
|
+
((buyNowLocalFulfillment == null ? void 0 : buyNowLocalFulfillment.summary) ? `\n\n${buyNowLocalFulfillment.summary}` : '');
|
|
4155
4306
|
const fallbackText = `Thanks for your purchase!\n\n${receiptLine} — $${amount}` + `\nOrder reference: ${object.id}` + (receiptFooter ? `\n\n${receiptFooter}` : '');
|
|
4156
4307
|
// Site-owner-designed template when published (AGL-771).
|
|
4157
4308
|
const designed = await renderHostEmailWithTokens(firebaseAdmin.app().firestore(), String(hostId), 'order-receipt', _extends({
|
|
@@ -4162,7 +4313,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4162
4313
|
}, receiptExtras.tokens));
|
|
4163
4314
|
await sendEmail(_extends({
|
|
4164
4315
|
to: String(buyerEmail),
|
|
4165
|
-
subject: (
|
|
4316
|
+
subject: (_ref88 = designed == null ? void 0 : designed.subject) != null ? _ref88 : `Receipt: ${productName}`,
|
|
4166
4317
|
text: (designed == null ? void 0 : designed.text) || fallbackText
|
|
4167
4318
|
}, (designed == null ? void 0 : designed.html) ? {
|
|
4168
4319
|
html: designed.html
|
|
@@ -4196,7 +4347,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4196
4347
|
// SSO.
|
|
4197
4348
|
const seller = (_this4 = await findUserByUidAcrossPools(sellerUid).catch(()=>null)) == null ? void 0 : _this4.record;
|
|
4198
4349
|
if (seller == null ? void 0 : seller.email) {
|
|
4199
|
-
var _hostSnapshot_get,
|
|
4350
|
+
var _hostSnapshot_get, _ref89;
|
|
4200
4351
|
const siteName = String((_hostSnapshot_get = hostSnapshot.get('displayName')) != null ? _hostSnapshot_get : hostId);
|
|
4201
4352
|
const fallbackText = `You made a sale on ${siteName}!\n\n${productName} — $${amount}` + (buyerEmail ? `\nBuyer: ${buyerEmail}` : '') + `\nOrder reference: ${object.id}`;
|
|
4202
4353
|
// Site-owner-designed template when published (AGL-771).
|
|
@@ -4209,7 +4360,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4209
4360
|
});
|
|
4210
4361
|
await sendEmail(_extends({
|
|
4211
4362
|
to: seller.email,
|
|
4212
|
-
subject: (
|
|
4363
|
+
subject: (_ref89 = designed == null ? void 0 : designed.subject) != null ? _ref89 : `New order: ${productName}`,
|
|
4213
4364
|
text: (designed == null ? void 0 : designed.text) || fallbackText
|
|
4214
4365
|
}, (designed == null ? void 0 : designed.html) ? {
|
|
4215
4366
|
html: designed.html
|
|
@@ -4239,28 +4390,28 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4239
4390
|
// the refund is written on the order's timeline. Nothing else is moved: a
|
|
4240
4391
|
// Dashboard refund is staff's act, and they chose its transfer reversal.
|
|
4241
4392
|
if (type === 'charge.refunded') {
|
|
4242
|
-
var
|
|
4393
|
+
var _ref90, _ref91;
|
|
4243
4394
|
var _object_payment_intent, _snapshot_ref_parent_parent;
|
|
4244
|
-
const paymentIntentId = typeof (object == null ? void 0 : object.payment_intent) === 'string' ? object.payment_intent : String((
|
|
4395
|
+
const paymentIntentId = typeof (object == null ? void 0 : object.payment_intent) === 'string' ? object.payment_intent : String((_ref90 = object == null ? void 0 : (_object_payment_intent = object.payment_intent) == null ? void 0 : _object_payment_intent.id) != null ? _ref90 : '');
|
|
4245
4396
|
const lookup = paymentIntentId ? await findOrderForDispute(paymentIntentId) : {
|
|
4246
4397
|
kind: 'not-ours'
|
|
4247
4398
|
};
|
|
4248
4399
|
if (lookup.kind !== 'order') return;
|
|
4249
4400
|
const snapshot = lookup.snapshot;
|
|
4250
|
-
const hostId = String((
|
|
4401
|
+
const hostId = String((_ref91 = (_snapshot_ref_parent_parent = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent.id) != null ? _ref91 : '');
|
|
4251
4402
|
const external = await recordExternalRefund(snapshot.ref, object);
|
|
4252
4403
|
if (external && hostId) {
|
|
4253
|
-
var
|
|
4404
|
+
var _ref92, _ref93, _ref94;
|
|
4254
4405
|
var _object_refunds;
|
|
4255
4406
|
// A Stripe Dashboard refund is a refund to every subscriber too
|
|
4256
4407
|
// (AGL-3645): accounting books it and the merchant's webhooks hear it,
|
|
4257
4408
|
// as they do a console refund. Keyed by the charge's refunded total,
|
|
4258
4409
|
// which the record above only ever advances once per amount.
|
|
4259
|
-
const latestRefund = ((
|
|
4410
|
+
const latestRefund = ((_ref92 = object == null ? void 0 : (_object_refunds = object.refunds) == null ? void 0 : _object_refunds.data) != null ? _ref92 : [])[0];
|
|
4260
4411
|
await raiseOrderEvent(ORDER_REFUNDED_EVENT, {
|
|
4261
4412
|
hostId,
|
|
4262
4413
|
orderId: snapshot.id,
|
|
4263
|
-
key: `external-refund:${String((
|
|
4414
|
+
key: `external-refund:${String((_ref93 = object == null ? void 0 : object.id) != null ? _ref93 : paymentIntentId)}:${Number((_ref94 = object == null ? void 0 : object.amount_refunded) != null ? _ref94 : 0)}`,
|
|
4264
4415
|
extra: {
|
|
4265
4416
|
refund: {
|
|
4266
4417
|
id: (latestRefund == null ? void 0 : latestRefund.id) ? String(latestRefund.id) : null,
|
|
@@ -4310,16 +4461,16 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4310
4461
|
// merchant; both report the site so the seller's fraud ledger can name it.
|
|
4311
4462
|
const risk = paymentRiskEventFrom(type, object);
|
|
4312
4463
|
if (risk && risk.signal.kind !== 'dispute') {
|
|
4313
|
-
var
|
|
4464
|
+
var _ref95, _snapshot_data1, _ref96, _ref97;
|
|
4314
4465
|
var _snapshot_ref_parent_parent1, _order_totals2;
|
|
4315
4466
|
const lookup = risk.paymentIntentId ? await findOrderForDispute(risk.paymentIntentId) : {
|
|
4316
4467
|
kind: 'not-ours'
|
|
4317
4468
|
};
|
|
4318
4469
|
if (lookup.kind !== 'order') return;
|
|
4319
4470
|
const snapshot = lookup.snapshot;
|
|
4320
|
-
const hostId = String((
|
|
4471
|
+
const hostId = String((_ref95 = (_snapshot_ref_parent_parent1 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent1.id) != null ? _ref95 : '');
|
|
4321
4472
|
const order = CommerceModel.liftLegacyOrder((_snapshot_data1 = snapshot.data()) != null ? _snapshot_data1 : {});
|
|
4322
|
-
const orderCents = Number((
|
|
4473
|
+
const orderCents = Number((_ref96 = (_ref97 = (_order_totals2 = order.totals) == null ? void 0 : _order_totals2.totalCents) != null ? _ref97 : order.amountCents) != null ? _ref96 : 0);
|
|
4323
4474
|
await recordPaymentRiskOnRecord({
|
|
4324
4475
|
ref: snapshot.ref,
|
|
4325
4476
|
signal: risk.signal,
|
|
@@ -4382,7 +4533,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4382
4533
|
// finds). AGL-1554 will add its own `closed` branch for the marketplace
|
|
4383
4534
|
// side; the two coexist because each self-selects by finding its own record.
|
|
4384
4535
|
if (type === 'charge.dispute.created' || type === 'charge.dispute.closed') {
|
|
4385
|
-
var _dispute_payment_intent,
|
|
4536
|
+
var _dispute_payment_intent, _ref98;
|
|
4386
4537
|
var _snapshot_ref_parent_parent2;
|
|
4387
4538
|
const dispute = object != null ? object : {};
|
|
4388
4539
|
const paymentIntentId = String((_dispute_payment_intent = dispute.payment_intent) != null ? _dispute_payment_intent : '');
|
|
@@ -4408,9 +4559,9 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4408
4559
|
const claimed = lookup.kind === 'order' || lookup.kind === 'unresolved';
|
|
4409
4560
|
const snapshot = lookup.kind === 'order' ? lookup.snapshot : null;
|
|
4410
4561
|
if (snapshot) {
|
|
4411
|
-
var
|
|
4562
|
+
var _ref99;
|
|
4412
4563
|
var _snapshot_ref_parent_parent3;
|
|
4413
|
-
const hostId = String((
|
|
4564
|
+
const hostId = String((_ref99 = (_snapshot_ref_parent_parent3 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent3.id) != null ? _ref99 : '');
|
|
4414
4565
|
if (type === 'charge.dispute.created') {
|
|
4415
4566
|
var _snapshot_data2;
|
|
4416
4567
|
// A chargeback's gift cards are frozen while it is open (AGL-3363).
|
|
@@ -4428,7 +4579,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4428
4579
|
}, notifyRiskEvent);
|
|
4429
4580
|
const { opened, record } = await recordDisputeOpened(snapshot, dispute);
|
|
4430
4581
|
if (opened && hostId) {
|
|
4431
|
-
var _snapshot_data3, _record_evidenceDueByMs,
|
|
4582
|
+
var _snapshot_data3, _record_evidenceDueByMs, _ref100;
|
|
4432
4583
|
// Time-critical — Stripe's evidence window is days, not weeks — so
|
|
4433
4584
|
// this is awaited rather than fired off with `void`: the handler is
|
|
4434
4585
|
// serverless and work left running past the response is work the
|
|
@@ -4447,16 +4598,16 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4447
4598
|
},
|
|
4448
4599
|
amount: `$${(record.amountCents / 100).toFixed(2)}`,
|
|
4449
4600
|
evidenceDueByMs: (_record_evidenceDueByMs = record.evidenceDueByMs) != null ? _record_evidenceDueByMs : null,
|
|
4450
|
-
dedupeKey: `sale:${String((
|
|
4601
|
+
dedupeKey: `sale:${String((_ref100 = dispute == null ? void 0 : dispute.id) != null ? _ref100 : snapshot.id)}`,
|
|
4451
4602
|
staffEvidence: record.reason ? `Reason: ${record.reason.replace(/_/g, ' ')}.` : null
|
|
4452
4603
|
});
|
|
4453
4604
|
}
|
|
4454
4605
|
} else {
|
|
4455
|
-
var
|
|
4606
|
+
var _ref101, _snapshot_data4, _ref102;
|
|
4456
4607
|
// Lost: the money went back, so the cards it bought are voided. Won
|
|
4457
4608
|
// (or closed on a warning): the dispute's freeze lifts; a freeze a
|
|
4458
4609
|
// fraud warning or review put on stays for the merchant (AGL-3363).
|
|
4459
|
-
await applyOrderGiftCardRisk(snapshot, String((
|
|
4610
|
+
await applyOrderGiftCardRisk(snapshot, String((_ref101 = dispute == null ? void 0 : dispute.status) != null ? _ref101 : '') === 'lost' ? {
|
|
4460
4611
|
kind: 'void',
|
|
4461
4612
|
reason: 'dispute-lost'
|
|
4462
4613
|
} : {
|
|
@@ -4527,7 +4678,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4527
4678
|
// transiently-failed reversal gets its retry — and gated inside on
|
|
4528
4679
|
// the order's own `reversedTransferCents` marker, so it runs at most
|
|
4529
4680
|
// once per dispute however many times Stripe delivers.
|
|
4530
|
-
if (String((
|
|
4681
|
+
if (String((_ref102 = dispute == null ? void 0 : dispute.status) != null ? _ref102 : '') === 'lost') {
|
|
4531
4682
|
const pulledBackCents = await reverseSellerShare(snapshot.ref, dispute);
|
|
4532
4683
|
// The merchant-experience half of the AGL-1794 decision, and not an
|
|
4533
4684
|
// optional extra: the reversal takes money out of the connected
|
|
@@ -4557,7 +4708,7 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
4557
4708
|
return _extends({
|
|
4558
4709
|
claimed
|
|
4559
4710
|
}, snapshot ? {
|
|
4560
|
-
hostId: String((
|
|
4711
|
+
hostId: String((_ref98 = (_snapshot_ref_parent_parent2 = snapshot.ref.parent.parent) == null ? void 0 : _snapshot_ref_parent_parent2.id) != null ? _ref98 : '')
|
|
4561
4712
|
} : {});
|
|
4562
4713
|
}
|
|
4563
4714
|
};
|