@sixtyninecommerce/admin 0.8.0 → 0.10.0

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 (179) hide show
  1. package/README.md +2739 -17
  2. package/dist/api-tokens/index.d.ts +15 -5
  3. package/dist/api-tokens/index.js +1 -0
  4. package/dist/apps/event-subscription.d.ts +59 -0
  5. package/dist/apps/event-subscription.js +32 -0
  6. package/dist/apps/hook-secret.d.ts +22 -0
  7. package/dist/apps/hook-secret.js +36 -0
  8. package/dist/apps/index.d.ts +54 -3
  9. package/dist/apps/index.js +17 -0
  10. package/dist/audit/index.d.ts +7 -0
  11. package/dist/auth/queries.d.ts +5 -1
  12. package/dist/auth/queries.js +6 -0
  13. package/dist/bulk/index.d.ts +323 -0
  14. package/dist/bulk/index.js +162 -0
  15. package/dist/catalog/assets.d.ts +147 -0
  16. package/dist/catalog/assets.js +164 -0
  17. package/dist/catalog/collections.d.ts +109 -0
  18. package/dist/catalog/collections.js +91 -0
  19. package/dist/catalog/facets.d.ts +103 -0
  20. package/dist/catalog/facets.js +100 -0
  21. package/dist/catalog/index.d.ts +115 -0
  22. package/dist/catalog/index.js +21 -0
  23. package/dist/catalog/options.d.ts +89 -0
  24. package/dist/catalog/options.js +88 -0
  25. package/dist/catalog/products-bulk.d.ts +21 -0
  26. package/dist/catalog/products-bulk.js +58 -0
  27. package/dist/catalog/products.d.ts +650 -0
  28. package/dist/catalog/products.js +458 -0
  29. package/dist/catalog/properties.d.ts +234 -0
  30. package/dist/catalog/properties.js +158 -0
  31. package/dist/catalog/types.d.ts +174 -0
  32. package/dist/catalog/types.js +141 -0
  33. package/dist/catalog/variants.d.ts +324 -0
  34. package/dist/catalog/variants.js +288 -0
  35. package/dist/catalog/visibility.d.ts +57 -0
  36. package/dist/catalog/visibility.js +59 -0
  37. package/dist/client.d.ts +192 -3
  38. package/dist/client.js +87 -12
  39. package/dist/compliance/index.d.ts +88 -0
  40. package/dist/compliance/index.js +88 -0
  41. package/dist/customer-data-redaction.d.ts +14 -0
  42. package/dist/customer-data-redaction.js +22 -0
  43. package/dist/customers/index.d.ts +428 -17
  44. package/dist/customers/index.js +322 -15
  45. package/dist/documents/index.d.ts +513 -16
  46. package/dist/documents/index.js +229 -3
  47. package/dist/events/index.d.ts +259 -0
  48. package/dist/events/index.js +147 -0
  49. package/dist/feeds/ai.d.ts +46 -0
  50. package/dist/feeds/ai.js +43 -0
  51. package/dist/feeds/categories.d.ts +50 -0
  52. package/dist/feeds/categories.js +56 -0
  53. package/dist/feeds/configs.d.ts +54 -0
  54. package/dist/feeds/configs.js +85 -0
  55. package/dist/feeds/identifier-fields.d.ts +25 -0
  56. package/dist/feeds/identifier-fields.js +29 -0
  57. package/dist/feeds/index.d.ts +54 -0
  58. package/dist/feeds/index.js +46 -0
  59. package/dist/feeds/preserve.d.ts +38 -0
  60. package/dist/feeds/preserve.js +74 -0
  61. package/dist/feeds/rules.d.ts +42 -0
  62. package/dist/feeds/rules.js +56 -0
  63. package/dist/feeds/types.d.ts +654 -0
  64. package/dist/feeds/types.js +135 -0
  65. package/dist/fulfillments/index.d.ts +437 -0
  66. package/dist/fulfillments/index.js +534 -0
  67. package/dist/heads/index.d.ts +60 -0
  68. package/dist/heads/index.js +45 -0
  69. package/dist/hooks/assignments.d.ts +90 -0
  70. package/dist/hooks/assignments.js +53 -0
  71. package/dist/hooks/index.d.ts +97 -0
  72. package/dist/hooks/index.js +76 -0
  73. package/dist/index.d.ts +95 -9
  74. package/dist/index.js +21 -1
  75. package/dist/integrations/index.d.ts +14 -0
  76. package/dist/integrations/index.js +9 -0
  77. package/dist/integrations/pipelines.d.ts +113 -0
  78. package/dist/integrations/pipelines.js +62 -0
  79. package/dist/integrations/types.d.ts +176 -0
  80. package/dist/integrations/types.js +8 -0
  81. package/dist/jobs/bulk-action-run.d.ts +74 -0
  82. package/dist/jobs/bulk-action-run.js +69 -0
  83. package/dist/locations/index.d.ts +6 -2
  84. package/dist/meta/index.d.ts +32 -0
  85. package/dist/orders/bulk.d.ts +75 -0
  86. package/dist/orders/bulk.js +150 -0
  87. package/dist/orders/commit-edit.d.ts +123 -0
  88. package/dist/orders/commit-edit.js +142 -0
  89. package/dist/orders/deposit-policy.d.ts +103 -0
  90. package/dist/orders/deposit-policy.js +202 -0
  91. package/dist/orders/get.d.ts +722 -0
  92. package/dist/orders/get.js +530 -0
  93. package/dist/orders/index.d.ts +186 -21
  94. package/dist/orders/index.js +57 -0
  95. package/dist/orders/line-price-preview.d.ts +297 -0
  96. package/dist/orders/line-price-preview.js +50 -0
  97. package/dist/orders/manual-discounts.d.ts +141 -0
  98. package/dist/orders/manual-discounts.js +97 -0
  99. package/dist/orders/manual-pricing.d.ts +192 -0
  100. package/dist/orders/manual-pricing.js +72 -0
  101. package/dist/orders/order-entry.d.ts +566 -0
  102. package/dist/orders/order-entry.js +129 -0
  103. package/dist/orders/parcel-charge.d.ts +45 -0
  104. package/dist/orders/parcel-charge.js +55 -0
  105. package/dist/orders/plan-edit.d.ts +489 -0
  106. package/dist/orders/plan-edit.js +93 -0
  107. package/dist/orders/status.d.ts +235 -0
  108. package/dist/orders/status.js +96 -0
  109. package/dist/orders/surcharges.d.ts +75 -2
  110. package/dist/orders/surcharges.js +110 -4
  111. package/dist/payments/account-credit.d.ts +171 -0
  112. package/dist/payments/account-credit.js +107 -0
  113. package/dist/payments/index.d.ts +241 -9
  114. package/dist/payments/index.js +92 -0
  115. package/dist/payments/methods.d.ts +37 -0
  116. package/dist/payments/methods.js +33 -0
  117. package/dist/platform/catalog.d.ts +148 -0
  118. package/dist/platform/catalog.js +74 -0
  119. package/dist/platform/entitlements.d.ts +111 -0
  120. package/dist/platform/entitlements.js +86 -0
  121. package/dist/platform/legal-entities.d.ts +139 -0
  122. package/dist/platform/legal-entities.js +126 -0
  123. package/dist/platform/legal-entity-numbering.d.ts +103 -0
  124. package/dist/platform/legal-entity-numbering.js +101 -0
  125. package/dist/platform/organization-membership.d.ts +80 -0
  126. package/dist/platform/organization-membership.js +71 -0
  127. package/dist/platform/organization-settings.d.ts +33 -0
  128. package/dist/platform/organization-settings.js +42 -0
  129. package/dist/platform/organization-sharing.d.ts +172 -0
  130. package/dist/platform/organization-sharing.js +120 -0
  131. package/dist/platform/organizations.d.ts +205 -0
  132. package/dist/platform/organizations.js +180 -0
  133. package/dist/platform/provision-store.d.ts +88 -8
  134. package/dist/platform/provision-store.js +12 -0
  135. package/dist/platform/reports.d.ts +46 -0
  136. package/dist/platform/reports.js +31 -0
  137. package/dist/platform/server-metrics.d.ts +58 -0
  138. package/dist/platform/server-metrics.js +11 -0
  139. package/dist/pos/index.d.ts +567 -0
  140. package/dist/pos/index.js +205 -0
  141. package/dist/pricing/index.d.ts +408 -0
  142. package/dist/pricing/index.js +353 -0
  143. package/dist/pricing/vouchers.d.ts +103 -0
  144. package/dist/pricing/vouchers.js +69 -0
  145. package/dist/provenance/index.d.ts +93 -0
  146. package/dist/provenance/index.js +53 -0
  147. package/dist/reports/index.d.ts +199 -0
  148. package/dist/reports/index.js +154 -0
  149. package/dist/returns/index.d.ts +225 -0
  150. package/dist/returns/index.js +160 -0
  151. package/dist/search/index.d.ts +99 -0
  152. package/dist/search/index.js +62 -0
  153. package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
  154. package/dist/shipping/parcel-count-suggestion.js +73 -0
  155. package/dist/shipping/parcel-rule.d.ts +48 -0
  156. package/dist/shipping/parcel-rule.js +91 -0
  157. package/dist/stock/index.d.ts +166 -0
  158. package/dist/stock/index.js +115 -0
  159. package/dist/stock/transfers.d.ts +520 -0
  160. package/dist/stock/transfers.js +437 -0
  161. package/dist/stored-value/index.d.ts +154 -0
  162. package/dist/stored-value/index.js +130 -0
  163. package/dist/tenant/capabilities.d.ts +10 -0
  164. package/dist/tenant/entitlements.d.ts +35 -0
  165. package/dist/tenant/entitlements.js +15 -0
  166. package/dist/tenant/field-groups.d.ts +64 -0
  167. package/dist/tenant/field-groups.js +34 -0
  168. package/dist/tenant/legal-entity.d.ts +32 -0
  169. package/dist/tenant/legal-entity.js +41 -0
  170. package/dist/tenant/notifications.d.ts +148 -0
  171. package/dist/tenant/notifications.js +79 -0
  172. package/dist/tenant/retention.d.ts +10 -4
  173. package/dist/tenant/settings-sources.d.ts +103 -0
  174. package/dist/tenant/settings-sources.js +92 -0
  175. package/dist/types.d.ts +86 -11
  176. package/dist/uploads/index.d.ts +11 -7
  177. package/dist/users/index.d.ts +104 -0
  178. package/dist/users/index.js +80 -0
  179. package/package.json +3 -2
