@final-commerce/command-frame 0.4.0-preprod.1 → 0.4.1-preprod.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/README.md CHANGED
@@ -10,13 +10,13 @@ Command Frame provides a structured way to build integrations that run inside Fi
10
10
 
11
11
  The library provides three main capabilities:
12
12
 
13
- | Capability | Purpose | Scope |
14
- | ------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------- |
15
- | **Commands** | Call host functions from the iframe (e.g. get products, open cash drawer) | Request/response per call |
16
- | **Pub/Sub** | Subscribe to real-time events from the host (e.g. cart changes, payments) | Page-scoped (while iframe is mounted) |
17
- | **Hooks** | Register business-logic callbacks that persist across all pages | Session-scoped (survives page navigation) |
18
- | **Interceptors** | Gate POS flows (approve / modify / block) at named points | Blocking; host waits for your response |
19
- | **Host → iframe refunds** | Render asks the extension to reverse redeem / gift-card payments before completing a POS refund | Parent `postMessage` + `requestId` (see below) |
13
+ | Capability | Purpose | Scope |
14
+ | ------------------- | ------------------------------------------------------------------------- | ----------------------------------------- |
15
+ | **Commands** | Call host functions from the iframe (e.g. get products, open cash drawer) | Request/response per call |
16
+ | **Pub/Sub** | Subscribe to real-time events from the host (e.g. cart changes, payments) | Page-scoped (while iframe is mounted) |
17
+ | **Hooks** | Register business-logic callbacks that persist across all pages | Session-scoped (survives page navigation) |
18
+ | **Interceptors** | Gate POS flows (approve / modify / block) at named points | Blocking; host waits for your response |
19
+ | **Refund commands** | Refund payments to gift cards or redeem tenders via `redeemRefund`, or mixed-destination legs on `processPartialRefund`; query engine capacity with `getRefundPlan` | Request/response per call |
20
20
 
21
21
  Domain models (orders, cart, customers, products, and related types) are documented in **[Types reference](./src/types/README.md)**.
22
22
 
@@ -158,40 +158,29 @@ interceptors.register(
158
158
  );
159
159
  ```
160
160
 
161
- ## Host-initiated extension refunds (redeem / gift card)
161
+ ## Refunding redeem / extension payments
162
162
 
163
- **Extensions that accept redeem / extension payments must implement a refund listener.** When staff refund an order paid with `paymentType: "redeem"`, Render (host) `postMessage`s into your iframe **before** it records the refund locally. If your app does not handle this message, redeem refunds will time out or fail.
163
+ When staff refund an order that was paid with `paymentType: "redeem"` (via `redeemPayment` or `extensionPayment`), use the **`redeemRefund`** command to refund the amount onto a gift card or redeem tender.
164
164
 
165
- ### What you should do
166
-
167
- 1. **Recommended:** call **`installExtensionRefundListener`** once when your extension boots (e.g. next to your `RenderClient` setup). Pass an `async` handler that calls your provider (gift card API, wallet, etc.) and returns an **`ExtensionRefundResponse`** (`success`, optional `error`, optional `extensionTransactionId` for receipts / support).
168
- 2. The helper validates `event.source === window.top`, parses params, and replies with the same **`PostMessageResponse`** envelope as the rest of Command Frame (`requestId`, `success`, `data` / `error`).
169
- 3. **Alternative:** implement a `window` `message` listener yourself using the same contract (action name: **`extensionRefundRequest`**, or import **`EXTENSION_REFUND_REQUEST_ACTION`** from this package).
170
-
171
- Exported APIs: `installExtensionRefundListener`, `EXTENSION_REFUND_REQUEST_ACTION`, types **`ExtensionRefundParams`** / **`ExtensionRefundResponse`**.
165
+ **Key point:** Plain refunds on redeem sources still fail by design (`REDEEM_REFUND_UNSUPPORTED`). Use `redeemRefund` to refund onto a gift card when your extension credits the card first.
172
166
 
173
167
  ```typescript
