@uengage.io/platform-sdk 2.1.0 → 2.3.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.
@@ -1,5 +1,5 @@
1
1
  import { type PlatformAuth, type PlatformAuthInput, type PlatformConfigInput } from '../config';
2
- import type { CreditInput, Currency, DebitInput, GetWalletOptions, ListTransactionsFilter, TransactionPage, TransactionResult, WalletBalance, WalletInstance, WalletTransaction } from './schema';
2
+ import type { CreditEvent, CreditInput, CreditLine, CreditUtilisationFilter, CreditUtilisationPage, Currency, DebitInput, GetWalletOptions, ListCreditEventsFilter, ListTransactionsFilter, ReverseSettlementInput, SetCreditLimitInput, SetCreditLimitResult, SettleInvoiceInput, SettleInvoiceResult, TransactionPage, TransactionResult, WalletBalance, WalletInstance, WalletOverview, WalletTransaction } from './schema';
3
3
  /**
4
4
  * A handle to one business wallet. Cheap to create — `getWallet(...)`
5
5
  * does no I/O. The wallet is resolved server-side on the first
@@ -7,6 +7,23 @@ import type { CreditInput, Currency, DebitInput, GetWalletOptions, ListTransacti
7
7
  * surface from the operation, not from `getWallet()`.
8
8
  */
