@final-commerce/command-frame 0.11.1-preprod.2 → 0.11.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.
- package/dist/CommonTypes.d.ts +1 -18
- package/dist/actions/get-outlets/action.js +2 -2
- package/dist/actions/get-outlets/mock.d.ts +0 -12
- package/dist/actions/get-outlets/mock.js +4 -28
- package/dist/actions/get-outlets/types.d.ts +1 -19
- package/dist/actions/get-product-modifier-selections/mock.js +0 -7
- package/dist/actions/get-product-modifier-selections/types.d.ts +0 -4
- package/dist/actions/get-products/types.d.ts +8 -8
- package/dist/actions/get-refund-plan/mockRows.js +1 -1
- package/dist/actions/get-refund-plan/types.d.ts +6 -9
- package/dist/actions/get-remaining-refundable-quantities/mock.js +0 -1
- package/dist/actions/get-remaining-refundable-quantities/types.d.ts +0 -5
- package/dist/actions/process-partial-refund/types.d.ts +1 -1
- package/dist/actions/record-external-payment/mock.js +5 -0
- package/dist/actions/record-external-payment/types.d.ts +16 -1
- package/dist/index.d.ts +2 -22
- package/dist/index.js +0 -19
- package/dist/projects/render/mocks.js +0 -20
- package/dist/projects/render/types.d.ts +1 -23
- package/dist/pubsub/topics/index.d.ts +17 -18
- package/dist/pubsub/topics/index.js +17 -18
- package/dist/pubsub/topics/types.d.ts +0 -8
- package/package.json +2 -2
- package/dist/actions/attach-checkout-contact/action.d.ts +0 -6
- package/dist/actions/attach-checkout-contact/action.js +0 -8
- package/dist/actions/attach-checkout-contact/mock.d.ts +0 -15
- package/dist/actions/attach-checkout-contact/mock.js +0 -22
- package/dist/actions/attach-checkout-contact/types.d.ts +0 -35
- package/dist/actions/attach-checkout-contact/types.js +0 -16
- package/dist/actions/get-address-options/action.d.ts +0 -6
- package/dist/actions/get-address-options/action.js +0 -8
- package/dist/actions/get-address-options/mock.d.ts +0 -3
- package/dist/actions/get-address-options/mock.js +0 -15
- package/dist/actions/get-address-options/types.d.ts +0 -25
- package/dist/actions/get-address-options/types.js +0 -8
- package/dist/actions/get-checkout-status/action.d.ts +0 -6
- package/dist/actions/get-checkout-status/action.js +0 -8
- package/dist/actions/get-checkout-status/mock.d.ts +0 -3
- package/dist/actions/get-checkout-status/mock.js +0 -11
- package/dist/actions/get-checkout-status/types.d.ts +0 -27
- package/dist/actions/get-checkout-status/types.js +0 -12
- package/dist/actions/get-shipping-options/action.d.ts +0 -6
- package/dist/actions/get-shipping-options/action.js +0 -8
- package/dist/actions/get-shipping-options/mock.d.ts +0 -3
- package/dist/actions/get-shipping-options/mock.js +0 -15
- package/dist/actions/get-shipping-options/types.d.ts +0 -43
- package/dist/actions/get-shipping-options/types.js +0 -1
- package/dist/actions/resume-checkout/action.d.ts +0 -6
- package/dist/actions/resume-checkout/action.js +0 -8
- package/dist/actions/resume-checkout/mock.d.ts +0 -16
- package/dist/actions/resume-checkout/mock.js +0 -51
- package/dist/actions/resume-checkout/types.d.ts +0 -59
- package/dist/actions/resume-checkout/types.js +0 -13
- package/dist/actions/select-shipping-option/action.d.ts +0 -6
- package/dist/actions/select-shipping-option/action.js +0 -8
- package/dist/actions/select-shipping-option/mock.d.ts +0 -3
- package/dist/actions/select-shipping-option/mock.js +0 -31
- package/dist/actions/select-shipping-option/types.d.ts +0 -15
- package/dist/actions/select-shipping-option/types.js +0 -1
- package/dist/actions/set-order-address/action.d.ts +0 -6
- package/dist/actions/set-order-address/action.js +0 -8
- package/dist/actions/set-order-address/mock.d.ts +0 -7
- package/dist/actions/set-order-address/mock.js +0 -29
- package/dist/actions/set-order-address/types.d.ts +0 -19
- package/dist/actions/set-order-address/types.js +0 -1
- package/dist/actions/set-outlet/action.d.ts +0 -6
- package/dist/actions/set-outlet/action.js +0 -8
- package/dist/actions/set-outlet/mock.d.ts +0 -13
- package/dist/actions/set-outlet/mock.js +0 -24
- package/dist/actions/set-outlet/types.d.ts +0 -31
- package/dist/actions/set-outlet/types.js +0 -21
- package/dist/actions/start-checkout/action.d.ts +0 -6
- package/dist/actions/start-checkout/action.js +0 -8
- package/dist/actions/start-checkout/mock.d.ts +0 -16
- package/dist/actions/start-checkout/mock.js +0 -80
- package/dist/actions/start-checkout/types.d.ts +0 -90
- package/dist/actions/start-checkout/types.js +0 -10
- package/dist/demo/shipping.d.ts +0 -8
- package/dist/demo/shipping.js +0 -69
- package/dist/pubsub/topics/checkout/checkout-started/types.d.ts +0 -26
- package/dist/pubsub/topics/checkout/checkout-started/types.js +0 -1
- package/dist/pubsub/topics/checkout/index.d.ts +0 -7
- package/dist/pubsub/topics/checkout/index.js +0 -28
- package/dist/pubsub/topics/checkout/payment-completed/types.d.ts +0 -31
- package/dist/pubsub/topics/checkout/payment-completed/types.js +0 -1
- package/dist/pubsub/topics/checkout/payment-failed/types.d.ts +0 -23
- package/dist/pubsub/topics/checkout/payment-failed/types.js +0 -1
- package/dist/pubsub/topics/checkout/types.d.ts +0 -12
- package/dist/pubsub/topics/checkout/types.js +0 -8
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
* Pub/Sub Topics
|
|
3
3
|
* Export all available topics and their types
|
|
4
4
|
*/
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
16
|
-
export * from
|
|
17
|
-
export * from
|
|
18
|
-
export * from
|
|
19
|
-
export * from
|
|
20
|
-
export * from
|
|
21
|
-
export * from
|
|
22
|
-
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 './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';
|
|
@@ -4,7 +4,6 @@ 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";
|
|
8
7
|
import { SplitPaymentsEventType, SplitPaymentsEventPayload } from "./split-payments/types";
|
|
9
8
|
import { CustomTablesEventPayload, CustomTablesEventType } from "./custom-tables/types";
|
|
10
9
|
import { PrintEventType, PrintEventPayload } from "./print/types";
|
|
@@ -24,13 +23,6 @@ export interface TopicEventPayloadMap {
|
|
|
24
23
|
products: Record<ProductsEventType, ProductsEventPayload>;
|
|
25
24
|
cart: Record<CartEventType, CartEventPayload>;
|
|
26
25
|
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>;
|
|
34
26
|
"split-payments": Record<SplitPaymentsEventType, SplitPaymentsEventPayload>;
|
|
35
27
|
customTables: Record<CustomTablesEventType, CustomTablesEventPayload>;
|
|
36
28
|
print: Record<PrintEventType, PrintEventPayload>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@final-commerce/command-frame",
|
|
3
|
-
"version": "0.11.1
|
|
3
|
+
"version": "0.11.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.8.
|
|
60
|
+
"@final-commerce/common": "2.8.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@commitlint/cli": "^19.0.0",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Attach Checkout Contact action
|
|
3
|
-
* Calls the attachCheckoutContact action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const attachCheckoutContact = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('attachCheckoutContact', params);
|
|
8
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { AttachCheckoutContact } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Standalone mock of attaching contact to an online order.
|
|
4
|
-
*
|
|
5
|
-
* It mirrors the one REFUSAL the real command makes — a missing email — because
|
|
6
|
-
* that is the mistake a builder actually hits, and a mock that accepted anything
|
|
7
|
-
* would let a checkout screen look finished and lose receipts on the published
|
|
8
|
-
* site.
|
|
9
|
-
*
|
|
10
|
-
* It does NOT mirror "no order to attach to". The real command answers
|
|
11
|
-
* `attached: false` there rather than throwing, precisely so a flow can call it
|
|
12
|
-
* optimistically and still let the shopper pay; the mock always has a checkout
|
|
13
|
-
* to attach to, so it reports `true`.
|
|
14
|
-
*/
|
|
15
|
-
export declare const mockAttachCheckoutContact: AttachCheckoutContact;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standalone mock of attaching contact to an online order.
|
|
3
|
-
*
|
|
4
|
-
* It mirrors the one REFUSAL the real command makes — a missing email — because
|
|
5
|
-
* that is the mistake a builder actually hits, and a mock that accepted anything
|
|
6
|
-
* would let a checkout screen look finished and lose receipts on the published
|
|
7
|
-
* site.
|
|
8
|
-
*
|
|
9
|
-
* It does NOT mirror "no order to attach to". The real command answers
|
|
10
|
-
* `attached: false` there rather than throwing, precisely so a flow can call it
|
|
11
|
-
* optimistically and still let the shopper pay; the mock always has a checkout
|
|
12
|
-
* to attach to, so it reports `true`.
|
|
13
|
-
*/
|
|
14
|
-
export const mockAttachCheckoutContact = async (params) => {
|
|
15
|
-
console.log('[Mock] attachCheckoutContact called', params);
|
|
16
|
-
if (!params)
|
|
17
|
-
throw new Error('Params required');
|
|
18
|
-
if (!params.email || !params.email.trim()) {
|
|
19
|
-
throw new Error('attachCheckoutContact: email is required — it is where the receipt goes');
|
|
20
|
-
}
|
|
21
|
-
return { attached: true, timestamp: new Date().toISOString() };
|
|
22
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
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 AttachCheckoutContactParams {
|
|
6
|
-
email: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
phone?: string;
|
|
9
|
-
/** Defaults to the outlet the storefront booted against. */
|
|
10
|
-
outletId?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface AttachCheckoutContactResponse {
|
|
13
|
-
/**
|
|
14
|
-
* `false` means there was nothing to attach to — no checkout had been started
|
|
15
|
-
* for this cart. It is NOT a failure to record the contact on an order that
|
|
16
|
-
* exists, and it never means the shopper was charged.
|
|
17
|
-
*/
|
|
18
|
-
attached: boolean;
|
|
19
|
-
timestamp: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Put the shopper's contact on the order `startCheckout` already created.
|
|
23
|
-
*
|
|
24
|
-
* Call it BEFORE paying, whenever the email is known — on blur, on submit, or
|
|
25
|
-
* as the shopper leaves the contact step. It reuses the order's idempotency
|
|
26
|
-
* key, so it updates that order rather than creating a second one.
|
|
27
|
-
*
|
|
28
|
-
* SAFE TO CALL TWICE. The server only ever ADDS contact to an order that has
|
|
29
|
-
* none, so a later call cannot redirect a receipt that was already addressed.
|
|
30
|
-
*
|
|
31
|
-
* NEVER THROWS FOR A MISSING ORDER. Failing to record an email must not stop a
|
|
32
|
-
* payment the shopper is trying to make, so the caller gets `attached: false`
|
|
33
|
-
* and can carry on to pay.
|
|
34
|
-
*/
|
|
35
|
-
export type AttachCheckoutContact = (params: AttachCheckoutContactParams) => Promise<AttachCheckoutContactResponse>;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Attach Checkout Contact Types
|
|
2
|
-
//
|
|
3
|
-
// The second half of the online checkout. `startCheckout` creates the order and
|
|
4
|
-
// mounts the payment fields the moment a shopper ARRIVES; this puts their email
|
|
5
|
-
// on that same order once they have typed it.
|
|
6
|
-
//
|
|
7
|
-
// WHY THESE ARE TWO COMMANDS. The card fields cannot render without a payment
|
|
8
|
-
// session, a session needs a server-priced amount, and an amount needs an order.
|
|
9
|
-
// So the order has to exist before the shopper has typed anything. Demanding an
|
|
10
|
-
// email first is what forced the old "fill the form, then see the card fields"
|
|
11
|
-
// checkout — and it also meant every cart edit minted a NEW order, because the
|
|
12
|
-
// idempotency key moved with the cart.
|
|
13
|
-
//
|
|
14
|
-
// Served ONLY by the storefront runtime (a published website), like
|
|
15
|
-
// `startCheckout` itself. On a register it does not exist.
|
|
16
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GetAddressOptions action
|
|
3
|
-
* Calls the getAddressOptions action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const getAddressOptions = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('getAddressOptions', params);
|
|
8
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { CANADA_PROVINCES, listCountries } from '@final-commerce/common';
|
|
2
|
-
/** Standalone mock: the same country and province lists the runtime serves. The demo store is in Canada. */
|
|
3
|
-
export const mockGetAddressOptions = async (params) => {
|
|
4
|
-
console.log('[Mock] getAddressOptions called', params);
|
|
5
|
-
const french = params?.locale?.toLowerCase().startsWith('fr') ?? false;
|
|
6
|
-
const provinces = CANADA_PROVINCES.map((p) => ({ code: p.code, name: french ? p.nameFr : p.name }));
|
|
7
|
-
return {
|
|
8
|
-
countries: listCountries(params?.locale ?? 'en').map((c) => ({
|
|
9
|
-
...c,
|
|
10
|
-
provinces: c.code === 'CA' ? provinces : [],
|
|
11
|
-
})),
|
|
12
|
-
defaultCountry: 'CA',
|
|
13
|
-
timestamp: new Date().toISOString(),
|
|
14
|
-
};
|
|
15
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export interface AddressProvinceOption {
|
|
2
|
-
/** Province code, e.g. `QC`. This is what goes in the address's `state`. */
|
|
3
|
-
code: string;
|
|
4
|
-
/** In the requested locale where we have it (English or French). */
|
|
5
|
-
name: string;
|
|
6
|
-
}
|
|
7
|
-
export interface AddressCountryOption {
|
|
8
|
-
/** ISO 3166-1 alpha-2, e.g. `CA`. This is what goes in the address's `country`. */
|
|
9
|
-
code: string;
|
|
10
|
-
name: string;
|
|
11
|
-
/** Empty when the country has no province list; the form then shows a free text field. */
|
|
12
|
-
provinces: AddressProvinceOption[];
|
|
13
|
-
}
|
|
14
|
-
export interface GetAddressOptionsParams {
|
|
15
|
-
/** BCP 47 locale for the names, e.g. `fr-CA`. Defaults to `en`. */
|
|
16
|
-
locale?: string;
|
|
17
|
-
}
|
|
18
|
-
export interface GetAddressOptionsResponse {
|
|
19
|
-
/** Sorted by name in the requested locale. */
|
|
20
|
-
countries: AddressCountryOption[];
|
|
21
|
-
/** The store's own country, to preselect. Null when it isn't known. */
|
|
22
|
-
defaultCountry: string | null;
|
|
23
|
-
timestamp: string;
|
|
24
|
-
}
|
|
25
|
-
export type GetAddressOptions = (params?: GetAddressOptionsParams) => Promise<GetAddressOptionsResponse>;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// Get Address Options Types
|
|
2
|
-
//
|
|
3
|
-
// What an address form offers: countries, and the provinces of the countries that
|
|
4
|
-
// have them (Canada today). A flow renders these as dropdowns and keeps no list of
|
|
5
|
-
// its own, so what the shopper picks is always a code the shipping rules match.
|
|
6
|
-
//
|
|
7
|
-
// Served by the till and by the storefront runtime.
|
|
8
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get Checkout Status action
|
|
3
|
-
* Calls the getCheckoutStatus action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const getCheckoutStatus = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('getCheckoutStatus', params ?? {});
|
|
8
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** Standalone mock: every order the preview knows about is already paid. */
|
|
2
|
-
export const mockGetCheckoutStatus = async (params) => {
|
|
3
|
-
console.log('[Mock] getCheckoutStatus called', params);
|
|
4
|
-
return {
|
|
5
|
-
success: true,
|
|
6
|
-
status: 'paid',
|
|
7
|
-
paid: true,
|
|
8
|
-
receiptId: params?.receiptId ?? 'ON-001-000001',
|
|
9
|
-
timestamp: new Date().toISOString(),
|
|
10
|
-
};
|
|
11
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/** The shopper-facing vocabulary: never the platform's payment / fulfilment states. */
|
|
2
|
-
export type CheckoutOrderStatus = 'awaiting_payment' | 'confirming' | 'payment_failed' | 'paid' | 'fulfilled' | 'partially_refunded' | 'refunded' | 'cancelled';
|
|
3
|
-
/** Why the server cancelled an order the shopper paid for. */
|
|
4
|
-
export type CheckoutCancelReason = 'sold_out';
|
|
5
|
-
export interface GetCheckoutStatusParams {
|
|
6
|
-
/**
|
|
7
|
-
* The receipt `startCheckout` returned, to name which order. Omitted: the checkout in flight,
|
|
8
|
-
* else the last one this tab finished.
|
|
9
|
-
*/
|
|
10
|
-
receiptId?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface GetCheckoutStatusResponse {
|
|
13
|
-
success: boolean;
|
|
14
|
-
/** `null` when this tab placed no such order, or the server could not be asked. */
|
|
15
|
-
status: CheckoutOrderStatus | null;
|
|
16
|
-
/** True once the money is in: `paid`, `fulfilled`, or refunded since. */
|
|
17
|
-
paid: boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Why a `cancelled` order was cancelled, when the server cancelled it. `sold_out`: the stock ran out
|
|
20
|
-
* before the payment was captured, so the payment was released and nothing was charged.
|
|
21
|
-
*/
|
|
22
|
-
cancelReason?: CheckoutCancelReason;
|
|
23
|
-
receiptId: string | null;
|
|
24
|
-
timestamp: string;
|
|
25
|
-
}
|
|
26
|
-
/** Never throws for an unknown order: answers `status: null`. */
|
|
27
|
-
export type GetCheckoutStatus = (params?: GetCheckoutStatusParams) => Promise<GetCheckoutStatusResponse>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Get Checkout Status Types
|
|
2
|
-
//
|
|
3
|
-
// Where an online order stands NOW, as the server holds it. A confirmation page uses it to move
|
|
4
|
-
// from "we're confirming your payment" to "paid" once the payment provider's notification has
|
|
5
|
-
// landed, which the browser alone can never know: it only ever sees that the provider ACCEPTED
|
|
6
|
-
// a payment.
|
|
7
|
-
//
|
|
8
|
-
// The runtime asks about a checkout THIS TAB placed (it keeps the checkout's key), so a page can
|
|
9
|
-
// only ever ask about its own order. No password: the server no longer issues one.
|
|
10
|
-
//
|
|
11
|
-
// Served ONLY by the storefront runtime (a published website). On a register it does not exist.
|
|
12
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GetShippingOptions action
|
|
3
|
-
* Calls the getShippingOptions action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const getShippingOptions = async () => {
|
|
7
|
-
return await commandFrameClient.call('getShippingOptions', undefined);
|
|
8
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { MOCK_SHIPPING_ZONES, mockShippingOptions } from '../../demo/shipping';
|
|
2
|
-
/** Standalone mock: the demo store's zones run through the real resolver, as the website would. */
|
|
3
|
-
export const mockGetShippingOptions = async () => {
|
|
4
|
-
console.log('[Mock] getShippingOptions called');
|
|
5
|
-
const { resolution, options } = mockShippingOptions();
|
|
6
|
-
const message = resolution.message ??
|
|
7
|
-
(options.length === 0 && resolution.reason === 'NO_COVERAGE' ? 'Sorry, we only ship within Canada.' : null);
|
|
8
|
-
return {
|
|
9
|
-
required: MOCK_SHIPPING_ZONES.length > 0,
|
|
10
|
-
options,
|
|
11
|
-
reason: resolution.reason,
|
|
12
|
-
message,
|
|
13
|
-
timestamp: new Date().toISOString(),
|
|
14
|
-
};
|
|
15
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { ShippingNoOptionReason, ShippingOptionType } from '@final-commerce/common';
|
|
2
|
-
export interface ShippingPickupView {
|
|
3
|
-
outletId: string;
|
|
4
|
-
/** The store's name, e.g. "Duckworth Street". */
|
|
5
|
-
name: string;
|
|
6
|
-
/** One line per open day, e.g. "Mon–Fri 9:00 AM – 6:00 PM". Empty when the store set no hours. */
|
|
7
|
-
hours: string[];
|
|
8
|
-
}
|
|
9
|
-
export interface ShippingOptionView {
|
|
10
|
-
optionId: string;
|
|
11
|
-
type: ShippingOptionType | `${ShippingOptionType}`;
|
|
12
|
-
/** "Standard shipping", or "Pickup at Duckworth Street". */
|
|
13
|
-
name: string;
|
|
14
|
-
/** What this option costs on this cart, minor units, before its tax. */
|
|
15
|
-
amount: number;
|
|
16
|
-
/** "$10.00" or "Free". */
|
|
17
|
-
priceText: string;
|
|
18
|
-
/** "Add $20.00 more for free shipping", when a free-shipping line exists and isn't reached. */
|
|
19
|
-
freeShippingHint: string | null;
|
|
20
|
-
/** "Arrives Tue, Oct 20 – Fri, Oct 23", counted in business days from today. Null for pickup. */
|
|
21
|
-
arrivalText: string | null;
|
|
22
|
-
pickup: ShippingPickupView | null;
|
|
23
|
-
/** The option on the cart now. The cheapest is chosen by default. */
|
|
24
|
-
selected: boolean;
|
|
25
|
-
}
|
|
26
|
-
export interface GetShippingOptionsResponse {
|
|
27
|
-
/**
|
|
28
|
-
* False when this store doesn't ship at all (no shipping set up) or the cart has
|
|
29
|
-
* nothing to ship: show no shipping step.
|
|
30
|
-
*/
|
|
31
|
-
required: boolean;
|
|
32
|
-
/** Ship options cheapest first, then pickups. */
|
|
33
|
-
options: ShippingOptionView[];
|
|
34
|
-
/** Why there is nothing to choose; null when `options` isn't empty. */
|
|
35
|
-
reason: ShippingNoOptionReason | `${ShippingNoOptionReason}` | null;
|
|
36
|
-
/**
|
|
37
|
-
* What to tell the customer: the store's "we don't ship here" message, or the
|
|
38
|
-
* default for the reason ("Sorry, we only ship within Canada."). Null when there are options.
|
|
39
|
-
*/
|
|
40
|
-
message: string | null;
|
|
41
|
-
timestamp: string;
|
|
42
|
-
}
|
|
43
|
-
export type GetShippingOptions = () => Promise<GetShippingOptionsResponse>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resume Checkout action
|
|
3
|
-
* Calls the resumeCheckout action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const resumeCheckout = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('resumeCheckout', params ?? {});
|
|
8
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ResumeCheckout } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Standalone mock of the checkout return leg.
|
|
4
|
-
*
|
|
5
|
-
* It reads the SAME query parameters the real provider sends a shopper back
|
|
6
|
-
* with, so a builder can exercise the redirect path in preview by appending
|
|
7
|
-
* them by hand:
|
|
8
|
-
*
|
|
9
|
-
* ?sessionId=CS_MOCK&redirectResult=MOCK
|
|
10
|
-
*
|
|
11
|
-
* Without them it answers `{ resumed: false }` and does nothing, which is what
|
|
12
|
-
* the real command does on an ordinary page load. That is the branch a
|
|
13
|
-
* checkout screen hits on every normal visit, so it is the one worth getting
|
|
14
|
-
* right in a mock.
|
|
15
|
-
*/
|
|
16
|
-
export declare const mockResumeCheckout: ResumeCheckout;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { mockPublishEvent } from '../../demo/database';
|
|
2
|
-
/**
|
|
3
|
-
* Standalone mock of the checkout return leg.
|
|
4
|
-
*
|
|
5
|
-
* It reads the SAME query parameters the real provider sends a shopper back
|
|
6
|
-
* with, so a builder can exercise the redirect path in preview by appending
|
|
7
|
-
* them by hand:
|
|
8
|
-
*
|
|
9
|
-
* ?sessionId=CS_MOCK&redirectResult=MOCK
|
|
10
|
-
*
|
|
11
|
-
* Without them it answers `{ resumed: false }` and does nothing, which is what
|
|
12
|
-
* the real command does on an ordinary page load. That is the branch a
|
|
13
|
-
* checkout screen hits on every normal visit, so it is the one worth getting
|
|
14
|
-
* right in a mock.
|
|
15
|
-
*/
|
|
16
|
-
export const mockResumeCheckout = async (params) => {
|
|
17
|
-
console.log('[Mock] resumeCheckout called', params);
|
|
18
|
-
const href = params?.url ?? (typeof window === 'undefined' ? '' : window.location.href);
|
|
19
|
-
let redirectResult = null;
|
|
20
|
-
try {
|
|
21
|
-
redirectResult = new URL(href).searchParams.get('redirectResult');
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
redirectResult = null;
|
|
25
|
-
}
|
|
26
|
-
if (!redirectResult) {
|
|
27
|
-
return {
|
|
28
|
-
success: true,
|
|
29
|
-
timestamp: new Date().toISOString(),
|
|
30
|
-
checkout: { resumed: false },
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
const suffix = String(Date.now()).slice(-6);
|
|
34
|
-
const checkout = {
|
|
35
|
-
resumed: true,
|
|
36
|
-
orderId: `mock-order-${suffix}`,
|
|
37
|
-
receiptId: `ON-001-${suffix}`,
|
|
38
|
-
// `Authorised` is what the real provider reports for a completed redirect.
|
|
39
|
-
// It is NOT settlement — see the checkout topic docs.
|
|
40
|
-
resultCode: 'Authorised',
|
|
41
|
-
sessionResult: `mock-session-result-${suffix}`,
|
|
42
|
-
orderPassword: `mock-pw-${suffix}`,
|
|
43
|
-
};
|
|
44
|
-
mockPublishEvent('checkout', 'payment-completed', {
|
|
45
|
-
orderId: checkout.orderId,
|
|
46
|
-
receiptId: checkout.receiptId,
|
|
47
|
-
resultCode: checkout.resultCode,
|
|
48
|
-
sessionResult: checkout.sessionResult,
|
|
49
|
-
});
|
|
50
|
-
return { success: true, timestamp: new Date().toISOString(), checkout };
|
|
51
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export interface ResumeCheckoutParams {
|
|
2
|
-
/**
|
|
3
|
-
* Where to read the provider's return data from. Defaults to the current
|
|
4
|
-
* page URL, which is where the shopper has just landed.
|
|
5
|
-
*
|
|
6
|
-
* Only override this if you moved the query string somewhere else before
|
|
7
|
-
* calling — for example if your router strips it on mount.
|
|
8
|
-
*/
|
|
9
|
-
url?: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* What the return leg produced. Every field past `resumed` is absent when
|
|
13
|
-
* `resumed` is `false`.
|
|
14
|
-
*/
|
|
15
|
-
export interface ResumeCheckoutResult {
|
|
16
|
-
/**
|
|
17
|
-
* `false` means THIS WAS AN ORDINARY PAGE LOAD — no provider return data was
|
|
18
|
-
* in the URL, so there was nothing to finish and nothing happened. It is not
|
|
19
|
-
* an error, and it is the answer on every normal visit to the page. Call this
|
|
20
|
-
* unconditionally when your checkout or confirmation screen mounts and branch
|
|
21
|
-
* on this field.
|
|
22
|
-
*/
|
|
23
|
-
resumed: boolean;
|
|
24
|
-
orderId?: string;
|
|
25
|
-
receiptId?: string;
|
|
26
|
-
/**
|
|
27
|
-
* The provider's result code for the completed attempt, e.g. `Authorised` or
|
|
28
|
-
* `Refused`. As everywhere else in this topic, `Authorised` is an
|
|
29
|
-
* authorisation and NOT a settlement.
|
|
30
|
-
*/
|
|
31
|
-
resultCode?: string;
|
|
32
|
-
/** Opaque proof of the payment — see `PaymentCompletedPayload.sessionResult`. */
|
|
33
|
-
sessionResult?: string;
|
|
34
|
-
/**
|
|
35
|
-
* The one-time order password from the original checkout, recovered from
|
|
36
|
-
* browser storage. The page that held it in memory is gone, so this is the
|
|
37
|
-
* only way back to the order's status after a redirect.
|
|
38
|
-
*/
|
|
39
|
-
orderPassword?: string;
|
|
40
|
-
}
|
|
41
|
-
export interface ResumeCheckoutResponse {
|
|
42
|
-
success: boolean;
|
|
43
|
-
timestamp: string;
|
|
44
|
-
checkout: ResumeCheckoutResult;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Finish a checkout the shopper was redirected away from.
|
|
48
|
-
*
|
|
49
|
-
* SAFE TO CALL ON EVERY PAGE LOAD, and that is how it is meant to be used: on
|
|
50
|
-
* an ordinary visit it finds no return data and answers `{ resumed: false }`
|
|
51
|
-
* without touching the network. Calling it twice for one return is also safe —
|
|
52
|
-
* the return data is consumed the first time.
|
|
53
|
-
*
|
|
54
|
-
* The outcome is ALSO published on the `checkout` topic (`payment-completed` or
|
|
55
|
-
* `payment-failed`), exactly as it would have been had the shopper never left,
|
|
56
|
-
* so a page that already subscribes needs no second code path. Subscribe first,
|
|
57
|
-
* then call this, or the event fires before you are listening.
|
|
58
|
-
*/
|
|
59
|
-
export type ResumeCheckout = (params?: ResumeCheckoutParams) => Promise<ResumeCheckoutResponse>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Resume Checkout Types
|
|
2
|
-
//
|
|
3
|
-
// The RETURN LEG of an online checkout. Some payment methods — and 3-D Secure
|
|
4
|
-
// on a card — take the shopper away to their bank or wallet and send them back
|
|
5
|
-
// to `returnUrl` on a FRESH PAGE LOAD. The payment is not finished at that
|
|
6
|
-
// point: the provider hands the browser a one-time result in the URL, and it
|
|
7
|
-
// has to be handed back to the provider to complete the charge.
|
|
8
|
-
//
|
|
9
|
-
// `startCheckout` cannot do this. It ran in the page that is now gone.
|
|
10
|
-
//
|
|
11
|
-
// Served ONLY by the storefront runtime (a published website), like
|
|
12
|
-
// `startCheckout`. On a register it does not exist.
|
|
13
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SelectShippingOption action
|
|
3
|
-
* Calls the selectShippingOption action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const selectShippingOption = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('selectShippingOption', params);
|
|
8
|
-
};
|