@final-commerce/command-frame 0.10.0 → 0.10.1-online.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/CommonTypes.d.ts +18 -1
  2. package/dist/actions/attach-checkout-contact/action.d.ts +6 -0
  3. package/dist/actions/attach-checkout-contact/action.js +8 -0
  4. package/dist/actions/attach-checkout-contact/mock.d.ts +15 -0
  5. package/dist/actions/attach-checkout-contact/mock.js +22 -0
  6. package/dist/actions/attach-checkout-contact/types.d.ts +35 -0
  7. package/dist/actions/attach-checkout-contact/types.js +16 -0
  8. package/dist/actions/get-address-options/action.d.ts +6 -0
  9. package/dist/actions/get-address-options/action.js +8 -0
  10. package/dist/actions/get-address-options/mock.d.ts +3 -0
  11. package/dist/actions/get-address-options/mock.js +15 -0
  12. package/dist/actions/get-address-options/types.d.ts +25 -0
  13. package/dist/actions/get-address-options/types.js +8 -0
  14. package/dist/actions/get-checkout-status/action.d.ts +6 -0
  15. package/dist/actions/get-checkout-status/action.js +8 -0
  16. package/dist/actions/get-checkout-status/mock.d.ts +3 -0
  17. package/dist/actions/get-checkout-status/mock.js +11 -0
  18. package/dist/actions/get-checkout-status/types.d.ts +20 -0
  19. package/dist/actions/get-checkout-status/types.js +12 -0
  20. package/dist/actions/get-outlets/action.js +2 -2
  21. package/dist/actions/get-outlets/mock.d.ts +12 -0
  22. package/dist/actions/get-outlets/mock.js +28 -4
  23. package/dist/actions/get-outlets/types.d.ts +19 -1
  24. package/dist/actions/get-product-modifier-selections/mock.js +7 -0
  25. package/dist/actions/get-product-modifier-selections/types.d.ts +4 -0
  26. package/dist/actions/get-products/types.d.ts +8 -8
  27. package/dist/actions/get-refund-plan/mockRows.js +1 -1
  28. package/dist/actions/get-refund-plan/types.d.ts +9 -6
  29. package/dist/actions/get-remaining-refundable-quantities/mock.js +1 -0
  30. package/dist/actions/get-remaining-refundable-quantities/types.d.ts +5 -0
  31. package/dist/actions/get-shipping-options/action.d.ts +6 -0
  32. package/dist/actions/get-shipping-options/action.js +8 -0
  33. package/dist/actions/get-shipping-options/mock.d.ts +3 -0
  34. package/dist/actions/get-shipping-options/mock.js +15 -0
  35. package/dist/actions/get-shipping-options/types.d.ts +43 -0
  36. package/dist/actions/get-shipping-options/types.js +1 -0
  37. package/dist/actions/process-partial-refund/types.d.ts +1 -1
  38. package/dist/actions/resume-checkout/action.d.ts +6 -0
  39. package/dist/actions/resume-checkout/action.js +8 -0
  40. package/dist/actions/resume-checkout/mock.d.ts +16 -0
  41. package/dist/actions/resume-checkout/mock.js +51 -0
  42. package/dist/actions/resume-checkout/types.d.ts +59 -0
  43. package/dist/actions/resume-checkout/types.js +13 -0
  44. package/dist/actions/select-shipping-option/action.d.ts +6 -0
  45. package/dist/actions/select-shipping-option/action.js +8 -0
  46. package/dist/actions/select-shipping-option/mock.d.ts +3 -0
  47. package/dist/actions/select-shipping-option/mock.js +31 -0
  48. package/dist/actions/select-shipping-option/types.d.ts +15 -0
  49. package/dist/actions/select-shipping-option/types.js +1 -0
  50. package/dist/actions/set-order-address/action.d.ts +6 -0
  51. package/dist/actions/set-order-address/action.js +8 -0
  52. package/dist/actions/set-order-address/mock.d.ts +7 -0
  53. package/dist/actions/set-order-address/mock.js +29 -0
  54. package/dist/actions/set-order-address/types.d.ts +19 -0
  55. package/dist/actions/set-order-address/types.js +1 -0
  56. package/dist/actions/set-outlet/action.d.ts +6 -0
  57. package/dist/actions/set-outlet/action.js +8 -0
  58. package/dist/actions/set-outlet/mock.d.ts +13 -0
  59. package/dist/actions/set-outlet/mock.js +24 -0
  60. package/dist/actions/set-outlet/types.d.ts +31 -0
  61. package/dist/actions/set-outlet/types.js +21 -0
  62. package/dist/actions/start-checkout/action.d.ts +6 -0
  63. package/dist/actions/start-checkout/action.js +8 -0
  64. package/dist/actions/start-checkout/mock.d.ts +16 -0
  65. package/dist/actions/start-checkout/mock.js +80 -0
  66. package/dist/actions/start-checkout/types.d.ts +90 -0
  67. package/dist/actions/start-checkout/types.js +10 -0
  68. package/dist/demo/shipping.d.ts +8 -0
  69. package/dist/demo/shipping.js +69 -0
  70. package/dist/index.d.ts +21 -1
  71. package/dist/index.js +19 -0
  72. package/dist/projects/render/mocks.js +20 -0
  73. package/dist/projects/render/types.d.ts +23 -1
  74. package/dist/pubsub/topics/checkout/checkout-started/types.d.ts +26 -0
  75. package/dist/pubsub/topics/checkout/checkout-started/types.js +1 -0
  76. package/dist/pubsub/topics/checkout/index.d.ts +7 -0
  77. package/dist/pubsub/topics/checkout/index.js +28 -0
  78. package/dist/pubsub/topics/checkout/payment-completed/types.d.ts +31 -0
  79. package/dist/pubsub/topics/checkout/payment-completed/types.js +1 -0
  80. package/dist/pubsub/topics/checkout/payment-failed/types.d.ts +20 -0
  81. package/dist/pubsub/topics/checkout/payment-failed/types.js +1 -0
  82. package/dist/pubsub/topics/checkout/types.d.ts +12 -0
  83. package/dist/pubsub/topics/checkout/types.js +8 -0
  84. package/dist/pubsub/topics/index.d.ts +18 -17
  85. package/dist/pubsub/topics/index.js +18 -17
  86. package/dist/pubsub/topics/types.d.ts +8 -0
  87. package/package.json +2 -2
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Guest contact for the order. There is no shopper account, so this is the only
3
+ * way to reach them — `email` is where the receipt goes and is required.
4
+ */
5
+ export interface StartCheckoutContact {
6
+ email: string;
7
+ name?: string;
8
+ phone?: string;
9
+ }
10
+ export interface StartCheckoutParams {
11
+ /**
12
+ * OPTIONAL, because checkout starts when the shopper ARRIVES rather than when
13
+ * they submit a form. The card fields cannot render without a payment session,
14
+ * a session needs a server-priced amount, and an amount needs an order — so the
15
+ * order has to exist before they have typed anything.
16
+ *
17
+ * Supply it afterwards with `attachCheckoutContact`, which re-sends the same
18
+ * idempotency key and so reaches the SAME order.
19
+ */
20
+ contact?: StartCheckoutContact;
21
+ /**
22
+ * CSS SELECTOR for the element the payment fields mount into, e.g.
23
+ * `'#card-fields'`. The element must already be in the DOM when this is
24
+ * called.
25
+ *
26
+ * A SELECTOR, NOT AN ELEMENT — and this is not a style preference. Command
27
+ * params cross a `postMessage` boundary, which serializes them with the
28
+ * structured clone algorithm; a DOM node is not cloneable, so passing
29
+ * `ref.current` throws `DataCloneError: HTMLDivElement object could not be
30
+ * cloned` before the command is ever sent. The string is resolved on the
31
+ * runtime's side against the same document the page rendered.
32
+ */
33
+ container: string;
34
+ /**
35
+ * Where the provider returns the shopper after a redirect payment method
36
+ * (bank apps, wallets). Defaults to the current URL.
37
+ *
38
+ * Must be HTTPS and on the SAME ORIGIN the storefront token was minted for;
39
+ * the server rejects anything else, since this URL is handed to a payment
40
+ * provider and an open redirect on a checkout is a phishing primitive.
41
+ */
42
+ returnUrl?: string;
43
+ /**
44
+ * Overrides the cart-derived idempotency key. Leave unset: the default is
45
+ * derived from the cart, which is what makes a shopper's double-tap on "Pay"
46
+ * return the SAME order instead of creating a second, abandoned one.
47
+ */
48
+ idempotencyKey?: string;
49
+ /** Defaults to the outlet the storefront booted against. */
50
+ outletId?: string;
51
+ /** Forwarded verbatim to the provider's Drop-in (`showPayButton`, `locale`, field styling, …). */
52
+ dropinConfiguration?: Record<string, unknown>;
53
+ }
54
+ /**
55
+ * The created order. Deliberately says nothing about money having moved — see
56
+ * `paymentStatus` and the `checkout` topic.
57
+ */
58
+ export interface StartCheckoutOrder {
59
+ orderId: string;
60
+ receiptId: string;
61
+ /** The SERVER-computed total in integer minor units — the only total that matters. */
62
+ serverTotal: number;
63
+ currency: string;
64
+ /**
65
+ * `ready` — the payment fields are mounted and the shopper can pay.
66
+ * `unavailable` — THE ORDER EXISTS but no payment could be started, so the
67
+ * shopper has NOT been charged. Never report this as a failed order.
68
+ */
69
+ paymentStatus: 'ready' | 'unavailable';
70
+ /**
71
+ * One-time password for reading this order back, returned only on the first
72
+ * create. It is the ONLY route to this order's status — the guest token
73
+ * grants order creation and deliberately not order reads — so a caller that
74
+ * drops it cannot check whether the payment settled.
75
+ */
76
+ orderPassword?: string;
77
+ }
78
+ export interface StartCheckoutResponse {
79
+ success: boolean;
80
+ timestamp: string;
81
+ order: StartCheckoutOrder;
82
+ }
83
+ /**
84
+ * Creates the server-priced order and mounts the provider's hosted card fields.
85
+ *
86
+ * RESOLVES WHEN THE SHOPPER *CAN* PAY, NOT WHEN THEY HAVE. The shopper has not
87
+ * typed a card yet when this returns. The outcome arrives on the `checkout`
88
+ * topic instead.
89
+ */
90
+ export type StartCheckout = (params: StartCheckoutParams) => Promise<StartCheckoutResponse>;
@@ -0,0 +1,10 @@
1
+ // Start Checkout Types
2
+ //
3
+ // The ONLINE counterpart of the POS tenders: a shopper on a published website
4
+ // pays for the current cart with their own card. Mirrors kaching's storefront
5
+ // `startCheckout` input and result. All money is integer MINOR currency units.
6
+ //
7
+ // This command is served ONLY by the storefront runtime (a published website).
8
+ // On a register it does not exist, exactly as the till tenders (`cashPayment`,
9
+ // `terminalPayment`, `tapToPayPayment`, `chargeMoto`) do not exist online.
10
+ export {};
@@ -0,0 +1,8 @@
1
+ import { type ShippingZoneRule } from '@final-commerce/common';
2
+ import type { ShippingOptionView } from '../actions/get-shipping-options/types';
3
+ export declare const MOCK_SHIPPING_ZONES: ShippingZoneRule[];
4
+ /** The demo cart's options, shaped like the runtime's answer. The mock runs as the website. */
5
+ export declare function mockShippingOptions(): {
6
+ resolution: import("@final-commerce/common").ShippingResolution;
7
+ options: ShippingOptionView[];
8
+ };
@@ -0,0 +1,69 @@
1
+ import { resolveShipping } from '@final-commerce/common';
2
+ import { MOCK_CART, MOCK_OUTLET_MAIN } from './database';
3
+ /*
4
+ * The demo store's Settings › Shipping, so a flow previewed against the mocks meets the real rules
5
+ * (common's `resolveShipping`) rather than a canned list: Canada $10 (free over $100) or Express,
6
+ * Quebec at $15, pickup at the demo store, and nowhere else.
7
+ */
8
+ export const MOCK_SHIPPING_ZONES = [
9
+ {
10
+ id: 'zone_canada',
11
+ kind: 'country',
12
+ places: [{ country: 'CA' }],
13
+ ships: true,
14
+ options: [
15
+ {
16
+ id: 'opt_standard',
17
+ type: 'ship',
18
+ name: 'Standard shipping',
19
+ price: 1000,
20
+ freeOver: 10000,
21
+ minDays: 3,
22
+ maxDays: 6,
23
+ channels: ['web', 'pos'],
24
+ },
25
+ { id: 'opt_express', type: 'ship', name: 'Express', price: 2000, minDays: 1, maxDays: 2, channels: ['web'] },
26
+ { id: 'opt_pickup', type: 'pickup', price: 0, channels: ['web'], outletId: MOCK_OUTLET_MAIN.id },
27
+ ],
28
+ },
29
+ {
30
+ id: 'zone_quebec',
31
+ kind: 'province',
32
+ places: [{ country: 'CA', province: 'QC' }],
33
+ ships: true,
34
+ options: [
35
+ {
36
+ id: 'opt_quebec',
37
+ type: 'ship',
38
+ name: 'Standard shipping',
39
+ price: 1500,
40
+ minDays: 4,
41
+ maxDays: 7,
42
+ channels: ['web', 'pos'],
43
+ },
44
+ ],
45
+ },
46
+ ];
47
+ const STORE_NAME = MOCK_OUTLET_MAIN.name ?? 'the store';
48
+ const money = (amount) => (amount === 0 ? 'Free' : `$${(amount / 100).toFixed(2)}`);
49
+ /** The demo cart's options, shaped like the runtime's answer. The mock runs as the website. */
50
+ export function mockShippingOptions() {
51
+ const resolution = resolveShipping({
52
+ zones: MOCK_SHIPPING_ZONES,
53
+ address: MOCK_CART.shippingAddress,
54
+ itemsTotal: MOCK_CART.subtotal,
55
+ channel: 'web',
56
+ });
57
+ const options = resolution.options.map((option) => ({
58
+ optionId: option.optionId,
59
+ type: option.type,
60
+ name: option.type === 'pickup' ? `Pickup at ${STORE_NAME}` : (option.name ?? ''),
61
+ amount: option.amount,
62
+ priceText: money(option.amount),
63
+ freeShippingHint: option.amountToFree ? `Add ${money(option.amountToFree)} more for free shipping` : null,
64
+ arrivalText: option.minDays != null ? `Arrives in ${option.minDays}–${option.maxDays} business days` : null,
65
+ pickup: option.type === 'pickup' ? { outletId: MOCK_OUTLET_MAIN.id, name: STORE_NAME, hours: [] } : null,
66
+ selected: MOCK_CART.shipping?.optionId === option.optionId,
67
+ }));
68
+ return { resolution, options };
69
+ }
package/dist/index.d.ts CHANGED
@@ -56,6 +56,15 @@ export declare const command: {
56
56
  readonly integrationPayment: import(".").IntegrationPayment;
57
57
  readonly createPaymentLink: import(".").CreatePaymentLink;
58
58
  readonly chargeMoto: import(".").ChargeMoto;
59
+ readonly startCheckout: import(".").StartCheckout;
60
+ readonly attachCheckoutContact: import(".").AttachCheckoutContact;
61
+ readonly getAddressOptions: import(".").GetAddressOptions;
62
+ readonly setOrderAddress: import(".").SetOrderAddress;
63
+ readonly getShippingOptions: import(".").GetShippingOptions;
64
+ readonly selectShippingOption: import(".").SelectShippingOption;
65
+ readonly setOutlet: import(".").SetOutlet;
66
+ readonly resumeCheckout: import(".").ResumeCheckout;
67
+ readonly getCheckoutStatus: import(".").GetCheckoutStatus;
59
68
  readonly addCustomerNote: import(".").AddCustomerNote;
60
69
  readonly removeCustomerNote: import(".").RemoveCustomerNote;
61
70
  readonly removeCustomerFromCart: import(".").RemoveCustomerFromCart;
@@ -151,7 +160,7 @@ export type { AddProduct, AddProductParams, AddProductResponse } from './actions
151
160
  export type { EditProduct, EditProductParams, EditProductResponse } from './actions/edit-product/types';
152
161
  export type { EditProductVariants, EditProductVariantsParams, EditProductVariantsResponse, } from './actions/edit-product-variants/types';
153
162
  export type { DeleteProduct, DeleteProductParams, DeleteProductResponse } from './actions/delete-product/types';
154
- export type { GetOutlets, GetOutletsResponse } from './actions/get-outlets/types';
163
+ export type { GetOutlets, GetOutletsParams, GetOutletsResponse } from './actions/get-outlets/types';
155
164
  export type { GetStations, GetStationsParams, GetStationsResponse } from './actions/get-stations/types';
156
165
  export type { GetSmartGridLayout, GetSmartGridLayoutParams, GetSmartGridLayoutResponse, } from './actions/get-smart-grid-layout/types';
157
166
  export type { SaveSmartGridLayout, SaveSmartGridLayoutParams, SaveSmartGridLayoutResponse, } from './actions/save-smart-grid-layout/types';
@@ -204,6 +213,15 @@ export type { RedeemPayment, RedeemPaymentParams, RedeemPaymentResponse } from '
204
213
  export type { IntegrationPayment, IntegrationPaymentParams, IntegrationPaymentResponse, IntegrationEmvData, } from './actions/integration-payment/types';
205
214
  export type { CreatePaymentLink, CreatePaymentLinkParams, CreatePaymentLinkResponse, } from './actions/create-payment-link/types';
206
215
  export type { ChargeMoto, ChargeMotoParams, ChargeMotoResponse, ChargeMotoCardFields, } from './actions/charge-moto/types';
216
+ export type { StartCheckout, StartCheckoutParams, StartCheckoutResponse, StartCheckoutContact, StartCheckoutOrder, } from './actions/start-checkout/types';
217
+ export type { AttachCheckoutContact, AttachCheckoutContactParams, AttachCheckoutContactResponse, } from './actions/attach-checkout-contact/types';
218
+ export type { GetAddressOptions, GetAddressOptionsParams, GetAddressOptionsResponse, AddressCountryOption, AddressProvinceOption, } from './actions/get-address-options/types';
219
+ export type { SetOrderAddress, SetOrderAddressParams, SetOrderAddressResponse, OrderAddressType, } from './actions/set-order-address/types';
220
+ export type { GetShippingOptions, GetShippingOptionsResponse, ShippingOptionView, ShippingPickupView, } from './actions/get-shipping-options/types';
221
+ export type { SelectShippingOption, SelectShippingOptionParams, SelectShippingOptionResponse, } from './actions/select-shipping-option/types';
222
+ export type { SetOutlet, SetOutletParams, SetOutletResponse } from './actions/set-outlet/types';
223
+ export type { ResumeCheckout, ResumeCheckoutParams, ResumeCheckoutResponse, ResumeCheckoutResult, } from './actions/resume-checkout/types';
224
+ export type { GetCheckoutStatus, GetCheckoutStatusParams, GetCheckoutStatusResponse, CheckoutOrderStatus, } from './actions/get-checkout-status/types';
207
225
  export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse, } from './actions/add-customer-note/types';