174
- import {
175
- installExtensionRefundListener,
176
- type ExtensionRefundParams,
177
- type ExtensionRefundResponse,
178
- } from '@final-commerce/command-frame';
179
-
180
- const unsubscribe = installExtensionRefundListener(
181
- async (params: ExtensionRefundParams): Promise<ExtensionRefundResponse> => {
182
- // params.paymentType === "redeem", params.amount in major currency units, params.saleId, params.processor, etc.
183
- const ok = await myGiftCardProvider.refund(params);
184
- return ok
185
- ? { success: true, extensionTransactionId: ok.providerRefundId }
186
- : { success: false, error: 'Refund declined' };
187
- },
188
- );
189
-
190
- // on teardown (optional)
191
- // unsubscribe();
168
+ import { command } from '@final-commerce/command-frame';
169
+
170
+ // Refund a redeem order back onto a gift card
171
+ const result = await command.redeemRefund({
172
+ orderId: 'order_123',
173
+ amount: 2500, // $25.00
174
+ referenceId: 'GIFTCARD-456', // destination card
175
+ processor: 'giftCard',
176
+ label: 'Gift Card Refund',
177
+ reason: 'Customer requested return',
178
+ });
192
179
  ```
193
180
 
194
- **Full protocol, edge cases, and manual handling:** **[Extension refund documentation](./src/actions/extension-refund/README.md)**.
181
+ **Full documentation:** **[redeemRefund](./src/actions/redeem-refund/README.md)**.
182
+
183
+ Before prompting the cashier for an amount, query **[getRefundPlan](./src/actions/get-refund-plan/README.md)** (read-only) for the order's own per-source caps (`maxRefundable`, `cardNumber` for same-card prefill) and order-level `remainingRefundable` — don't recompute this client-side, and always handle a `REFUND_AMOUNT_EXCEEDS_CAPACITY` rejection from the mutating call since the plan is only an advisory snapshot.
195
184
 
196
185
  ## Development & Testing
197
186
 
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Get refund plan action
3
+ * Calls the getRefundPlan action on the parent window
4
+ */
5
+ import type { GetRefundPlan } from './types';
6
+ export declare const getRefundPlan: GetRefundPlan;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Get refund plan action
3
+ * Calls the getRefundPlan action on the parent window
4
+ */
5
+ import { commandFrameClient } from '../../client';
6
+ export const getRefundPlan = async (params) => {
7
+ return await commandFrameClient.call('getRefundPlan', params);
8
+ };
@@ -0,0 +1,14 @@
1
+ import { GetRefundPlan } from './types';
2
+ /**
3
+ * Demo derivation of the runtime `getRefundPlan`. Builds the per-source rows
4
+ * from the mock order's `paymentMethods`, mirroring the runtime's capacity
5
+ * definition (principal + captured tip).
6
+ *
7
+ * HONEST INERTNESS: the demo DB records no prior-refund ledger and no `emv`
8
+ * blocks on its mock captures, so this mock reports `refundedAmount: 0` /
9
+ * `totalRefunded: 0` and `cardNumber: undefined` for every source, and treats
10
+ * `maxRefundable` as the full captured amount. Against real kaching those
11
+ * numbers come from `order.refund[]` and the capture's `emv` JSON. Use this
12
+ * only to shape UI in local/standalone mode — never to assert real capacity.
13
+ */
14
+ export declare const mockGetRefundPlan: GetRefundPlan;
@@ -0,0 +1,59 @@
1
+ import { MOCK_ORDERS } from '../../demo/database';
2
+ /**
3
+ * Demo derivation of the runtime `getRefundPlan`. Builds the per-source rows
4
+ * from the mock order's `paymentMethods`, mirroring the runtime's capacity
5
+ * definition (principal + captured tip).
6
+ *
7
+ * HONEST INERTNESS: the demo DB records no prior-refund ledger and no `emv`
8
+ * blocks on its mock captures, so this mock reports `refundedAmount: 0` /
9
+ * `totalRefunded: 0` and `cardNumber: undefined` for every source, and treats
10
+ * `maxRefundable` as the full captured amount. Against real kaching those
11
+ * numbers come from `order.refund[]` and the capture's `emv` JSON. Use this
12
+ * only to shape UI in local/standalone mode — never to assert real capacity.
13
+ */
14
+ export const mockGetRefundPlan = async (params) => {
15
+ console.log('[Mock] getRefundPlan called', params);
16
+ const order = params?.orderId ? MOCK_ORDERS.find((o) => o._id === params.orderId) : MOCK_ORDERS[0];
17
+ if (!order) {
18
+ throw new Error(`Order with ID ${params?.orderId} not found`);
19
+ }
20
+ const capturedOf = (pm) => Math.round(pm.amount ?? 0) + Math.round(pm.tip?.amount ?? 0);
21
+ const sources = (order.paymentMethods ?? []).map((pm) => {
22
+ const captured = capturedOf(pm);
23
+ let cardNumber;
24
+ // Demo captures carry no emv, so this is always undefined here; kept to
25
+ // document the runtime's redeem-source card-number extraction.
26
+ if (pm.paymentType === 'redeem' && pm.emv) {
27
+ try {
28
+ cardNumber = JSON.parse(pm.emv)['Card Number'];
29
+ }
30
+ catch {
31
+ cardNumber = undefined;
32
+ }
33
+ }
34
+ return {
35
+ transactionId: pm.transactionId,
36
+ paymentType: pm.paymentType,
37
+ processor: pm.processor ?? undefined,
38
+ capturedAmount: captured,
39
+ // Demo DB has no refund ledger — nothing has been refunded yet here.
40
+ refundedAmount: 0,
41
+ maxRefundable: captured,
42
+ refundableToSource: pm.paymentType !== 'redeem',
43
+ cardNumber,
44
+ };
45
+ });
46
+ const totalCaptured = sources.reduce((sum, s) => sum + s.capturedAmount, 0);
47
+ const nonRefundableLiability = order.summary?.nonRevenueTotal ?? 0;
48
+ return {
49
+ success: true,
50
+ orderId: order._id,
51
+ sources,
52
+ // Demo: no prior refunds, so remaining = captured minus the non-revenue load.
53
+ remainingRefundable: Math.max(0, totalCaptured - nonRefundableLiability),
54
+ nonRefundableLiability,
55
+ totalCaptured,
56
+ totalRefunded: 0,
57
+ timestamp: new Date().toISOString(),
58
+ };
59
+ };
@@ -0,0 +1,32 @@
1
+ export interface GetRefundPlanParams {
2
+ /** Order to inspect; defaults to the active order. */
3
+ orderId?: string;
4
+ }
5
+ export interface RefundPlanSource {
6
+ transactionId: string;
7
+ paymentType: string;
8
+ processor?: string;
9
+ /** Captured on this payment (minor units). */
10
+ capturedAmount: number;
11
+ /** Already refunded against this source (minor units). */
12
+ refundedAmount: number;
13
+ /** Remaining refundable on this source (minor units) — the engine's own per-source cap. */
14
+ maxRefundable: number;
15
+ /** False for sources the engine cannot refund to directly (redeem without a gift-card destination). */
16
+ refundableToSource: boolean;
17
+ /** For redeem sources: the card number from the payment entry's emv, when present. */
18
+ cardNumber?: string;
19
+ }
20
+ export interface GetRefundPlanResponse {
21
+ success: boolean;
22
+ orderId: string;
23
+ sources: RefundPlanSource[];
24
+ /** Order-level remaining refundable (minor units) — non-revenue liability already excluded. */
25
+ remainingRefundable: number;
26
+ /** Non-refundable liability (gift-card loads etc., minor units). */
27
+ nonRefundableLiability: number;
28
+ totalCaptured: number;
29
+ totalRefunded: number;
30
+ timestamp: string;
31
+ }
32
+ export type GetRefundPlan = (params?: GetRefundPlanParams) => Promise<GetRefundPlanResponse>;
@@ -0,0 +1,7 @@
1
+ // Get Refund Plan Types
2
+ //
3
+ // READ-ONLY capacity query. Exposes the refund engine's OWN per-source and
4
+ // order-level math so flows can PRESENT accurate refund options without
5
+ // re-deriving the numbers client-side (the mutating commands —
6
+ // `processPartialRefund` / `redeemRefund` — re-validate at submit time).
7
+ export {};
@@ -1,5 +1,13 @@
1
1
  export const mockProcessPartialRefund = async (params) => {
2
- console.log("[Mock] processPartialRefund called", params);
2
+ // The mock has no split-payment modal or order engine, so `openUI` (default
3
+ // true on the real command), `legs` (the headless per-tender allocation) and
4
+ // any per-leg `giftCard` destination (mixed returns) are inert here — the
5
+ // shape is accepted and echoed, nothing else. No gift card is credited.
6
+ console.log("[Mock] processPartialRefund called", {
7
+ ...params,
8
+ openUI: params?.openUI ?? true,
9
+ legs: params?.legs ?? null,
10
+ });
3
11
  return {
4
12
  success: true,
5
13
  refundId: 'mock_refund_' + Date.now(),
@@ -1,15 +1,113 @@
1
1
  import type { CFTransitionResult } from "../../common-types/order-state";
2
2
  export interface ProcessPartialRefundParams {
3
- /** Optional refund reason. */
3
+ /**
4
+ * Optional refund reason.
5
+ *
6
+ * KNOWN LIMITATION: not currently persisted on the `Refund` doc or the
7
+ * state-event audit row via this command — the runtime falls back to a
8
+ * fixed 'partial-refund' label instead. Unlike `redeemRefund`, whose
9
+ * `reason` IS recorded. See the README's "Known limitation" section.
10
+ */
4
11
  reason?: string;
5
12
  /** Optional: specify which order to refund (sets it as active). */
6
13
  orderId?: string;
14
+ /**
15
+ * Controls the refund UI for a MULTI-TENDER order (one paid across more
16
+ * than one payment method). Defaults to `true`.
17
+ *
18
+ * - `true` (default, back-compat): the POS raises its split-payment refund
19
+ * modal so the cashier allocates the refund across the original payment
20
+ * sources; `processPartialRefund` returns without committing and the
21
+ * modal drives the commit.
22
+ * - `false`: no modal is raised — the refund is committed headlessly
23
+ * against the planner's default proportional allocation across those
24
+ * sources (all cash-rounding invariants preserved). Use this when your
25
+ * flow renders its own refund UI and needs a fully headless multi-tender
26
+ * partial refund.
27
+ *
28
+ * Has no effect on single-tender orders (already headless — there is
29
+ * nothing to allocate).
30
+ */
31
+ openUI?: boolean;
32
+ /**
33
+ * Explicit per-tender allocation for the refund — the headless replacement
34
+ * for choosing, in the split-payment refund modal, WHICH original payment
35
+ * each refunded dollar returns to. Each entry names an original payment by
36
+ * its `transactionId` and the amount, **in minor units** (cents), to return
37
+ * to that source.
38
+ *
39
+ * Requires `openUI: false` — with the modal path (`openUI` omitted/`true`)
40
+ * the modal owns allocation and `legs` are ignored. Validation:
41
+ * - Σ of all `amount`s **must equal the allocatable refund budget** —
42
+ * `min(the refund total computed from the selected items, Σ of each
43
+ * source's remaining refundable capacity)`; on a full selection this is
44
+ * the captured total and the cash-rounding gap is auto-stamped (a
45
+ * mismatch throws; nothing is committed);
46
+ * - the amounts **aggregated per source** must be ≤ that source's remaining
47
+ * refundable capacity (over-cap throws, naming the source);
48
+ * - a **zero** `amount` entry is IGNORED — dropped like an omitted row,
49
+ * matching the modal (which let a cashier leave a tender at 0 and filtered
50
+ * it at commit) — while a **negative** `amount` is rejected;
51
+ * - an unknown `transactionId` throws, naming it.
52
+ *
53
+ * MIXED RETURNS — set `giftCard` on a leg to land that leg's amount on a
54
+ * gift-card / store-credit tender instead of returning it to the source. A
55
+ * single `legs` array may freely mix source-return legs and `giftCard` legs
56
+ * (some money back to the original tenders, the rest onto a card). An
57
+ * all-`giftCard` staging is the `redeemRefund` equivalent through this path.
58
+ * **Credit-first:** the flow must credit the card for the sum of all
59
+ * `giftCard` legs BEFORE calling; on any throw nothing was recorded — reverse
60
+ * the credit.
61
+ *
62
+ * Omit `legs` to keep the default proportional allocation across sources.
63
+ * See "Choosing which payments to refund to" and "Mixed returns" in the README.
64
+ */
65
+ legs?: {
66
+ /** `transactionId` of the original payment this leg draws from. */
67
+ transactionId: string;
68
+ /** Amount for this leg, in minor units (cents). `0` is ignored (dropped
69
+ * like an omitted row); a negative value is rejected. */
70
+ amount: number;
71
+ /**
72
+ * When set, this leg's amount lands on the gift-card / store-credit
73
+ * ("redeem") tender instead of returning to the source. The leg still
74
+ * draws from `transactionId` for capacity/audit — only the landing
75
+ * tender changes.
76
+ *
77
+ * CREDIT-FIRST: the flow must have already credited the card for the sum
78
+ * of all `giftCard` legs before calling; on any throw nothing was
79
+ * recorded and the caller must reverse that credit. `referenceId` is
80
+ * required when `giftCard` is present.
81
+ */
82
+ giftCard?: {
83
+ /** Card/account id the flow already credited (stored raw). */
84
+ referenceId: string;
85
+ /** Provider/program name. Defaults to `giftCard`. */
86
+ processor?: string;
87
+ /** Human label for the destination tender. */
88
+ label?: string;
89
+ };
90
+ }[];
7
91
  /** Optional items to refund. */
8
92
  items?: {
9
93
  /** internalId or variantId or customSaleId. */
10
94
  itemKey: string;
11
95
  quantity: number;
12
96
  type?: 'product' | 'customSale' | 'fee' | 'tip';
97
+ /**
98
+ * Per-item stock disposition for a refunded **product** line — the
99
+ * headless equivalent of the old refund popup's per-row restock/damaged
100
+ * dropdown. Recorded on the persisted refund line so hub-side inventory
101
+ * ingest knows whether the returned units go back on the shelf.
102
+ *
103
+ * - `'RESTOCK'` (default when omitted): units return to sellable stock
104
+ * — the popup's default first option.
105
+ * - `'REFUND_DAMAGE'`: units are written off as damaged, not restocked.
106
+ *
107
+ * Ignored for non-`product` items (custom sales / fees / tips carry no
108
+ * stock action, exactly as the popup only offered it on line items).
109
+ */
110
+ stockAction?: 'RESTOCK' | 'REFUND_DAMAGE';
13
111
  }[];
14
112
  }
