@aglyn/plugins-commerce 1.0.0-beta.230 → 1.0.0-beta.232
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/index.d.ts +0 -1
- package/src/index.js +0 -1
- package/src/index.js.map +1 -1
- package/src/lib/barcode/barcode-decode.d.ts +71 -0
- package/src/lib/barcode/barcode-decode.js +498 -0
- package/src/lib/barcode/barcode-decode.js.map +1 -0
- package/src/lib/barcode/barcode-encode.d.ts +44 -0
- package/src/lib/barcode/barcode-encode.js +138 -0
- package/src/lib/barcode/barcode-encode.js.map +1 -0
- package/src/lib/barcode/barcode-scanner.component.d.ts +23 -0
- package/src/lib/barcode/barcode-scanner.component.js +260 -0
- package/src/lib/barcode/barcode-scanner.component.js.map +1 -0
- package/src/lib/barcode/scan-button.component.d.ts +10 -0
- package/src/lib/barcode/scan-button.component.js +62 -0
- package/src/lib/barcode/scan-button.component.js.map +1 -0
- package/src/lib/barcode/scanner-wedge.d.ts +35 -0
- package/src/lib/barcode/scanner-wedge.js +108 -0
- package/src/lib/barcode/scanner-wedge.js.map +1 -0
- package/src/lib/components/account.js +10 -1
- package/src/lib/components/account.js.map +1 -1
- package/src/lib/components/cart-extras.d.ts +45 -0
- package/src/lib/components/cart-extras.js +127 -0
- package/src/lib/components/cart-extras.js.map +1 -0
- package/src/lib/components/cart.js +82 -15
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/checkout-return-notice.d.ts +26 -0
- package/src/lib/components/checkout-return-notice.js +48 -0
- package/src/lib/components/checkout-return-notice.js.map +1 -0
- package/src/lib/components/commerce-console-page.js +124 -0
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/commerce-console-sections.d.ts +1 -1
- package/src/lib/components/commerce-console-sections.js +4 -0
- package/src/lib/components/commerce-console-sections.js.map +1 -1
- package/src/lib/components/console/bulk-fulfill.d.ts +44 -0
- package/src/lib/components/console/bulk-fulfill.js +84 -0
- package/src/lib/components/console/bulk-fulfill.js.map +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/customer-notifications-card.component.d.ts +19 -0
- package/src/lib/components/console/customer-notifications-card.component.js +149 -0
- package/src/lib/components/console/customer-notifications-card.component.js.map +1 -0
- package/src/lib/components/console/host-orders-card.component.js +88 -6
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/locations-card.component.js +164 -57
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +209 -61
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-fulfillment-panel.component.d.ts +48 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js +542 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-invoice.component.d.ts +33 -0
- package/src/lib/components/console/order-invoice.component.js +81 -0
- package/src/lib/components/console/order-invoice.component.js.map +1 -0
- package/src/lib/components/console/order-receipt-resend.component.d.ts +21 -0
- package/src/lib/components/console/order-receipt-resend.component.js +203 -0
- package/src/lib/components/console/order-receipt-resend.component.js.map +1 -0
- package/src/lib/components/console/order-returns.component.d.ts +36 -0
- package/src/lib/components/console/order-returns.component.js +142 -0
- package/src/lib/components/console/order-returns.component.js.map +1 -0
- package/src/lib/components/console/order-shipping-actions.component.d.ts +54 -0
- package/src/lib/components/console/order-shipping-actions.component.js +149 -0
- package/src/lib/components/console/order-shipping-actions.component.js.map +1 -0
- package/src/lib/components/console/order-webhooks-card.component.d.ts +50 -0
- package/src/lib/components/console/order-webhooks-card.component.js +623 -0
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -0
- package/src/lib/components/console/order-zones.d.ts +155 -0
- package/src/lib/components/console/order-zones.js +40 -0
- package/src/lib/components/console/order-zones.js.map +1 -0
- package/src/lib/components/console/payment-methods-card.component.d.ts +67 -0
- package/src/lib/components/console/payment-methods-card.component.js +395 -0
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +124 -0
- package/src/lib/components/console/pos/pos-api.js +101 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +36 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +160 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +352 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-product-grid.component.d.ts +47 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js +272 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.d.ts +27 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js +282 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +53 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +445 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +31 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +640 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.d.ts +43 -0
- package/src/lib/components/console/pos/use-pos-display.js +161 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +14 -0
- package/src/lib/components/console/pos-devices-card.component.js +546 -0
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -0
- package/src/lib/components/console/pos-display/brand-screen.d.ts +33 -0
- package/src/lib/components/console/pos-display/brand-screen.js +85 -0
- package/src/lib/components/console/pos-display/brand-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/cart-screen.d.ts +29 -0
- package/src/lib/components/console/pos-display/cart-screen.js +166 -0
- package/src/lib/components/console/pos-display/cart-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +24 -0
- package/src/lib/components/console/pos-display/pairing-screen.js +127 -0
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +90 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +140 -0
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -0
- package/src/lib/components/console/pos-display/receipt-screen.d.ts +35 -0
- package/src/lib/components/console/pos-display/receipt-screen.js +200 -0
- package/src/lib/components/console/pos-display/receipt-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/tip-screen.d.ts +36 -0
- package/src/lib/components/console/pos-display/tip-screen.js +211 -0
- package/src/lib/components/console/pos-display/tip-screen.js.map +1 -0
- package/src/lib/components/console/pos-display-page.component.d.ts +16 -0
- package/src/lib/components/console/pos-display-page.component.js +407 -0
- package/src/lib/components/console/pos-display-page.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +289 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js +61 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +38 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +129 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js +60 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.d.ts +48 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js +220 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.d.ts +63 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js +186 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt.d.ts +39 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js +182 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js +465 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.d.ts +29 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +253 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +494 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js +102 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.d.ts +30 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js +277 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/register-ops.d.ts +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.d.ts +46 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js +128 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.d.ts +36 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js +64 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js.map +1 -0
- package/src/lib/components/console/pos-page.component.d.ts +13 -5
- package/src/lib/components/console/pos-page.component.js +756 -654
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-zones.d.ts +23 -0
- package/src/lib/components/console/pos-zones.js +31 -0
- package/src/lib/components/console/pos-zones.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.js +61 -71
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-labels-dialog.component.d.ts +13 -0
- package/src/lib/components/console/product-labels-dialog.component.js +197 -0
- package/src/lib/components/console/product-labels-dialog.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +19 -0
- package/src/lib/components/console/product-register-fields.component.js +241 -0
- package/src/lib/components/console/product-register-fields.component.js.map +1 -0
- package/src/lib/components/console/product-zones.d.ts +44 -0
- package/src/lib/components/console/product-zones.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +23 -20
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +33 -0
- package/src/lib/components/console/register-hardware-card.component.js +826 -0
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -0
- package/src/lib/components/console/registers-card.component.js +24 -5
- package/src/lib/components/console/registers-card.component.js.map +1 -1
- package/src/lib/components/console/return-actions.d.ts +38 -0
- package/src/lib/components/console/return-actions.js +76 -0
- package/src/lib/components/console/return-actions.js.map +1 -0
- package/src/lib/components/console/return-detail-dialog.component.d.ts +34 -0
- package/src/lib/components/console/return-detail-dialog.component.js +718 -0
- package/src/lib/components/console/return-detail-dialog.component.js.map +1 -0
- package/src/lib/components/console/return-settings-card.component.d.ts +34 -0
- package/src/lib/components/console/return-settings-card.component.js +195 -0
- package/src/lib/components/console/return-settings-card.component.js.map +1 -0
- package/src/lib/components/console/return-zones.d.ts +87 -0
- package/src/lib/components/console/return-zones.js +31 -0
- package/src/lib/components/console/return-zones.js.map +1 -0
- package/src/lib/components/console/returns-card.component.d.ts +45 -0
- package/src/lib/components/console/returns-card.component.js +159 -0
- package/src/lib/components/console/returns-card.component.js.map +1 -0
- package/src/lib/components/console/shipping-settings-card.component.js +161 -5
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.d.ts +59 -0
- package/src/lib/components/console/shippingeasy-card.component.js +378 -0
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -0
- package/src/lib/components/console/shipstation-card.component.d.ts +35 -0
- package/src/lib/components/console/shipstation-card.component.js +345 -0
- package/src/lib/components/console/shipstation-card.component.js.map +1 -0
- package/src/lib/components/console/start-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/start-return-dialog.component.js +243 -0
- package/src/lib/components/console/start-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.js +2 -1
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-settings-card.component.js +2 -66
- package/src/lib/components/console/store-settings-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +42 -0
- package/src/lib/components/console/store-zones.js +39 -0
- package/src/lib/components/console/store-zones.js.map +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
- package/src/lib/components/order-status.d.ts +36 -0
- package/src/lib/components/order-status.js +502 -0
- package/src/lib/components/order-status.js.map +1 -0
- package/src/lib/components/product-detail.js +41 -2
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/return-request.d.ts +32 -0
- package/src/lib/components/return-request.js +576 -0
- package/src/lib/components/return-request.js.map +1 -0
- package/src/lib/components/storefront-payment-appearance.d.ts +32 -0
- package/src/lib/components/storefront-payment-appearance.js +114 -0
- package/src/lib/components/storefront-payment-appearance.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +57 -1
- package/src/lib/components/storefront-payment-element.js +332 -33
- package/src/lib/components/storefront-payment-element.js.map +1 -1
- package/src/lib/constants/order-status.d.ts +22 -0
- package/src/lib/constants/order-status.js +22 -0
- package/src/lib/constants/order-status.js.map +1 -0
- package/src/lib/constants/return-request.d.ts +27 -0
- package/src/lib/constants/return-request.js +32 -0
- package/src/lib/constants/return-request.js.map +1 -0
- package/src/lib/constants/stock-movement-query.js +2 -1
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/declarations.console-server.js +9 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.server.d.ts +2 -1
- package/src/lib/declarations.server.js +68 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +59 -0
- package/src/lib/model/buyer-notifications.js +97 -0
- package/src/lib/model/buyer-notifications.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +171 -2
- package/src/lib/model/commerce-orders.js +26 -16
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-payment-methods.d.ts +146 -0
- package/src/lib/model/commerce-payment-methods.js +247 -0
- package/src/lib/model/commerce-payment-methods.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +437 -0
- package/src/lib/model/commerce-pos-ops.js +721 -0
- package/src/lib/model/commerce-pos-ops.js.map +1 -0
- package/src/lib/model/commerce-pos.d.ts +263 -0
- package/src/lib/model/commerce-pos.js +375 -0
- package/src/lib/model/commerce-pos.js.map +1 -0
- package/src/lib/model/commerce-printers.d.ts +211 -0
- package/src/lib/model/commerce-printers.js +181 -0
- package/src/lib/model/commerce-printers.js.map +1 -0
- package/src/lib/model/commerce-receipt.d.ts +97 -0
- package/src/lib/model/commerce-receipt.js +180 -0
- package/src/lib/model/commerce-receipt.js.map +1 -0
- package/src/lib/model/commerce-returns.d.ts +207 -0
- package/src/lib/model/commerce-returns.js +300 -0
- package/src/lib/model/commerce-returns.js.map +1 -0
- package/src/lib/model/commerce-shipping.d.ts +44 -1
- package/src/lib/model/commerce-shipping.js +53 -9
- package/src/lib/model/commerce-shipping.js.map +1 -1
- package/src/lib/model/commerce-tax-engine.d.ts +90 -0
- package/src/lib/model/commerce-tax-engine.js +129 -0
- package/src/lib/model/commerce-tax-engine.js.map +1 -0
- package/src/lib/model/commerce.d.ts +91 -2
- package/src/lib/model/commerce.js +89 -1
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +16 -0
- package/src/lib/model/index.js +16 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/order-events.d.ts +154 -0
- package/src/lib/model/order-events.js +153 -0
- package/src/lib/model/order-events.js.map +1 -0
- package/src/lib/model/order-fulfillment.d.ts +117 -0
- package/src/lib/model/order-fulfillment.js +217 -0
- package/src/lib/model/order-fulfillment.js.map +1 -0
- package/src/lib/model/order-history.d.ts +58 -0
- package/src/lib/model/order-history.js +22 -0
- package/src/lib/model/order-history.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +9 -1
- package/src/lib/model/order-list-fields.js +7 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-shipping-export.d.ts +91 -0
- package/src/lib/model/order-shipping-export.js +192 -0
- package/src/lib/model/order-shipping-export.js.map +1 -0
- package/src/lib/model/order-status-view.d.ts +103 -0
- package/src/lib/model/order-status-view.js +156 -0
- package/src/lib/model/order-status-view.js.map +1 -0
- package/src/lib/model/order-webhooks.d.ts +142 -0
- package/src/lib/model/order-webhooks.js +91 -0
- package/src/lib/model/order-webhooks.js.map +1 -0
- package/src/lib/model/product-channel.d.ts +56 -0
- package/src/lib/model/product-channel.js +86 -0
- package/src/lib/model/product-channel.js.map +1 -0
- package/src/lib/model/product-modifiers.d.ts +80 -0
- package/src/lib/model/product-modifiers.js +140 -0
- package/src/lib/model/product-modifiers.js.map +1 -0
- package/src/lib/model/product-write.d.ts +186 -0
- package/src/lib/model/product-write.js +116 -0
- package/src/lib/model/product-write.js.map +1 -0
- package/src/lib/model/shippingeasy.d.ts +94 -0
- package/src/lib/model/shippingeasy.js +267 -0
- package/src/lib/model/shippingeasy.js.map +1 -0
- package/src/lib/model/shipstation.d.ts +125 -0
- package/src/lib/model/shipstation.js +399 -0
- package/src/lib/model/shipstation.js.map +1 -0
- package/src/lib/model/smart-collection-reads.d.ts +32 -0
- package/src/lib/model/smart-collection-reads.js +63 -0
- package/src/lib/model/smart-collection-reads.js.map +1 -0
- package/src/lib/model/tracking-url.d.ts +74 -0
- package/src/lib/model/tracking-url.js +159 -0
- package/src/lib/model/tracking-url.js.map +1 -0
- package/src/lib/plugin-config.d.ts +13 -0
- package/src/lib/plugin-config.js +77 -5
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +26 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-ops-config.d.ts +39 -0
- package/src/lib/pos-ops-config.js +88 -0
- package/src/lib/pos-ops-config.js.map +1 -0
- package/src/lib/printing/print-document.d.ts +106 -0
- package/src/lib/printing/print-document.js +464 -0
- package/src/lib/printing/print-document.js.map +1 -0
- package/src/lib/printing/product-labels.d.ts +58 -0
- package/src/lib/printing/product-labels.js +116 -0
- package/src/lib/printing/product-labels.js.map +1 -0
- package/src/lib/printing/render-epson.d.ts +57 -0
- package/src/lib/printing/render-epson.js +135 -0
- package/src/lib/printing/render-epson.js.map +1 -0
- package/src/lib/printing/render-star.d.ts +45 -0
- package/src/lib/printing/render-star.js +100 -0
- package/src/lib/printing/render-star.js.map +1 -0
- package/src/lib/printing/render-text.d.ts +25 -0
- package/src/lib/printing/render-text.js +53 -0
- package/src/lib/printing/render-text.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +27 -4
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +67 -0
- package/src/lib/server/api-v1/order-view.js +120 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -0
- package/src/lib/server/api-v1/orders-and-products.js +58 -65
- package/src/lib/server/api-v1/orders-and-products.js.map +1 -1
- package/src/lib/server/billing-webhook.js +135 -28
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +29 -0
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/carrier-rates-availability.d.ts +26 -0
- package/src/lib/server/carrier-rates-availability.js +76 -0
- package/src/lib/server/carrier-rates-availability.js.map +1 -0
- package/src/lib/server/carrier-shipping.d.ts +84 -0
- package/src/lib/server/carrier-shipping.js +135 -0
- package/src/lib/server/carrier-shipping.js.map +1 -0
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +226 -22
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/channel-order-updates.d.ts +50 -0
- package/src/lib/server/channel-order-updates.js +290 -0
- package/src/lib/server/channel-order-updates.js.map +1 -0
- package/src/lib/server/channel-orders.d.ts +85 -0
- package/src/lib/server/channel-orders.js +543 -0
- package/src/lib/server/channel-orders.js.map +1 -0
- package/src/lib/server/checkout-extras.d.ts +64 -0
- package/src/lib/server/checkout-extras.js +157 -0
- package/src/lib/server/checkout-extras.js.map +1 -0
- package/src/lib/server/{feed.d.ts → checkout-status.d.ts} +2 -7
- package/src/lib/server/checkout-status.js +111 -0
- package/src/lib/server/checkout-status.js.map +1 -0
- package/src/lib/server/checkout.js +86 -9
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/draft-order.js +34 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.d.ts +127 -10
- package/src/lib/server/fulfill-order.js +451 -49
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/legacy-feed.d.ts +28 -0
- package/src/lib/server/legacy-feed.js +52 -0
- package/src/lib/server/legacy-feed.js.map +1 -0
- package/src/lib/server/native-checkout.d.ts +34 -15
- package/src/lib/server/native-checkout.js +32 -17
- package/src/lib/server/native-checkout.js.map +1 -1
- package/src/lib/server/order-event-host-emit.d.ts +23 -0
- package/src/lib/server/order-event-host-emit.js +30 -0
- package/src/lib/server/order-event-host-emit.js.map +1 -0
- package/src/lib/server/order-event-triggers.d.ts +37 -0
- package/src/lib/server/order-event-triggers.js +119 -0
- package/src/lib/server/order-event-triggers.js.map +1 -0
- package/src/lib/server/order-events.d.ts +62 -0
- package/src/lib/server/order-events.js +109 -0
- package/src/lib/server/order-events.js.map +1 -0
- package/src/lib/server/order-history.d.ts +23 -0
- package/src/lib/server/order-history.js +65 -0
- package/src/lib/server/order-history.js.map +1 -0
- package/src/lib/server/order-notifications.d.ts +185 -0
- package/src/lib/server/order-notifications.js +567 -0
- package/src/lib/server/order-notifications.js.map +1 -0
- package/src/lib/server/order-receipt-send.d.ts +39 -0
- package/src/lib/server/order-receipt-send.js +151 -0
- package/src/lib/server/order-receipt-send.js.map +1 -0
- package/src/lib/server/order-status-token.d.ts +31 -0
- package/src/lib/server/order-status-token.js +75 -0
- package/src/lib/server/order-status-token.js.map +1 -0
- package/src/lib/server/order-status.d.ts +58 -0
- package/src/lib/server/order-status.js +141 -0
- package/src/lib/server/order-status.js.map +1 -0
- package/src/lib/server/order-webhooks.d.ts +108 -0
- package/src/lib/server/order-webhooks.js +622 -0
- package/src/lib/server/order-webhooks.js.map +1 -0
- package/src/lib/server/orders-shipping-prepare.d.ts +26 -0
- package/src/lib/server/orders-shipping-prepare.js +121 -0
- package/src/lib/server/orders-shipping-prepare.js.map +1 -0
- package/src/lib/server/payment-method-domains.d.ts +209 -0
- package/src/lib/server/payment-method-domains.js +444 -0
- package/src/lib/server/payment-method-domains.js.map +1 -0
- package/src/lib/server/payment-methods.d.ts +77 -0
- package/src/lib/server/payment-methods.js +284 -0
- package/src/lib/server/payment-methods.js.map +1 -0
- package/src/lib/server/pos-auth.d.ts +50 -0
- package/src/lib/server/pos-auth.js +121 -0
- package/src/lib/server/pos-auth.js.map +1 -0
- package/src/lib/server/pos-customer.d.ts +49 -0
- package/src/lib/server/pos-customer.js +257 -0
- package/src/lib/server/pos-customer.js.map +1 -0
- package/src/lib/server/pos-display.d.ts +57 -0
- package/src/lib/server/pos-display.js +419 -0
- package/src/lib/server/pos-display.js.map +1 -0
- package/src/lib/server/pos-fee-month.d.ts +34 -0
- package/src/lib/server/pos-fee-month.js +36 -0
- package/src/lib/server/pos-fee-month.js.map +1 -0
- package/src/lib/server/pos-ops-gate.d.ts +161 -0
- package/src/lib/server/pos-ops-gate.js +295 -0
- package/src/lib/server/pos-ops-gate.js.map +1 -0
- package/src/lib/server/pos-ops-routes.d.ts +22 -0
- package/src/lib/server/pos-ops-routes.js +36 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -0
- package/src/lib/server/pos-order.d.ts +1 -18
- package/src/lib/server/pos-order.js +222 -42
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +39 -0
- package/src/lib/server/pos-payment.js +922 -0
- package/src/lib/server/pos-payment.js.map +1 -0
- package/src/lib/server/pos-print.d.ts +82 -0
- package/src/lib/server/pos-print.js +193 -0
- package/src/lib/server/pos-print.js.map +1 -0
- package/src/lib/server/pos-readers.d.ts +27 -0
- package/src/lib/server/pos-readers.js +276 -0
- package/src/lib/server/pos-readers.js.map +1 -0
- package/src/lib/server/pos-refund-authority.d.ts +60 -0
- package/src/lib/server/pos-refund-authority.js +72 -0
- package/src/lib/server/pos-refund-authority.js.map +1 -0
- package/src/lib/server/pos-return.d.ts +58 -0
- package/src/lib/server/pos-return.js +891 -0
- package/src/lib/server/pos-return.js.map +1 -0
- package/src/lib/server/pos-sale-stamp.d.ts +66 -0
- package/src/lib/server/pos-sale-stamp.js +84 -0
- package/src/lib/server/pos-sale-stamp.js.map +1 -0
- package/src/lib/server/pos-sale.d.ts +170 -0
- package/src/lib/server/pos-sale.js +461 -0
- package/src/lib/server/pos-sale.js.map +1 -0
- package/src/lib/server/pos-shift.d.ts +45 -0
- package/src/lib/server/pos-shift.js +484 -0
- package/src/lib/server/pos-shift.js.map +1 -0
- package/src/lib/server/pos-staff-pin.d.ts +26 -0
- package/src/lib/server/pos-staff-pin.js +339 -0
- package/src/lib/server/pos-staff-pin.js.map +1 -0
- package/src/lib/server/pos-stripe.d.ts +91 -0
- package/src/lib/server/pos-stripe.js +129 -0
- package/src/lib/server/pos-stripe.js.map +1 -0
- package/src/lib/server/pos-terminal-connection-token.d.ts +48 -0
- package/src/lib/server/pos-terminal-connection-token.js +166 -0
- package/src/lib/server/pos-terminal-connection-token.js.map +1 -0
- package/src/lib/server/pos-terminal.d.ts +218 -0
- package/src/lib/server/pos-terminal.js +1014 -0
- package/src/lib/server/pos-terminal.js.map +1 -0
- package/src/lib/server/print-queue.d.ts +124 -0
- package/src/lib/server/print-queue.js +301 -0
- package/src/lib/server/print-queue.js.map +1 -0
- package/src/lib/server/printer-poll.d.ts +75 -0
- package/src/lib/server/printer-poll.js +325 -0
- package/src/lib/server/printer-poll.js.map +1 -0
- package/src/lib/server/printer-secret.d.ts +39 -0
- package/src/lib/server/printer-secret.js +56 -0
- package/src/lib/server/printer-secret.js.map +1 -0
- package/src/lib/server/printers.d.ts +114 -0
- package/src/lib/server/printers.js +546 -0
- package/src/lib/server/printers.js.map +1 -0
- package/src/lib/server/product-catalog.d.ts +42 -0
- package/src/lib/server/product-catalog.js +309 -0
- package/src/lib/server/product-catalog.js.map +1 -0
- package/src/lib/server/product-drafts.d.ts +5 -1
- package/src/lib/server/product-drafts.js +3 -3
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product-writer.d.ts +19 -0
- package/src/lib/server/product-writer.js +261 -0
- package/src/lib/server/product-writer.js.map +1 -0
- package/src/lib/server/products-write.d.ts +61 -0
- package/src/lib/server/products-write.js +375 -0
- package/src/lib/server/products-write.js.map +1 -0
- package/src/lib/server/refund.js +110 -45
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reserve.js +2 -0
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/return-status-action.d.ts +37 -0
- package/src/lib/server/return-status-action.js +57 -0
- package/src/lib/server/return-status-action.js.map +1 -0
- package/src/lib/server/returns.d.ts +119 -0
- package/src/lib/server/returns.js +938 -0
- package/src/lib/server/returns.js.map +1 -0
- package/src/lib/server/shipment-records.d.ts +36 -0
- package/src/lib/server/shipment-records.js +289 -0
- package/src/lib/server/shipment-records.js.map +1 -0
- package/src/lib/server/shipping-connector-gates.d.ts +40 -0
- package/src/lib/server/shipping-connector-gates.js +97 -0
- package/src/lib/server/shipping-connector-gates.js.map +1 -0
- package/src/lib/server/shipping-connectors.d.ts +29 -0
- package/src/lib/server/shipping-connectors.js +236 -0
- package/src/lib/server/shipping-connectors.js.map +1 -0
- package/src/lib/server/shippingeasy.d.ts +238 -0
- package/src/lib/server/shippingeasy.js +787 -0
- package/src/lib/server/shippingeasy.js.map +1 -0
- package/src/lib/server/shipstation.d.ts +129 -0
- package/src/lib/server/shipstation.js +483 -0
- package/src/lib/server/shipstation.js.map +1 -0
- package/src/lib/server/site-page-resolver.d.ts +5 -0
- package/src/lib/server/site-page-resolver.js +156 -1
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/stock-levels.d.ts +21 -0
- package/src/lib/server/stock-levels.js +263 -0
- package/src/lib/server/stock-levels.js.map +1 -0
- package/src/lib/server/stripe-refund.d.ts +47 -0
- package/src/lib/server/stripe-refund.js +87 -0
- package/src/lib/server/stripe-refund.js.map +1 -0
- package/src/lib/server/supplier-update.js +46 -5
- package/src/lib/server/supplier-update.js.map +1 -1
- package/src/lib/server/tax-engine-quote.d.ts +47 -0
- package/src/lib/server/tax-engine-quote.js +105 -0
- package/src/lib/server/tax-engine-quote.js.map +1 -0
- package/src/lib/server.js +143 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/site.js +12 -0
- package/src/lib/site.js.map +1 -1
- package/src/lib/subprocessors.d.ts +26 -0
- package/src/lib/subprocessors.js +50 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/tenant-emails.js +461 -3
- package/src/lib/tenant-emails.js.map +1 -1
- package/src/lib/testing/fake-firestore.d.ts +45 -0
- package/src/lib/testing/fake-firestore.js +189 -0
- package/src/lib/testing/fake-firestore.js.map +1 -0
- package/src/lib/testing/memory-firestore.d.ts +136 -0
- package/src/lib/testing/memory-firestore.js +282 -0
- package/src/lib/testing/memory-firestore.js.map +1 -0
- package/src/lib/testing/pos-ops-harness.d.ts +50 -0
- package/src/lib/testing/pos-ops-harness.js +184 -0
- package/src/lib/testing/pos-ops-harness.js.map +1 -0
- package/src/lib/testing/pos-ops-memory-firestore.d.ts +55 -0
- package/src/lib/testing/pos-ops-memory-firestore.js +376 -0
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -0
- package/src/lib/transfer/products.server.d.ts +5 -0
- package/src/lib/transfer/products.server.js +2 -2
- package/src/lib/transfer/products.server.js.map +1 -1
- package/src/lib/transfer/records-transfer.d.ts +11 -1
- package/src/lib/transfer/records-transfer.js +127 -5
- package/src/lib/transfer/records-transfer.js.map +1 -1
- package/src/lib/transfer/records.server.d.ts +9 -2
- package/src/lib/transfer/records.server.js +58 -7
- package/src/lib/transfer/records.server.js.map +1 -1
- package/src/lib/transfer/register-transfer-resources.js +40 -1
- package/src/lib/transfer/register-transfer-resources.js.map +1 -1
- package/src/lib/transfer/register-transfer-ui.js +4 -1
- package/src/lib/transfer/register-transfer-ui.js.map +1 -1
- package/src/lib/transfer/shipping-presets.d.ts +23 -0
- package/src/lib/transfer/shipping-presets.js +156 -0
- package/src/lib/transfer/shipping-presets.js.map +1 -0
- package/src/lib/transfer/tracking-transfer.d.ts +101 -0
- package/src/lib/transfer/tracking-transfer.js +546 -0
- package/src/lib/transfer/tracking-transfer.js.map +1 -0
- package/src/lib/transfer/tracking.server.d.ts +37 -0
- package/src/lib/transfer/tracking.server.js +393 -0
- package/src/lib/transfer/tracking.server.js.map +1 -0
- package/src/lib/transfer/transfer-keys.d.ts +2 -1
- package/src/lib/transfer/transfer-keys.js +6 -2
- package/src/lib/transfer/transfer-keys.js.map +1 -1
- package/src/lib/utils/code128.d.ts +37 -0
- package/src/lib/utils/code128.js +199 -0
- package/src/lib/utils/code128.js.map +1 -0
- package/src/lib/utils/order-invoice.d.ts +55 -0
- package/src/lib/utils/order-invoice.js +127 -0
- package/src/lib/utils/order-invoice.js.map +1 -0
- package/src/lib/utils/use-checkout-return-notice.d.ts +34 -0
- package/src/lib/utils/use-checkout-return-notice.js +78 -0
- package/src/lib/utils/use-checkout-return-notice.js.map +1 -0
- package/src/lib/server/feed.js +0 -69
- package/src/lib/server/feed.js.map +0 -1
|
@@ -0,0 +1,1014 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { firebaseAdmin } from "@aglyn/tenant-data-admin";
|
|
18
|
+
import { merchantAccountIsReady } from "@aglyn/tenant-data-admin/server/payment-provider";
|
|
19
|
+
import { cardAuthenticationParams, checkoutSessionCardAuthenticationParams } from "@aglyn/tenant-data-admin/server/stripe-card-authentication";
|
|
20
|
+
import * as CommerceModel from "../model/index.js";
|
|
21
|
+
import { POS_CURRENCY, posCardApplicationFeeCents, posStripe, posStripeErrorMessage, posStripeTestMode, posTerminalAvailable } from "./pos-stripe.js";
|
|
22
|
+
import { applyPosPayment, readPosSale } from "./pos-sale.js";
|
|
23
|
+
/*==========================================
|
|
24
|
+
* STRIPE TERMINAL AND THE REGISTER'S OTHER CARD TENDERS (AGL-3607).
|
|
25
|
+
*
|
|
26
|
+
* ## Where the readers live
|
|
27
|
+
*
|
|
28
|
+
* Every register charge is a DESTINATION charge on the platform account, so
|
|
29
|
+
* Stripe's rule for that model applies: Locations and Readers are created on
|
|
30
|
+
* the PLATFORM with the platform key, and identify their merchant by
|
|
31
|
+
* metadata. One Location per site (`hosts/{hostId}/terminal/config`), and one
|
|
32
|
+
* `hosts/{hostId}/terminalReaders/{readerId}` document per reader, written
|
|
33
|
+
* only here. The document is what makes a reader THIS site's: every call that
|
|
34
|
+
* names a reader reads it under the caller's own site first, so one store can
|
|
35
|
+
* never drive, rename or remove another's reader, and the reader's own
|
|
36
|
+
* `metadata.hostId` is checked again before a payment is sent to it.
|
|
37
|
+
*
|
|
38
|
+
* ## Why the reader charges with MANUAL capture
|
|
39
|
+
*
|
|
40
|
+
* On-reader tipping changes the amount after the PaymentIntent exists: the
|
|
41
|
+
* reader adds the tip on confirmation and reports it in
|
|
42
|
+
* `amount_details.tip.amount`. `application_fee_amount` set at creation was
|
|
43
|
+
* sized on the pre-tip amount, and the platform's take must exclude the tip
|
|
44
|
+
* while Stripe's processing cost (debited from the platform) is on the whole
|
|
45
|
+
* charge. So the reader only AUTHORIZES; {@link refreshPosCardPayment} reads
|
|
46
|
+
* the tip, re-prices the fee as
|
|
47
|
+
*
|
|
48
|
+
* take share (of the sale, never of the tip) + card processing (whole charge)
|
|
49
|
+
*
|
|
50
|
+
* and captures with that exact `application_fee_amount`. Stripe's own Connect
|
|
51
|
+
* guidance for Terminal is the same: inspect, fix the application fee, then
|
|
52
|
+
* capture. An authorization expires after two days, and a register capture
|
|
53
|
+
* happens seconds after the tap.
|
|
54
|
+
*=========================================*/ const NOT_A_SALE = {
|
|
55
|
+
ok: false,
|
|
56
|
+
status: 409,
|
|
57
|
+
error: 'This sale is no longer open'
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The payment without its failure reason. Removed, never set to `undefined`:
|
|
61
|
+
* Firestore refuses an undefined field inside the `payments` array.
|
|
62
|
+
*/ function withoutFailure(payment) {
|
|
63
|
+
const next = _extends({}, payment);
|
|
64
|
+
delete next.failureMessage;
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
67
|
+
/** The merchant's connected account, when it can take card payments now. */ export async function posMerchantAccount(hostId, org) {
|
|
68
|
+
var _ref;
|
|
69
|
+
const ownerUid = String((_ref = org == null ? void 0 : org['ownerUid']) != null ? _ref : '');
|
|
70
|
+
if (!ownerUid) return null;
|
|
71
|
+
const profile = await firebaseAdmin.app().firestore().collection('profiles').doc(ownerUid).get();
|
|
72
|
+
const accountId = profile.get('stripeAccountId');
|
|
73
|
+
if (!merchantAccountIsReady({
|
|
74
|
+
accountId,
|
|
75
|
+
chargesEnabled: profile.get('stripeChargesEnabled'),
|
|
76
|
+
accountLivemode: profile.get('stripeAccountLivemode')
|
|
77
|
+
}, {
|
|
78
|
+
subject: `POS card payment host ${hostId}`
|
|
79
|
+
})) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return String(accountId);
|
|
83
|
+
}
|
|
84
|
+
function terminalConfigRef(hostId) {
|
|
85
|
+
return firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminal').doc('config');
|
|
86
|
+
}
|
|
87
|
+
function readerRef(hostId, readerId) {
|
|
88
|
+
return firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminalReaders').doc(readerId);
|
|
89
|
+
}
|
|
90
|
+
/** A reader id as Stripe mints them; anything else never reaches Stripe. */ export function isTerminalReaderId(value) {
|
|
91
|
+
return typeof value === 'string' && /^tmr_[A-Za-z0-9]{6,64}$/.test(value);
|
|
92
|
+
}
|
|
93
|
+
/** The reader, when it is THIS site's; null for anyone else's or none. */ export async function ownedTerminalReader(hostId, readerId) {
|
|
94
|
+
if (!isTerminalReaderId(readerId)) return null;
|
|
95
|
+
const snapshot = await readerRef(hostId, readerId).get();
|
|
96
|
+
if (!snapshot.exists) return null;
|
|
97
|
+
return _extends({}, snapshot.data(), {
|
|
98
|
+
id: readerId
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
export function posTerminalAddressProblem(address) {
|
|
102
|
+
if (!(address == null ? void 0 : address.line1) || !(address == null ? void 0 : address.city) || !(address == null ? void 0 : address.postalCode) || !(address == null ? void 0 : address.country)) {
|
|
103
|
+
return 'Enter the street, city, postal code and country where the reader is used.';
|
|
104
|
+
}
|
|
105
|
+
if (!/^[A-Z]{2}$/.test(String(address.country))) return 'Choose a two-letter country code, like US.';
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The site's Terminal Location, created on first use (on the PLATFORM, with
|
|
110
|
+
* the merchant named in metadata). Its address is the store's, because Stripe
|
|
111
|
+
* uses it to configure the reader for the right country.
|
|
112
|
+
*/ export async function ensurePosTerminalLocation(options) {
|
|
113
|
+
var _existing_get;
|
|
114
|
+
var _created_body;
|
|
115
|
+
const ref = terminalConfigRef(options.hostId);
|
|
116
|
+
const existing = await ref.get();
|
|
117
|
+
const known = String((_existing_get = existing.get('stripeLocationId')) != null ? _existing_get : '');
|
|
118
|
+
if (known) return {
|
|
119
|
+
ok: true,
|
|
120
|
+
locationId: known
|
|
121
|
+
};
|
|
122
|
+
const problem = posTerminalAddressProblem(options.address);
|
|
123
|
+
if (problem) return {
|
|
124
|
+
ok: false,
|
|
125
|
+
status: 400,
|
|
126
|
+
error: problem
|
|
127
|
+
};
|
|
128
|
+
const address = options.address;
|
|
129
|
+
const created = await posStripe('POST', 'terminal/locations', {
|
|
130
|
+
idempotencyKey: `pos-location:${options.hostId}`,
|
|
131
|
+
params: {
|
|
132
|
+
display_name: options.displayName.slice(0, 100) || 'Store',
|
|
133
|
+
'address[line1]': address.line1,
|
|
134
|
+
'address[line2]': address.line2 || undefined,
|
|
135
|
+
'address[city]': address.city,
|
|
136
|
+
'address[state]': address.state || undefined,
|
|
137
|
+
'address[postal_code]': address.postalCode,
|
|
138
|
+
'address[country]': address.country,
|
|
139
|
+
'metadata[orgId]': options.orgId,
|
|
140
|
+
'metadata[hostId]': options.hostId
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
if (!created.ok || !((_created_body = created.body) == null ? void 0 : _created_body.id)) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
status: 502,
|
|
147
|
+
error: posStripeErrorMessage(created.body, 'The reader location could not be set up.')
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
await ref.set({
|
|
151
|
+
stripeLocationId: String(created.body.id),
|
|
152
|
+
livemode: Boolean(created.body.livemode),
|
|
153
|
+
createdAtMs: Date.now()
|
|
154
|
+
}, {
|
|
155
|
+
merge: true
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
ok: true,
|
|
159
|
+
locationId: String(created.body.id)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/** The tipping a reader shows: Stripe offers three buttons, so three presets. */ export function posReaderTippingKey(settings) {
|
|
163
|
+
return settings.tippingEnabled ? settings.tipPercentages.slice(0, 3).join(',') : 'off';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Keeps the site's reader tipping in step with the merchant's settings: one
|
|
167
|
+
* Terminal Configuration per site, assigned to its Location, rewritten only
|
|
168
|
+
* when the presets changed. Never fatal: a reader that keeps the previous
|
|
169
|
+
* presets still takes the payment.
|
|
170
|
+
*/ export async function syncPosReaderTipping(hostId, settings) {
|
|
171
|
+
var _config_get, _config_get1;
|
|
172
|
+
var _saved_body;
|
|
173
|
+
if (!settings.tippingEnabled) return;
|
|
174
|
+
const ref = terminalConfigRef(hostId);
|
|
175
|
+
const config = await ref.get();
|
|
176
|
+
const locationId = String((_config_get = config.get('stripeLocationId')) != null ? _config_get : '');
|
|
177
|
+
if (!locationId) return;
|
|
178
|
+
const key = posReaderTippingKey(settings);
|
|
179
|
+
if (config.get('tippingKey') === key) return;
|
|
180
|
+
const percentages = settings.tipPercentages.slice(0, 3);
|
|
181
|
+
const configurationId = String((_config_get1 = config.get('stripeConfigurationId')) != null ? _config_get1 : '');
|
|
182
|
+
const params = {
|
|
183
|
+
[`tipping[${POS_CURRENCY}][percentages]`]: percentages.map(String)
|
|
184
|
+
};
|
|
185
|
+
const saved = await posStripe('POST', configurationId ? `terminal/configurations/${configurationId}` : 'terminal/configurations', _extends({
|
|
186
|
+
params
|
|
187
|
+
}, configurationId ? {} : {
|
|
188
|
+
idempotencyKey: `pos-configuration:${hostId}:${key}`
|
|
189
|
+
}));
|
|
190
|
+
if (!saved.ok || !((_saved_body = saved.body) == null ? void 0 : _saved_body.id)) {
|
|
191
|
+
var _saved_body1;
|
|
192
|
+
console.error('[pos-terminal] tipping configuration failed', hostId, (_saved_body1 = saved.body) == null ? void 0 : _saved_body1.error);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (!configurationId) {
|
|
196
|
+
const assigned = await posStripe('POST', `terminal/locations/${locationId}`, {
|
|
197
|
+
params: {
|
|
198
|
+
configuration_overrides: String(saved.body.id)
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
if (!assigned.ok) {
|
|
202
|
+
var _assigned_body;
|
|
203
|
+
console.error('[pos-terminal] configuration assignment failed', hostId, (_assigned_body = assigned.body) == null ? void 0 : _assigned_body.error);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
await ref.set({
|
|
208
|
+
stripeConfigurationId: String(saved.body.id),
|
|
209
|
+
tippingKey: key
|
|
210
|
+
}, {
|
|
211
|
+
merge: true
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/** Reads a reader from Stripe and keeps its status on the site's document. */ export async function refreshPosReaderStatus(hostId, readerId) {
|
|
215
|
+
var _ref, _ref1;
|
|
216
|
+
var _fetched_body, _fetched_body1;
|
|
217
|
+
const fetched = await posStripe('GET', `terminal/readers/${readerId}`);
|
|
218
|
+
if (!fetched.ok) return null;
|
|
219
|
+
const status = String((_ref = (_fetched_body = fetched.body) == null ? void 0 : _fetched_body.status) != null ? _ref : 'offline');
|
|
220
|
+
await readerRef(hostId, readerId).set({
|
|
221
|
+
status,
|
|
222
|
+
lastSeenAtMs: Date.now()
|
|
223
|
+
}, {
|
|
224
|
+
merge: true
|
|
225
|
+
}).catch(()=>undefined);
|
|
226
|
+
return {
|
|
227
|
+
status,
|
|
228
|
+
action: (_ref1 = (_fetched_body1 = fetched.body) == null ? void 0 : _fetched_body1.action) != null ? _ref1 : null
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/** Reserves a pending card payment in the ledger, or finds the one this attempt made. */ async function reserveCardPayment(start, method, extra) {
|
|
232
|
+
return await applyPosPayment({
|
|
233
|
+
hostId: start.hostId,
|
|
234
|
+
orderId: start.orderId,
|
|
235
|
+
paymentId: start.paymentId,
|
|
236
|
+
decide: ({ order, payments, existing })=>{
|
|
237
|
+
var _ref, _order_posTakeFeeCents;
|
|
238
|
+
var _order_totals;
|
|
239
|
+
if (existing) {
|
|
240
|
+
// The same attempt again: hand back what it started. A failed card
|
|
241
|
+
// is re-armed by `retry`, not by pressing the tender a second time.
|
|
242
|
+
return {
|
|
243
|
+
kind: 'keep'
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
if (order.status !== 'pending') return _extends({
|
|
247
|
+
kind: 'refuse'
|
|
248
|
+
}, NOT_A_SALE);
|
|
249
|
+
const total = Number((_ref = (_order_totals = order.totals) == null ? void 0 : _order_totals.totalCents) != null ? _ref : 0);
|
|
250
|
+
const tenderable = CommerceModel.posTenderableCents(total, payments);
|
|
251
|
+
if (!(start.amountCents > 0)) {
|
|
252
|
+
return {
|
|
253
|
+
kind: 'refuse',
|
|
254
|
+
status: 400,
|
|
255
|
+
error: 'Enter an amount to charge.'
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
if (start.amountCents > tenderable) {
|
|
259
|
+
return {
|
|
260
|
+
kind: 'refuse',
|
|
261
|
+
status: 409,
|
|
262
|
+
error: tenderable > 0 ? `Only $${(tenderable / 100).toFixed(2)} is left to pay on this sale.` : 'Nothing is left to pay on this sale.'
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const tipProblem = CommerceModel.posTipProblem(start.tipCents, start.amountCents);
|
|
266
|
+
if (tipProblem) return {
|
|
267
|
+
kind: 'refuse',
|
|
268
|
+
status: 400,
|
|
269
|
+
error: tipProblem
|
|
270
|
+
};
|
|
271
|
+
const takeFeeCents = CommerceModel.posTakeShareCents({
|
|
272
|
+
takeFeeCents: Number((_order_posTakeFeeCents = order.posTakeFeeCents) != null ? _order_posTakeFeeCents : 0),
|
|
273
|
+
totalCents: total,
|
|
274
|
+
amountCents: start.amountCents
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
kind: 'put',
|
|
278
|
+
payment: _extends({
|
|
279
|
+
id: start.paymentId,
|
|
280
|
+
method,
|
|
281
|
+
amountCents: start.amountCents
|
|
282
|
+
}, start.tipCents > 0 ? {
|
|
283
|
+
tipCents: start.tipCents
|
|
284
|
+
} : {}, {
|
|
285
|
+
status: 'pending',
|
|
286
|
+
atMs: Date.now(),
|
|
287
|
+
takeFeeCents,
|
|
288
|
+
cashierId: start.cashierId
|
|
289
|
+
}, extra)
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/** Writes Stripe's answer onto a pending card payment. */ async function patchCardPayment(hostId, orderId, paymentId, patch, event) {
|
|
295
|
+
return await applyPosPayment({
|
|
296
|
+
hostId,
|
|
297
|
+
orderId,
|
|
298
|
+
paymentId,
|
|
299
|
+
decide: ({ existing })=>{
|
|
300
|
+
if (!existing) return {
|
|
301
|
+
kind: 'refuse',
|
|
302
|
+
status: 404,
|
|
303
|
+
error: 'Unknown payment'
|
|
304
|
+
};
|
|
305
|
+
const next = patch(existing);
|
|
306
|
+
if (!next) return {
|
|
307
|
+
kind: 'keep'
|
|
308
|
+
};
|
|
309
|
+
return _extends({
|
|
310
|
+
kind: 'put',
|
|
311
|
+
payment: next
|
|
312
|
+
}, event ? {
|
|
313
|
+
event
|
|
314
|
+
} : {});
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function paymentIntentParams(start, payment, destination, extra) {
|
|
319
|
+
var _payment_takeFeeCents;
|
|
320
|
+
const chargeCents = start.amountCents + start.tipCents;
|
|
321
|
+
const fee = posCardApplicationFeeCents({
|
|
322
|
+
takeShareCents: Number((_payment_takeFeeCents = payment.takeFeeCents) != null ? _payment_takeFeeCents : 0),
|
|
323
|
+
chargeCents
|
|
324
|
+
});
|
|
325
|
+
return _extends({
|
|
326
|
+
amount: chargeCents,
|
|
327
|
+
currency: POS_CURRENCY,
|
|
328
|
+
'transfer_data[destination]': destination
|
|
329
|
+
}, fee > 0 ? {
|
|
330
|
+
application_fee_amount: fee
|
|
331
|
+
} : {}, {
|
|
332
|
+
'metadata[kind]': 'pos',
|
|
333
|
+
'metadata[hostId]': start.hostId,
|
|
334
|
+
'metadata[orderId]': start.orderId,
|
|
335
|
+
'metadata[paymentId]': start.paymentId,
|
|
336
|
+
'metadata[tipCents]': String(start.tipCents)
|
|
337
|
+
}, extra);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Creates (or finds) the card-present PaymentIntent for one payment WITHOUT
|
|
341
|
+
* choosing how the card is collected: reserves the amount in the ledger and
|
|
342
|
+
* creates a manual-capture destination charge to the merchant (settled on
|
|
343
|
+
* Aglyn's platform account, with no `on_behalf_of`, as ToS §10.7 states),
|
|
344
|
+
* keyed by the payment so a retry returns the same intent.
|
|
345
|
+
*
|
|
346
|
+
* Two collectors use it. {@link startCardPresentPayment} pushes the intent
|
|
347
|
+
* to a smart reader the site owns; a native companion app (AGL-3618)
|
|
348
|
+
* collects it with the Stripe Terminal SDK (Tap to Pay, Bluetooth readers)
|
|
349
|
+
* using the returned `clientSecret`. However the card is collected, the
|
|
350
|
+
* payment is recorded by {@link refreshPosCardPayment}, keyed on the intent's
|
|
351
|
+
* metadata, from the register's poll or the webhook alike.
|
|
352
|
+
*/ export async function createCardPresentIntent(start) {
|
|
353
|
+
var _intent_body;
|
|
354
|
+
// Live card-present payments wait for Terminal to be switched on for the
|
|
355
|
+
// platform (`STRIPE_TERMINAL_LIVE_ENABLED`); the hidden controls are not
|
|
356
|
+
// the only gate.
|
|
357
|
+
if (!posTerminalAvailable()) {
|
|
358
|
+
return {
|
|
359
|
+
ok: false,
|
|
360
|
+
status: 409,
|
|
361
|
+
error: 'Card readers are not available for this store yet.'
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const destination = await posMerchantAccount(start.hostId, start.org);
|
|
365
|
+
if (!destination) return {
|
|
366
|
+
ok: false,
|
|
367
|
+
status: 409,
|
|
368
|
+
error: 'Card payments not set up'
|
|
369
|
+
};
|
|
370
|
+
const reserved = await reserveCardPayment(start, 'card_present', start.readerId ? {
|
|
371
|
+
readerId: start.readerId
|
|
372
|
+
} : {});
|
|
373
|
+
if (!reserved.ok || !reserved.payment) return reserved;
|
|
374
|
+
const payment = reserved.payment;
|
|
375
|
+
if (payment.status !== 'pending') return reserved;
|
|
376
|
+
// Keyed by the payment: a second call for the same payment replays the
|
|
377
|
+
// intent Stripe already made rather than opening another.
|
|
378
|
+
const intent = await posStripe('POST', 'payment_intents', {
|
|
379
|
+
idempotencyKey: `pos-pi:${payment.id}`,
|
|
380
|
+
params: paymentIntentParams(start, payment, destination, _extends({
|
|
381
|
+
payment_method_types: POS_CURRENCY === 'usd' ? [
|
|
382
|
+
'card_present'
|
|
383
|
+
] : [
|
|
384
|
+
'card_present',
|
|
385
|
+
'interac_present'
|
|
386
|
+
],
|
|
387
|
+
capture_method: 'manual'
|
|
388
|
+
}, start.readerId ? {
|
|
389
|
+
'metadata[readerId]': start.readerId
|
|
390
|
+
} : {}, {
|
|
391
|
+
description: 'In-store purchase'
|
|
392
|
+
}))
|
|
393
|
+
});
|
|
394
|
+
if (!intent.ok || !((_intent_body = intent.body) == null ? void 0 : _intent_body.id)) {
|
|
395
|
+
return await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
396
|
+
status: 'failed',
|
|
397
|
+
failureMessage: posStripeErrorMessage(intent.body, 'The card payment could not be started.')
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
400
|
+
const paymentIntentId = String(intent.body.id);
|
|
401
|
+
const recorded = payment.paymentIntentId ? reserved : await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
402
|
+
paymentIntentId,
|
|
403
|
+
livemode: Boolean(intent.body.livemode)
|
|
404
|
+
}));
|
|
405
|
+
return _extends({}, recorded, {
|
|
406
|
+
paymentIntentId
|
|
407
|
+
}, intent.body.client_secret ? {
|
|
408
|
+
clientSecret: String(intent.body.client_secret)
|
|
409
|
+
} : {});
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* A smart-reader payment: the card-present intent from
|
|
413
|
+
* {@link createCardPresentIntent}, pushed to a reader THIS site owns. The
|
|
414
|
+
* register then polls {@link refreshPosCardPayment} until the reader answers;
|
|
415
|
+
* webhooks land on the same function.
|
|
416
|
+
*/ export async function startCardPresentPayment(start) {
|
|
417
|
+
const reader = await ownedTerminalReader(start.hostId, start.readerId);
|
|
418
|
+
if (!reader) return {
|
|
419
|
+
ok: false,
|
|
420
|
+
status: 404,
|
|
421
|
+
error: 'That card reader is not on this site.'
|
|
422
|
+
};
|
|
423
|
+
await syncPosReaderTipping(start.hostId, start.settings).catch((error)=>console.error('[pos-terminal] tipping sync failed', error));
|
|
424
|
+
const created = await createCardPresentIntent(_extends({}, start, {
|
|
425
|
+
readerId: reader.id
|
|
426
|
+
}));
|
|
427
|
+
if (!created.ok || !created.payment || !created.paymentIntentId) return created;
|
|
428
|
+
if (created.payment.status !== 'pending') return created;
|
|
429
|
+
return await sendToReader({
|
|
430
|
+
hostId: start.hostId,
|
|
431
|
+
orderId: start.orderId,
|
|
432
|
+
paymentId: created.payment.id,
|
|
433
|
+
readerId: reader.id,
|
|
434
|
+
paymentIntentId: created.paymentIntentId,
|
|
435
|
+
// A tip the customer already chose on the display is in the amount;
|
|
436
|
+
// asking again on the reader would ask twice.
|
|
437
|
+
skipTipping: !start.settings.tippingEnabled || start.tipCents > 0,
|
|
438
|
+
attempt: 0
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/** The site's Terminal Location id, or null before a reader was ever set up. */ export async function posTerminalLocationId(hostId) {
|
|
442
|
+
var _config_get;
|
|
443
|
+
const config = await terminalConfigRef(hostId).get();
|
|
444
|
+
return String((_config_get = config.get('stripeLocationId')) != null ? _config_get : '') || null;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* A Terminal SDK connection token scoped to the site's own Location, for a
|
|
448
|
+
* native companion app's SDK (AGL-3618). Scoping it to the Location is what
|
|
449
|
+
* keeps one store's app from discovering another store's readers: Stripe
|
|
450
|
+
* only lets a location-scoped token connect to readers in that Location.
|
|
451
|
+
* Null when the site has no Location yet, never an unscoped token.
|
|
452
|
+
*/ export async function createPosTerminalConnectionToken(hostId) {
|
|
453
|
+
var _token_body;
|
|
454
|
+
const locationId = await posTerminalLocationId(hostId);
|
|
455
|
+
if (!locationId) return null;
|
|
456
|
+
const token = await posStripe('POST', 'terminal/connection_tokens', {
|
|
457
|
+
params: {
|
|
458
|
+
location: locationId
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
if (!token.ok || !((_token_body = token.body) == null ? void 0 : _token_body.secret)) return null;
|
|
462
|
+
return {
|
|
463
|
+
secret: String(token.body.secret),
|
|
464
|
+
locationId
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
async function sendToReader(input) {
|
|
468
|
+
const processed = await posStripe('POST', `terminal/readers/${input.readerId}/process_payment_intent`, {
|
|
469
|
+
idempotencyKey: `pos-process:${input.paymentId}:${input.attempt}`,
|
|
470
|
+
params: _extends({
|
|
471
|
+
payment_intent: input.paymentIntentId,
|
|
472
|
+
'process_config[enable_customer_cancellation]': true
|
|
473
|
+
}, input.skipTipping ? {
|
|
474
|
+
'process_config[skip_tipping]': true
|
|
475
|
+
} : {})
|
|
476
|
+
});
|
|
477
|
+
if (!processed.ok) {
|
|
478
|
+
return await patchCardPayment(input.hostId, input.orderId, input.paymentId, (current)=>_extends({}, current, {
|
|
479
|
+
status: 'failed',
|
|
480
|
+
failureMessage: posStripeErrorMessage(processed.body, 'The card reader could not start the payment.')
|
|
481
|
+
}));
|
|
482
|
+
}
|
|
483
|
+
return await patchCardPayment(input.hostId, input.orderId, input.paymentId, (current)=>{
|
|
484
|
+
if (!current.failureMessage) return null;
|
|
485
|
+
return withoutFailure(current);
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Re-arms a declined or failed reader payment on the SAME PaymentIntent, as
|
|
490
|
+
* Stripe asks (a new one per attempt risks a double charge).
|
|
491
|
+
*/ export async function retryCardPresentPayment(input) {
|
|
492
|
+
var _payment_tipCents;
|
|
493
|
+
const order = await readPosSale(input.hostId, input.orderId);
|
|
494
|
+
if (!order || order.status !== 'pending') return NOT_A_SALE;
|
|
495
|
+
const payment = CommerceModel.orderPayments(order).find((entry)=>entry.id === input.paymentId);
|
|
496
|
+
if (!payment || payment.method !== 'card_present' || !payment.paymentIntentId || !payment.readerId) {
|
|
497
|
+
return {
|
|
498
|
+
ok: false,
|
|
499
|
+
status: 404,
|
|
500
|
+
error: 'Unknown payment'
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
if (payment.status === 'succeeded') return {
|
|
504
|
+
ok: true,
|
|
505
|
+
order,
|
|
506
|
+
payment,
|
|
507
|
+
completed: false,
|
|
508
|
+
changed: false
|
|
509
|
+
};
|
|
510
|
+
const reader = await ownedTerminalReader(input.hostId, payment.readerId);
|
|
511
|
+
if (!reader) return {
|
|
512
|
+
ok: false,
|
|
513
|
+
status: 404,
|
|
514
|
+
error: 'That card reader is not on this site.'
|
|
515
|
+
};
|
|
516
|
+
// Back to pending first, so the amount is reserved again before the reader
|
|
517
|
+
// is asked; a sale paid meanwhile by another tender refuses here.
|
|
518
|
+
const rearmed = await applyPosPayment({
|
|
519
|
+
hostId: input.hostId,
|
|
520
|
+
orderId: input.orderId,
|
|
521
|
+
paymentId: input.paymentId,
|
|
522
|
+
decide: ({ order: fresh, payments, existing })=>{
|
|
523
|
+
var _ref;
|
|
524
|
+
var _fresh_totals;
|
|
525
|
+
if (!existing) return {
|
|
526
|
+
kind: 'refuse',
|
|
527
|
+
status: 404,
|
|
528
|
+
error: 'Unknown payment'
|
|
529
|
+
};
|
|
530
|
+
if (existing.status === 'pending') return {
|
|
531
|
+
kind: 'keep'
|
|
532
|
+
};
|
|
533
|
+
if (existing.status !== 'failed' && existing.status !== 'canceled') {
|
|
534
|
+
return {
|
|
535
|
+
kind: 'refuse',
|
|
536
|
+
status: 409,
|
|
537
|
+
error: 'This payment cannot be retried.'
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
const tenderable = CommerceModel.posTenderableCents(Number((_ref = (_fresh_totals = fresh.totals) == null ? void 0 : _fresh_totals.totalCents) != null ? _ref : 0), payments.filter((entry)=>entry.id !== existing.id));
|
|
541
|
+
if (existing.amountCents > tenderable) {
|
|
542
|
+
return {
|
|
543
|
+
kind: 'refuse',
|
|
544
|
+
status: 409,
|
|
545
|
+
error: 'The balance changed. Start a new card payment.'
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
return {
|
|
549
|
+
kind: 'put',
|
|
550
|
+
payment: _extends({}, withoutFailure(existing), {
|
|
551
|
+
status: 'pending'
|
|
552
|
+
})
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
if (!rearmed.ok) return rearmed;
|
|
557
|
+
const attempt = Date.now();
|
|
558
|
+
return await sendToReader({
|
|
559
|
+
hostId: input.hostId,
|
|
560
|
+
orderId: input.orderId,
|
|
561
|
+
paymentId: input.paymentId,
|
|
562
|
+
readerId: reader.id,
|
|
563
|
+
paymentIntentId: payment.paymentIntentId,
|
|
564
|
+
skipTipping: !input.settings.tippingEnabled || Number((_payment_tipCents = payment.tipCents) != null ? _payment_tipCents : 0) > 0,
|
|
565
|
+
attempt
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* A typed card (card not present): a PaymentIntent the console confirms with
|
|
570
|
+
* the Payment Element. No MOTO: the card is keyed into Stripe's own field and
|
|
571
|
+
* goes through Stripe's normal online checks, 3-D Secure included.
|
|
572
|
+
*/ export async function startCardKeyedPayment(start) {
|
|
573
|
+
var _intent_body, _intent_body1;
|
|
574
|
+
const destination = await posMerchantAccount(start.hostId, start.org);
|
|
575
|
+
if (!destination) return {
|
|
576
|
+
ok: false,
|
|
577
|
+
status: 409,
|
|
578
|
+
error: 'Card payments not set up'
|
|
579
|
+
};
|
|
580
|
+
const reserved = await reserveCardPayment(start, 'card_keyed', {});
|
|
581
|
+
if (!reserved.ok || !reserved.payment) return reserved;
|
|
582
|
+
const payment = reserved.payment;
|
|
583
|
+
if (payment.status !== 'pending') return reserved;
|
|
584
|
+
const intent = await posStripe('POST', 'payment_intents', {
|
|
585
|
+
idempotencyKey: `pos-pi:${payment.id}`,
|
|
586
|
+
params: paymentIntentParams(start, payment, destination, _extends({
|
|
587
|
+
payment_method_types: [
|
|
588
|
+
'card'
|
|
589
|
+
],
|
|
590
|
+
description: 'In-store purchase (typed card)'
|
|
591
|
+
}, cardAuthenticationParams('one-time')))
|
|
592
|
+
});
|
|
593
|
+
if (!intent.ok || !((_intent_body = intent.body) == null ? void 0 : _intent_body.id) || !((_intent_body1 = intent.body) == null ? void 0 : _intent_body1.client_secret)) {
|
|
594
|
+
return await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
595
|
+
status: 'failed',
|
|
596
|
+
failureMessage: posStripeErrorMessage(intent.body, 'The card payment could not be started.')
|
|
597
|
+
}));
|
|
598
|
+
}
|
|
599
|
+
const updated = payment.paymentIntentId ? reserved : await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
600
|
+
paymentIntentId: String(intent.body.id),
|
|
601
|
+
livemode: Boolean(intent.body.livemode)
|
|
602
|
+
}));
|
|
603
|
+
return _extends({}, updated, {
|
|
604
|
+
clientSecret: String(intent.body.client_secret)
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* The customer pays on their own phone from a QR code: a Stripe payment page
|
|
609
|
+
* for this payment's amount (and tip, as its own line). Settled by
|
|
610
|
+
* `checkout.session.completed` or by the register's poll.
|
|
611
|
+
*/ export async function startCardLinkPayment(start) {
|
|
612
|
+
var _payment_takeFeeCents;
|
|
613
|
+
var _session_body;
|
|
614
|
+
const destination = await posMerchantAccount(start.hostId, start.org);
|
|
615
|
+
if (!destination) return {
|
|
616
|
+
ok: false,
|
|
617
|
+
status: 409,
|
|
618
|
+
error: 'Card payments not set up'
|
|
619
|
+
};
|
|
620
|
+
const reserved = await reserveCardPayment(start, 'card_link', {});
|
|
621
|
+
if (!reserved.ok || !reserved.payment) return reserved;
|
|
622
|
+
const payment = reserved.payment;
|
|
623
|
+
if (payment.checkoutSessionId || payment.status !== 'pending') return reserved;
|
|
624
|
+
const fee = posCardApplicationFeeCents({
|
|
625
|
+
takeShareCents: Number((_payment_takeFeeCents = payment.takeFeeCents) != null ? _payment_takeFeeCents : 0),
|
|
626
|
+
chargeCents: start.amountCents + start.tipCents
|
|
627
|
+
});
|
|
628
|
+
const session = await posStripe('POST', 'checkout/sessions', {
|
|
629
|
+
idempotencyKey: `pos-link:${payment.id}`,
|
|
630
|
+
params: _extends({
|
|
631
|
+
mode: 'payment'
|
|
632
|
+
}, checkoutSessionCardAuthenticationParams('payment'), {
|
|
633
|
+
'payment_method_types': [
|
|
634
|
+
'card'
|
|
635
|
+
],
|
|
636
|
+
'line_items[0][quantity]': 1,
|
|
637
|
+
'line_items[0][price_data][currency]': POS_CURRENCY,
|
|
638
|
+
'line_items[0][price_data][unit_amount]': start.amountCents,
|
|
639
|
+
'line_items[0][price_data][product_data][name]': 'In-store purchase'
|
|
640
|
+
}, start.tipCents > 0 ? {
|
|
641
|
+
'line_items[1][quantity]': 1,
|
|
642
|
+
'line_items[1][price_data][currency]': POS_CURRENCY,
|
|
643
|
+
'line_items[1][price_data][unit_amount]': start.tipCents,
|
|
644
|
+
'line_items[1][price_data][product_data][name]': 'Tip'
|
|
645
|
+
} : {}, {
|
|
646
|
+
'payment_intent_data[transfer_data][destination]': destination
|
|
647
|
+
}, fee > 0 ? {
|
|
648
|
+
'payment_intent_data[application_fee_amount]': fee
|
|
649
|
+
} : {}, {
|
|
650
|
+
'payment_intent_data[metadata][kind]': 'pos',
|
|
651
|
+
'payment_intent_data[metadata][hostId]': start.hostId,
|
|
652
|
+
'payment_intent_data[metadata][orderId]': start.orderId,
|
|
653
|
+
'payment_intent_data[metadata][paymentId]': payment.id,
|
|
654
|
+
'payment_intent_data[metadata][tipCents]': String(start.tipCents),
|
|
655
|
+
success_url: `${start.returnUrl}?paid=1`,
|
|
656
|
+
cancel_url: `${start.returnUrl}?paid=0`,
|
|
657
|
+
'metadata[type]': 'pos-payment',
|
|
658
|
+
'metadata[hostId]': start.hostId,
|
|
659
|
+
'metadata[orderId]': start.orderId,
|
|
660
|
+
'metadata[paymentId]': payment.id
|
|
661
|
+
})
|
|
662
|
+
});
|
|
663
|
+
if (!session.ok || !((_session_body = session.body) == null ? void 0 : _session_body.url)) {
|
|
664
|
+
return await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
665
|
+
status: 'failed',
|
|
666
|
+
failureMessage: posStripeErrorMessage(session.body, 'The payment page could not be created.')
|
|
667
|
+
}));
|
|
668
|
+
}
|
|
669
|
+
return await patchCardPayment(start.hostId, start.orderId, payment.id, (current)=>_extends({}, current, {
|
|
670
|
+
checkoutSessionId: String(session.body.id),
|
|
671
|
+
checkoutUrl: String(session.body.url),
|
|
672
|
+
livemode: Boolean(session.body.livemode)
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
/*==========================================
|
|
676
|
+
* SETTLING A CARD PAYMENT.
|
|
677
|
+
*=========================================*/ /** The card's brand and last four, off the charge Stripe made. */ function cardDetailsOf(intent) {
|
|
678
|
+
var _ref, _ref1, _ref2;
|
|
679
|
+
var _charge_payment_method_details, _charge_payment_method_details1, _charge_payment_method_details2;
|
|
680
|
+
const charge = typeof (intent == null ? void 0 : intent.latest_charge) === 'object' ? intent.latest_charge : null;
|
|
681
|
+
const details = (_ref = (_ref1 = (_ref2 = charge == null ? void 0 : (_charge_payment_method_details = charge.payment_method_details) == null ? void 0 : _charge_payment_method_details.card_present) != null ? _ref2 : charge == null ? void 0 : (_charge_payment_method_details1 = charge.payment_method_details) == null ? void 0 : _charge_payment_method_details1.interac_present) != null ? _ref1 : charge == null ? void 0 : (_charge_payment_method_details2 = charge.payment_method_details) == null ? void 0 : _charge_payment_method_details2.card) != null ? _ref : null;
|
|
682
|
+
return _extends({}, (details == null ? void 0 : details.brand) ? {
|
|
683
|
+
cardBrand: String(details.brand)
|
|
684
|
+
} : {}, (details == null ? void 0 : details.last4) ? {
|
|
685
|
+
last4: String(details.last4)
|
|
686
|
+
} : {});
|
|
687
|
+
}
|
|
688
|
+
/** The tip on an intent: what the display chose plus what the reader added. */ export function posIntentTipCents(intent) {
|
|
689
|
+
var _ref, _ref1;
|
|
690
|
+
var _intent_metadata, _intent_amount_details_tip, _intent_amount_details;
|
|
691
|
+
const preset = Math.max(0, Math.round(Number((_ref = intent == null ? void 0 : (_intent_metadata = intent.metadata) == null ? void 0 : _intent_metadata.tipCents) != null ? _ref : 0)) || 0);
|
|
692
|
+
const onReader = Math.max(0, Math.round(Number((_ref1 = intent == null ? void 0 : (_intent_amount_details = intent.amount_details) == null ? void 0 : (_intent_amount_details_tip = _intent_amount_details.tip) == null ? void 0 : _intent_amount_details_tip.amount) != null ? _ref1 : 0)) || 0);
|
|
693
|
+
return preset + onReader;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* The fee a register card charge is captured with: the payment's share of the
|
|
697
|
+
* take (fixed at reservation, the sale's share and never the tip's) plus the
|
|
698
|
+
* card processing cost on the whole amount, tip included.
|
|
699
|
+
*/ export function posCaptureFeeCents(payment, intent) {
|
|
700
|
+
var _payment_takeFeeCents, _ref;
|
|
701
|
+
return posCardApplicationFeeCents({
|
|
702
|
+
takeShareCents: Number((_payment_takeFeeCents = payment.takeFeeCents) != null ? _payment_takeFeeCents : 0),
|
|
703
|
+
chargeCents: Math.max(0, Math.round(Number((_ref = intent == null ? void 0 : intent.amount) != null ? _ref : 0)))
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Brings one card payment up to date with Stripe, from a webhook or the
|
|
708
|
+
* register's poll alike: captures an authorized reader payment with its final
|
|
709
|
+
* fee, records a success, a decline or a cancellation. Idempotent: the
|
|
710
|
+
* capture is keyed by the intent, and the ledger change is a no-op when the
|
|
711
|
+
* payment already says what Stripe says.
|
|
712
|
+
*/ export async function refreshPosCardPayment(input) {
|
|
713
|
+
var _payment_paymentIntentId, _CommerceModel_orderPayments_find;
|
|
714
|
+
var _intent_metadata, _intent_metadata1;
|
|
715
|
+
const order = await readPosSale(input.hostId, input.orderId);
|
|
716
|
+
if (!order) return {
|
|
717
|
+
ok: false,
|
|
718
|
+
status: 404,
|
|
719
|
+
error: 'Unknown sale'
|
|
720
|
+
};
|
|
721
|
+
const payment = CommerceModel.orderPayments(order).find((entry)=>entry.id === input.paymentId);
|
|
722
|
+
if (!payment) return {
|
|
723
|
+
ok: false,
|
|
724
|
+
status: 404,
|
|
725
|
+
error: 'Unknown payment'
|
|
726
|
+
};
|
|
727
|
+
if (!CommerceModel.isCardPaymentMethod(payment.method)) {
|
|
728
|
+
return {
|
|
729
|
+
ok: true,
|
|
730
|
+
order,
|
|
731
|
+
payment,
|
|
732
|
+
completed: false,
|
|
733
|
+
changed: false
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
let paymentIntentId = (_payment_paymentIntentId = payment.paymentIntentId) != null ? _payment_paymentIntentId : '';
|
|
737
|
+
if (!paymentIntentId && payment.checkoutSessionId) {
|
|
738
|
+
var _ref;
|
|
739
|
+
var _session_body, _session_body1;
|
|
740
|
+
const session = await posStripe('GET', `checkout/sessions/${payment.checkoutSessionId}`);
|
|
741
|
+
if (session.ok && ((_session_body = session.body) == null ? void 0 : _session_body.status) === 'expired' && payment.status === 'pending') {
|
|
742
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>current.status === 'pending' ? _extends({}, current, {
|
|
743
|
+
status: 'canceled'
|
|
744
|
+
}) : null);
|
|
745
|
+
}
|
|
746
|
+
paymentIntentId = String((_ref = (_session_body1 = session.body) == null ? void 0 : _session_body1.payment_intent) != null ? _ref : '');
|
|
747
|
+
}
|
|
748
|
+
if (!paymentIntentId) return {
|
|
749
|
+
ok: true,
|
|
750
|
+
order,
|
|
751
|
+
payment,
|
|
752
|
+
completed: false,
|
|
753
|
+
changed: false
|
|
754
|
+
};
|
|
755
|
+
let intent = (await posStripe('GET', `payment_intents/${paymentIntentId}`, {
|
|
756
|
+
params: {
|
|
757
|
+
'expand[]': 'latest_charge'
|
|
758
|
+
}
|
|
759
|
+
})).body;
|
|
760
|
+
if (!(intent == null ? void 0 : intent.id)) return {
|
|
761
|
+
ok: true,
|
|
762
|
+
order,
|
|
763
|
+
payment,
|
|
764
|
+
completed: false,
|
|
765
|
+
changed: false
|
|
766
|
+
};
|
|
767
|
+
if (((_intent_metadata = intent.metadata) == null ? void 0 : _intent_metadata.hostId) !== input.hostId || ((_intent_metadata1 = intent.metadata) == null ? void 0 : _intent_metadata1.paymentId) !== payment.id) {
|
|
768
|
+
console.error('[pos-terminal] intent does not belong to this payment', paymentIntentId);
|
|
769
|
+
return {
|
|
770
|
+
ok: false,
|
|
771
|
+
status: 409,
|
|
772
|
+
error: 'This payment does not match its card charge.'
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
if (intent.status === 'requires_capture') {
|
|
776
|
+
var _captured_body;
|
|
777
|
+
if (order.status !== 'pending' && payment.status !== 'pending') {
|
|
778
|
+
// Nothing to capture into: the sale is gone. Release the hold.
|
|
779
|
+
await posStripe('POST', `payment_intents/${intent.id}/cancel`, {
|
|
780
|
+
idempotencyKey: `pos-release:${intent.id}`
|
|
781
|
+
});
|
|
782
|
+
return {
|
|
783
|
+
ok: true,
|
|
784
|
+
order,
|
|
785
|
+
payment,
|
|
786
|
+
completed: false,
|
|
787
|
+
changed: false
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
const fee = posCaptureFeeCents(payment, intent);
|
|
791
|
+
const captured = await posStripe('POST', `payment_intents/${intent.id}/capture`, {
|
|
792
|
+
idempotencyKey: `pos-capture:${intent.id}`,
|
|
793
|
+
params: _extends({}, fee > 0 ? {
|
|
794
|
+
application_fee_amount: fee
|
|
795
|
+
} : {}, {
|
|
796
|
+
'expand[]': 'latest_charge'
|
|
797
|
+
})
|
|
798
|
+
});
|
|
799
|
+
if (captured.ok && ((_captured_body = captured.body) == null ? void 0 : _captured_body.id)) intent = captured.body;
|
|
800
|
+
else {
|
|
801
|
+
var _captured_body1;
|
|
802
|
+
console.error('[pos-terminal] capture failed', intent.id, (_captured_body1 = captured.body) == null ? void 0 : _captured_body1.error);
|
|
803
|
+
return {
|
|
804
|
+
ok: true,
|
|
805
|
+
order,
|
|
806
|
+
payment,
|
|
807
|
+
completed: false,
|
|
808
|
+
changed: false
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
if (intent.status === 'succeeded') {
|
|
813
|
+
var _intent_amount;
|
|
814
|
+
const tipCents = posIntentTipCents(intent);
|
|
815
|
+
const amountCents = Math.max(0, Math.round(Number((_intent_amount = intent.amount) != null ? _intent_amount : 0))) - tipCents;
|
|
816
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>{
|
|
817
|
+
var _intent_application_fee_amount;
|
|
818
|
+
if (current.status === 'succeeded' && current.paymentIntentId === intent.id) return null;
|
|
819
|
+
return _extends({}, withoutFailure(current), {
|
|
820
|
+
status: 'succeeded',
|
|
821
|
+
settledAtMs: Date.now(),
|
|
822
|
+
paymentIntentId: String(intent.id),
|
|
823
|
+
// What the charge actually put toward the sale. Equal to the
|
|
824
|
+
// reserved amount; restated from Stripe so the ledger records the
|
|
825
|
+
// money that moved rather than the money that was asked for.
|
|
826
|
+
amountCents: amountCents > 0 ? amountCents : current.amountCents
|
|
827
|
+
}, tipCents > 0 ? {
|
|
828
|
+
tipCents
|
|
829
|
+
} : {}, {
|
|
830
|
+
feeCents: Math.max(0, Math.round(Number((_intent_application_fee_amount = intent.application_fee_amount) != null ? _intent_application_fee_amount : 0))),
|
|
831
|
+
livemode: Boolean(intent.livemode)
|
|
832
|
+
}, cardDetailsOf(intent));
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
if (intent.status === 'canceled') {
|
|
836
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>current.status === 'pending' || current.status === 'failed' ? _extends({}, current, {
|
|
837
|
+
status: 'canceled'
|
|
838
|
+
}) : null);
|
|
839
|
+
}
|
|
840
|
+
if (intent.status === 'requires_payment_method' && intent.last_payment_error) {
|
|
841
|
+
var _ref1;
|
|
842
|
+
var _intent_last_payment_error;
|
|
843
|
+
const message = String((_ref1 = (_intent_last_payment_error = intent.last_payment_error) == null ? void 0 : _intent_last_payment_error.message) != null ? _ref1 : 'The card was declined.');
|
|
844
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>current.status === 'pending' ? _extends({}, current, {
|
|
845
|
+
status: 'failed',
|
|
846
|
+
failureMessage: message
|
|
847
|
+
}) : null);
|
|
848
|
+
}
|
|
849
|
+
// Still waiting on the customer. A reader action that already failed (a
|
|
850
|
+
// card removed, a cancel on the reader) says so on the reader, not the
|
|
851
|
+
// intent, so ask the reader too.
|
|
852
|
+
if (payment.method === 'card_present' && payment.readerId && payment.status === 'pending') {
|
|
853
|
+
var _action_process_payment_intent;
|
|
854
|
+
const reader = await refreshPosReaderStatus(input.hostId, payment.readerId);
|
|
855
|
+
const action = reader == null ? void 0 : reader.action;
|
|
856
|
+
if ((action == null ? void 0 : action.type) === 'process_payment_intent' && (action == null ? void 0 : (_action_process_payment_intent = action.process_payment_intent) == null ? void 0 : _action_process_payment_intent.payment_intent) === intent.id && (action == null ? void 0 : action.status) === 'failed') {
|
|
857
|
+
var _action_failure_message;
|
|
858
|
+
const message = String((_action_failure_message = action.failure_message) != null ? _action_failure_message : 'The reader could not take the card.');
|
|
859
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>current.status === 'pending' ? _extends({}, current, {
|
|
860
|
+
status: 'failed',
|
|
861
|
+
failureMessage: message
|
|
862
|
+
}) : null);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
const fresh = await readPosSale(input.hostId, input.orderId);
|
|
866
|
+
return {
|
|
867
|
+
ok: true,
|
|
868
|
+
order: fresh != null ? fresh : order,
|
|
869
|
+
payment: (_CommerceModel_orderPayments_find = CommerceModel.orderPayments(fresh != null ? fresh : order).find((entry)=>entry.id === payment.id)) != null ? _CommerceModel_orderPayments_find : payment,
|
|
870
|
+
completed: false,
|
|
871
|
+
changed: false
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Stops a card payment that has not been paid: clears the reader, cancels the
|
|
876
|
+
* intent, expires the payment page. A charge that already went through is
|
|
877
|
+
* left alone and recorded as paid, never cancelled under the customer.
|
|
878
|
+
*/ export async function cancelPosCardPayment(input) {
|
|
879
|
+
var _settled_payment;
|
|
880
|
+
const refreshed = await refreshPosCardPayment(input);
|
|
881
|
+
if (!refreshed.ok || !refreshed.payment) return refreshed;
|
|
882
|
+
const payment = refreshed.payment;
|
|
883
|
+
if (payment.status === 'succeeded' || payment.status === 'canceled') return refreshed;
|
|
884
|
+
if (payment.method === 'card_present' && payment.readerId) {
|
|
885
|
+
var _cleared_body_error, _cleared_body;
|
|
886
|
+
const cleared = await posStripe('POST', `terminal/readers/${payment.readerId}/cancel_action`);
|
|
887
|
+
if (!cleared.ok && ((_cleared_body = cleared.body) == null ? void 0 : (_cleared_body_error = _cleared_body.error) == null ? void 0 : _cleared_body_error.code) === 'terminal_reader_busy') {
|
|
888
|
+
return {
|
|
889
|
+
ok: false,
|
|
890
|
+
status: 409,
|
|
891
|
+
error: 'The customer is mid-payment on the reader. Wait for it to finish.'
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
if (payment.paymentIntentId) {
|
|
896
|
+
await posStripe('POST', `payment_intents/${payment.paymentIntentId}/cancel`, {
|
|
897
|
+
idempotencyKey: `pos-cancel:${payment.paymentIntentId}`
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
if (payment.checkoutSessionId) {
|
|
901
|
+
await posStripe('POST', `checkout/sessions/${payment.checkoutSessionId}/expire`, {
|
|
902
|
+
idempotencyKey: `pos-expire:${payment.checkoutSessionId}`
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
// Re-read: a payment that completed in the gap is recorded as paid.
|
|
906
|
+
const settled = await refreshPosCardPayment(input);
|
|
907
|
+
if (settled.ok && ((_settled_payment = settled.payment) == null ? void 0 : _settled_payment.status) === 'succeeded') return settled;
|
|
908
|
+
return await patchCardPayment(input.hostId, input.orderId, payment.id, (current)=>current.status === 'pending' || current.status === 'failed' ? _extends({}, current, {
|
|
909
|
+
status: 'canceled'
|
|
910
|
+
}) : null);
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* TEST MODE ONLY: Stripe's simulated reader is "tapped" with a test card.
|
|
914
|
+
* Refused outright on a live key, whatever the request says.
|
|
915
|
+
*/ export async function simulatePosReaderTap(input) {
|
|
916
|
+
if (!posStripeTestMode()) return {
|
|
917
|
+
ok: false,
|
|
918
|
+
status: 403,
|
|
919
|
+
error: 'Only in test mode'
|
|
920
|
+
};
|
|
921
|
+
const order = await readPosSale(input.hostId, input.orderId);
|
|
922
|
+
if (!order) return {
|
|
923
|
+
ok: false,
|
|
924
|
+
status: 404,
|
|
925
|
+
error: 'Unknown sale'
|
|
926
|
+
};
|
|
927
|
+
const payment = CommerceModel.orderPayments(order).find((entry)=>entry.id === input.paymentId);
|
|
928
|
+
if (!(payment == null ? void 0 : payment.readerId) || payment.method !== 'card_present') {
|
|
929
|
+
return {
|
|
930
|
+
ok: false,
|
|
931
|
+
status: 404,
|
|
932
|
+
error: 'Unknown payment'
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
const reader = await ownedTerminalReader(input.hostId, payment.readerId);
|
|
936
|
+
if (!reader) return {
|
|
937
|
+
ok: false,
|
|
938
|
+
status: 404,
|
|
939
|
+
error: 'That card reader is not on this site.'
|
|
940
|
+
};
|
|
941
|
+
const presented = await posStripe('POST', `test_helpers/terminal/readers/${reader.id}/present_payment_method`, {
|
|
942
|
+
params: _extends({
|
|
943
|
+
type: 'card_present'
|
|
944
|
+
}, input.cardNumber && /^[0-9]{12,19}$/.test(input.cardNumber) ? {
|
|
945
|
+
'card_present[number]': input.cardNumber
|
|
946
|
+
} : {})
|
|
947
|
+
});
|
|
948
|
+
if (!presented.ok) {
|
|
949
|
+
return {
|
|
950
|
+
ok: false,
|
|
951
|
+
status: 502,
|
|
952
|
+
error: posStripeErrorMessage(presented.body, 'The simulated tap failed.')
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
return await refreshPosCardPayment(input);
|
|
956
|
+
}
|
|
957
|
+
/*==========================================
|
|
958
|
+
* WEBHOOKS (the small branch `billing-webhook.ts` calls).
|
|
959
|
+
*=========================================*/ /** Where a Stripe object says a register payment lives, or null. */ function posPaymentRef(metadata) {
|
|
960
|
+
var _ref, _ref1, _ref2;
|
|
961
|
+
const hostId = String((_ref = metadata == null ? void 0 : metadata['hostId']) != null ? _ref : '');
|
|
962
|
+
const orderId = String((_ref1 = metadata == null ? void 0 : metadata['orderId']) != null ? _ref1 : '');
|
|
963
|
+
const paymentId = String((_ref2 = metadata == null ? void 0 : metadata['paymentId']) != null ? _ref2 : '');
|
|
964
|
+
if (!hostId || !orderId || !paymentId) return null;
|
|
965
|
+
return {
|
|
966
|
+
hostId,
|
|
967
|
+
orderId,
|
|
968
|
+
paymentId
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* The register's Stripe events: a reader finished or failed an action, a
|
|
973
|
+
* register PaymentIntent was authorized, paid, declined or cancelled, or a
|
|
974
|
+
* register QR page was paid or expired. Each resolves to ONE payment and is
|
|
975
|
+
* answered by re-reading Stripe through {@link refreshPosCardPayment}, never
|
|
976
|
+
* by trusting the event's own copy (whose API version predates the tip
|
|
977
|
+
* fields). Returns the site when the event was the register's, so the
|
|
978
|
+
* dispatcher can count it as claimed; null for every other event.
|
|
979
|
+
*/ export async function handlePosStripeEvent(input) {
|
|
980
|
+
var _object_metadata;
|
|
981
|
+
const { type, object } = input;
|
|
982
|
+
let ref = null;
|
|
983
|
+
if (type === 'terminal.reader.action_succeeded' || type === 'terminal.reader.action_failed') {
|
|
984
|
+
var _ref;
|
|
985
|
+
var _object_action_process_payment_intent, _object_action, _object_action1, _intent_body_metadata, _intent_body;
|
|
986
|
+
const intentId = String((_ref = object == null ? void 0 : (_object_action = object.action) == null ? void 0 : (_object_action_process_payment_intent = _object_action.process_payment_intent) == null ? void 0 : _object_action_process_payment_intent.payment_intent) != null ? _ref : '');
|
|
987
|
+
if ((object == null ? void 0 : (_object_action1 = object.action) == null ? void 0 : _object_action1.type) !== 'process_payment_intent' || !intentId) return null;
|
|
988
|
+
const intent = await posStripe('GET', `payment_intents/${intentId}`);
|
|
989
|
+
if (!intent.ok || ((_intent_body = intent.body) == null ? void 0 : (_intent_body_metadata = _intent_body.metadata) == null ? void 0 : _intent_body_metadata.kind) !== 'pos') return null;
|
|
990
|
+
ref = posPaymentRef(intent.body.metadata);
|
|
991
|
+
} else if (type === 'payment_intent.amount_capturable_updated' || type === 'payment_intent.succeeded' || type === 'payment_intent.payment_failed' || type === 'payment_intent.canceled') {
|
|
992
|
+
var _object_metadata1;
|
|
993
|
+
if ((object == null ? void 0 : (_object_metadata1 = object.metadata) == null ? void 0 : _object_metadata1.kind) !== 'pos') return null;
|
|
994
|
+
ref = posPaymentRef(object.metadata);
|
|
995
|
+
} else if ((type === 'checkout.session.completed' || type === 'checkout.session.expired') && (object == null ? void 0 : (_object_metadata = object.metadata) == null ? void 0 : _object_metadata.type) === 'pos-payment') {
|
|
996
|
+
ref = posPaymentRef(object.metadata);
|
|
997
|
+
} else {
|
|
998
|
+
return null;
|
|
999
|
+
}
|
|
1000
|
+
if (!ref) return null;
|
|
1001
|
+
// A reader can be re-registered by nobody else, but an event is only a
|
|
1002
|
+
// claim: the intent's own metadata must name a reader this site owns.
|
|
1003
|
+
await refreshPosCardPayment(ref).catch((error)=>{
|
|
1004
|
+
console.error('[pos-terminal] webhook settle failed', ref, error);
|
|
1005
|
+
// Rethrown so the delivery is retried: a lost settlement is a sale the
|
|
1006
|
+
// register cannot complete without its poll.
|
|
1007
|
+
throw error;
|
|
1008
|
+
});
|
|
1009
|
+
return {
|
|
1010
|
+
hostId: ref.hostId
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
//# sourceMappingURL=pos-terminal.js.map
|