208
226
  export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse, } from './actions/remove-customer-note/types';
209
227
  export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from './actions/remove-customer-from-cart/types';
@@ -260,6 +278,7 @@ export { refundsTopic } from './pubsub/topics/refunds';
260
278
  export { productsTopic } from './pubsub/topics/products';
261
279
  export { cartTopic } from './pubsub/topics/cart';
262
280
  export { paymentsTopic } from './pubsub/topics/payments';
281
+ export { checkoutTopic } from './pubsub/topics/checkout';
263
282
  export { splitPaymentsTopic } from './pubsub/topics/split-payments';
264
283
  export { customTablesTopic } from './pubsub/topics/custom-tables';
265
284
  export { printTopic } from './pubsub/topics/print';
@@ -287,6 +306,7 @@ export type { CategoryCreatedPayload, CategoryCreatedEvent, CategoryUpdatedPaylo
287
306
  export type { AttributeCreatedPayload, AttributeCreatedEvent, AttributeUpdatedPayload, AttributeUpdatedEvent, AttributesEventType, AttributesEventPayload, } from './pubsub/topics/attributes/types';
288
307
  export type { CartCreatedPayload, CartCustomerAssignedPayload, ProductAddedPayload, ProductDeletedPayload, CartDiscountAddedPayload, CartDiscountRemovedPayload, CartFeeAddedPayload, CartFeeRemovedPayload, ProductDiscountAddedPayload, ProductDiscountRemovedPayload, ProductFeeAddedPayload, ProductFeeRemovedPayload, ProductNoteAddedPayload, ProductNoteRemovedPayload, CartCreatedEvent, CartCustomerAssignedEvent, ProductAddedEvent, ProductDeletedEvent, CartDiscountAddedEvent, CartDiscountRemovedEvent, CartFeeAddedEvent, CartFeeRemovedEvent, ProductDiscountAddedEvent, ProductDiscountRemovedEvent, ProductFeeAddedEvent, ProductFeeRemovedEvent, ProductNoteAddedEvent, ProductNoteRemovedEvent, CartEventType, CartEventPayload, } from './pubsub/topics/cart/types';
289
308
  export type { PaymentDonePayload, PaymentErrPayload, PaymentDoneEvent, PaymentErrEvent, PaymentsEventType, PaymentsEventPayload, } from './pubsub/topics/payments/types';
309
+ export type { CheckoutStartedPayload, PaymentCompletedPayload, PaymentFailedPayload, CheckoutStartedEvent, PaymentCompletedEvent, PaymentFailedEvent, CheckoutEventType, CheckoutEventPayload, } from './pubsub/topics/checkout/types';
290
310
  export type { SplitPaymentUpdatedPayload, SplitPaymentUpdatedEvent, SplitPaymentsEventType, SplitPaymentsEventPayload, } from './pubsub/topics/split-payments/types';
291
311
  export type { RowCreatedPayload, RowUpdatedPayload, RowDeletedPayload, RowCreatedEvent, RowUpdatedEvent, RowDeletedEvent, CustomTablesEventType, CustomTablesEventPayload, } from './pubsub/topics/custom-tables/types';
292
312
  export type { PrintStartedPayload, PrintCompletedPayload, PrintErrorPayload, PrintStartedEvent, PrintCompletedEvent, PrintErrorEvent, PrintEventType, PrintEventPayload, } from './pubsub/topics/print/types';
package/dist/index.js CHANGED
@@ -56,6 +56,15 @@ import { redeemPayment } from './actions/redeem-payment/action';
56
56
  import { integrationPayment } from './actions/integration-payment/action';
57
57
  import { createPaymentLink } from './actions/create-payment-link/action';
58
58
  import { chargeMoto } from './actions/charge-moto/action';
59
+ import { startCheckout } from './actions/start-checkout/action';
60
+ import { attachCheckoutContact } from './actions/attach-checkout-contact/action';
61
+ import { getAddressOptions } from './actions/get-address-options/action';
62
+ import { setOrderAddress } from './actions/set-order-address/action';
63
+ import { getShippingOptions } from './actions/get-shipping-options/action';
64
+ import { selectShippingOption } from './actions/select-shipping-option/action';
65
+ import { setOutlet } from './actions/set-outlet/action';
66
+ import { resumeCheckout } from './actions/resume-checkout/action';
67
+ import { getCheckoutStatus } from './actions/get-checkout-status/action';
59
68
  // Customer Actions
60
69
  import { addCustomerNote } from './actions/add-customer-note/action';
61
70
  import { removeCustomerNote } from './actions/remove-customer-note/action';
@@ -206,6 +215,15 @@ export const command = {
206
215
  integrationPayment,
207
216
  createPaymentLink,
208
217
  chargeMoto,
218
+ startCheckout,
219
+ attachCheckoutContact,
220
+ getAddressOptions,
221
+ setOrderAddress,
222
+ getShippingOptions,
223
+ selectShippingOption,
224
+ setOutlet,
225
+ resumeCheckout,
226
+ getCheckoutStatus,
209
227
  // Customer Actions
210
228
  addCustomerNote,
211
229
  removeCustomerNote,
@@ -316,6 +334,7 @@ export { refundsTopic } from './pubsub/topics/refunds';
316
334
  export { productsTopic } from './pubsub/topics/products';
317
335
  export { cartTopic } from './pubsub/topics/cart';
318
336
  export { paymentsTopic } from './pubsub/topics/payments';
337
+ export { checkoutTopic } from './pubsub/topics/checkout';
319
338
  export { splitPaymentsTopic } from './pubsub/topics/split-payments';
320
339
  export { customTablesTopic } from './pubsub/topics/custom-tables';
321
340
  export { printTopic } from './pubsub/topics/print';
@@ -37,6 +37,16 @@ import { mockCashPayment } from '../../actions/cash-payment/mock';
37
37
  import { mockGetCashRoundingAmount } from '../../actions/get-cash-rounding-amount/mock';
38
38
  import { mockCreatePaymentLink } from '../../actions/create-payment-link/mock';
39
39
  import { mockChargeMoto } from '../../actions/charge-moto/mock';
40
+ import { mockStartCheckout } from '../../actions/start-checkout/mock';
41
+ import { mockAttachCheckoutContact } from '../../actions/attach-checkout-contact/mock';
42
+ import { mockGetAddressOptions } from '../../actions/get-address-options/mock';
43
+ import { mockSetOrderAddress } from '../../actions/set-order-address/mock';
44
+ import { mockGetShippingOptions } from '../../actions/get-shipping-options/mock';
45
+ import { mockSelectShippingOption } from '../../actions/select-shipping-option/mock';
46
+ import { mockGetOutlets } from '../../actions/get-outlets/mock';
47
+ import { mockSetOutlet } from '../../actions/set-outlet/mock';
48
+ import { mockResumeCheckout } from '../../actions/resume-checkout/mock';
49
+ import { mockGetCheckoutStatus } from '../../actions/get-checkout-status/mock';
40
50
  import { mockGetTimeClockStatus } from '../../actions/get-time-clock-status/mock';
41
51
  import { mockClearCart } from '../../actions/clear-cart/mock';
42
52
  import { mockDeleteParkedOrder } from '../../actions/delete-parked-order/mock';
@@ -147,6 +157,16 @@ export const RENDER_MOCKS = {
147
157
  getCashRoundingAmount: mockGetCashRoundingAmount,
148
158
  createPaymentLink: mockCreatePaymentLink,
149
159
  chargeMoto: mockChargeMoto,
160
+ startCheckout: mockStartCheckout,
161
+ attachCheckoutContact: mockAttachCheckoutContact,
162
+ getAddressOptions: mockGetAddressOptions,
163
+ setOrderAddress: mockSetOrderAddress,
164
+ getShippingOptions: mockGetShippingOptions,
165
+ selectShippingOption: mockSelectShippingOption,
166
+ getOutlets: mockGetOutlets,
167
+ setOutlet: mockSetOutlet,
168
+ resumeCheckout: mockResumeCheckout,
169
+ getCheckoutStatus: mockGetCheckoutStatus,
150
170
  clearCart: mockClearCart,
151
171
  deleteParkedOrder: mockDeleteParkedOrder,
152
172
  voidOrder: mockVoidOrder,
@@ -1,4 +1,4 @@
1
- import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, GetCustomStockActions, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, GetProductModifierSelections, GetCompositePrice, GetCompositeAvailability, SetProductModifierSelections, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, SetVariantUnavailable, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, VoidOrder, InitiateRefund, CashPayment, GetCashRoundingAmount, TapToPayPayment, TerminalPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, RedeemRefund, GetRefundPlan, CheckPermission, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles, RemoveCartDiscount, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, GetActiveStation, GetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem, CanTransition, GetAvailableTransitions, ApplyTransition, IntegrationPayment, GetSmartGridLayout, SaveSmartGridLayout, SendEmail, SendSms, GetBookingResources, GetBookingAvailability, GetBookings, HoldBooking, AddBookingToCart, RemoveBookingFromCart, CancelBooking, CreatePaymentLink, ChargeMoto, GetTimeClockStatus } from '../../index';
1
+ import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, GetCustomStockActions, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, GetProductModifierSelections, GetCompositePrice, GetCompositeAvailability, SetProductModifierSelections, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, SetVariantUnavailable, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, VoidOrder, InitiateRefund, CashPayment, GetCashRoundingAmount, TapToPayPayment, TerminalPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, RedeemRefund, GetRefundPlan, CheckPermission, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles, RemoveCartDiscount, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, GetActiveStation, GetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem, CanTransition, GetAvailableTransitions, ApplyTransition, IntegrationPayment, GetSmartGridLayout, SaveSmartGridLayout, SendEmail, SendSms, GetBookingResources, GetBookingAvailability, GetBookings, HoldBooking, AddBookingToCart, RemoveBookingFromCart, CancelBooking, CreatePaymentLink, ChargeMoto, StartCheckout, AttachCheckoutContact, GetAddressOptions, SetOrderAddress, GetShippingOptions, SelectShippingOption, GetOutlets, SetOutlet, ResumeCheckout, GetCheckoutStatus, GetTimeClockStatus } from '../../index';
2
2
  export interface RenderProviderActions {
3
3
  exampleFunction: ExampleFunction;
4
4
  getProducts: GetProducts;
@@ -56,6 +56,28 @@ export interface RenderProviderActions {
56
56
  integrationPayment: IntegrationPayment;
57
57
  createPaymentLink: CreatePaymentLink;
58
58
  chargeMoto: ChargeMoto;
59
+ /**
60
+ * ONLINE checkout — served only by the storefront runtime (a published
61
+ * website). The till tenders above are refused there, and this is refused on
62
+ * a register, because the two declare different things to the card networks.
63
+ */
64
+ startCheckout: StartCheckout;
65
+ attachCheckoutContact: AttachCheckoutContact;
66
+ /** Shipping, on the till (ship-to) and the website alike. The runtime prices; the flow renders. */
67
+ getAddressOptions: GetAddressOptions;
68
+ setOrderAddress: SetOrderAddress;
69
+ getShippingOptions: GetShippingOptions;
70
+ selectShippingOption: SelectShippingOption;
71
+ getOutlets: GetOutlets;
72
+ setOutlet: SetOutlet;
73
+ /**
74
+ * The RETURN LEG of an online checkout, after a redirect payment method or
75
+ * 3-D Secure sent the shopper away and back. Storefront-only, like
76
+ * `startCheckout`, and safe to call on every page load.
77
+ */
78
+ resumeCheckout: ResumeCheckout;
79
+ /** Where an online order stands now, by its order password. Storefront-only. */
80
+ getCheckoutStatus: GetCheckoutStatus;
59
81
  addNonRevenueItem: AddNonRevenueItem;
60
82
  addCustomerNote: AddCustomerNote;
61
83
  removeCustomerNote: RemoveCustomerNote;
@@ -0,0 +1,26 @@
1
+ import type { TopicEvent } from "../../../types";
2
+ /**
3
+ * Payload for checkout-started event
4
+ *
5
+ * The order EXISTS and is unpaid. `serverTotal` is the server's own price for
6
+ * the cart, in integer minor units — the browser never sends a price, so this
7
+ * is the first and only authoritative total.
8
+ */
9
+ export interface CheckoutStartedPayload {
10
+ orderId: string;
11
+ receiptId: string;
12
+ serverTotal: number;
13
+ currency: string;
14
+ /**
15
+ * `ready` — the payment fields are mounted and the shopper can pay.
16
+ * `unavailable` — the order exists but no payment could be started, so the
17
+ * shopper has NOT been charged.
18
+ */
19
+ paymentStatus: "ready" | "unavailable";
20
+ /** One-time password for reading this order back. Returned only on the first create. */
21
+ orderPassword?: string;
22
+ }
23
+ /**
24
+ * Typed event for checkout-started
25
+ */
26
+ export type CheckoutStartedEvent = TopicEvent<CheckoutStartedPayload>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Checkout Topic Definition
3
+ * Defines the checkout topic and its available event types
4
+ */
5
+ import type { TopicDefinition } from "../../types";
6
+ export declare const checkoutTopic: TopicDefinition;
7
+ export * from "./types";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Checkout Topic Definition
3
+ * Defines the checkout topic and its available event types
4
+ */
5
+ export const checkoutTopic = {
6
+ id: "checkout",
7
+ name: "Checkout",
8
+ description: "Topic for online (website) checkout events",
9
+ eventTypes: [
10
+ {
11
+ id: "checkout-started",
12
+ name: "Checkout Started",
13
+ description: "Published when the order has been created and the payment fields are mounted"
14
+ },
15
+ {
16
+ id: "payment-completed",
17
+ name: "Payment Completed",
18
+ description: "Published when the shopper's payment succeeds on their side (authorisation, not settlement)"
19
+ },
20
+ {
21
+ id: "payment-failed",
22
+ name: "Payment Failed",
23
+ description: "Published when a payment attempt is refused or errors; the shopper can retry"
24
+ }
25
+ ]
26
+ };
27
+ // Re-export types
28
+ export * from "./types";
@@ -0,0 +1,31 @@
1
+ import type { TopicEvent } from "../../../types";
2
+ /**
3
+ * Payload for payment-completed event
4
+ *
5
+ * THIS IS NOT SETTLEMENT. It reports that the SHOPPER'S side finished —
6
+ * `resultCode` is the provider's own outcome, typically `Authorised`. The money
7
+ * is confirmed by the provider's capture webhook reaching the backend, out of
8
+ * band and after this page is done, so this event cannot and does not claim it.
9
+ */
10
+ export interface PaymentCompletedPayload {
11
+ orderId: string;
12
+ receiptId: string;
13
+ /** The provider's result code, e.g. `Authorised`. */
14
+ resultCode: string;
15
+ /**
16
+ * OPAQUE PROOF OF THIS PAYMENT, handed to the browser by the provider and to
17
+ * nobody else. Pass it to the order-status read and the server verifies it
18
+ * with the provider before believing a word of it.
19
+ *
20
+ * It is the only evidence of an outcome that exists outside the provider's
21
+ * webhook, so it is what recovers an order whose confirmation never arrived.
22
+ * Treat it as a credential: do not log it, do not put it in a URL you share.
23
+ *
24
+ * Absent when the provider reported no payment (see `resultCode`).
25
+ */
26
+ sessionResult?: string;
27
+ }
28
+ /**
29
+ * Typed event for payment-completed
30
+ */
31
+ export type PaymentCompletedEvent = TopicEvent<PaymentCompletedPayload>;
@@ -0,0 +1,20 @@
1
+ import type { TopicEvent } from "../../../types";
2
+ /**
3
+ * Payload for payment-failed event
4
+ *
5
+ * ONE DECLINED ATTEMPT, NOT A DEAD CHECKOUT. The order and the mounted payment
6
+ * fields both survive, so the shopper can try another card without the page
7
+ * starting a new checkout.
8
+ */
9
+ export interface PaymentFailedPayload {
10
+ orderId: string;
11
+ receiptId: string;
12
+ /** The provider's result code, e.g. `Refused`, or an error name. */
13
+ resultCode: string;
14
+ /** Present when the failure carried a message worth showing. */
15
+ message?: string;
16
+ }
17
+ /**
18
+ * Typed event for payment-failed
19
+ */
20
+ export type PaymentFailedEvent = TopicEvent<PaymentFailedPayload>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Checkout Topic Types
3
+ * Aggregated types for all online-checkout events
4
+ */
5
+ export * from "./checkout-started/types";
6
+ export * from "./payment-completed/types";
7
+ export * from "./payment-failed/types";
8
+ import type { CheckoutStartedPayload } from "./checkout-started/types";
9
+ import type { PaymentCompletedPayload } from "./payment-completed/types";
10
+ import type { PaymentFailedPayload } from "./payment-failed/types";
11
+ export type CheckoutEventPayload = CheckoutStartedPayload | PaymentCompletedPayload | PaymentFailedPayload;
12
+ export type CheckoutEventType = "checkout-started" | "payment-completed" | "payment-failed";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Checkout Topic Types
3
+ * Aggregated types for all online-checkout events
4
+ */
5
+ // Re-export all event types
6
+ export * from "./checkout-started/types";
7
+ export * from "./payment-completed/types";
8
+ export * from "./payment-failed/types";
@@ -2,20 +2,21 @@
2
2
  * Pub/Sub Topics
3
3
  * Export all available topics and their types
4
4
  */
5
- export * from './customers';
6
- export * from './orders';
7
- export * from './bookings';
8
- export * from './refunds';
9
- export * from './products';
10
- export * from './cart';
11
- export * from './payments';
12
- export * from './custom-tables';
13
- export * from './print';
14
- export * from './outlet';
15
- export * from './station';
16
- export * from './session';
17
- export * from './users';
18
- export * from './variants';
19
- export * from './transactions';
20
- export * from './categories';
21
- export * from './attributes';
5
+ export * from "./customers";
6
+ export * from "./orders";
7
+ export * from "./bookings";
8
+ export * from "./refunds";
9
+ export * from "./products";
10
+ export * from "./cart";
11
+ export * from "./payments";
12
+ export * from "./checkout";
13
+ export * from "./custom-tables";
14
+ export * from "./print";
15
+ export * from "./outlet";
16
+ export * from "./station";
17
+ export * from "./session";
18
+ export * from "./users";
19
+ export * from "./variants";
20
+ export * from "./transactions";
21
+ export * from "./categories";
22
+ export * from "./attributes";
@@ -2,20 +2,21 @@
2
2
  * Pub/Sub Topics
3
3
  * Export all available topics and their types
4
4
  */
5
- export * from './customers';
6
- export * from './orders';
7
- export * from './bookings';
8
- export * from './refunds';
9
- export * from './products';
10
- export * from './cart';
11
- export * from './payments';
12
- export * from './custom-tables';
13
- export * from './print';
14
- export * from './outlet';
15
- export * from './station';
16
- export * from './session';
17
- export * from './users';
18
- export * from './variants';
19
- export * from './transactions';
20
- export * from './categories';
21
- export * from './attributes';
5
+ export * from "./customers";
6
+ export * from "./orders";
7
+ export * from "./bookings";
8
+ export * from "./refunds";
9
+ export * from "./products";
10
+ export * from "./cart";
11
+ export * from "./payments";
12
+ export * from "./checkout";
13
+ export * from "./custom-tables";
14
+ export * from "./print";
15
+ export * from "./outlet";
16
+ export * from "./station";
17
+ export * from "./session";
18
+ export * from "./users";
19
+ export * from "./variants";
20
+ export * from "./transactions";
21
+ export * from "./categories";
22
+ export * from "./attributes";
@@ -4,6 +4,7 @@ import { RefundsEventType, RefundsEventPayload } from "./refunds/types";
4
4
  import { ProductsEventType, ProductsEventPayload } from "./products/types";
5
5
  import { CartEventType, CartEventPayload } from "./cart/types";
6
6
  import { PaymentsEventType, PaymentsEventPayload } from "./payments/types";
7
+ import { CheckoutEventType, CheckoutEventPayload } from "./checkout/types";
7
8
  import { SplitPaymentsEventType, SplitPaymentsEventPayload } from "./split-payments/types";
8
9
  import { CustomTablesEventPayload, CustomTablesEventType } from "./custom-tables/types";
9
10
  import { PrintEventType, PrintEventPayload } from "./print/types";
@@ -23,6 +24,13 @@ export interface TopicEventPayloadMap {
23
24
  products: Record<ProductsEventType, ProductsEventPayload>;
24
25
  cart: Record<CartEventType, CartEventPayload>;
25
26
  payments: Record<PaymentsEventType, PaymentsEventPayload>;
27
+ /**
28
+ * ONLINE checkout only (a published website), where the POS `payments`
29
+ * topic never fires: `payments` reports a till tender settling in front of
30
+ * a cashier, while a web shopper's outcome arrives asynchronously and can
31
+ * only ever be an authorisation until the provider's webhook lands.
32
+ */
33
+ checkout: Record<CheckoutEventType, CheckoutEventPayload>;
26
34
  "split-payments": Record<SplitPaymentsEventType, SplitPaymentsEventPayload>;
27
35
  customTables: Record<CustomTablesEventType, CustomTablesEventPayload>;
28
36
  print: Record<PrintEventType, PrintEventPayload>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/command-frame",
3
- "version": "0.10.0",
3
+ "version": "0.10.1-online.1",
4
4
  "description": "Commands Frame library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -57,7 +57,7 @@
57
57
  "ignoreBranchesMissingTickets": true
58
58
  },
59
59
  "dependencies": {
60
- "@final-commerce/common": "2.6.0"
60
+ "@final-commerce/common": "2.7.1-online.1"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@commitlint/cli": "^19.0.0",