@@ -0,0 +1,567 @@
1
+ import { type Page, type Transport } from '@sixtyninecommerce/core';
2
+ import type { Call } from '../types.js';
3
+ /**
4
+ * Point of sale on a machine principal (spec §8.8): a vertical's own backend
5
+ * runs the till — register sessions, cash, tenders, the sale, refunds, X and Z —
6
+ * with no paired tablet.
7
+ *
8
+ * ## The credential and the place
9
+ *
10
+ * Mint an API token with the **`pos` template** (permission `OperatePos`) and
11
+ * restrict it to the stock location it sells from (`locationIds`). Every call
12
+ * then needs `TenantContext.location` set to that location — the SDK sends it as
13
+ * `x-location`, the server verifies it belongs to the store and to the token's
14
+ * restriction, and the SALE DEBITS THAT LOCATION'S STOCK. A till is never given
15
+ * a default location: without one every call is refused
16
+ * `POS_LOCATION_REQUIRED`. A location-restricted token cannot operate at another
17
+ * location (`LOCATION_NOT_ALLOWED` at the door; `POS_LOCATION_MISMATCH` for a
18
+ * cart, register or session that stands somewhere else).
19
+ *
20
+ * A `pos` token cannot change the store's POS settings: `updatePosConfig`
21
+ * stays on `UpdateSettings`. Managing the estate (`devices`, creating
22
+ * `registers`, `receiptNumbering.set`) needs `ManagePosDevices`, which the
23
+ * template deliberately leaves out.
24
+ *
25
+ * ## Who acted
26
+ *
27
+ * A machine credential has no cashier PIN. Send the person as
28
+ * `TenantContext.actor` (`staffRef` → `x-on-behalf-of`, and your own `deviceRef`
29
+ * / `registerRef`)
30
+ * — the platform records those refs on each payment only when it vouches for
31
+ * the credential; they are attribution, never authorization. For a principal
32
+ * the CREDENTIAL is the manager gate for discounts and refunds.
33
+ *
34
+ * ## Money
35
+ *
36
+ * Integer minor units of the order's currency, everywhere. **Every money method
37
+ * requires `{ idempotencyKey }`**: a retry under the same key returns the first
38
+ * call's result instead of moving the money again. Use a fresh key per intended
39
+ * operation (a UUIDv7 is ideal) and reuse it only to retry that operation.
40
+ *
41
+ * The flow: `sessions.open` on a register → `sale.createCart({ registerId })`
42
+ * → `sale.addItem` → `tenders.cash` / `tenders.card` → `sale.complete` →
43
+ * `sessions.xReport` → `sessions.close` (the Z) → `sessions.zReport`.
44
+ *
45
+ * ## Which orders a till may act on
46
+ *
47
+ * An order id of another store is not found (`ENTITY_NOT_FOUND`), exactly as an
48
+ * id that does not exist, on every method that takes one. Within the store:
49
+ *
50
+ * - the cart methods (`sale.addItem`, `sale.applyDiscount`) change only an OPEN
51
+ * till cart, one a till opened with `sale.createCart` that is not yet placed,
52
+ * at your location. A shopper's cart, a back-office or order-entry draft and
53
+ * every placed order (a completed till sale included) are refused
54
+ * `POS_ORDER_NOT_EDITABLE`, and nothing is changed: start a new cart;
55
+ * - the tenders take money on such a cart (once it is placed, more money is
56
+ * `POS_ORDER_NOT_PAYABLE`) or on an order the till did not open while it can
57
+ * still take payment (see {@link PosTendersModule.card});
58
+ * - `refunds.create` refunds a payment of a till's sale.
59
+ */
60
+ export interface PosModule {
61
+ registers: PosRegistersModule;
62
+ sessions: PosSessionsModule;
63
+ cash: PosCashModule;
64
+ sale: PosSaleModule;
65
+ tenders: PosTendersModule;
66
+ refunds: PosRefundsModule;
67
+ devices: PosDevicesModule;
68
+ receiptNumbering: PosReceiptNumberingModule;
69
+ }
70
+ /**
71
+ * A money call: the key is REQUIRED, not optional. The server claims it before
72
+ * the work runs: a repeat of a finished call returns the first result, and a
73
+ * repeat while the first is still running is refused `IDEMPOTENCY_IN_PROGRESS`
74
+ * (retry shortly with the SAME key).
75
+ */
76
+ export type PosMoneyCall = Call & {
77
+ idempotencyKey: string;
78
+ };
79
+ /**
80
+ * Options for a till call. `staffToken` is a paired DEVICE's cashier PIN
81
+ * session; a machine principal omits it and sends `tenant.actor` instead.
82
+ */
83
+ export type PosCall = Call & {
84
+ staffToken?: string;
85
+ };
86
+ export interface PosRegister {
87
+ id: string;
88
+ stockLocationId: string;
89
+ name: string;
90
+ /** `active`, or whatever the merchant retired it as. Only an active register opens a session. */
91
+ status: string;
92
+ createdAt: string;
93
+ updatedAt: string;
94
+ }
95
+ export interface PosRegistersModule {
96
+ /**
97
+ * The store's registers. A machine principal sees only the registers at its
98
+ * own verified location — the ids it may open a session on.
99
+ */
100
+ list(options?: Call): Promise<Page<PosRegister>>;
101
+ /** One register, or null (also for another location's register, to a principal). */
102
+ get(id: string, options?: Call): Promise<PosRegister | null>;
103
+ /** Needs `ManagePosDevices` (or `UpdateSettings`). */
104
+ create(input: {
105
+ name: string;
106
+ stockLocationId: string;
107
+ }, options?: Call): Promise<PosRegister>;
108
+ /** Needs `ManagePosDevices` (or `UpdateSettings`). */
109
+ update(id: string, input: {
110
+ name?: string;
111
+ status?: string;
112
+ }, options?: Call): Promise<PosRegister>;
113
+ }
114
+ export interface PosSessionTotals {
115
+ /** Cash taken in sales, minor units. */
116
+ cash: number;
117
+ /** Card and other tenders are reconciled from payments, not the drawer: always 0 here. */
118
+ card: number;
119
+ other: number;
120
+ refunds: number;
121
+ net: number;
122
+ saleCount: number;
123
+ }
124
+ /** A register session: one drawer, from its opening float to its Z. */
125
+ export interface PosRegisterSession {
126
+ id: string;
127
+ registerId: string;
128
+ /** The paired tablet that opened it; null when a machine principal did. */
129
+ deviceId: string | null;
130
+ /** The cashier's PIN session; null when a machine principal opened it. */
131
+ openedByStaffId: string | null;
132
+ openingFloat: number;
133
+ status: 'open' | 'closed';
134
+ /** Set by the Z (`sessions.close`); null while open. */
135
+ expectedCash: number | null;
136
+ countedCash: number | null;
137
+ /** `countedCash - expectedCash`; negative is short. Null while open. */
138
+ cashOverShort: number | null;
139
+ totals: PosSessionTotals | null;
140
+ openedAt: string;
141
+ closedAt: string | null;
142
+ }
143
+ /** A mid-shift snapshot. Reading it changes nothing. */
144
+ export interface PosXReport {
145
+ sessionId: string;
146
+ openingFloat: number;
147
+ expectedCash: number;
148
+ totals: PosSessionTotals;
149
+ movementCount: number;
150
+ }
151
+ export interface OpenPosSessionInput {
152
+ /**
153
+ * REQUIRED for a machine principal: the register (at your verified location)
154
+ * whose drawer this is. One open session per register.
155
+ */
156
+ registerId?: string;
157
+ /** A paired tablet only; a machine principal naming one is refused `POS_DEVICE_NOT_ALLOWED`. */
158
+ deviceId?: string;
159
+ openingFloat: number;
160
+ /** Denomination counts, e.g. `{ "500": 2, "200": 5 }`. */
161
+ openingCounts?: Record<string, number>;
162
+ }
163
+ export interface PosSessionsModule {
164
+ /**
165
+ * Open a drawer. Refusals: `POS_REGISTER_REQUIRED`, `POS_REGISTER_NOT_FOUND`,
166
+ * `POS_REGISTER_INACTIVE`, `POS_LOCATION_MISMATCH`, `POS_DEVICE_NOT_ALLOWED`,
167
+ * and an already-open session on that register.
168
+ */
169
+ open(input: OpenPosSessionInput, options?: PosCall): Promise<PosRegisterSession>;
170
+ /**
171
+ * Close it — this IS the Z report: expected cash from the ledger, your count,
172
+ * the variance and the totals are stored on the session and returned.
173
+ */
174
+ close(input: {
175
+ sessionId: string;
176
+ countedCash: number;
177
+ closingCounts?: Record<string, number>;
178
+ }, options?: PosCall): Promise<PosRegisterSession>;
179
+ /** The X report: the drawer so far, read-only. */
180
+ xReport(sessionId: string, options?: Call): Promise<PosXReport>;
181
+ /**
182
+ * The stored Z of a CLOSED session (the session as `close` left it). On a
183
+ * session that is still open the Z fields are null — close it first.
184
+ */
185
+ zReport(sessionId: string, options?: Call): Promise<PosRegisterSession | null>;
186
+ }
187
+ export type PosCashMovementType = 'sale' | 'refund' | 'paid_in' | 'paid_out' | 'no_sale' | 'float_adjust';
188
+ export interface PosCashMovement {
189
+ id: string;
190
+ sessionId: string;
191
+ type: PosCashMovementType;
192
+ /** Signed minor units: positive into the drawer, negative out. */
193
+ amount: number;
194
+ reason: string | null;
195
+ orderId: string | null;
196
+ createdAt: string;
197
+ }
198
+ export interface PosCashModule {
199
+ /**
200
+ * Record a drawer movement that is not a sale — paid in, paid out, a no-sale
201
+ * open. Sales and refunds record their own.
202
+ *
203
+ * The drawer holds the store's default currency. A movement naming the
204
+ * `orderId` of an order in another currency is refused
205
+ * `CASH_TENDER_CURRENCY_NOT_SUPPORTED` and nothing is recorded. An `orderId`
206
+ * that is not an order of this store (another store's, or none at all) is
207
+ * refused `ENTITY_NOT_FOUND`, and nothing is recorded.
208
+ */
209
+ record(input: {
210
+ sessionId: string;
211
+ type: PosCashMovementType;
212
+ amount: number;
213
+ reason?: string;
214
+ orderId?: string;
215
+ }, options?: PosCall): Promise<PosCashMovement>;
216
+ }
217
+ /** A till cart — a draft order — as far as this module projects it. */
218
+ export interface PosCart {
219
+ id: string;
220
+ code: string;
221
+ state: string;
222
+ currencyCode: string;
223
+ /** Net total, minor units. */
224
+ total: number;
225
+ /** Gross total, minor units — what the customer pays. */
226
+ totalWithTax: number;
227
+ /**
228
+ * The coupon codes on the cart. A unique code shows as its promotion's own
229
+ * code; `pricing.discounts(id)` names what each discount did to each line.
230
+ */
231
+ couponCodes: string[];
232
+ lines: Array<{
233
+ id: string;
234
+ quantity: number;
235
+ productVariantId: string;
236
+ linePriceWithTax: number;
237
+ }>;
238
+ surcharges: Array<{
239
+ description: string;
240
+ sku: string;
241
+ price: number;
242
+ priceWithTax: number;
243
+ taxRate: number;
244
+ }>;
245
+ }
246
+ export interface CompletedPosSale {
247
+ orderId: string;
248
+ orderCode: string;
249
+ /** Gap-free per register. */
250
+ receiptNumber: string;
251
+ state: string;
252
+ }
253
+ export interface PosSaleModule {
254
+ /**
255
+ * Open a cart at your verified location. Name the `registerId` whose OPEN
256
+ * session takes this cart's cash — without one the cart can still take card,
257
+ * but `tenders.cash` is refused `POS_SESSION_REQUIRED`.
258
+ */
259
+ createCart(input?: {
260
+ registerId?: string;
261
+ }, options?: Call): Promise<PosCart>;
262
+ /**
263
+ * Add a variant to an open till cart opened at your location. Any other order
264
+ * of the store is refused `POS_ORDER_NOT_EDITABLE` (a paired tablet's cart:
265
+ * `POS_LOCATION_MISMATCH`), and nothing is changed.
266
+ */
267
+ addItem(input: {
268
+ orderId: string;
269
+ variantId: string;
270
+ quantity: number;
271
+ }, options?: Call): Promise<PosCart>;
272
+ /**
273
+ * An ad-hoc discount, `amount` in minor units on the basis the lines are
274
+ * priced in (gross on a tax-inclusive store, net otherwise). It takes the VAT
275
+ * off with the money: one negative surcharge per tax rate in the basket,
276
+ * each carrying that rate. Omit `lineId` for the whole cart. Only on an open
277
+ * till cart, as {@link PosSaleModule.addItem}; a cart that already holds a
278
+ * payment is refused `POS_ORDER_HAS_PAYMENTS`.
279
+ *
280
+ * `reasonCode` is optional: one of the store's active discount reasons
281
+ * (`orders.manualDiscounts.reasons.list`, readable with the `pos` token),
282
+ * recorded with the discount. A discount without one is accepted whatever the
283
+ * store's policy says (the policy binds the back office's doors, not the
284
+ * till); a code that is not an active reason is `DISCOUNT_REASON_UNKNOWN`, and
285
+ * the cart is unchanged. Each discount is recorded in the order's
286
+ * manual-discount log (`orders.manualDiscounts.list`, door `till`). Takes
287
+ * `options.idempotencyKey`: a retry under the same key answers the cart as it
288
+ * is now instead of taking the money off twice.
289
+ */
290
+ applyDiscount(input: {
291
+ orderId: string;
292
+ amount: number;
293
+ description?: string;
294
+ lineId?: string;
295
+ reasonCode?: string;
296
+ }, options?: PosCall): Promise<PosCart>;
297
+ /**
298
+ * Apply a coupon — a promotion's own code or a unique code generated for it —
299
+ * to an open till cart opened at your location, before any tender
300
+ * (`POS_ORDER_HAS_PAYMENTS` after one). The platform's coupon rules and
301
+ * refusals, as `pricing.coupons.apply`: `COUPON_INVALID`, `COUPON_EXPIRED`,
302
+ * `COUPON_NOT_YET_VALID`, `COUPON_USAGE_EXHAUSTED`, `COUPON_NOT_APPLICABLE`;
303
+ * the cart is unchanged on a refusal. Takes `options.idempotencyKey`: the
304
+ * same key and code replay the first answer.
305
+ */
306
+ applyCouponCode(input: {
307
+ orderId: string;
308
+ couponCode: string;
309
+ }, options?: Call): Promise<PosCart>;
310
+ /**
311
+ * Take a coupon off an open till cart before any tender. A code that is not
312
+ * on the cart answers the cart unchanged.
313
+ */
314
+ removeCouponCode(input: {
315
+ orderId: string;
316
+ couponCode: string;
317
+ }, options?: Call): Promise<PosCart>;
318
+ /**
319
+ * Finalise a fully paid sale: settles the order, debits your location's
320
+ * stock through its fulfillment profile (none at that location is
321
+ * `POS_NO_FULFILLMENT_PROFILE`, never a default), and numbers the receipt.
322
+ */
323
+ complete(orderId: string, options: PosMoneyCall & {
324
+ staffToken?: string;
325
+ }): Promise<CompletedPosSale>;
326
+ }
327
+ export interface PosTenderResult {
328
+ orderId: string;
329
+ paymentId: string;
330
+ /** True once settled payments cover the order total. */
331
+ covered: boolean;
332
+ outstanding: number;
333
+ /** Cash only: `tendered - amount`, floored at zero. */
334
+ change: number;
335
+ }
336
+ export interface PosTendersModule {
337
+ /**
338
+ * Cash into the drawer of the cart's register session. `tendered` is what the
339
+ * customer handed over; the difference comes back as `change`.
340
+ *
341
+ * On an order the till did NOT open (see {@link PosTendersModule.card}) there
342
+ * is no cart session, so name the `registerId` whose open session takes the
343
+ * cash — without it the tender is refused `POS_SESSION_REQUIRED`. Send
344
+ * `registerId` only for such an order: a server older than this field
345
+ * refuses the whole call.
346
+ *
347
+ * Cash is taken only on an order in the store's default currency, the
348
+ * currency the drawer holds. On an order in another currency the tender is
349
+ * refused `CASH_TENDER_CURRENCY_NOT_SUPPORTED`, its message naming both
350
+ * currencies, and nothing is taken. Take the payment with
351
+ * {@link PosTendersModule.card} or {@link PosTendersModule.manual} instead:
352
+ * neither touches the drawer, so this rule does not apply to them.
353
+ *
354
+ * The first tender of a sale asks the apps the store installed
355
+ * (`order.validate`) before anything is taken: a refusal is `HOOK_REJECTED`
356
+ * (`HookRejectedError`, with the app's `customerMessage`) or
357
+ * `HOOK_UNAVAILABLE` (`HookUnavailableError`), and no tender is recorded.
358
+ * A cart the store's placement rules refuse as it is readied for payment (an
359
+ * order minimum not met, a product out of stock, …) is
360
+ * `ORDER_TRANSITION_REFUSED` (a `BusinessRuleError`), as order entry answers
361
+ * it, whose `message` says which rule refused: the cart stays open, so fix it
362
+ * and tender again. The rule's own code and the buyer's sentence
363
+ * (`placementCode`, `customerMessage`) are only on the raw GraphQL
364
+ * `extensions.details` for now: this SDK does not lift them yet, so the
365
+ * error's `details` is empty.
366
+ * A coupon used up since it went on is `COUPON_USAGE_EXHAUSTED` (take it off)
367
+ * and a tax provider's changed answer `TAX_CHANGED` (tender again at the new
368
+ * total). Only a cart that is no longer open is `POS_ORDER_NOT_PAYABLE`.
369
+ * The same holds for {@link PosTendersModule.card} and
370
+ * {@link PosTendersModule.manual}.
371
+ */
372
+ cash(input: {
373
+ orderId: string;
374
+ amount: number;
375
+ tendered: number;
376
+ registerId?: string;
377
+ }, options: PosMoneyCall & {
378
+ staffToken?: string;
379
+ }): Promise<PosTenderResult>;
380
+ /**
381
+ * A card payment on the terminal assigned to your location (Settings →
382
+ * Payments), through the store's payment connection. It lands `Authorized`
383
+ * and settles when the provider confirms the tap; `covered` stays false until
384
+ * then. No terminal there is `POS_TERMINAL_NOT_AVAILABLE`. A location with
385
+ * several readers (one per till) needs `terminalId` — the reader's provider id
386
+ * — or the tender is refused `POS_TERMINAL_AMBIGUOUS` rather than prompting a
387
+ * customer at another till.
388
+ *
389
+ * ## An order the till did not open
390
+ *
391
+ * The tenders also take money on an EXISTING order of your store — a deposit
392
+ * order parked in the back office whose customer pays the rest at the counter
393
+ * — when it is `Parked` or `ArrangingPayment`, still owes something, and
394
+ * names your location or no location (its `posLocationId`, or the `location`
395
+ * it was composed for). The money goes through the store's payment position,
396
+ * exactly like `payments.record`:
397
+ *
398
+ * - at most what the order still owes, or `POS_TENDER_EXCEEDS_OUTSTANDING`
399
+ * (the order's position rides the error's `extensions.position`);
400
+ * - a tender that leaves a balance on a store without deposits is refused
401
+ * `DEPOSITS_NOT_ENABLED`;
402
+ * - each settled tender raises `payment.partial_recorded`. A card tender
403
+ * raises it when the provider settles it, which is why `covered` can stay
404
+ * false for a moment;
405
+ * - a `Parked` order stays parked while money is owed, and the tender that
406
+ * clears it settles, places and allocates the order;
407
+ * - `sale.complete` then numbers the receipt and fulfils at your location —
408
+ * only on an order your credential took money on; any other order you did
409
+ * not open is refused `POS_ORDER_UNSTAMPED`, as before.
410
+ *
411
+ * Refusals: another location's order is `POS_LOCATION_MISMATCH`. Any other
412
+ * state (`Cancelled` included) is `POS_ORDER_NOT_PAYABLE`. Another store's
413
+ * order is not found (`ENTITY_NOT_FOUND`). A paired device's cart stays the
414
+ * device's.
415
+ */
416
+ card(input: {
417
+ orderId: string;
418
+ amount: number;
419
+ terminalId?: string;
420
+ }, options: PosMoneyCall & {
421
+ staffToken?: string;
422
+ }): Promise<PosTenderResult>;
423
+ /**
424
+ * A tender taken OUTSIDE the platform's terminal — a standalone card machine,
425
+ * a voucher — recorded as settled on an offline payment method of this store
426
+ * (never the cash or terminal method). At most the outstanding amount.
427
+ */
428
+ manual(input: {
429
+ orderId: string;
430
+ amount: number;
431
+ method: string;
432
+ reference?: string;
433
+ }, options: PosMoneyCall & {
434
+ staffToken?: string;
435
+ }): Promise<PosTenderResult>;
436
+ /**
437
+ * A gift card or store credit pays (`posTenderStoredValue`): a settled payment on the store's
438
+ * stored-value method, the account debited in the payment's own transaction. At most the
439
+ * outstanding amount (stored value gives no change). Refusals: `POS_STORED_VALUE_UNAVAILABLE`
440
+ * and the ledger's `STORED_VALUE_*` (balance, expiry, block, owner, currency).
441
+ */
442
+ storedValue(input: {
443
+ orderId: string;
444
+ amount: number;
445
+ accountId: string;
446
+ }, options: PosMoneyCall & {
447
+ staffToken?: string;
448
+ }): Promise<PosTenderResult>;
449
+ }
450
+ export interface PosRefund {
451
+ orderId: string;
452
+ refundId: string;
453
+ /** `Settled` once the money moved (an offline refund settles on the spot). */
454
+ state: string;
455
+ }
456
+ export interface PosRefundsModule {
457
+ /**
458
+ * Hand money back against one payment of the order, never more than the order
459
+ * took (`REFUND_EXCEEDS_SETTLED`). Refusals that mean NO money moved:
460
+ * `REFUND_METHOD_UNAVAILABLE` (that payment's method is disabled or gone),
461
+ * `REFUND_REFUSED` (the gateway said no, with its reason) — retry is safe.
462
+ *
463
+ * `IDEMPOTENCY_OUTCOME_UNKNOWN` is neither: the card refund reached the
464
+ * payment provider and then failed (no answer, a timeout, a provider error),
465
+ * so the money MAY have been returned. The key is spent — this call and every
466
+ * repeat under it answer the same code, and the provider is never asked
467
+ * twice. The attempt is recorded as a refund whose outcome is unknown and
468
+ * its amount stays reserved: the till, `payments.refund`, credit notes,
469
+ * returns and core's own `refundOrder` (the dashboard's Refund button) can
470
+ * then no longer refund that payment past what it took, but a new request
471
+ * for the same partial amount is not
472
+ * stopped, so never retry under a new key. The recorded refund's id is not on
473
+ * the SDK error (`PlatformError` carries only code, message, details and
474
+ * trace id): read it with `payments.unreconciledRefunds(orderId)`. Show the
475
+ * till a "check before refunding" state, not "refused": someone checks the
476
+ * provider and records the answer with `payments.reconcileRefund` — after
477
+ * which a repeat under the SAME key answers the refund (made) or runs again
478
+ * (not made).
479
+ *
480
+ * A refund of a CASH payment pays out of the drawer, so on an order that is
481
+ * not in the store's default currency it is refused
482
+ * `CASH_TENDER_CURRENCY_NOT_SUPPORTED` before anything moves. Refund that
483
+ * payment from the order in the back office instead.
484
+ *
485
+ * The order must be a till's sale made at your location, and the payment one
486
+ * of ITS payments: an order no till opened is `POS_ORDER_UNSTAMPED`, a payment
487
+ * of another order `USER_INPUT_ERROR`, another store's order `ENTITY_NOT_FOUND`.
488
+ */
489
+ create(input: {
490
+ orderId: string;
491
+ paymentId: string;
492
+ amount: number;
493
+ reason?: string;
494
+ }, options: PosMoneyCall & {
495
+ staffToken?: string;
496
+ }): Promise<PosRefund>;
497
+ }
498
+ export interface PosDevice {
499
+ id: string;
500
+ stockLocationId: string;
501
+ registerId: string | null;
502
+ label: string;
503
+ status: 'active' | 'revoked';
504
+ paired: boolean;
505
+ /** Recorded server-side every time the tablet authenticates. */
506
+ lastSeenAt: string | null;
507
+ }
508
+ /** Paired tablets. Every method needs `ManagePosDevices` (or `UpdateSettings`). */
509
+ export interface PosDevicesModule {
510
+ list(options?: Call): Promise<Page<PosDevice>>;
511
+ /**
512
+ * A one-time pairing code the tablet redeems; it expires. Needs a human session: an API token
513
+ * is refused (`PermissionDeniedError` `TOKEN_CREDENTIAL_NOT_ALLOWED`), because the paired
514
+ * device's session would outlive the token.
515
+ */
516
+ pair(deviceId: string, options?: Call): Promise<{
517
+ code: string;
518
+ expiresAt: string;
519
+ }>;
520
+ revoke(deviceId: string, options?: Call): Promise<PosDevice>;
521
+ /**
522
+ * The device's last sign of life. There is no heartbeat WRITE for an SDK to
523
+ * send: the server stamps `lastSeenAt` on every authenticated tablet request,
524
+ * so this reads it.
525
+ */
526
+ heartbeat(deviceId: string, options?: Call): Promise<{
527
+ lastSeenAt: string | null;
528
+ } | null>;
529
+ }
530
+ export interface PosReceiptNumbering {
531
+ prefix: string;
532
+ suffix: string;
533
+ /** Zero-padding width, 3..8. */
534
+ digits: number;
535
+ }
536
+ /** Needs `ManagePosDevices` (or `UpdateSettings`). */
537
+ export interface PosReceiptNumberingModule {
538
+ get(options?: Call): Promise<PosReceiptNumbering>;
539
+ set(input: Partial<PosReceiptNumbering>, options?: Call): Promise<PosReceiptNumbering>;
540
+ }
541
+ export declare const POS_REGISTERS_QUERY = "query PosRegisters { posRegisters { id stockLocationId name status createdAt updatedAt } }";
542
+ export declare const POS_REGISTER_QUERY = "query PosRegister($id: ID!) { posRegister(id: $id) { id stockLocationId name status createdAt updatedAt } }";
543
+ export declare const CREATE_POS_REGISTER_MUTATION = "mutation CreatePosRegister($input: CreatePosRegisterInput!) { createPosRegister(input: $input) { id stockLocationId name status createdAt updatedAt } }";
544
+ export declare const UPDATE_POS_REGISTER_MUTATION = "mutation UpdatePosRegister($id: ID!, $input: UpdatePosRegisterInput!) { updatePosRegister(id: $id, input: $input) { id stockLocationId name status createdAt updatedAt } }";
545
+ export declare const OPEN_POS_SESSION_MUTATION = "mutation OpenPosRegisterSession($input: OpenPosRegisterSessionInput!, $staffToken: String) { openPosRegisterSession(input: $input, staffToken: $staffToken) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
546
+ export declare const CLOSE_POS_SESSION_MUTATION = "mutation ClosePosRegisterSession($input: ClosePosRegisterSessionInput!, $staffToken: String) { closePosRegisterSession(input: $input, staffToken: $staffToken) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
547
+ export declare const POS_X_REPORT_QUERY = "query PosXReport($sessionId: ID!) { posXReport(sessionId: $sessionId) { sessionId openingFloat expectedCash movementCount totals { cash card other refunds net saleCount } } }";
548
+ export declare const POS_SESSION_QUERY = "query PosRegisterSession($id: ID!) { posRegisterSession(id: $id) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
549
+ export declare const RECORD_POS_CASH_MOVEMENT_MUTATION = "mutation RecordPosCashMovement($input: RecordPosCashMovementInput!, $staffToken: String) { recordPosCashMovement(input: $input, staffToken: $staffToken) { id sessionId type amount reason orderId createdAt } }";
550
+ export declare const POS_CREATE_CART_MUTATION = "mutation PosCreateCart($registerId: ID) { posCreateCart(registerId: $registerId) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
551
+ export declare const POS_ADD_ITEM_MUTATION = "mutation PosAddItem($input: PosAddItemInput!) { posAddItem(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
552
+ export declare const POS_APPLY_DISCOUNT_MUTATION = "mutation PosApplyDiscount($input: PosApplyDiscountInput!, $staffToken: String) { posApplyDiscount(input: $input, staffToken: $staffToken) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
553
+ export declare const POS_APPLY_COUPON_CODE_MUTATION = "mutation PosApplyCouponCode($input: PosCouponCodeInput!) { posApplyCouponCode(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
554
+ export declare const POS_REMOVE_COUPON_CODE_MUTATION = "mutation PosRemoveCouponCode($input: PosCouponCodeInput!) { posRemoveCouponCode(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
555
+ export declare const POS_COMPLETE_SALE_MUTATION = "mutation PosCompleteSale($input: PosCompleteSaleInput!, $staffToken: String) { posCompleteSale(input: $input, staffToken: $staffToken) { orderId orderCode receiptNumber state } }";
556
+ export declare const POS_TENDER_CASH_MUTATION = "mutation PosTenderCash($input: PosTenderCashInput!, $staffToken: String) { posTenderCash(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
557
+ export declare const POS_TENDER_CARD_MUTATION = "mutation PosTenderCard($input: PosTenderCardInput!, $staffToken: String) { posTenderCard(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
558
+ export declare const POS_TENDER_STORED_VALUE_MUTATION = "mutation PosTenderStoredValue($input: PosTenderStoredValueInput!, $staffToken: String) { posTenderStoredValue(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
559
+ export declare const POS_TENDER_MANUAL_MUTATION = "mutation PosTenderManual($input: PosTenderManualInput!, $staffToken: String) { posTenderManual(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
560
+ export declare const POS_REFUND_MUTATION = "mutation PosRefund($input: PosRefundInput!, $staffToken: String) { posRefund(input: $input, staffToken: $staffToken) { orderId refundId state } }";
561
+ export declare const POS_DEVICES_QUERY = "query PosDevices { posDevices { id stockLocationId registerId label status paired lastSeenAt } }";
562
+ export declare const POS_DEVICE_QUERY = "query PosDevice($id: ID!) { posDevice(id: $id) { lastSeenAt } }";
563
+ export declare const POS_PAIRING_CODE_MUTATION = "mutation GeneratePosPairingCode($deviceId: ID!) { generatePosPairingCode(deviceId: $deviceId) { code expiresAt } }";
564
+ export declare const REVOKE_POS_DEVICE_MUTATION = "mutation RevokePosDevice($deviceId: ID!) { revokePosDevice(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt } }";
565
+ export declare const POS_RECEIPT_NUMBERING_QUERY = "query PosReceiptNumberingConfig { posReceiptNumberingConfig { prefix suffix digits } }";
566
+ export declare const UPDATE_POS_RECEIPT_NUMBERING_MUTATION = "mutation UpdatePosReceiptNumberingConfig($input: UpdatePosReceiptNumberingConfigInput!) { updatePosReceiptNumberingConfig(input: $input) { prefix suffix digits } }";
567
+ export declare function createPosModule(transport: Transport): PosModule;