@final-commerce/command-frame 0.8.0-online.1 → 0.8.0-online.2
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/actions/resume-checkout/action.d.ts +6 -0
- package/dist/actions/resume-checkout/action.js +8 -0
- package/dist/actions/resume-checkout/mock.d.ts +16 -0
- package/dist/actions/resume-checkout/mock.js +51 -0
- package/dist/actions/resume-checkout/types.d.ts +59 -0
- package/dist/actions/resume-checkout/types.js +13 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/projects/render/mocks.js +2 -0
- package/dist/projects/render/types.d.ts +7 -1
- package/dist/pubsub/topics/checkout/payment-completed/types.d.ts +12 -0
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
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;
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
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>;
|
|
@@ -0,0 +1,13 @@
|
|
|
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 {};
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export declare const command: {
|
|
|
44
44
|
readonly createPaymentLink: import(".").CreatePaymentLink;
|
|
45
45
|
readonly chargeMoto: import(".").ChargeMoto;
|
|
46
46
|
readonly startCheckout: import(".").StartCheckout;
|
|
47
|
+
readonly resumeCheckout: import(".").ResumeCheckout;
|
|
47
48
|
readonly addCustomerNote: import(".").AddCustomerNote;
|
|
48
49
|
readonly removeCustomerNote: import(".").RemoveCustomerNote;
|
|
49
50
|
readonly removeCustomerFromCart: import(".").RemoveCustomerFromCart;
|
|
@@ -180,6 +181,7 @@ export type { IntegrationPayment, IntegrationPaymentParams, IntegrationPaymentRe
|
|
|
180
181
|
export type { CreatePaymentLink, CreatePaymentLinkParams, CreatePaymentLinkResponse, } from './actions/create-payment-link/types';
|
|
181
182
|
export type { ChargeMoto, ChargeMotoParams, ChargeMotoResponse, ChargeMotoCardFields, } from './actions/charge-moto/types';
|
|
182
183
|
export type { StartCheckout, StartCheckoutParams, StartCheckoutResponse, StartCheckoutContact, StartCheckoutOrder, } from './actions/start-checkout/types';
|
|
184
|
+
export type { ResumeCheckout, ResumeCheckoutParams, ResumeCheckoutResponse, ResumeCheckoutResult, } from './actions/resume-checkout/types';
|
|
183
185
|
export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse, } from './actions/add-customer-note/types';
|
|
184
186
|
export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse, } from './actions/remove-customer-note/types';
|
|
185
187
|
export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from './actions/remove-customer-from-cart/types';
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ import { integrationPayment } from './actions/integration-payment/action';
|
|
|
44
44
|
import { createPaymentLink } from './actions/create-payment-link/action';
|
|
45
45
|
import { chargeMoto } from './actions/charge-moto/action';
|
|
46
46
|
import { startCheckout } from './actions/start-checkout/action';
|
|
47
|
+
import { resumeCheckout } from './actions/resume-checkout/action';
|
|
47
48
|
// Customer Actions
|
|
48
49
|
import { addCustomerNote } from './actions/add-customer-note/action';
|
|
49
50
|
import { removeCustomerNote } from './actions/remove-customer-note/action';
|
|
@@ -182,6 +183,7 @@ export const command = {
|
|
|
182
183
|
createPaymentLink,
|
|
183
184
|
chargeMoto,
|
|
184
185
|
startCheckout,
|
|
186
|
+
resumeCheckout,
|
|
185
187
|
// Customer Actions
|
|
186
188
|
addCustomerNote,
|
|
187
189
|
removeCustomerNote,
|
|
@@ -32,6 +32,7 @@ import { mockGetCashRoundingAmount } from '../../actions/get-cash-rounding-amoun
|
|
|
32
32
|
import { mockCreatePaymentLink } from '../../actions/create-payment-link/mock';
|
|
33
33
|
import { mockChargeMoto } from '../../actions/charge-moto/mock';
|
|
34
34
|
import { mockStartCheckout } from '../../actions/start-checkout/mock';
|
|
35
|
+
import { mockResumeCheckout } from '../../actions/resume-checkout/mock';
|
|
35
36
|
import { mockGetTimeClockStatus } from '../../actions/get-time-clock-status/mock';
|
|
36
37
|
import { mockClearCart } from '../../actions/clear-cart/mock';
|
|
37
38
|
import { mockDeleteParkedOrder } from '../../actions/delete-parked-order/mock';
|
|
@@ -130,6 +131,7 @@ export const RENDER_MOCKS = {
|
|
|
130
131
|
createPaymentLink: mockCreatePaymentLink,
|
|
131
132
|
chargeMoto: mockChargeMoto,
|
|
132
133
|
startCheckout: mockStartCheckout,
|
|
134
|
+
resumeCheckout: mockResumeCheckout,
|
|
133
135
|
clearCart: mockClearCart,
|
|
134
136
|
deleteParkedOrder: mockDeleteParkedOrder,
|
|
135
137
|
voidOrder: mockVoidOrder,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, 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, CreatePaymentLink, ChargeMoto, StartCheckout, GetTimeClockStatus } from '../../index';
|
|
1
|
+
import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, 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, CreatePaymentLink, ChargeMoto, StartCheckout, ResumeCheckout, GetTimeClockStatus } from '../../index';
|
|
2
2
|
export interface RenderProviderActions {
|
|
3
3
|
exampleFunction: ExampleFunction;
|
|
4
4
|
getProducts: GetProducts;
|
|
@@ -49,6 +49,12 @@ export interface RenderProviderActions {
|
|
|
49
49
|
* a register, because the two declare different things to the card networks.
|
|
50
50
|
*/
|
|
51
51
|
startCheckout: StartCheckout;
|
|
52
|
+
/**
|
|
53
|
+
* The RETURN LEG of an online checkout, after a redirect payment method or
|
|
54
|
+
* 3-D Secure sent the shopper away and back. Storefront-only, like
|
|
55
|
+
* `startCheckout`, and safe to call on every page load.
|
|
56
|
+
*/
|
|
57
|
+
resumeCheckout: ResumeCheckout;
|
|
52
58
|
addNonRevenueItem: AddNonRevenueItem;
|
|
53
59
|
addCustomerNote: AddCustomerNote;
|
|
54
60
|
removeCustomerNote: RemoveCustomerNote;
|
|
@@ -12,6 +12,18 @@ export interface PaymentCompletedPayload {
|
|
|
12
12
|
receiptId: string;
|
|
13
13
|
/** The provider's result code, e.g. `Authorised`. */
|
|
14
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;
|
|
15
27
|
}
|
|
16
28
|
/**
|
|
17
29
|
* Typed event for payment-completed
|