9
9
  export interface Wallet {
10
+ /**
11
+ * WHICH MODEL IS THIS MERCHANT ON — call this first.
12
+ *
13
+ * Returns a discriminated union on `mode`, so a dashboard settles
14
+ * "wallet balance or credit line?" from a value rather than by
15
+ * catching a 404, and TypeScript narrows the rest for you:
16
+ *
17
+ * ```ts
18
+ * const o = await wallet.getOverview();
19
+ * if (o.mode === 'credit') renderCreditWidget(o.creditLine);
20
+ * else renderWalletPanel(o.balance);
21
+ * ```
22
+ *
23
+ * One request for a prepaid merchant, two for a credit one, and never
24
+ * a 404 on the happy path — see the implementation for why that order.
25
+ */
26
+ getOverview(): Promise<WalletOverview>;
10
27
  /** GET /v1/wallet/balance — resolves the wallet and returns its balance + currency. */
11
28
  getBalance(): Promise<WalletBalance>;
12
29
  /** GET /v1/wallet/instance — wallet identity + currency, without the balance. */
@@ -29,6 +46,39 @@ export interface Wallet {
29
46
  listTransactions(filter?: ListTransactionsFilter): Promise<TransactionPage>;
30
47
  /** GET /v1/wallet/transactions/:id — scoped to this wallet. */
31
48
  getTransaction(id: string): Promise<WalletTransaction>;
49
+ /**
50
+ * GET /v1/wallet/credit — everything the merchant widget renders.
51
+ * Throws `CreditLineNotFoundError` (404) when the merchant is not on
52
+ * the credit line, which is the normal state for a prepaid merchant.
53
+ * Requires `wallet.credit:read`.
54
+ */
55
+ getCreditLine(): Promise<CreditLine>;
56
+ /**
57
+ * GET /v1/wallet/credit/events — the limit-change and settlement
58
+ * trail, newest first. Requires `wallet.credit:read`.
59
+ *
60
+ * Pass a `limit` to widen the page: the service defaults to 50, which
61
+ * a merchant on the line for a year will have outgrown.
62
+ */
63
+ listCreditEvents(filter?: ListCreditEventsFilter): Promise<CreditEvent[]>;
64
+ /**
65
+ * PUT /v1/wallet/credit/limit — set the limit, creating the credit
66
+ * line on first use. Consumption is never touched, so raising a limit
67
+ * hands back exactly the difference. Requires `wallet.credit:write`.
68
+ */
69
+ setCreditLimit(input: SetCreditLimitInput): Promise<SetCreditLimitResult>;
70
+ /**
71
+ * POST /v1/wallet/credit/settlements — release the credit an invoice
72
+ * was holding, on payment IN FULL. Releases the invoice's net figure;
73
+ * see `SettleInvoiceInput.netMinor`. Requires `wallet.credit:settle`.
74
+ */
75
+ settleInvoice(input: SettleInvoiceInput): Promise<SettleInvoiceResult>;
76
+ /**
77
+ * POST /v1/wallet/credit/settlements/reversal — undo a settlement
78
+ * recorded in error, re-holding exactly what it released. Requires
79
+ * `wallet.credit:settle`.
80
+ */
81
+ reverseSettlement(input: ReverseSettlementInput): Promise<SettleInvoiceResult>;
32
82
  }
33
83
  export interface WalletClient {
34
84
  config(input: PlatformConfigInput): WalletClient;
@@ -39,6 +89,16 @@ export interface WalletClient {
39
89
  * `wallet.*` scope for the operations on the returned handle.
40
90
  */
41
91
  getWallet(opts: GetWalletOptions): Wallet;
92
+ /**
93
+ * GET /v1/wallet/credit/utilisation — every merchant on the credit
94
+ * line, most-utilised first.
95
+ *
96
+ * On the client rather than on a wallet handle because it is the one
97
+ * wallet operation that is not scoped to a business, and it carries
98
+ * its own capability (`wallet.credit:list`) for the same reason: it is
99
+ * a materially broader grant than reading one merchant's line.
100
+ */
101
+ getCreditUtilisation(filter?: CreditUtilisationFilter): Promise<CreditUtilisationPage>;
42
102
  }
43
103
  export declare class WalletApiError extends Error {
44
104
  readonly status: number;
@@ -79,4 +139,148 @@ export declare class UnresolvableWalletError extends WalletApiError {
79
139
  export declare class WalletNotFoundError extends WalletApiError {
80
140
  constructor(body: string);
81
141
  }
142
+ /**
143
+ * The charge would exceed the merchant's credit limit; nothing was moved
144
+ * (HTTP 409).
145
+ *
146
+ * Distinct from `InsufficientBalanceError` because the merchant's next
147
+ * step is different — settle an invoice or talk to their account
148
+ * manager, not top up. The figures also separate two cases that share
149
+ * this error and need different copy:
150
+ *
151
+ * - `availableMinor === 0` — the limit is used up.
152
+ * - `availableMinor > 0` — this one charge is larger than what is
153
+ * left, which can happen at any utilisation. Telling that merchant
154
+ * their "credit limit is reached" would be wrong.
155
+ * - `availableMinor === undefined` — the response carried no figures
156
+ * (a trimmed or proxied body). Fall back to generic copy; do not
157
+ * read it as zero, which is the sentinel above.
158
+ *
159
+ * And a third the fields cannot distinguish on their own: consumption
160
+ * spans months, so a merchant can be at their ceiling purely because
161
+ * older invoices are unpaid. `getCreditLine()` tells you which.
162
+ */
163
+ export declare class CreditLimitReachedError extends WalletApiError {
164
+ readonly limitMinor?: number;
165
+ readonly consumedMinor?: number;
166
+ readonly availableMinor?: number;
167
+ readonly requestedMinor?: number;
168
+ constructor(figures: {
169
+ limitMinor?: number;
170
+ consumedMinor?: number;
171
+ availableMinor?: number;
172
+ requestedMinor?: number;
173
+ }, body: string);
174
+ }
175
+ /**
176
+ * A charge on a credit-line merchant arrived without its GST split
177
+ * (HTTP 400).
178
+ *
179
+ * Consumption is tracked net of GST, so `breakup` is required rather
180
+ * than a rate being inferred. If you hit this, the caller is sending
181
+ * gross-only amounts and needs to send `breakup` — the same split it
182
+ * almost certainly already computes.
183
+ */
184
+ export declare class CreditBreakupRequiredError extends WalletApiError {
185
+ constructor(body: string);
186
+ }
187
+ /** `allowNegative` was passed for a credit-line merchant (HTTP 400). */
188
+ export declare class CreditOverrideRefusedError extends WalletApiError {
189
+ constructor(body: string);
190
+ }
191
+ /**
192
+ * A re-settlement changed an invoice's figures without saying why
193
+ * (HTTP 400).
194
+ *
195
+ * Re-settling a REVERSED invoice with different figures is how a settled
196
+ * amount is corrected, so the service does not refuse it the way it
197
+ * refuses a conflicting first settlement. But it releases against the
198
+ * merchant's whole outstanding consumption rather than the invoice's own
199
+ * amount, so a mistyped figure can hand back far more than the invoice
200
+ * held — and a deliberate correction can say what it is correcting where
201
+ * a replayed webhook cannot. Pass `reason` and retry. Re-settling with
202
+ * the SAME figures needs none.
203
+ */
204
+ export declare class CreditCorrectionReasonRequiredError extends WalletApiError {
205
+ /** What the invoice was previously settled for, in minor units. */
206
+ readonly previousNetMinor: number | undefined;
207
+ constructor(
208
+ /** What the invoice was previously settled for, in minor units. */
209
+ previousNetMinor: number | undefined, body: string);
210
+ }
211
+ /**
212
+ * A limit change named a currency the credit line is not denominated in
213
+ * (HTTP 409).
214
+ *
215
+ * The line's currency is fixed when it is created, because it sets the
216
+ * exponent every stored figure is already scaled by — changing it would
217
+ * re-denominate the limit and the consumption without touching either
218
+ * number. Re-denominating a live line is a migration, not a field
219
+ * update, so this is not something a caller can retry past: send the
220
+ * currency the line already carries.
221
+ */
222
+ export declare class CreditCurrencyConflictError extends WalletApiError {
223
+ readonly storedCurrency: string | undefined;
224
+ readonly requestedCurrency: string | undefined;
225
+ constructor(storedCurrency: string | undefined, requestedCurrency: string | undefined, body: string);
226
+ }
227
+ /**
228
+ * The merchant's credit line and the wallet the charge routed to are in
229
+ * different currencies (HTTP 409).
230
+ *
231
+ * `amountMinor` and `breakup` carry no currency of their own — they are
232
+ * read with the exponent of the resolved wallet — so when the two
233
+ * disagree there is no reading of them that is right for both, and the
234
+ * service refuses rather than mis-scaling by a factor of ten or a
235
+ * hundred. Not caller-fixable: it means the merchant's routing and their
236
+ * credit line disagree, which is an ops/data problem.
237
+ */
238
+ export declare class CreditCurrencyMismatchError extends WalletApiError {
239
+ constructor(body: string);
240
+ }
241
+ /**
242
+ * A plain top-up was sent for a credit-line merchant (HTTP 400).
243
+ *
244
+ * These merchants have no balance to top up: `wallet_balance` is the
245
+ * fiction the credit line replaces and is deliberately frozen, so the
246
+ * write would move nothing while appearing to succeed. Credit is handed
247
+ * back by settling an invoice (`settleInvoice`), never by crediting the
248
+ * wallet. A genuine refund is accepted — send it as `reversalOf` or
249
+ * `isRefund` and it releases the credit the original charge consumed.
250
+ */
251
+ export declare class CreditTopUpRefusedError extends WalletApiError {
252
+ constructor(body: string);
253
+ }
254
+ /**
255
+ * The merchant is not on the credit line (HTTP 404).
256
+ *
257
+ * The normal state for a prepaid merchant, so a widget should treat it
258
+ * as "show the wallet balance instead", not as an error.
259
+ */
260
+ export declare class CreditLineNotFoundError extends WalletApiError {
261
+ constructor(body: string);
262
+ }
263
+ /**
264
+ * `enabled: false` was refused because the merchant still owes for the
265
+ * credit line (HTTP 409).
266
+ *
267
+ * Disabling moves a merchant back to a wallet balance, and doing that
268
+ * with consumption outstanding abandons it. Show `consumedMinor` and
269
+ * tell the operator to settle first — or, if the intent was to stop the
270
+ * merchant trading rather than to move them off the model, set
271
+ * `limitMinor: 0`, which blocks every charge and keeps the balance.
272
+ */
273
+ export declare class CreditLineHasOutstandingError extends WalletApiError {
274
+ readonly consumedMinor: number;
275
+ readonly gstAccruedMinor: number;
276
+ constructor(consumedMinor: number, gstAccruedMinor: number, body: string);
277
+ }
278
+ /** A limit `referenceId` or an invoice was reused for different figures (HTTP 409). */
279
+ export declare class CreditIdempotencyConflictError extends WalletApiError {
280
+ constructor(body: string);
281
+ }
282
+ /** No settlement to reverse for that invoice (HTTP 404). */
283
+ export declare class SettlementNotFoundError extends WalletApiError {
284
+ constructor(body: string);
285
+ }
82
286
  export declare function createWalletClient(input?: PlatformConfigInput): WalletClient;