platform-types 1.10.814 → 1.10.816

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/audit.d.ts CHANGED
@@ -177,6 +177,30 @@ declare global {
177
177
  * `holdReason`. `after`: `obligationId`, `state`, `refundDueAt?` and the reason by presence only.
178
178
  */
179
179
  | 'refund_obligation_reopened'
180
+ /**
181
+ * A purchase withdrawal was requested on the order (`POST /orders/purchase-withdrawal`, origin
182
+ * `customer`). `after`: `withdrawalId`, `state` (`'requested'`), `source`, `wholeOrder`,
183
+ * `lineCount`, `amount`, `currency`, `windowClosesAt?`.
184
+ */
185
+ | 'purchase_withdrawal_requested'
186
+ /**
187
+ * An operator relayed a purchase withdrawal the store received by email or WhatsApp
188
+ * (`POST /purchase-withdrawals { mode: 'relay' }`). `after`: as `purchase_withdrawal_requested`,
189
+ * plus `channel`, `receivedAt`, `codeMintedLate` and the operator's note as `'[present]'` |
190
+ * `'[absent]'` — presence only, the words stay on the withdrawal.
191
+ */
192
+ | 'purchase_withdrawal_relayed'
193
+ /**
194
+ * An operator accepted a purchase withdrawal (`POST /purchase-withdrawals { mode: 'accept' }`).
195
+ * `before`/`after`: `withdrawalId`, `state`, `revision`.
196
+ */
197
+ | 'purchase_withdrawal_accepted'
198
+ /**
199
+ * An operator declined a purchase withdrawal (`POST /purchase-withdrawals { mode: 'decline' }`).
200
+ * `before`/`after`: `withdrawalId`, `state`, `revision`; `after` adds the typed `declineReason` and
201
+ * the note as `'[present]'` | `'[absent]'` — presence only, the words stay on the withdrawal.
202
+ */
203
+ | 'purchase_withdrawal_declined'
180
204
  /** HISTORICAL: written only by the removed outbound MercadoPago refund; kept so old timeline rows still parse. */
181
205
  | 'payment_refunded'
182
206
  /** At least one till tender leg was appended (an absorbed replay writes none). */
package/dist/cjs/index.js CHANGED
@@ -91,6 +91,7 @@ __exportStar(require("./productBulkEdit.js"), exports);
91
91
  __exportStar(require("./productDuplicate.js"), exports);
92
92
  __exportStar(require("./productGroup.js"), exports);
93
93
  __exportStar(require("./purchaseOrder.js"), exports);
94
+ __exportStar(require("./purchaseWithdrawal.js"), exports);
94
95
  __exportStar(require("./purchaseReceipt.js"), exports);
95
96
  __exportStar(require("./pushDevice.js"), exports);
96
97
  __exportStar(require("./refundObligation.js"), exports);
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Purchase withdrawals — the shopper's statutory right to withdraw from a
4
+ * distance purchase (*arrepentimiento*), as a record of its own.
5
+ *
6
+ * A withdrawal is a REQUEST with an identification code (`withdrawalId`, `ARR`
7
+ * plus 6–10 digits), a window and a decision. It never moves stock or money by
8
+ * itself: once accepted, the order's own cancellation (before fulfilment) or a
9
+ * return (after it) does, and the money owed back is a {@link RefundObligation}
10
+ * whose `parentId` is the `withdrawalId`.
11
+ *
12
+ * Naming: "withdrawal" alone already names the guest-telemetry consent
13
+ * withdrawal and `cash.withdrawal` on the till, so every name here carries the
14
+ * `PurchaseWithdrawal` / `purchaseWithdrawal` stem.
15
+ *
16
+ * ⚠️ The stored row carries one main-table index-key attribute on purpose,
17
+ * `customerId` (the order's customer when the request was made, a guest row's
18
+ * id for a guest order), so the customer erasure finds it through the existing
19
+ * `PK-customerId` read. It carries none of the others: `state` replaces
20
+ * `status`, `revisedAt` replaces `updatedAt`, and there is no `dated`.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.PURCHASE_WITHDRAWAL_CODE_DUE_MS = exports.PURCHASE_WITHDRAWAL_CODE_DUE_SOURCE = exports.PURCHASE_WITHDRAWAL_WINDOW_SOURCE = exports.PURCHASE_WITHDRAWAL_WINDOW_DAYS = exports.PURCHASE_WITHDRAWAL_LINES_MAX = exports.PURCHASE_WITHDRAWAL_NOTE_MAX = exports.PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = exports.PURCHASE_WITHDRAWAL_ACTION_MODES = exports.PURCHASE_WITHDRAWAL_RELAY_CHANNELS = exports.PURCHASE_WITHDRAWAL_DECLINE_REASONS = exports.PURCHASE_WITHDRAWAL_SOURCES = exports.PURCHASE_WITHDRAWAL_LIST_FILTERS = exports.PURCHASE_WITHDRAWAL_STATES = void 0;
24
+ /**
25
+ * - `requested` — submitted, the code minted, the order's dispatch locked
26
+ * (`purchase-withdrawal-pending`) until an operator decides.
27
+ * - `declined` — an operator declined it with a typed exemption reason.
28
+ * Terminal.
29
+ * - `accepted` — an operator accepted it. The order's cancellation (before
30
+ * fulfilment) or its return authorisation (after it) follows from here.
31
+ * - `awaiting-goods` — after fulfilment, the goods are on their way back.
32
+ * - `refund-pending` — money is owed back (an open refund obligation).
33
+ * - `completed` — nothing is owed any more. Not final while money can still
34
+ * arrive: a late capture moves it back to `refund-pending`.
35
+ */
36
+ exports.PURCHASE_WITHDRAWAL_STATES = [
37
+ 'requested',
38
+ 'declined',
39
+ 'accepted',
40
+ 'awaiting-goods',
41
+ 'refund-pending',
42
+ 'completed',
43
+ ];
44
+ /**
45
+ * The `state` filter of `GET /purchase-withdrawals`: one state, or `open` —
46
+ * every state but `declined` and `completed`.
47
+ */
48
+ exports.PURCHASE_WITHDRAWAL_LIST_FILTERS = [...exports.PURCHASE_WITHDRAWAL_STATES, 'open'];
49
+ /** `shopper` — the storefront form; `operator-relay` — an operator recording a request received by email or WhatsApp. */
50
+ exports.PURCHASE_WITHDRAWAL_SOURCES = ['shopper', 'operator-relay'];
51
+ /**
52
+ * The only reasons an operator may decline a request, each backed by a row of
53
+ * the consumer-commerce applicability matrix: made to order or personalised,
54
+ * quick deterioration, unsealed media or software, periodicals, a used
55
+ * product, perishables, and a purchase made for resale or production.
56
+ */
57
+ exports.PURCHASE_WITHDRAWAL_DECLINE_REASONS = [
58
+ 'exempt-custom-made',
59
+ 'exempt-quick-deterioration',
60
+ 'exempt-unsealed-media',
61
+ 'exempt-periodical',
62
+ 'exempt-used-product',
63
+ 'exempt-perishable',
64
+ 'resale-purchase',
65
+ ];
66
+ /** Where a relayed request reached the store. */
67
+ exports.PURCHASE_WITHDRAWAL_RELAY_CHANNELS = ['email', 'whatsapp'];
68
+ /** The modes of `POST /purchase-withdrawals`. */
69
+ exports.PURCHASE_WITHDRAWAL_ACTION_MODES = ['accept', 'decline', 'relay'];
70
+ /**
71
+ * Why a request is refused `409 PURCHASE_WITHDRAWAL_INELIGIBLE` (`data.reason`):
72
+ *
73
+ * - `order-cancelled` — the order is cancelled or disabled.
74
+ * - `no-customer` — the order names no customer (a relay on a walk-in sale).
75
+ * - `partial-before-fulfilment` — `lines` were named on an order not yet
76
+ * delivered or shipped; before fulfilment a withdrawal is the whole order.
77
+ * - `line-not-on-order` — a named line is not a goods line of the order.
78
+ * - `line-unavailable` — a named line (or quantity) is already in another
79
+ * withdrawal that was not declined, in an open return authorisation, or
80
+ * already returned (`data.orderItemIndex`).
81
+ * - `nothing-to-withdraw` — every line is already withdrawn or returned.
82
+ */
83
+ exports.PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
84
+ 'order-cancelled',
85
+ 'no-customer',
86
+ 'partial-before-fulfilment',
87
+ 'line-not-on-order',
88
+ 'line-unavailable',
89
+ 'nothing-to-withdraw',
90
+ ];
91
+ /** The longest decline or relay `note`, in characters after trimming. */
92
+ exports.PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
93
+ /** The most lines one request may name. */
94
+ exports.PURCHASE_WITHDRAWAL_LINES_MAX = 100;
95
+ /** Calendar days of the withdrawal window after the later of delivery and purchase. */
96
+ exports.PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
97
+ /** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
98
+ exports.PURCHASE_WITHDRAWAL_WINDOW_SOURCE = 'W2';
99
+ /** The matrix row a relayed request's `codeDueAt` (24 hours after it was received) comes from. */
100
+ exports.PURCHASE_WITHDRAWAL_CODE_DUE_SOURCE = 'W1';
101
+ /** How long after a relayed request was received its code is due, in ms. */
102
+ exports.PURCHASE_WITHDRAWAL_CODE_DUE_MS = 24 * 60 * 60 * 1000;
@@ -543,6 +543,27 @@ exports.SOCKET_ACTIONS = [
543
543
  * a customer socket: the shopper's own frame is `orderPaymentAttempt`.
544
544
  */
545
545
  'paymentAttemptChanged',
546
+ /**
547
+ * A storefront order's purchase withdrawal was requested or decided. `data`
548
+ * is `OrderPurchaseWithdrawalFrameData` (`purchaseWithdrawal.ts`) — the order
549
+ * id and the shopper's `OrderPurchaseWithdrawalView`, never the operator's
550
+ * notes.
551
+ *
552
+ * ⚠️ To the order's OWN customer only (`wsPostCustomer`), never a store-wide
553
+ * customer broadcast. The operator frame for the same write is
554
+ * `purchaseWithdrawalChanged`.
555
+ */
556
+ 'orderPurchaseWithdrawal',
557
+ /**
558
+ * A purchase withdrawal was requested, relayed or decided. `data` is the
559
+ * `PurchaseWithdrawal` record as `GET /purchase-withdrawals` answers it.
560
+ *
561
+ * ⚠️ OPERATOR sockets of the store only, and ADMIN tier only (`wsPostStore`
562
+ * with `audience: 'operator'` and `lowTierData: null`): it carries the
563
+ * customer id and the operator's notes. The shopper's own frame is
564
+ * `orderPurchaseWithdrawal`.
565
+ */
566
+ 'purchaseWithdrawalChanged',
546
567
  'stripe',
547
568
  'subscription',
548
569
  // Fiscal.
@@ -156,12 +156,21 @@ exports.STOREFRONT_DESIGN_REGISTRY = {
156
156
  *
157
157
  * Responsable Inscripto only (`integrations.afip.condFiscal === 30`). Both
158
158
  * writers refuse `true` on any other store with 409 NET_PLUS_IVA_REQUIRES_RI;
159
- * `false` and `null` always pass. Storefront exits (web `GET /store`, the
160
- * preview's store frame, the customer `stores` frame) send the EFFECTIVE value,
161
- * stored flag AND RI; app reads (`GET /store`, the operator `/tenants` read)
162
- * send the STORED one beside `integrations.afip.condFiscal`.
159
+ * `false` and `null` always pass. App reads (`GET /store`, the operator
160
+ * `/tenants` read) send the STORED value beside `integrations.afip.condFiscal`.
161
+ *
162
+ * Wholesale customers only. Storefront exits send the EFFECTIVE value per
163
+ * viewer: stored flag AND RI AND an approved customer whose effective price
164
+ * list is `audienceClass: 'wholesale'`. A guest, a pending registrant and a
165
+ * retail customer read `false`.
166
+ * - Web `GET /store` judges its resolved caller. A customer's answer is
167
+ * `private, no-store`, and every answer varies on `Authorization`.
168
+ * - The preview's store frame judges the grant fixture's simulated caller.
169
+ * A grant without a fixture is judged as a guest.
170
+ * - The customer `stores` frame reaches every shopper at once, so it always
171
+ * sends `false`. The storefront re-reads web `GET /store` on that frame.
163
172
  */
164
- showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Mostrar también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
173
+ showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Tus clientes mayoristas ven también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
165
174
  prices: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
166
175
  stock: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
167
176
  checkout: { ...LIVE_METADATA, storage: { source: 'store' } },
@@ -1355,7 +1355,7 @@ declare global {
1355
1355
  * many operator notes existed about them, and minus the RMA reason counts,
1356
1356
  * for the same reason (the rejection reasons are operator-written).
1357
1357
  */
1358
- type WebAnonymizeCustomerResult = Omit<AnonymizeCustomerResult, 'notesErased' | 'notesEraseComplete' | 'rmaReasonsErased' | 'rmaEraseComplete'> & {
1358
+ type WebAnonymizeCustomerResult = Omit<AnonymizeCustomerResult, 'notesErased' | 'notesEraseComplete' | 'rmaReasonsErased' | 'rmaEraseComplete' | 'purchaseWithdrawalNotesErased' | 'purchaseWithdrawalEraseComplete'> & {
1359
1359
  /**
1360
1360
  * `false` until the store's analytics events about the subject are erased
1361
1361
  * and verified — what folds the request's retention job to `completed`
@@ -1626,6 +1626,21 @@ declare global {
1626
1626
  * (`WebAnonymizeCustomerResult`).
1627
1627
  */
1628
1628
  rmaEraseComplete: boolean;
1629
+ /**
1630
+ * `PURCHASE_WITHDRAWAL#` rows of this customer (or of an id folded into it, a
1631
+ * guest row an attach merged in included) whose operator notes (`declineNote`,
1632
+ * `relay.note`) this erasure REMOVEd. The withdrawal itself is kept, with its
1633
+ * ids and amounts — it is the record of a consumer right exercised. Operator
1634
+ * wire only. Optional only so the field is additive.
1635
+ */
1636
+ purchaseWithdrawalNotesErased?: number;
1637
+ /**
1638
+ * `false` when those rows could not be read or written to the end, so a note
1639
+ * may remain. Re-issuing the erasure re-runs the step; BOTH erasure handlers
1640
+ * write a deduped `ERROR` row (`CUSTOMER_ANONYMIZE_PURCHASE_WITHDRAWAL_INCOMPLETE`).
1641
+ * Operator wire only — the storefront response omits both.
1642
+ */
1643
+ purchaseWithdrawalEraseComplete?: boolean;
1629
1644
  /**
1630
1645
  * Storefront quote requests the subject sent signed in
1631
1646
  * (`QUOTEREQUEST#{storeId}`), DELETED by this erasure — the whole row goes:
package/dist/index.d.ts CHANGED
@@ -67,6 +67,7 @@ export * from './productBulkEdit.ts';
67
67
  export * from './productDuplicate.ts';
68
68
  export * from './productGroup.ts';
69
69
  export * from './purchaseOrder.ts';
70
+ export * from './purchaseWithdrawal.ts';
70
71
  export * from './purchaseReceipt.ts';
71
72
  export * from './pushDevice.ts';
72
73
  export * from './refundObligation.ts';
package/dist/index.js CHANGED
@@ -75,6 +75,7 @@ export * from "./productBulkEdit.js";
75
75
  export * from "./productDuplicate.js";
76
76
  export * from "./productGroup.js";
77
77
  export * from "./purchaseOrder.js";
78
+ export * from "./purchaseWithdrawal.js";
78
79
  export * from "./purchaseReceipt.js";
79
80
  export * from "./pushDevice.js";
80
81
  export * from "./refundObligation.js";
package/dist/order.d.ts CHANGED
@@ -1270,6 +1270,20 @@ declare global {
1270
1270
  /** Who cancelled: the customerId for a self-cancellation, the operator's userId for an operator cancellation. */
1271
1271
  cancelledBy?: string;
1272
1272
  cancellationSource?: OrderCancellationSource;
1273
+ /**
1274
+ * The purchase withdrawal awaiting an operator's decision, while there is
1275
+ * one (`POST /orders/purchase-withdrawal`, or an operator's relay). Server-
1276
+ * owned: written in the request's transaction and removed in the
1277
+ * decision's. Its presence is the `purchase-withdrawal-pending` dispatch
1278
+ * lock; `GET /purchase-withdrawals?orderId=` reads the request itself.
1279
+ */
1280
+ purchaseWithdrawalPending?: OrderPurchaseWithdrawalPending;
1281
+ /**
1282
+ * How many purchase withdrawals were ever requested on the order. Server-
1283
+ * owned: every request pins it and bumps it, so two requests on one order
1284
+ * never commit off the same read.
1285
+ */
1286
+ purchaseWithdrawalCount?: number;
1273
1287
  /** Bounded free text supplied by the canceller. */
1274
1288
  cancellationReason?: string;
1275
1289
  mercadolibreCreditNote?: {
@@ -1389,6 +1403,12 @@ declare global {
1389
1403
  * A voucher with no `fiscalStatus` at all is legacy and counts as live.
1390
1404
  * - `payment-linked` — `linkedPayments` is non-empty. The platform never
1391
1405
  * unlinks or refunds a provider payment on the operator's behalf.
1406
+ * - `purchase-withdrawal-pending` — `purchaseWithdrawalPending` is set: the
1407
+ * shopper asked to withdraw from the purchase and no operator has decided
1408
+ * yet. The DISPATCH lock: marking the order ready (or clearing the mark),
1409
+ * delivering it and shipping it are refused until the request is decided,
1410
+ * so a dispatch cannot race a withdrawal before fulfilment. Last in the
1411
+ * order, so every other reason reports first.
1392
1412
  *
1393
1413
  * ⚠️ As a FIRST match this list rarely reports `cancelled`: both dead-state
1394
1414
  * writers stamp `readyAt`, so `ready` wins on `mode: 'edit'`. The rank pays
@@ -1396,7 +1416,7 @@ declare global {
1396
1416
  * the single-field legs (`mode: 'delivery'`, `'return'`) test
1397
1417
  * `cancelled` ahead of `disabled` explicitly for the same reason.
1398
1418
  */
1399
- type OrderLockReason = 'ready' | 'delivered' | 'disabled' | 'invoiced' | 'payment-linked' | 'cancelled';
1419
+ type OrderLockReason = 'ready' | 'delivered' | 'disabled' | 'invoiced' | 'payment-linked' | 'cancelled' | 'purchase-withdrawal-pending';
1400
1420
  /**
1401
1421
  * FULFILMENT axis of the order state model: where the goods are.
1402
1422
  *
@@ -126,12 +126,16 @@ declare global {
126
126
  /**
127
127
  * The shopper's own order read: the order plus its payment attempt, when it
128
128
  * has one, and where its delivery stands (`OrderDeliveryView`, `delivery.ts`),
129
- * when there is anything to show. Both are attached on read and never stored
130
- * on the order.
129
+ * when there is anything to show. Also its purchase withdrawals, newest
130
+ * first (`purchaseWithdrawal.ts`), when it has any, and whether the
131
+ * withdrawal window is open. Each is attached on read and never stored on
132
+ * the order.
131
133
  */
132
134
  type StorefrontOrderView = Order & {
133
135
  paymentAttempt?: OrderPaymentAttemptView;
134
136
  delivery?: OrderDeliveryView;
137
+ purchaseWithdrawals?: OrderPurchaseWithdrawalView[];
138
+ purchaseWithdrawalEligibility?: OrderPurchaseWithdrawalEligibility;
135
139
  };
136
140
  /**
137
141
  * `data` of an `orderPaymentAttempt` socket frame, sent to the order's own
@@ -26,6 +26,7 @@ export interface PlatformConfigEntry extends Partial<StorefrontRegistryMetadata>
26
26
  max?: number;
27
27
  integer?: true;
28
28
  calendarDay?: true;
29
+ calendarDayList?: true;
29
30
  nonDecreasing?: true;
30
31
  maxLength?: number;
31
32
  allowedValues?: string[];
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Purchase withdrawals — the shopper's statutory right to withdraw from a
3
+ * distance purchase (*arrepentimiento*), as a record of its own.
4
+ *
5
+ * A withdrawal is a REQUEST with an identification code (`withdrawalId`, `ARR`
6
+ * plus 6–10 digits), a window and a decision. It never moves stock or money by
7
+ * itself: once accepted, the order's own cancellation (before fulfilment) or a
8
+ * return (after it) does, and the money owed back is a {@link RefundObligation}
9
+ * whose `parentId` is the `withdrawalId`.
10
+ *
11
+ * Naming: "withdrawal" alone already names the guest-telemetry consent
12
+ * withdrawal and `cash.withdrawal` on the till, so every name here carries the
13
+ * `PurchaseWithdrawal` / `purchaseWithdrawal` stem.
14
+ *
15
+ * ⚠️ The stored row carries one main-table index-key attribute on purpose,
16
+ * `customerId` (the order's customer when the request was made, a guest row's
17
+ * id for a guest order), so the customer erasure finds it through the existing
18
+ * `PK-customerId` read. It carries none of the others: `state` replaces
19
+ * `status`, `revisedAt` replaces `updatedAt`, and there is no `dated`.
20
+ */
21
+ /**
22
+ * - `requested` — submitted, the code minted, the order's dispatch locked
23
+ * (`purchase-withdrawal-pending`) until an operator decides.
24
+ * - `declined` — an operator declined it with a typed exemption reason.
25
+ * Terminal.
26
+ * - `accepted` — an operator accepted it. The order's cancellation (before
27
+ * fulfilment) or its return authorisation (after it) follows from here.
28
+ * - `awaiting-goods` — after fulfilment, the goods are on their way back.
29
+ * - `refund-pending` — money is owed back (an open refund obligation).
30
+ * - `completed` — nothing is owed any more. Not final while money can still
31
+ * arrive: a late capture moves it back to `refund-pending`.
32
+ */
33
+ export declare const PURCHASE_WITHDRAWAL_STATES: readonly ["requested", "declined", "accepted", "awaiting-goods", "refund-pending", "completed"];
34
+ /**
35
+ * The `state` filter of `GET /purchase-withdrawals`: one state, or `open` —
36
+ * every state but `declined` and `completed`.
37
+ */
38
+ export declare const PURCHASE_WITHDRAWAL_LIST_FILTERS: readonly ["requested", "declined", "accepted", "awaiting-goods", "refund-pending", "completed", "open"];
39
+ /** `shopper` — the storefront form; `operator-relay` — an operator recording a request received by email or WhatsApp. */
40
+ export declare const PURCHASE_WITHDRAWAL_SOURCES: readonly ["shopper", "operator-relay"];
41
+ /**
42
+ * The only reasons an operator may decline a request, each backed by a row of
43
+ * the consumer-commerce applicability matrix: made to order or personalised,
44
+ * quick deterioration, unsealed media or software, periodicals, a used
45
+ * product, perishables, and a purchase made for resale or production.
46
+ */
47
+ export declare const PURCHASE_WITHDRAWAL_DECLINE_REASONS: readonly ["exempt-custom-made", "exempt-quick-deterioration", "exempt-unsealed-media", "exempt-periodical", "exempt-used-product", "exempt-perishable", "resale-purchase"];
48
+ /** Where a relayed request reached the store. */
49
+ export declare const PURCHASE_WITHDRAWAL_RELAY_CHANNELS: readonly ["email", "whatsapp"];
50
+ /** The modes of `POST /purchase-withdrawals`. */
51
+ export declare const PURCHASE_WITHDRAWAL_ACTION_MODES: readonly ["accept", "decline", "relay"];
52
+ /**
53
+ * Why a request is refused `409 PURCHASE_WITHDRAWAL_INELIGIBLE` (`data.reason`):
54
+ *
55
+ * - `order-cancelled` — the order is cancelled or disabled.
56
+ * - `no-customer` — the order names no customer (a relay on a walk-in sale).
57
+ * - `partial-before-fulfilment` — `lines` were named on an order not yet
58
+ * delivered or shipped; before fulfilment a withdrawal is the whole order.
59
+ * - `line-not-on-order` — a named line is not a goods line of the order.
60
+ * - `line-unavailable` — a named line (or quantity) is already in another
61
+ * withdrawal that was not declined, in an open return authorisation, or
62
+ * already returned (`data.orderItemIndex`).
63
+ * - `nothing-to-withdraw` — every line is already withdrawn or returned.
64
+ */
65
+ export declare const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS: readonly ["order-cancelled", "no-customer", "partial-before-fulfilment", "line-not-on-order", "line-unavailable", "nothing-to-withdraw"];
66
+ /** The longest decline or relay `note`, in characters after trimming. */
67
+ export declare const PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
68
+ /** The most lines one request may name. */
69
+ export declare const PURCHASE_WITHDRAWAL_LINES_MAX = 100;
70
+ /** Calendar days of the withdrawal window after the later of delivery and purchase. */
71
+ export declare const PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
72
+ /** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
73
+ export declare const PURCHASE_WITHDRAWAL_WINDOW_SOURCE = "W2";
74
+ /** The matrix row a relayed request's `codeDueAt` (24 hours after it was received) comes from. */
75
+ export declare const PURCHASE_WITHDRAWAL_CODE_DUE_SOURCE = "W1";
76
+ /** How long after a relayed request was received its code is due, in ms. */
77
+ export declare const PURCHASE_WITHDRAWAL_CODE_DUE_MS: number;
78
+ declare global {
79
+ type PurchaseWithdrawalState = (typeof PURCHASE_WITHDRAWAL_STATES)[number];
80
+ type PurchaseWithdrawalSource = (typeof PURCHASE_WITHDRAWAL_SOURCES)[number];
81
+ type PurchaseWithdrawalDeclineReason = (typeof PURCHASE_WITHDRAWAL_DECLINE_REASONS)[number];
82
+ type PurchaseWithdrawalRelayChannel = (typeof PURCHASE_WITHDRAWAL_RELAY_CHANNELS)[number];
83
+ type PurchaseWithdrawalActionMode = (typeof PURCHASE_WITHDRAWAL_ACTION_MODES)[number];
84
+ type PurchaseWithdrawalIneligibleReason = (typeof PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS)[number];
85
+ /** One withdrawn order line, by its index in `Order.items`. */
86
+ interface PurchaseWithdrawalLine {
87
+ orderItemIndex: number;
88
+ quantity: number;
89
+ }
90
+ /**
91
+ * How the identification code reached the shopper. `shownAt` is when the
92
+ * `201` carried it on screen (the same medium as the request); the
93
+ * `purchase-withdrawal-received` mail is queued after the commit and
94
+ * stamps `emailQueuedAt`, and the mail worker records `emailStatus`:
95
+ * `sent`, or `not-sent` when the order's customer has no address to mail
96
+ * or the send was refused for good (a suppressed address included).
97
+ */
98
+ interface PurchaseWithdrawalAcknowledgement {
99
+ /** Unix ms. */
100
+ shownAt: number;
101
+ /** Unix ms. */
102
+ emailQueuedAt?: number;
103
+ emailStatus?: 'sent' | 'not-sent';
104
+ }
105
+ /**
106
+ * A request an operator relayed from another channel. `codeDueAt` is
107
+ * `receivedAt` + 24 hours (`W1`); `codeMintedLate` is `true` when the code
108
+ * was minted after it.
109
+ */
110
+ interface PurchaseWithdrawalRelay {
111
+ channel: PurchaseWithdrawalRelayChannel;
112
+ /** Unix ms — when the shopper's message reached the store. */
113
+ receivedAt: number;
114
+ codeDueAt: StatutoryInstant;
115
+ codeMintedLate: boolean;
116
+ /** The operator's own words. Removed by a customer erasure; never in an audit row. */
117
+ note?: string;
118
+ }
119
+ /** Who decided a request, and when. */
120
+ interface PurchaseWithdrawalDecision {
121
+ /** `operator` — `POST /purchase-withdrawals`; `auto` — accepted with nothing to undo (reserved). */
122
+ by: 'operator' | 'auto';
123
+ /** Unix ms. */
124
+ at: number;
125
+ /** The store user, for `operator`. */
126
+ actor?: string;
127
+ }
128
+ /**
129
+ * A purchase withdrawal: `PURCHASE_WITHDRAWAL#{storeId}` / SK
130
+ * `{orderId}#{withdrawalId}`, no `ttl` (evidence of a consumer right
131
+ * exercised). One request per order can be undecided at a time.
132
+ */
133
+ interface PurchaseWithdrawal {
134
+ /** The identification code: `ARR` + 6–10 digits. */
135
+ withdrawalId: string;
136
+ orderId: string;
137
+ /** The order's customer when the request was made (a guest row's id for a guest order). */
138
+ customerId: string;
139
+ state: PurchaseWithdrawalState;
140
+ source: PurchaseWithdrawalSource;
141
+ /**
142
+ * `true` when the request is for the whole order — always before
143
+ * fulfilment, and after it when no lines were named.
144
+ */
145
+ wholeOrder: boolean;
146
+ /** The withdrawn lines and quantities, never freight (a later return decides freight). */
147
+ lines: PurchaseWithdrawalLine[];
148
+ /** What the withdrawn lines were charged, in `currency` (the order total for a whole-order request). */
149
+ amount: number;
150
+ currency: string;
151
+ /** Unix ms — when the request was made (`relay.receivedAt` for a relay). */
152
+ requestedAt: number;
153
+ /**
154
+ * The end of the window the request was judged against, when the order
155
+ * was delivered (source `W2`). Absent before delivery: the window was open.
156
+ */
157
+ windowClosesAt?: StatutoryInstant;
158
+ relay?: PurchaseWithdrawalRelay;
159
+ /** For a `shopper` request. */
160
+ acknowledgement?: PurchaseWithdrawalAcknowledgement;
161
+ /** Set by the move out of `requested`. */
162
+ decision?: PurchaseWithdrawalDecision;
163
+ /** Set by a decline. */
164
+ declineReason?: PurchaseWithdrawalDeclineReason;
165
+ /** The operator's own words on a decline. Removed by a customer erasure; never in an audit row. */
166
+ declineNote?: string;
167
+ /** Bumped by every move, for a compare-and-set. */
168
+ revision: number;
169
+ /** Unix ms. */
170
+ createdAt: number;
171
+ /** Unix ms of the last move. */
172
+ revisedAt: number;
173
+ }
174
+ /**
175
+ * The undecided request an order carries, stamped on the ORDER row while
176
+ * the request is `requested` and removed in the decision's transaction. Its
177
+ * presence is the dispatch lock (`OrderLockReason`
178
+ * `purchase-withdrawal-pending`).
179
+ */
180
+ interface OrderPurchaseWithdrawalPending {
181
+ withdrawalId: string;
182
+ /** Unix ms. */
183
+ requestedAt: number;
184
+ }
185
+ /** One refund owed on a withdrawal, as the shopper sees it — one per refund obligation. */
186
+ interface OrderPurchaseWithdrawalRefundView {
187
+ /** `pending` — owed (`open` or `overdue`, or awaiting the goods); `in-review` — held by a dispute; `refunded` — closed. */
188
+ state: 'pending' | 'in-review' | 'refunded';
189
+ amount: number;
190
+ currency: string;
191
+ /** Unix ms — when it is due, while `pending` with a due date. */
192
+ dueAt?: number;
193
+ /** Unix ms — when it was closed. */
194
+ refundedAt?: number;
195
+ }
196
+ /**
197
+ * A withdrawal as its shopper sees it, on `StorefrontOrderView` and in the
198
+ * `orderPurchaseWithdrawal` socket frame. Never the operator's notes.
199
+ */
200
+ interface OrderPurchaseWithdrawalView {
201
+ /** The identification code. */
202
+ withdrawalId: string;
203
+ state: PurchaseWithdrawalState;
204
+ /** Unix ms. */
205
+ requestedAt: number;
206
+ wholeOrder: boolean;
207
+ lines: PurchaseWithdrawalLine[];
208
+ declineReason?: PurchaseWithdrawalDeclineReason;
209
+ /** One per refund obligation of this withdrawal, when there is any. */
210
+ refunds?: OrderPurchaseWithdrawalRefundView[];
211
+ }
212
+ /**
213
+ * Whether the shopper may submit a withdrawal for the order now. `open` is
214
+ * the window alone (not the lines); `windowClosesAt` is set once the order
215
+ * was delivered.
216
+ */
217
+ interface OrderPurchaseWithdrawalEligibility {
218
+ open: boolean;
219
+ /** Unix ms. */
220
+ windowClosesAt?: number;
221
+ }
222
+ /** `data` of an `orderPurchaseWithdrawal` socket frame, sent to the order's own customer on each change. */
223
+ interface OrderPurchaseWithdrawalFrameData {
224
+ orderId: string;
225
+ purchaseWithdrawal: OrderPurchaseWithdrawalView;
226
+ }
227
+ /**
228
+ * `POST /orders/purchase-withdrawal` (Web host, `customerToken`). Strict body.
229
+ * `lines` names the lines to withdraw after fulfilment; absent, the request is
230
+ * for every line still withdrawable. Before fulfilment it must be absent.
231
+ */
232
+ interface PurchaseWithdrawalSubmitRequest {
233
+ /** `ORD` + 6–10 digits. */
234
+ orderId: string;
235
+ /** 1–{@link PURCHASE_WITHDRAWAL_LINES_MAX} distinct lines, each with a positive quantity. */
236
+ lines?: PurchaseWithdrawalLine[];
237
+ }
238
+ /** `data` of the `201` of `POST /orders/purchase-withdrawal`: the code is `purchaseWithdrawal.withdrawalId`. */
239
+ interface PurchaseWithdrawalSubmitResponse {
240
+ purchaseWithdrawal: OrderPurchaseWithdrawalView;
241
+ }
242
+ /** `data` of `409 PURCHASE_WITHDRAWAL_ALREADY_REQUESTED`: the undecided request's code. */
243
+ interface PurchaseWithdrawalAlreadyRequestedData {
244
+ withdrawalId: string;
245
+ }
246
+ /** `data` of `409 PURCHASE_WITHDRAWAL_WINDOW_CLOSED`. */
247
+ interface PurchaseWithdrawalWindowClosedData {
248
+ /** Unix ms. */
249
+ windowClosesAt: number;
250
+ source: 'W2';
251
+ }
252
+ /** `data` of `409 PURCHASE_WITHDRAWAL_INELIGIBLE`. */
253
+ interface PurchaseWithdrawalIneligibleData {
254
+ reason: PurchaseWithdrawalIneligibleReason;
255
+ /** The line refused, for `line-not-on-order` and `line-unavailable`. */
256
+ orderItemIndex?: number;
257
+ }
258
+ /** One of {@link PURCHASE_WITHDRAWAL_LIST_FILTERS}. */
259
+ type PurchaseWithdrawalListFilter = (typeof PURCHASE_WITHDRAWAL_LIST_FILTERS)[number];
260
+ /**
261
+ * The query of `GET /purchase-withdrawals` (App host, `staffToken`). Reads the
262
+ * token's store only, in `{orderId}#{withdrawalId}` order.
263
+ */
264
+ interface PurchaseWithdrawalListQuery {
265
+ state?: PurchaseWithdrawalListFilter;
266
+ /** Only this order's withdrawals (`ORD` + 6–10 digits), by key. */
267
+ orderId?: string;
268
+ /** Rows EVALUATED per page, 1–100 (default 25): a page can be short or empty with `nextCursor` present. */
269
+ limit?: number;
270
+ /** The previous page's `nextCursor`, bound to the store and to `state` + `orderId`. */
271
+ cursor?: string;
272
+ }
273
+ /** `data` of `GET /purchase-withdrawals`. Page on `nextCursor`'s presence, never on the page's length. */
274
+ interface PurchaseWithdrawalListResponse {
275
+ purchaseWithdrawals: PurchaseWithdrawal[];
276
+ /** Opaque. Absent on the last page. */
277
+ nextCursor?: string;
278
+ }
279
+ /**
280
+ * `POST /purchase-withdrawals` (App host, `adminToken`). Strict body.
281
+ *
282
+ * - `accept` / `decline` — decide a `requested` withdrawal under
283
+ * `expectedRevision` (the `revision` the operator acted on). A decline
284
+ * names one {@link PurchaseWithdrawalDeclineReason} and may carry a note.
285
+ * Both release the order's dispatch lock in the same transaction.
286
+ * - `relay` — record a request the store received by email or WhatsApp and
287
+ * mint its code, which the operator then sends on that channel.
288
+ */
289
+ type PurchaseWithdrawalActionRequest = {
290
+ mode: 'accept';
291
+ orderId: string;
292
+ withdrawalId: string;
293
+ expectedRevision: number;
294
+ } | {
295
+ mode: 'decline';
296
+ orderId: string;
297
+ withdrawalId: string;
298
+ expectedRevision: number;
299
+ reason: PurchaseWithdrawalDeclineReason;
300
+ /** 1–{@link PURCHASE_WITHDRAWAL_NOTE_MAX} characters after trimming. */
301
+ note?: string;
302
+ } | {
303
+ mode: 'relay';
304
+ orderId: string;
305
+ channel: PurchaseWithdrawalRelayChannel;
306
+ /** Unix ms, not in the future. */
307
+ receivedAt: number;
308
+ /** As on the shopper's request. */
309
+ lines?: PurchaseWithdrawalLine[];
310
+ /** 1–{@link PURCHASE_WITHDRAWAL_NOTE_MAX} characters after trimming. */
311
+ note?: string;
312
+ };
313
+ /**
314
+ * `data` of a successful `POST /purchase-withdrawals`: the withdrawal as it
315
+ * now stands. For `relay` (`201`) its `withdrawalId` is the code to send.
316
+ */
317
+ interface PurchaseWithdrawalActionResponse {
318
+ purchaseWithdrawal: PurchaseWithdrawal;
319
+ }
320
+ /** `data` of `409 PURCHASE_WITHDRAWAL_ALREADY_DECIDED`: the decision that stands. */
321
+ interface PurchaseWithdrawalAlreadyDecidedData {
322
+ state: PurchaseWithdrawalState;
323
+ decision?: PurchaseWithdrawalDecision;
324
+ declineReason?: PurchaseWithdrawalDeclineReason;
325
+ }
326
+ /** `data` of `409 PURCHASE_WITHDRAWAL_CHANGED`: the withdrawal as it now stands — review it and resend. */
327
+ interface PurchaseWithdrawalChangedData {
328
+ purchaseWithdrawal: PurchaseWithdrawal;
329
+ }
330
+ }
331
+ export {};
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Purchase withdrawals — the shopper's statutory right to withdraw from a
3
+ * distance purchase (*arrepentimiento*), as a record of its own.
4
+ *
5
+ * A withdrawal is a REQUEST with an identification code (`withdrawalId`, `ARR`
6
+ * plus 6–10 digits), a window and a decision. It never moves stock or money by
7
+ * itself: once accepted, the order's own cancellation (before fulfilment) or a
8
+ * return (after it) does, and the money owed back is a {@link RefundObligation}
9
+ * whose `parentId` is the `withdrawalId`.
10
+ *
11
+ * Naming: "withdrawal" alone already names the guest-telemetry consent
12
+ * withdrawal and `cash.withdrawal` on the till, so every name here carries the
13
+ * `PurchaseWithdrawal` / `purchaseWithdrawal` stem.
14
+ *
15
+ * ⚠️ The stored row carries one main-table index-key attribute on purpose,
16
+ * `customerId` (the order's customer when the request was made, a guest row's
17
+ * id for a guest order), so the customer erasure finds it through the existing
18
+ * `PK-customerId` read. It carries none of the others: `state` replaces
19
+ * `status`, `revisedAt` replaces `updatedAt`, and there is no `dated`.
20
+ */
21
+ /**
22
+ * - `requested` — submitted, the code minted, the order's dispatch locked
23
+ * (`purchase-withdrawal-pending`) until an operator decides.
24
+ * - `declined` — an operator declined it with a typed exemption reason.
25
+ * Terminal.
26
+ * - `accepted` — an operator accepted it. The order's cancellation (before
27
+ * fulfilment) or its return authorisation (after it) follows from here.
28
+ * - `awaiting-goods` — after fulfilment, the goods are on their way back.
29
+ * - `refund-pending` — money is owed back (an open refund obligation).
30
+ * - `completed` — nothing is owed any more. Not final while money can still
31
+ * arrive: a late capture moves it back to `refund-pending`.
32
+ */
33
+ export const PURCHASE_WITHDRAWAL_STATES = [
34
+ 'requested',
35
+ 'declined',
36
+ 'accepted',
37
+ 'awaiting-goods',
38
+ 'refund-pending',
39
+ 'completed',
40
+ ];
41
+ /**
42
+ * The `state` filter of `GET /purchase-withdrawals`: one state, or `open` —
43
+ * every state but `declined` and `completed`.
44
+ */
45
+ export const PURCHASE_WITHDRAWAL_LIST_FILTERS = [...PURCHASE_WITHDRAWAL_STATES, 'open'];
46
+ /** `shopper` — the storefront form; `operator-relay` — an operator recording a request received by email or WhatsApp. */
47
+ export const PURCHASE_WITHDRAWAL_SOURCES = ['shopper', 'operator-relay'];
48
+ /**
49
+ * The only reasons an operator may decline a request, each backed by a row of
50
+ * the consumer-commerce applicability matrix: made to order or personalised,
51
+ * quick deterioration, unsealed media or software, periodicals, a used
52
+ * product, perishables, and a purchase made for resale or production.
53
+ */
54
+ export const PURCHASE_WITHDRAWAL_DECLINE_REASONS = [
55
+ 'exempt-custom-made',
56
+ 'exempt-quick-deterioration',
57
+ 'exempt-unsealed-media',
58
+ 'exempt-periodical',
59
+ 'exempt-used-product',
60
+ 'exempt-perishable',
61
+ 'resale-purchase',
62
+ ];
63
+ /** Where a relayed request reached the store. */
64
+ export const PURCHASE_WITHDRAWAL_RELAY_CHANNELS = ['email', 'whatsapp'];
65
+ /** The modes of `POST /purchase-withdrawals`. */
66
+ export const PURCHASE_WITHDRAWAL_ACTION_MODES = ['accept', 'decline', 'relay'];
67
+ /**
68
+ * Why a request is refused `409 PURCHASE_WITHDRAWAL_INELIGIBLE` (`data.reason`):
69
+ *
70
+ * - `order-cancelled` — the order is cancelled or disabled.
71
+ * - `no-customer` — the order names no customer (a relay on a walk-in sale).
72
+ * - `partial-before-fulfilment` — `lines` were named on an order not yet
73
+ * delivered or shipped; before fulfilment a withdrawal is the whole order.
74
+ * - `line-not-on-order` — a named line is not a goods line of the order.
75
+ * - `line-unavailable` — a named line (or quantity) is already in another
76
+ * withdrawal that was not declined, in an open return authorisation, or
77
+ * already returned (`data.orderItemIndex`).
78
+ * - `nothing-to-withdraw` — every line is already withdrawn or returned.
79
+ */
80
+ export const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
81
+ 'order-cancelled',
82
+ 'no-customer',
83
+ 'partial-before-fulfilment',
84
+ 'line-not-on-order',
85
+ 'line-unavailable',
86
+ 'nothing-to-withdraw',
87
+ ];
88
+ /** The longest decline or relay `note`, in characters after trimming. */
89
+ export const PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
90
+ /** The most lines one request may name. */
91
+ export const PURCHASE_WITHDRAWAL_LINES_MAX = 100;
92
+ /** Calendar days of the withdrawal window after the later of delivery and purchase. */
93
+ export const PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
94
+ /** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
95
+ export const PURCHASE_WITHDRAWAL_WINDOW_SOURCE = 'W2';
96
+ /** The matrix row a relayed request's `codeDueAt` (24 hours after it was received) comes from. */
97
+ export const PURCHASE_WITHDRAWAL_CODE_DUE_SOURCE = 'W1';
98
+ /** How long after a relayed request was received its code is due, in ms. */
99
+ export const PURCHASE_WITHDRAWAL_CODE_DUE_MS = 24 * 60 * 60 * 1000;
package/dist/socket.d.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  * A client must ignore actions it does not own rather than assume it
27
27
  * receives all of them.
28
28
  */
29
- export declare const SOCKET_ACTIONS: readonly ["account", "appointments", "appointmentWaitlist", "attendance", "attributes", "automation-rules", "baskets", "cart", "brands", "cash", "catalogOperation", "categories", "campaigns", "customers", "customerNote", "customerAddress", "customerContact", "deliveries", "globals", "inventory", "invoices", "literals", "loyalty", "orders", "presupuestos", "products", "promotions", "segments", "returns", "rma", "templates", "services", "service-templates", "shifts", "stores", "suppliers", "supplier-invoice", "support", "surveys", "users", "warehouses", "zones", "favorites", "webhooks", "account-delete", "baskets-delete", "cart-delete", "log-delete", "notifications", "support-message", "payment_received", "mp_payment_status_changed", "payment_linked", "payment_unlinked", "mercadopago", "mercadopago_dynamic_qr_created", "mercadopago_static_qr_created", "mp_hook_log_appended", "mp_ipn_log_appended", "orderPaymentAttempt", "orderDelivery", "paymentAttemptChanged", "stripe", "subscription", "caea", "print", "print-order", "print-invoice", "print-product", "print-tag", "print_job_failed", "request_printers", "printers_changed", "agent_status_changed", "print_rules_changed", "printers_active", "agent_command", "maintenance", "currency_auto_updated", "drain_progress", "integration_event_appended", "userActivityRecorded", "mercadolibre_settlement_period", "customDomain", "purchaseOrders", "cycleCounts", "stockTransfers", "workItems", "wholesaleRequests"];
29
+ export declare const SOCKET_ACTIONS: readonly ["account", "appointments", "appointmentWaitlist", "attendance", "attributes", "automation-rules", "baskets", "cart", "brands", "cash", "catalogOperation", "categories", "campaigns", "customers", "customerNote", "customerAddress", "customerContact", "deliveries", "globals", "inventory", "invoices", "literals", "loyalty", "orders", "presupuestos", "products", "promotions", "segments", "returns", "rma", "templates", "services", "service-templates", "shifts", "stores", "suppliers", "supplier-invoice", "support", "surveys", "users", "warehouses", "zones", "favorites", "webhooks", "account-delete", "baskets-delete", "cart-delete", "log-delete", "notifications", "support-message", "payment_received", "mp_payment_status_changed", "payment_linked", "payment_unlinked", "mercadopago", "mercadopago_dynamic_qr_created", "mercadopago_static_qr_created", "mp_hook_log_appended", "mp_ipn_log_appended", "orderPaymentAttempt", "orderDelivery", "paymentAttemptChanged", "orderPurchaseWithdrawal", "purchaseWithdrawalChanged", "stripe", "subscription", "caea", "print", "print-order", "print-invoice", "print-product", "print-tag", "print_job_failed", "request_printers", "printers_changed", "agent_status_changed", "print_rules_changed", "printers_active", "agent_command", "maintenance", "currency_auto_updated", "drain_progress", "integration_event_appended", "userActivityRecorded", "mercadolibre_settlement_period", "customDomain", "purchaseOrders", "cycleCounts", "stockTransfers", "workItems", "wholesaleRequests"];
30
30
  /** Union of every server→client data-frame action. */
31
31
  export type SocketAction = (typeof SOCKET_ACTIONS)[number];
32
32
  /**
package/dist/socket.js CHANGED
@@ -540,6 +540,27 @@ export const SOCKET_ACTIONS = [
540
540
  * a customer socket: the shopper's own frame is `orderPaymentAttempt`.
541
541
  */
542
542
  'paymentAttemptChanged',
543
+ /**
544
+ * A storefront order's purchase withdrawal was requested or decided. `data`
545
+ * is `OrderPurchaseWithdrawalFrameData` (`purchaseWithdrawal.ts`) — the order
546
+ * id and the shopper's `OrderPurchaseWithdrawalView`, never the operator's
547
+ * notes.
548
+ *
549
+ * ⚠️ To the order's OWN customer only (`wsPostCustomer`), never a store-wide
550
+ * customer broadcast. The operator frame for the same write is
551
+ * `purchaseWithdrawalChanged`.
552
+ */
553
+ 'orderPurchaseWithdrawal',
554
+ /**
555
+ * A purchase withdrawal was requested, relayed or decided. `data` is the
556
+ * `PurchaseWithdrawal` record as `GET /purchase-withdrawals` answers it.
557
+ *
558
+ * ⚠️ OPERATOR sockets of the store only, and ADMIN tier only (`wsPostStore`
559
+ * with `audience: 'operator'` and `lowTierData: null`): it carries the
560
+ * customer id and the operator's notes. The shopper's own frame is
561
+ * `orderPurchaseWithdrawal`.
562
+ */
563
+ 'purchaseWithdrawalChanged',
543
564
  'stripe',
544
565
  'subscription',
545
566
  // Fiscal.
package/dist/store.d.ts CHANGED
@@ -567,6 +567,13 @@ declare global {
567
567
  whatsapp?: StorefrontPublicContact['whatsapp'];
568
568
  };
569
569
  hours?: StorefrontContactHours;
570
+ /**
571
+ * `true` while the platform's purchase-withdrawal form is on
572
+ * (`purchaseWithdrawalFormEnabled`): the button opens the form
573
+ * (`POST /orders/purchase-withdrawal`) and the storefront retires the
574
+ * prefilled email or WhatsApp link. `false` keeps that link as the request.
575
+ */
576
+ requestForm: boolean;
570
577
  };
571
578
  privacy: {
572
579
  /** The same verdict as `ecommerce.config.guestCheckoutAvailable`. */
@@ -148,12 +148,21 @@ export const STOREFRONT_DESIGN_REGISTRY = {
148
148
  *
149
149
  * Responsable Inscripto only (`integrations.afip.condFiscal === 30`). Both
150
150
  * writers refuse `true` on any other store with 409 NET_PLUS_IVA_REQUIRES_RI;
151
- * `false` and `null` always pass. Storefront exits (web `GET /store`, the
152
- * preview's store frame, the customer `stores` frame) send the EFFECTIVE value,
153
- * stored flag AND RI; app reads (`GET /store`, the operator `/tenants` read)
154
- * send the STORED one beside `integrations.afip.condFiscal`.
151
+ * `false` and `null` always pass. App reads (`GET /store`, the operator
152
+ * `/tenants` read) send the STORED value beside `integrations.afip.condFiscal`.
153
+ *
154
+ * Wholesale customers only. Storefront exits send the EFFECTIVE value per
155
+ * viewer: stored flag AND RI AND an approved customer whose effective price
156
+ * list is `audienceClass: 'wholesale'`. A guest, a pending registrant and a
157
+ * retail customer read `false`.
158
+ * - Web `GET /store` judges its resolved caller. A customer's answer is
159
+ * `private, no-store`, and every answer varies on `Authorization`.
160
+ * - The preview's store frame judges the grant fixture's simulated caller.
161
+ * A grant without a fixture is judged as a guest.
162
+ * - The customer `stores` frame reaches every shopper at once, so it always
163
+ * sends `false`. The storefront re-reads web `GET /store` on that frame.
155
164
  */
156
- showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Mostrar también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
165
+ showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Tus clientes mayoristas ven también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
157
166
  prices: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
158
167
  stock: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
159
168
  checkout: { ...LIVE_METADATA, storage: { source: 'store' } },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.814",
3
+ "version": "1.10.816",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",