15
113
  export interface ProcessPartialRefundResponse {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Redeem refund action
3
+ * Calls the redeemRefund action on the parent window
4
+ */
5
+ import type { RedeemRefund } from './types';
6
+ export declare const redeemRefund: RedeemRefund;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Redeem refund action
3
+ * Calls the redeemRefund action on the parent window
4
+ */
5
+ import { commandFrameClient } from '../../client';
6
+ export const redeemRefund = async (params) => {
7
+ return await commandFrameClient.call('redeemRefund', params);
8
+ };
@@ -0,0 +1,2 @@
1
+ import { RedeemRefund } from './types';
2
+ export declare const mockRedeemRefund: RedeemRefund;
@@ -0,0 +1,55 @@
1
+ import { MOCK_ORDERS, mockPublishEvent } from '../../demo/database';
2
+ // Track refunded amounts per order to enforce remaining capacity gate
3
+ const mockRefundedAmounts = {};
4
+ export const mockRedeemRefund = async (params) => {
5
+ console.log('[Mock] redeemRefund called', params);
6
+ // Validate required params
7
+ if (!params.amount || params.amount <= 0) {
8
+ throw new Error('Amount must be greater than 0');
9
+ }
10
+ if (!params.referenceId) {
11
+ throw new Error('referenceId is required');
12
+ }
13
+ // Find order
14
+ const order = params.orderId ? MOCK_ORDERS.find((o) => o._id === params.orderId) : MOCK_ORDERS[0];
15
+ if (!order) {
16
+ throw new Error(`Order with ID ${params.orderId} not found`);
17
+ }
18
+ const orderId = order._id;
19
+ // NO payment-state gate — the runtime has none (partially_paid orders are
20
+ // refundable too); mirroring it here would teach devs a phantom error class.
21
+ // Track refunded amounts and check remaining capacity
22
+ const refundedSoFar = mockRefundedAmounts[orderId] || 0;
23
+ const remainingCapacity = order.summary.total - refundedSoFar;
24
+ if (params.amount > remainingCapacity) {
25
+ throw new Error(`REFUND_AMOUNT_EXCEEDS_CAPACITY: Refund amount ${params.amount} exceeds remaining refundable capacity ${remainingCapacity}`);
26
+ }
27
+ // Update refunded amount tracking
28
+ const refundedAfter = refundedSoFar + params.amount;
29
+ mockRefundedAmounts[orderId] = refundedAfter;
30
+ // Update order state based on remaining capacity after this refund
31
+ const remainingAfterRefund = order.summary.total - refundedAfter;
32
+ if (remainingAfterRefund > 0) {
33
+ order.paymentState = 'partially_refunded';
34
+ }
35
+ else {
36
+ order.paymentState = 'refunded';
37
+ }
38
+ // Publish refund event
39
+ mockPublishEvent('refunds', 'refund-created', {
40
+ orderId,
41
+ amount: params.amount,
42
+ referenceId: params.referenceId,
43
+ processor: params.processor || 'giftCard',
44
+ label: params.label,
45
+ reason: params.reason,
46
+ });
47
+ return {
48
+ success: true,
49
+ orderId,
50
+ amount: params.amount,
51
+ referenceId: params.referenceId,
52
+ legCount: 1,
53
+ timestamp: new Date().toISOString(),
54
+ };
55
+ };
@@ -0,0 +1,39 @@
1
+ export interface RedeemRefundParams {
2
+ /** Order to refund; defaults to the active order. */
3
+ orderId?: string;
4
+ /**
5
+ * Amount to refund onto the redeem tender, integer MINOR currency units
6
+ * (1575 = $15.75). Required; must be > 0 and within the order's remaining
7
+ * refundable capacity (tip-inclusive, across all source payments).
8
+ */
9
+ amount: number;
10
+ /**
11
+ * Destination card/account identifier the funds were credited to
12
+ * (e.g. the gift-card number). Recorded in the emv block (`'Card Number'`)
13
+ * of every refund payment entry on the order, and in paymentData on the
14
+ * local transaction rows, for the audit trail. Required.
15
+ */
16
+ referenceId: string;
17
+ /** Destination provider label; defaults to "giftCard" (matches redeemPayment). */
18
+ processor?: string;
19
+ /** Human-readable label for receipts/reporting. */
20
+ label?: string;
21
+ /** Extension identity, recorded on the legs when provided. */
22
+ extensionId?: string;
23
+ /** Opaque extension payload, recorded on the legs when provided. */
24
+ metadata?: Record<string, unknown>;
25
+ /** Cashier-facing reason, recorded on the refund + state-event audit rows. */
26
+ reason?: string;
27
+ }
28
+ export interface RedeemRefundResponse {
29
+ success: boolean;
30
+ orderId: string;
31
+ /** Total refunded onto the redeem tender (minor units). */
32
+ amount: number;
33
+ /** Echo of the destination identifier the legs were recorded against. */
34
+ referenceId: string;
35
+ /** Number of source payments the amount was drawn from. */
36
+ legCount: number;
37
+ timestamp: string;
38
+ }
39
+ export type RedeemRefund = (params: RedeemRefundParams) => Promise<RedeemRefundResponse>;
@@ -0,0 +1,2 @@
1
+ // Redeem Refund Types
2
+ export {};
package/dist/index.d.ts CHANGED
@@ -80,6 +80,8 @@ export declare const command: {
80
80
  readonly calculateRefundTotal: import(".").CalculateRefundTotal;
81
81
  readonly getRemainingRefundableQuantities: import(".").GetRemainingRefundableQuantities;
82
82
  readonly processPartialRefund: import(".").ProcessPartialRefund;
83
+ readonly redeemRefund: import(".").RedeemRefund;
84
+ readonly getRefundPlan: import(".").GetRefundPlan;
83
85
  readonly addProduct: import(".").AddProduct;
84
86
  readonly editProduct: import(".").EditProduct;
85
87
  readonly editProductVariants: import(".").EditProductVariants;
@@ -138,6 +140,8 @@ export type { ResetRefundDetails, ResetRefundDetailsResponse } from './actions/r
138
140
  export type { CalculateRefundTotal, CalculateRefundTotalParams, CalculateRefundTotalResponse, } from './actions/calculate-refund-total/types';
139
141
  export type { GetRemainingRefundableQuantities, GetRemainingRefundableQuantitiesParams, GetRemainingRefundableQuantitiesResponse, } from './actions/get-remaining-refundable-quantities/types';
140
142
  export type { ProcessPartialRefund, ProcessPartialRefundParams, ProcessPartialRefundResponse, } from './actions/process-partial-refund/types';
143
+ export type { RedeemRefund, RedeemRefundParams, RedeemRefundResponse } from './actions/redeem-refund/types';
144
+ export type { GetRefundPlan, GetRefundPlanParams, GetRefundPlanResponse, RefundPlanSource, } from './actions/get-refund-plan/types';
141
145
  export type { InitiateRefund, InitiateRefundParams, InitiateRefundResponse } from './actions/initiate-refund/types';
142
146
  export type { OpenExtensionOverlay, OpenExtensionOverlayParams, OpenExtensionOverlayResponse, } from './actions/open-extension-overlay/types';
143
147
  export type { ResolveExtensionOverlay, ResolveExtensionOverlayParams, ResolveExtensionOverlayResponse, } from './actions/resolve-extension-overlay/types';
package/dist/index.js CHANGED
@@ -87,6 +87,8 @@ import { resetRefundDetails } from './actions/reset-refund-details/action';
87
87
  import { calculateRefundTotal } from './actions/calculate-refund-total/action';
88
88
  import { getRemainingRefundableQuantities } from './actions/get-remaining-refundable-quantities/action';
89
89
  import { processPartialRefund } from './actions/process-partial-refund/action';
90
+ import { redeemRefund } from './actions/redeem-refund/action';
91
+ import { getRefundPlan } from './actions/get-refund-plan/action';
90
92
  // Custom Tables Actions
91
93
  import { getCustomTables } from './actions/get-custom-tables/action';
92
94
  import { getCustomTableFields } from './actions/get-custom-table-fields/action';
@@ -217,6 +219,8 @@ export const command = {
217
219
  calculateRefundTotal,
218
220
  getRemainingRefundableQuantities,
219
221
  processPartialRefund,
222
+ redeemRefund,
223
+ getRefundPlan,
220
224
  // Product CRUD Actions
221
225
  addProduct,
222
226
  editProduct,
@@ -50,6 +50,8 @@ import { mockOpenCashDrawer } from '../../actions/open-cash-drawer/mock';
50
50
  import { mockParkOrder } from '../../actions/park-order/mock';
51
51
  import { mockPartialPayment } from '../../actions/partial-payment/mock';
52
52
  import { mockProcessPartialRefund } from '../../actions/process-partial-refund/mock';
53
+ import { mockRedeemRefund } from '../../actions/redeem-refund/mock';
54
+ import { mockGetRefundPlan } from '../../actions/get-refund-plan/mock';
53
55
  import { mockRemoveCustomerFromCart } from '../../actions/remove-customer-from-cart/mock';
54
56
  import { mockResetRefundDetails } from '../../actions/reset-refund-details/mock';
55
57
  import { mockResumeParkedOrder } from '../../actions/resume-parked-order/mock';
@@ -144,6 +146,8 @@ export const RENDER_MOCKS = {
144
146
  parkOrder: mockParkOrder,
145
147
  partialPayment: mockPartialPayment,
146
148
  processPartialRefund: mockProcessPartialRefund,
149
+ redeemRefund: mockRedeemRefund,
150
+ getRefundPlan: mockGetRefundPlan,
147
151
  removeCustomerFromCart: mockRemoveCustomerFromCart,
148
152
  removeCartDiscount: mockRemoveCartDiscount,
149
153
  resetRefundDetails: mockResetRefundDetails,
@@ -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, VendaraPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, 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 } 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, VendaraPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, RedeemRefund, GetRefundPlan, 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 } from '../../index';
2
2
  import type { OpenExtensionOverlay } from '../../actions/open-extension-overlay/types';
3
3
  import type { ResolveExtensionOverlay } from '../../actions/resolve-extension-overlay/types';
4
4
  export interface RenderProviderActions {
@@ -64,6 +64,8 @@ export interface RenderProviderActions {
64
64
  calculateRefundTotal: CalculateRefundTotal;
65
65
  getRemainingRefundableQuantities: GetRemainingRefundableQuantities;
66
66
  processPartialRefund: ProcessPartialRefund;
67
+ redeemRefund: RedeemRefund;
68
+ getRefundPlan: GetRefundPlan;
67
69
  getCurrentCart: GetCurrentCart;
68
70
  print: Print;
69
71
  setActiveOrder: SetActiveOrder;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/command-frame",
3
- "version": "0.4.0-preprod.1",
3
+ "version": "0.4.1-preprod.2",
4
4
  "description": "Commands Frame library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",