@avvio/payments 0.1.0 → 0.5.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.
- package/CHANGELOG.md +190 -5
- package/ERRORS.md +120 -58
- package/QUICKSTART.md +162 -54
- package/README.md +136 -37
- package/index.d.ts +801 -82
- package/package.json +11 -5
- package/src/cli.js +204 -20
- package/src/client.js +576 -58
- package/src/mcp.js +279 -29
package/index.d.ts
CHANGED
|
@@ -35,7 +35,6 @@ export type PayoutFailureCode =
|
|
|
35
35
|
| 'authorization_not_completed'
|
|
36
36
|
| 'returned_by_bank'
|
|
37
37
|
| 'execution_failed'
|
|
38
|
-
| 'canceled_by_platform'
|
|
39
38
|
| 'unknown';
|
|
40
39
|
|
|
41
40
|
/** Informational only. Never branch integration behaviour on it. */
|
|
@@ -55,6 +54,12 @@ export interface Payout {
|
|
|
55
54
|
* wallet. Absent on routings that settle on acceptance, so its presence is
|
|
56
55
|
* the signal — call `getFunding()`.
|
|
57
56
|
*/
|
|
57
|
+
/**
|
|
58
|
+
* Waiting on YOU to fund it, right now. Call `getFunding(payoutId)`, send the
|
|
59
|
+
* money, then `confirmFunding`. Absent once it is on its way, and absent
|
|
60
|
+
* entirely where accepting the payout already paid it — so its presence is
|
|
61
|
+
* the instruction, not a flag to interpret.
|
|
62
|
+
*/
|
|
58
63
|
requiresFunding?: boolean;
|
|
59
64
|
/** When this payout last changed. Your `updatedSince` watermark. */
|
|
60
65
|
updatedAt?: string;
|
|
@@ -68,6 +73,12 @@ export interface Payout {
|
|
|
68
73
|
sourceAmount: Money | null;
|
|
69
74
|
destinationAmount: Money | null;
|
|
70
75
|
destinationAccountId: string | null;
|
|
76
|
+
/**
|
|
77
|
+
* Already inside `sourceAmount` (deducted from the send, not added on top).
|
|
78
|
+
* The same value the event `data` carries. Null means the rail has not
|
|
79
|
+
* disclosed it, which is not zero.
|
|
80
|
+
*/
|
|
81
|
+
fee: Money | null;
|
|
71
82
|
rate: string | null;
|
|
72
83
|
reference: string | null;
|
|
73
84
|
endUser: EndUser | null;
|
|
@@ -92,14 +103,31 @@ export interface CorridorField {
|
|
|
92
103
|
title: string;
|
|
93
104
|
type: string;
|
|
94
105
|
pattern?: string;
|
|
106
|
+
/**
|
|
107
|
+
* A check the server applies beyond `pattern`, present only on fields that
|
|
108
|
+
* have one. `clabe`: the Mexican CLABE check digit (digit 18 over digits
|
|
109
|
+
* 1-17, weights 3,7,1 repeating, each product mod 10, then (10 - sum mod 10)
|
|
110
|
+
* mod 10). A value that matches `pattern` but fails this is refused with
|
|
111
|
+
* `400 VALIDATION_ERROR`.
|
|
112
|
+
*/
|
|
113
|
+
checksum?: 'clabe';
|
|
95
114
|
required: boolean;
|
|
96
115
|
description?: string;
|
|
116
|
+
options?: { value: unknown; label: string }[];
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
export interface Corridor {
|
|
100
120
|
currency: string;
|
|
121
|
+
/** Only when the routing publishes one; the sandbox does not. Key on `currency`. */
|
|
122
|
+
country?: string;
|
|
101
123
|
fields: CorridorField[];
|
|
102
|
-
limits?: { min
|
|
124
|
+
limits?: { min?: string; max?: string };
|
|
125
|
+
/**
|
|
126
|
+
* Always `null` today: settlement windows and cutoffs are not published per
|
|
127
|
+
* corridor yet. `Payout.expectedSettlementAt` carries what the network
|
|
128
|
+
* reports for one payout.
|
|
129
|
+
*/
|
|
130
|
+
settlement: null;
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
export interface BeneficiaryMethod {
|
|
@@ -117,6 +145,9 @@ export interface Beneficiary {
|
|
|
117
145
|
name: string;
|
|
118
146
|
email?: string;
|
|
119
147
|
country?: string;
|
|
148
|
+
/** Both are settable through `updateBeneficiary`, and both come back here. */
|
|
149
|
+
type?: 'individual' | 'business';
|
|
150
|
+
phone?: string | null;
|
|
120
151
|
externalId?: string;
|
|
121
152
|
endUserId?: string | null;
|
|
122
153
|
paymentMethods: BeneficiaryMethod[];
|
|
@@ -144,6 +175,7 @@ export type PayoutsErrorType =
|
|
|
144
175
|
| 'UNAUTHORIZED'
|
|
145
176
|
| 'FORBIDDEN'
|
|
146
177
|
| 'NOT_FOUND'
|
|
178
|
+
| 'ROUTE_NOT_FOUND'
|
|
147
179
|
| 'RATE_LIMITED'
|
|
148
180
|
| 'BAD_REQUEST'
|
|
149
181
|
| 'PROVIDER_REJECTED'
|
|
@@ -155,8 +187,32 @@ export type PayoutsErrorType =
|
|
|
155
187
|
| 'CONFLICT'
|
|
156
188
|
| 'ACCOUNT_BLOCKED'
|
|
157
189
|
| 'INSUFFICIENT_BALANCE'
|
|
190
|
+
| 'CRYPTO_PAYOUTS_DISABLED'
|
|
191
|
+
| 'WALLET_NOT_PROVISIONED'
|
|
158
192
|
| 'ORDERS_TEMPORARILY_UNAVAILABLE'
|
|
193
|
+
| 'PAYOUT_ACCOUNT_PROVIDER_UNAVAILABLE'
|
|
194
|
+
// Controls on API payouts. Neither is retried into success by the caller:
|
|
195
|
+
// a cap is split or raised, a refusal is final.
|
|
196
|
+
| 'PAYOUT_LIMIT_EXCEEDED'
|
|
197
|
+
| 'PAYOUT_REFUSED'
|
|
198
|
+
// Quote-accept and payout links, when the organization has an approval
|
|
199
|
+
// threshold or a velocity cap: only `POST /payouts` enforces them.
|
|
200
|
+
| 'USE_POST_PAYOUTS'
|
|
159
201
|
| 'INTERNAL'
|
|
202
|
+
| 'PAYOUT_OUTCOME_UNKNOWN'
|
|
203
|
+
| 'PAYOUT_LINKS_UNAVAILABLE'
|
|
204
|
+
// PARKED request-signing error types:
|
|
205
|
+
// | 'SIGNATURE_CHALLENGE'
|
|
206
|
+
// | 'SIGNATURE_CHALLENGE_EXPIRED'
|
|
207
|
+
// | 'SIGNATURE_REQUIRED'
|
|
208
|
+
// | 'SIGNATURE_INVALID'
|
|
209
|
+
// | 'SIGNATURE_REPLAYED'
|
|
210
|
+
// | 'SIGNATURE_TIMESTAMP_SKEW'
|
|
211
|
+
// | 'SIGNATURE_TIMESTAMP_INVALID'
|
|
212
|
+
// | 'PUBLIC_KEY_INVALID'
|
|
213
|
+
// | 'KEY_RETIRED'
|
|
214
|
+
| 'KEY_EXPIRED'
|
|
215
|
+
| 'KEY_IP_NOT_ALLOWED'
|
|
160
216
|
// Idempotency
|
|
161
217
|
| 'IDEMPOTENCY_KEY_REQUIRED'
|
|
162
218
|
| 'IDEMPOTENCY_KEY_INVALID'
|
|
@@ -168,11 +224,23 @@ export type PayoutsErrorType =
|
|
|
168
224
|
| 'DESTINATION_ACCOUNT_NOT_FOUND'
|
|
169
225
|
| 'RATE_DRIFT_EXCEEDED'
|
|
170
226
|
| 'QUOTE_UNVERIFIABLE'
|
|
227
|
+
| 'QUOTE_NOT_POSITIVE'
|
|
171
228
|
| 'EXACT_OUTPUT_UNSUPPORTED'
|
|
172
229
|
| 'PAYOUT_NOT_CANCELABLE'
|
|
230
|
+
// Asking where to send funds for a payout that settles from your balance.
|
|
231
|
+
// `requiresFunding` on the payout is the branch, and this means that branch
|
|
232
|
+
// is wrong, so retrying never helps.
|
|
233
|
+
| 'FUNDING_NOT_APPLICABLE'
|
|
173
234
|
| 'INSUFFICIENT_SCOPE'
|
|
174
235
|
| 'INDICATIVE_PRICING_UNAVAILABLE'
|
|
175
236
|
| 'PAYOUT_LINK_UNUSABLE'
|
|
237
|
+
// Batch payouts
|
|
238
|
+
| 'BATCH_NOT_FOUND'
|
|
239
|
+
| 'PAYOUT_BATCH_NOT_CONFIRMABLE'
|
|
240
|
+
| 'PAYOUT_BATCH_AWAITING_APPROVAL'
|
|
241
|
+
| 'PAYOUT_BATCH_NOT_CANCELABLE'
|
|
242
|
+
| 'PAYOUT_BATCH_DUPLICATE_REFERENCE'
|
|
243
|
+
| 'MASS_PAYOUTS_DISABLED'
|
|
176
244
|
// Raised by this client, with no HTTP response behind them. `TIMEOUT` is the
|
|
177
245
|
// important one: it is an UNKNOWN outcome, not a failure, and the payout may
|
|
178
246
|
// exist. `CORRIDOR_UNAVAILABLE` is raised here too, and is in the table.
|
|
@@ -198,7 +266,9 @@ export declare class PayoutsError extends Error {
|
|
|
198
266
|
}
|
|
199
267
|
|
|
200
268
|
export interface PayoutsClientOptions {
|
|
201
|
-
|
|
269
|
+
// PARKED request-signing option:
|
|
270
|
+
// privateKeyPem?: string;
|
|
271
|
+
/** Complete bearer credential: `avvio_live_*` or `avvio_test_*`. */
|
|
202
272
|
apiKey?: string;
|
|
203
273
|
orgId?: string;
|
|
204
274
|
baseUrl?: string;
|
|
@@ -206,8 +276,30 @@ export interface PayoutsClientOptions {
|
|
|
206
276
|
}
|
|
207
277
|
|
|
208
278
|
export interface PayoutArgs {
|
|
279
|
+
/**
|
|
280
|
+
* How much. Read as what you SEND, unless `amountLeg` says otherwise — in
|
|
281
|
+
* which case it is what the beneficiary RECEIVES, in their currency.
|
|
282
|
+
*/
|
|
209
283
|
amount: string;
|
|
210
284
|
destinationAccountId: string;
|
|
285
|
+
/**
|
|
286
|
+
* Which side of the payout `amount` describes.
|
|
287
|
+
*
|
|
288
|
+
* `'source'` (the default) takes every fee out of what you sent, so the
|
|
289
|
+
* beneficiary gets less than the figure you named.
|
|
290
|
+
*
|
|
291
|
+
* `'destination'` pays them that figure exactly, in THEIR currency, and adds
|
|
292
|
+
* the fees to your debit instead.
|
|
293
|
+
*
|
|
294
|
+
* `'source_net'` keeps the figure in YOUR currency and means it the same way
|
|
295
|
+
* — "send them $200 worth". We convert at the market rate from `quote()` and
|
|
296
|
+
* lock that, so the fees land on your debit rather than on what they receive.
|
|
297
|
+
*
|
|
298
|
+
* The two locking modes need `capabilities.exactOutput` on the corridors
|
|
299
|
+
* call; elsewhere they are refused with `EXACT_OUTPUT_UNSUPPORTED` rather
|
|
300
|
+
* than silently pricing the other side.
|
|
301
|
+
*/
|
|
302
|
+
amountLeg?: 'source' | 'destination' | 'source_net';
|
|
211
303
|
/**
|
|
212
304
|
* What you told the payer they would receive. The send is REFUSED if the
|
|
213
305
|
* binding quote drifts past `maxRateDrift` from it. Without this you send at
|
|
@@ -247,10 +339,104 @@ export interface PayoutArgs {
|
|
|
247
339
|
*/
|
|
248
340
|
allowDuplicate?: boolean;
|
|
249
341
|
reference?: string;
|
|
342
|
+
/** From `listPaymentReasons()`. Validated whenever sent; will be required for INR/GHS/CNY/BRL from a dated future release. */
|
|
250
343
|
purposeOfPayment?: string;
|
|
251
344
|
endUser?: EndUser;
|
|
252
345
|
}
|
|
253
346
|
|
|
347
|
+
/**
|
|
348
|
+
* The batch lifecycle. A batch tracks CREATION, not settlement: `completed`
|
|
349
|
+
* means every line either became a payout or was refused — read the `counts`.
|
|
350
|
+
*/
|
|
351
|
+
export type PayoutBatchStatus =
|
|
352
|
+
| 'received'
|
|
353
|
+
| 'validating'
|
|
354
|
+
| 'awaiting_confirmation'
|
|
355
|
+
| 'creating'
|
|
356
|
+
| 'completed'
|
|
357
|
+
| 'canceled'
|
|
358
|
+
| 'failed'
|
|
359
|
+
| (string & {});
|
|
360
|
+
|
|
361
|
+
export type PayoutBatchItemStatus =
|
|
362
|
+
| 'received'
|
|
363
|
+
| 'invalid'
|
|
364
|
+
| 'validated'
|
|
365
|
+
| 'creating'
|
|
366
|
+
| 'created'
|
|
367
|
+
| 'create_failed'
|
|
368
|
+
| 'canceled'
|
|
369
|
+
/**
|
|
370
|
+
* Outcome unknown (the process died mid-create). NEVER auto-retried —
|
|
371
|
+
* contact support with the batchId rather than resubmitting the line.
|
|
372
|
+
*/
|
|
373
|
+
| 'requires_review'
|
|
374
|
+
| (string & {});
|
|
375
|
+
|
|
376
|
+
export interface PayoutBatch {
|
|
377
|
+
batchId: string;
|
|
378
|
+
/** Your own run id, echoed back. */
|
|
379
|
+
externalReferenceId: string | null;
|
|
380
|
+
status: PayoutBatchStatus;
|
|
381
|
+
autoCommit: boolean;
|
|
382
|
+
/** Lines by status. The values sum to the number of lines submitted. */
|
|
383
|
+
counts: Record<PayoutBatchItemStatus, number>;
|
|
384
|
+
/** Present only when `status` is `failed` — the run-level reason. */
|
|
385
|
+
error?: unknown;
|
|
386
|
+
/**
|
|
387
|
+
* Advisory. What the valid lines will draw from your balance, set when
|
|
388
|
+
* validation finishes; null while validation runs and when any line locks
|
|
389
|
+
* the destination side. Compare against `getBalance()` BEFORE confirming.
|
|
390
|
+
*/
|
|
391
|
+
estimatedSourceTotal: string | null;
|
|
392
|
+
createdAt: string;
|
|
393
|
+
updatedAt: string;
|
|
394
|
+
completedAt: string | null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export interface PayoutBatchItem {
|
|
398
|
+
/** Zero-based position in the `items` array you submitted. */
|
|
399
|
+
index: number;
|
|
400
|
+
status: PayoutBatchItemStatus;
|
|
401
|
+
/** The line you submitted, echoed back verbatim — join on content. */
|
|
402
|
+
instruction: unknown;
|
|
403
|
+
/** Present on `invalid` and `create_failed` lines. */
|
|
404
|
+
errors?: { code: string; message: string }[];
|
|
405
|
+
/** Present once `created` — the payout to track from here on. */
|
|
406
|
+
payoutId?: string;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface PayoutBatchArgs {
|
|
410
|
+
/**
|
|
411
|
+
* 1–1,000 payout instructions, each exactly a `POST /payouts` body (the
|
|
412
|
+
* WIRE shape — `expectDestination`, `maxDriftBps` — not the Node-only
|
|
413
|
+
* `PayoutArgs` conveniences, which are translated by `payout()` alone).
|
|
414
|
+
*/
|
|
415
|
+
items: unknown[];
|
|
416
|
+
/**
|
|
417
|
+
* Your own run id (a payroll file name, a cycle). Required, and unique per
|
|
418
|
+
* organization: a second batch with the same id is refused with
|
|
419
|
+
* `PAYOUT_BATCH_DUPLICATE_REFERENCE` naming the original, so a submit job
|
|
420
|
+
* that re-runs the same file under a fresh idempotency key cannot pay
|
|
421
|
+
* twice. A corrected resubmission is a new run and needs its own id.
|
|
422
|
+
* 1-128 characters: letters, digits, space, `. _ : -`.
|
|
423
|
+
*/
|
|
424
|
+
externalReferenceId: string;
|
|
425
|
+
/**
|
|
426
|
+
* True (the default): a run with zero validation errors proceeds straight
|
|
427
|
+
* to creation. False, or any errors found: the batch holds at
|
|
428
|
+
* `awaiting_confirmation` for `confirmPayoutBatch` / `cancelPayoutBatch`.
|
|
429
|
+
*/
|
|
430
|
+
autoCommit?: boolean;
|
|
431
|
+
/**
|
|
432
|
+
* Covers the RUN: resubmitting the same file under the same key returns the
|
|
433
|
+
* same batch, never a second payroll. Persist it before you send.
|
|
434
|
+
*/
|
|
435
|
+
idempotencyKey?: string;
|
|
436
|
+
/** Repeat a byte-identical run on purpose. Sets `X-Allow-Duplicate: true`. */
|
|
437
|
+
allowDuplicate?: boolean;
|
|
438
|
+
}
|
|
439
|
+
|
|
254
440
|
export declare class PayoutsClient {
|
|
255
441
|
constructor(opts?: PayoutsClientOptions);
|
|
256
442
|
|
|
@@ -259,8 +445,8 @@ export declare class PayoutsClient {
|
|
|
259
445
|
* suite — `expect(avvio.mode).toBe('test')` before a test that sends is the
|
|
260
446
|
* cheapest guard there is against a live key reaching a payroll fixture.
|
|
261
447
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
448
|
+
* The constructor rejects unrecognized and retired credential formats before
|
|
449
|
+
* deriving this value.
|
|
264
450
|
*/
|
|
265
451
|
readonly mode: 'test' | 'live';
|
|
266
452
|
|
|
@@ -272,7 +458,7 @@ export declare class PayoutsClient {
|
|
|
272
458
|
* caller following the instruction had no typed path to the field and had to
|
|
273
459
|
* reach for an unsound cast.
|
|
274
460
|
*/
|
|
275
|
-
corridors(): Promise<{
|
|
461
|
+
corridors(currency?: string): Promise<{
|
|
276
462
|
corridors: Corridor[];
|
|
277
463
|
capabilities: { exactOutput: boolean; indicativePricing: boolean };
|
|
278
464
|
}>;
|
|
@@ -299,9 +485,7 @@ export declare class PayoutsClient {
|
|
|
299
485
|
idempotencyKey?: string;
|
|
300
486
|
}): Promise<Beneficiary>;
|
|
301
487
|
|
|
302
|
-
listBeneficiaries(args?: {
|
|
303
|
-
endUserId?: string;
|
|
304
|
-
}): Promise<{
|
|
488
|
+
listBeneficiaries(args?: { endUserId?: string }): Promise<{
|
|
305
489
|
/** 'organization' or the end user the list was scoped to. Undeclared previously. */
|
|
306
490
|
scope: string;
|
|
307
491
|
recipients: Beneficiary[];
|
|
@@ -313,6 +497,75 @@ export declare class PayoutsClient {
|
|
|
313
497
|
nextCursor?: string | null;
|
|
314
498
|
}>;
|
|
315
499
|
|
|
500
|
+
/** One beneficiary, by the id we returned. `NOT_FOUND` if it is not yours. */
|
|
501
|
+
getBeneficiary(recipientId: string): Promise<Beneficiary>;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* One beneficiary, by YOUR id for them — the same `externalId` that makes
|
|
505
|
+
* creation idempotent. Unique per organization, so this is exactly one
|
|
506
|
+
* beneficiary or a `NOT_FOUND`, rather than paging your whole book.
|
|
507
|
+
*/
|
|
508
|
+
getBeneficiaryByExternalId(externalId: string): Promise<Beneficiary>;
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Correct a beneficiary's own details. Only the fields you pass are changed.
|
|
512
|
+
*
|
|
513
|
+
* **Bank details are NOT editable.** The rail validated that account, and
|
|
514
|
+
* swapping it underneath would send the next payout somewhere you never
|
|
515
|
+
* registered — a wrong account is a new payment method, and the old one is
|
|
516
|
+
* deleted with `deleteBeneficiaryMethod`.
|
|
517
|
+
*/
|
|
518
|
+
updateBeneficiary(
|
|
519
|
+
recipientId: string,
|
|
520
|
+
patch: {
|
|
521
|
+
type?: 'individual' | 'business';
|
|
522
|
+
name?: string;
|
|
523
|
+
email?: string;
|
|
524
|
+
phone?: string;
|
|
525
|
+
/** ISO-3166 alpha-2. */
|
|
526
|
+
country?: string;
|
|
527
|
+
},
|
|
528
|
+
opts?: { idempotencyKey?: string },
|
|
529
|
+
): Promise<Beneficiary>;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Remove a beneficiary and every payment method on it. Payouts already sent
|
|
533
|
+
* are history, not references — this cancels nothing in flight.
|
|
534
|
+
*/
|
|
535
|
+
deleteBeneficiary(
|
|
536
|
+
recipientId: string,
|
|
537
|
+
opts?: { idempotencyKey?: string },
|
|
538
|
+
): Promise<{ success: true }>;
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Remove one way of paying a beneficiary — an account that closed, or one
|
|
542
|
+
* entered wrong. Returns the beneficiary without it; the
|
|
543
|
+
* `destinationAccountId` that method carried stops being payable.
|
|
544
|
+
*/
|
|
545
|
+
deleteBeneficiaryMethod(
|
|
546
|
+
recipientId: string,
|
|
547
|
+
methodId: string,
|
|
548
|
+
opts?: { idempotencyKey?: string },
|
|
549
|
+
): Promise<Beneficiary>;
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* The full account details behind one payment method — lists carry only
|
|
553
|
+
* `last4`. Deliberately loose: the fields are the corridor's own, so they
|
|
554
|
+
* differ by rail exactly as `requirements()` does.
|
|
555
|
+
*/
|
|
556
|
+
getBeneficiaryMethodDetails(
|
|
557
|
+
recipientId: string,
|
|
558
|
+
methodId: string,
|
|
559
|
+
): Promise<Record<string, unknown>>;
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* The stated payment reasons this organization may use — the vocabulary
|
|
563
|
+
* `purposeOfPayment` on a payout, and `paymentReason` on a quote you accept,
|
|
564
|
+
* are validated against. Read it rather than guessing: a rejected value is a
|
|
565
|
+
* 400 on a payout you have already promised somebody.
|
|
566
|
+
*/
|
|
567
|
+
paymentReasons(): Promise<{ payment_reasons: Record<string, unknown>[] }>;
|
|
568
|
+
|
|
316
569
|
/**
|
|
317
570
|
* Every event since a watermark, paged for you. At-least-once — `since` is
|
|
318
571
|
* inclusive, so a resumed run re-reads the row at your watermark. Dedupe on
|
|
@@ -322,8 +575,17 @@ export declare class PayoutsClient {
|
|
|
322
575
|
since?: string;
|
|
323
576
|
limit?: number;
|
|
324
577
|
payoutId?: string;
|
|
578
|
+
/** Event types to include; a string (`'payout.completed,payout.returned'`) or an array. */
|
|
579
|
+
type?: PayoutEventType | PayoutEventType[] | string;
|
|
325
580
|
}): AsyncIterableIterator<PayoutEvent>;
|
|
326
581
|
|
|
582
|
+
/** Every audit event matching a filter, newest first, paged for you. */
|
|
583
|
+
eachAuditEvent(
|
|
584
|
+
args?: AuditEventFilters & {
|
|
585
|
+
limit?: number;
|
|
586
|
+
},
|
|
587
|
+
): AsyncIterableIterator<AuditEvent>;
|
|
588
|
+
|
|
327
589
|
/** Every payout matching a filter, paged for you. */
|
|
328
590
|
eachPayout(args?: {
|
|
329
591
|
limit?: number;
|
|
@@ -401,15 +663,55 @@ export declare class PayoutsClient {
|
|
|
401
663
|
limit?: number;
|
|
402
664
|
/** Everything that ever happened to one payout. */
|
|
403
665
|
payoutId?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Event types to include; a string (`'payout.completed,payout.returned'`)
|
|
668
|
+
* or an array. Unknown values are a 400, never an empty page.
|
|
669
|
+
*/
|
|
670
|
+
type?: PayoutEventType | PayoutEventType[] | string;
|
|
404
671
|
}): Promise<{
|
|
405
672
|
data: PayoutEvent[];
|
|
406
673
|
hasMore: boolean;
|
|
407
674
|
nextSince: string | null;
|
|
408
675
|
}>;
|
|
409
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Payouts and batch runs waiting on your approvers. `payout()` and
|
|
679
|
+
* `confirmPayoutBatch()` answer 202 with a `PendingApproval` when the
|
|
680
|
+
* organization's policy holds them; this is that queue. Approving and
|
|
681
|
+
* rejecting are dashboard actions — a key cannot, so there is no method.
|
|
682
|
+
*/
|
|
683
|
+
listApprovals(args?: {
|
|
684
|
+
status?: PayoutApprovalStatus;
|
|
685
|
+
/** 1–100, default 50. */
|
|
686
|
+
limit?: number;
|
|
687
|
+
}): Promise<{ data: PayoutApproval[] }>;
|
|
688
|
+
|
|
689
|
+
/** One approval, by the `approvalId` a 202 gave you. */
|
|
690
|
+
getApproval(approvalId: string): Promise<PayoutApproval>;
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* A PAGE of audit events, newest first — who did what, from where, with which
|
|
694
|
+
* credential. `id` is the cursor. A read-only key may read this.
|
|
695
|
+
*/
|
|
696
|
+
listAuditEvents(
|
|
697
|
+
args?: AuditEventFilters & {
|
|
698
|
+
/** 1–100, default 50. */
|
|
699
|
+
limit?: number;
|
|
700
|
+
/** A `nextCursor` we issued: rows strictly older than it. */
|
|
701
|
+
cursor?: string;
|
|
702
|
+
},
|
|
703
|
+
): Promise<{
|
|
704
|
+
data: AuditEvent[];
|
|
705
|
+
hasMore: boolean;
|
|
706
|
+
nextCursor: string | null;
|
|
707
|
+
}>;
|
|
708
|
+
|
|
410
709
|
/**
|
|
411
710
|
* How to fund a payout that came back with `requiresFunding: true`. Your funds
|
|
412
711
|
* stay in your wallet until you move them.
|
|
712
|
+
*
|
|
713
|
+
* A pure read — poll it freely. It no longer returns `signableOperations`:
|
|
714
|
+
* that are a dashboard action — an API key cannot sign them.
|
|
413
715
|
*/
|
|
414
716
|
getFunding(payoutId: string): Promise<{
|
|
415
717
|
payoutId: string;
|
|
@@ -417,19 +719,22 @@ export declare class PayoutsClient {
|
|
|
417
719
|
currency: string;
|
|
418
720
|
depositAddress: string;
|
|
419
721
|
network: string;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
722
|
+
/**
|
|
723
|
+
* Normally `null`. There is no countdown on the deposit address — the rail
|
|
724
|
+
* decides when an unfunded payout is over and reports that as the payout's
|
|
725
|
+
* own status, so read `getPayout()` before sending against instructions you
|
|
726
|
+
* fetched a while ago. Declared as a non-null `string` until now, so a
|
|
727
|
+
* TypeScript caller had no reason not to build a timer on it.
|
|
728
|
+
*/
|
|
729
|
+
expiresAt: string | null;
|
|
423
730
|
instructions: string;
|
|
424
731
|
}>;
|
|
425
732
|
|
|
426
|
-
/** Proof you sent the funds:
|
|
733
|
+
/** Proof you sent the funds: the transaction hash you broadcast. */
|
|
427
734
|
confirmFunding(
|
|
428
735
|
payoutId: string,
|
|
429
736
|
proof: {
|
|
430
|
-
transactionHash
|
|
431
|
-
signedOperations?: unknown[];
|
|
432
|
-
tamperProofSignature?: string;
|
|
737
|
+
transactionHash: string;
|
|
433
738
|
idempotencyKey?: string;
|
|
434
739
|
},
|
|
435
740
|
): Promise<Payout>;
|
|
@@ -466,40 +771,134 @@ export declare class PayoutsClient {
|
|
|
466
771
|
updatedSince?: string;
|
|
467
772
|
}): Promise<{ data: Payout[]; hasMore: boolean; nextCursor: string | null }>;
|
|
468
773
|
|
|
774
|
+
/**
|
|
775
|
+
* Submit up to 1,000 payouts as one run. `202` means RECEIVED, not paid:
|
|
776
|
+
* every line is validated first (nothing priced, nothing debited), then the
|
|
777
|
+
* valid lines become ordinary payouts, each with its own `payoutId`.
|
|
778
|
+
*/
|
|
779
|
+
createPayoutBatch(args: PayoutBatchArgs): Promise<PayoutBatch>;
|
|
780
|
+
|
|
781
|
+
/** A PAGE of batches, newest first — not an array. */
|
|
782
|
+
listPayoutBatches(args?: {
|
|
783
|
+
status?: PayoutBatchStatus;
|
|
784
|
+
/** Exact match on your own run id. */
|
|
785
|
+
externalReferenceId?: string;
|
|
786
|
+
/** 1–100, default 50. */
|
|
787
|
+
limit?: number;
|
|
788
|
+
/** A `nextCursor` we issued. Anything else is a 400, never an empty page. */
|
|
789
|
+
cursor?: string;
|
|
790
|
+
}): Promise<{
|
|
791
|
+
data: PayoutBatch[];
|
|
792
|
+
hasMore: boolean;
|
|
793
|
+
nextCursor: string | null;
|
|
794
|
+
}>;
|
|
795
|
+
|
|
796
|
+
/** One run, with its counts. Authoritative for the batch, not the payouts. */
|
|
797
|
+
getPayoutBatch(batchId: string): Promise<PayoutBatch>;
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* The lines of a run, instruction echoed back verbatim. `status: 'invalid'`
|
|
801
|
+
* is the review screen after `awaiting_confirmation`; `'created'` joins the
|
|
802
|
+
* run to the payout ledger. The CSV export (`?format=csv`) is a plain file
|
|
803
|
+
* download — this method returns the JSON page.
|
|
804
|
+
*/
|
|
805
|
+
listPayoutBatchItems(
|
|
806
|
+
batchId: string,
|
|
807
|
+
args?: {
|
|
808
|
+
status?: PayoutBatchItemStatus;
|
|
809
|
+
/** 1–1,000, default 100. */
|
|
810
|
+
limit?: number;
|
|
811
|
+
/** The `nextCursor` from your previous page — the last line index. */
|
|
812
|
+
cursor?: string;
|
|
813
|
+
},
|
|
814
|
+
): Promise<{
|
|
815
|
+
data: PayoutBatchItem[];
|
|
816
|
+
hasMore: boolean;
|
|
817
|
+
nextCursor: string | null;
|
|
818
|
+
}>;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Proceed with the valid lines of a held run. Only legal from
|
|
822
|
+
* `awaiting_confirmation` — anything else is `PAYOUT_BATCH_NOT_CONFIRMABLE`.
|
|
823
|
+
*/
|
|
824
|
+
confirmPayoutBatch(
|
|
825
|
+
batchId: string,
|
|
826
|
+
opts?: { idempotencyKey?: string },
|
|
827
|
+
): Promise<PayoutBatch>;
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Stop a run before any payout exists. Once creation begins the run is
|
|
831
|
+
* committed and this is `PAYOUT_BATCH_NOT_CANCELABLE` — cancel individual
|
|
832
|
+
* payouts via `cancelPayout` instead.
|
|
833
|
+
*/
|
|
834
|
+
cancelPayoutBatch(
|
|
835
|
+
batchId: string,
|
|
836
|
+
opts?: { idempotencyKey?: string },
|
|
837
|
+
): Promise<PayoutBatch>;
|
|
838
|
+
|
|
469
839
|
fundingAccounts(): Promise<unknown>;
|
|
470
840
|
|
|
471
|
-
/**
|
|
472
|
-
|
|
841
|
+
/**
|
|
842
|
+
* What your organization is bound by, read live. Read it first: caps,
|
|
843
|
+
* approval threshold, features, rate limits, idempotency windows and the
|
|
844
|
+
* currencies that need a `purposeOfPayment`.
|
|
845
|
+
*/
|
|
846
|
+
getPolicy(): Promise<Policy>;
|
|
473
847
|
|
|
474
848
|
/**
|
|
475
|
-
*
|
|
476
|
-
*
|
|
849
|
+
* Everything a payout can draw on (cached up to 60 s): what the payment
|
|
850
|
+
* network holds for you (`provider`) plus the USD stablecoins in your own
|
|
851
|
+
* wallet (`wallet`, per chain, at face value), summed per currency into
|
|
852
|
+
* `balances` with USD as the `amount` headline. Size payouts against that,
|
|
853
|
+
* knowing wallet figures are face value before the network and conversion
|
|
854
|
+
* cost of moving them onto the settling rail — a payout for exactly
|
|
855
|
+
* `amount` can fail to fund when the money must be gathered from several
|
|
856
|
+
* chains first.
|
|
857
|
+
* `ledger` is our own append-only record of the network-held part, with
|
|
858
|
+
* what holds currently reserve. Never summed with the others; a difference
|
|
859
|
+
* from `provider` is what `listBalanceTransactions()` explains.
|
|
860
|
+
* `unavailable` names any source that failed to read: when non-empty the
|
|
861
|
+
* figures are a floor, not the balance — retry before concluding you
|
|
862
|
+
* cannot fund a payout.
|
|
477
863
|
*/
|
|
478
|
-
|
|
864
|
+
balance(): Promise<{
|
|
479
865
|
currency: string;
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
type: 'funding' | 'payout' | 'reversal';
|
|
489
|
-
/**
|
|
490
|
-
* What this ENTRY records, frozen at the moment it was written — not the
|
|
491
|
-
* payout's current status, which would make a historical row mutate.
|
|
492
|
-
* `DEBITED` money left, `RETURNED` money came back, `COMPLETED` funding
|
|
493
|
-
* landed. For a payout's live fate, read `getPayout()`.
|
|
494
|
-
*/
|
|
495
|
-
status: 'DEBITED' | 'RETURNED' | 'COMPLETED' | (string & {});
|
|
496
|
-
amount: string;
|
|
497
|
-
balanceAfter: string;
|
|
498
|
-
reference?: string;
|
|
499
|
-
at: string;
|
|
500
|
-
}[];
|
|
866
|
+
amount: string;
|
|
867
|
+
balances: Money[];
|
|
868
|
+
provider: Money[];
|
|
869
|
+
/** Always empty in sandbox. */
|
|
870
|
+
wallet: WalletBalance[];
|
|
871
|
+
/** Sources that failed to read; non-empty results are not cached, so retry. */
|
|
872
|
+
unavailable: Array<'network' | 'wallet'>;
|
|
873
|
+
ledger: LedgerBalance[];
|
|
501
874
|
}>;
|
|
502
875
|
|
|
876
|
+
/**
|
|
877
|
+
* A PAGE of balance transactions, newest first — not an array. Every change
|
|
878
|
+
* to what you can spend, each with `balanceAfter`; `id` is the cursor and
|
|
879
|
+
* the dedupe key. Served on every environment; an empty page means no rows
|
|
880
|
+
* yet, not an error.
|
|
881
|
+
*/
|
|
882
|
+
listBalanceTransactions(
|
|
883
|
+
args?: BalanceTransactionFilters & {
|
|
884
|
+
/** 1–100, default 100. */
|
|
885
|
+
limit?: number;
|
|
886
|
+
/** A `nextCursor` we issued: rows strictly older than it. */
|
|
887
|
+
cursor?: string;
|
|
888
|
+
},
|
|
889
|
+
): Promise<{
|
|
890
|
+
data: BalanceTransaction[];
|
|
891
|
+
hasMore: boolean;
|
|
892
|
+
nextCursor: string | null;
|
|
893
|
+
}>;
|
|
894
|
+
|
|
895
|
+
/** Every balance transaction matching a filter, newest first, paged for you. */
|
|
896
|
+
eachBalanceTransaction(
|
|
897
|
+
args?: BalanceTransactionFilters & {
|
|
898
|
+
limit?: number;
|
|
899
|
+
},
|
|
900
|
+
): AsyncIterableIterator<BalanceTransaction>;
|
|
901
|
+
|
|
503
902
|
/** Credit a sandbox balance. Test keys only. */
|
|
504
903
|
fund(amount?: string, idempotencyKey?: string): Promise<{ balance: string }>;
|
|
505
904
|
|
|
@@ -528,13 +927,10 @@ export declare class PayoutsClient {
|
|
|
528
927
|
|
|
529
928
|
/**
|
|
530
929
|
* Register a sandbox webhook endpoint. The `secret` is returned ONCE and is
|
|
531
|
-
* not retrievable afterwards. Test keys only.
|
|
930
|
+
* not retrievable afterwards. Test keys only. Sends no `Idempotency-Key` and
|
|
931
|
+
* is never retried: a stored replay would keep the secret.
|
|
532
932
|
*/
|
|
533
|
-
createWebhookEndpoint(args: {
|
|
534
|
-
url: string;
|
|
535
|
-
events?: string[];
|
|
536
|
-
idempotencyKey?: string;
|
|
537
|
-
}): Promise<{
|
|
933
|
+
createWebhookEndpoint(args: { url: string; events?: string[] }): Promise<{
|
|
538
934
|
id: string;
|
|
539
935
|
url: string;
|
|
540
936
|
events: string[];
|
|
@@ -542,7 +938,53 @@ export declare class PayoutsClient {
|
|
|
542
938
|
warning: string;
|
|
543
939
|
}>;
|
|
544
940
|
|
|
545
|
-
/**
|
|
941
|
+
/**
|
|
942
|
+
* The webhook endpoints registered for your organization.
|
|
943
|
+
*
|
|
944
|
+
* Read-only by design, and there is no create/pause/delete counterpart here:
|
|
945
|
+
* a key that could repoint its own webhook URL could redirect every payout
|
|
946
|
+
* notification. The signing secret is never returned — it is shown once, at
|
|
947
|
+
* creation.
|
|
948
|
+
*/
|
|
949
|
+
webhookEndpoints(): Promise<
|
|
950
|
+
{
|
|
951
|
+
id: string;
|
|
952
|
+
url: string;
|
|
953
|
+
events: string[];
|
|
954
|
+
/** Non-null while the endpoint is paused or auto-disabled. */
|
|
955
|
+
disabledAt: string | null;
|
|
956
|
+
disabledReason: 'paused_by_owner' | 'auto_disabled_after_failures' | null;
|
|
957
|
+
/** Retry ladders exhausted since the last accepted delivery. */
|
|
958
|
+
consecutiveFailures: number;
|
|
959
|
+
lastSuccessAt: string | null;
|
|
960
|
+
lastFailureAt: string | null;
|
|
961
|
+
createdAt: string;
|
|
962
|
+
}[]
|
|
963
|
+
>;
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* The 50 most recent delivery attempts for one endpoint, newest first. No
|
|
967
|
+
* payloads — replay from the dashboard if you need the body, which re-fires
|
|
968
|
+
* under the same `eventId` so your dedupe still holds.
|
|
969
|
+
*/
|
|
970
|
+
webhookEndpointDeliveries(endpointId: string): Promise<
|
|
971
|
+
{
|
|
972
|
+
id: string;
|
|
973
|
+
/** The event id: the `svix-id` we sent and the feed row's `id`. Dedupe on this. */
|
|
974
|
+
eventId: string;
|
|
975
|
+
eventType: string;
|
|
976
|
+
attempts: number;
|
|
977
|
+
/** Null until an attempt is accepted. */
|
|
978
|
+
deliveredAt: string | null;
|
|
979
|
+
/** When we will try again. Retries back off over roughly 70 hours. */
|
|
980
|
+
nextAttemptAt: string | null;
|
|
981
|
+
/** Your server's response on the most recent failure. */
|
|
982
|
+
lastError: string | null;
|
|
983
|
+
createdAt: string;
|
|
984
|
+
}[]
|
|
985
|
+
>;
|
|
986
|
+
|
|
987
|
+
/** What we sent, what came back, and what we retried. Sandbox endpoints. */
|
|
546
988
|
webhookDeliveries(endpointId: string): Promise<unknown>;
|
|
547
989
|
}
|
|
548
990
|
|
|
@@ -580,8 +1022,175 @@ export declare function stableKey(...parts: (string | number)[]): string;
|
|
|
580
1022
|
* so they cannot be confused, and `scripts/sdk-contract.ts` asserts this one
|
|
581
1023
|
* against a real delivered event.
|
|
582
1024
|
*/
|
|
1025
|
+
/** What your organization is bound by, from `getPolicy()`. `null` on a cap or threshold means not set. */
|
|
1026
|
+
export interface Policy {
|
|
1027
|
+
/** The id you addressed; a test key sends the live organization id and gets it back. */
|
|
1028
|
+
organizationId: string;
|
|
1029
|
+
/** `test`: nothing reaches a payment network. */
|
|
1030
|
+
mode: 'test' | 'live';
|
|
1031
|
+
/** Effective feature names, sorted. `mass_payouts` enables batches, `developer` enables webhook endpoints. */
|
|
1032
|
+
features: string[];
|
|
1033
|
+
/** USD caps; over one is `422 PAYOUT_LIMIT_EXCEEDED`. Two-decimal strings. */
|
|
1034
|
+
limits: {
|
|
1035
|
+
maxSinglePayoutUsd: string | null;
|
|
1036
|
+
maxDailyPayoutUsd: string | null;
|
|
1037
|
+
/** Counted against `endUser.id`; when set, a payout without an `endUser` is refused. */
|
|
1038
|
+
maxDailyPerEndUserUsd: string | null;
|
|
1039
|
+
};
|
|
1040
|
+
/** When `thresholdUsd` is set, a send above it answers 202 and needs `requiredApprovals` humans. */
|
|
1041
|
+
approvals: {
|
|
1042
|
+
thresholdUsd: string | null;
|
|
1043
|
+
requiredApprovals: number | null;
|
|
1044
|
+
appliesTo: ('payouts' | 'batches' | 'payout_links')[];
|
|
1045
|
+
};
|
|
1046
|
+
purposeOfPayment: {
|
|
1047
|
+
/** Destination currencies that require `purposeOfPayment` on a payout. */
|
|
1048
|
+
requiredForCurrencies: string[];
|
|
1049
|
+
};
|
|
1050
|
+
/**
|
|
1051
|
+
* What your routing can state about its fees BEFORE a quote exists. `null`
|
|
1052
|
+
* on a number means "not published before a quote", never zero. The binding
|
|
1053
|
+
* figure is `fee` on the quote and the payout.
|
|
1054
|
+
*/
|
|
1055
|
+
fees: {
|
|
1056
|
+
payout: {
|
|
1057
|
+
/** Basis points of the send for corridors not in `byCurrency`. */
|
|
1058
|
+
bps: number | null;
|
|
1059
|
+
/** Fixed component in USD, two decimals. */
|
|
1060
|
+
fixedUsd: string | null;
|
|
1061
|
+
/** Corridors priced differently from the default, by destination currency. */
|
|
1062
|
+
byCurrency: Record<string, { bps: number; fixedUsd: string | null }>;
|
|
1063
|
+
/** Prose; do not branch on it. */
|
|
1064
|
+
note: string;
|
|
1065
|
+
};
|
|
1066
|
+
};
|
|
1067
|
+
/** Requests per minute per credential, by bucket. */
|
|
1068
|
+
rateLimits: {
|
|
1069
|
+
default: number;
|
|
1070
|
+
payouts: number;
|
|
1071
|
+
batches: number;
|
|
1072
|
+
reads: number;
|
|
1073
|
+
};
|
|
1074
|
+
idempotency: {
|
|
1075
|
+
/** An API key must send `Idempotency-Key` on every money route. */
|
|
1076
|
+
required: boolean;
|
|
1077
|
+
replayWindowDays: number;
|
|
1078
|
+
nearDuplicateWindowMinutes: number;
|
|
1079
|
+
};
|
|
1080
|
+
/** Relative paths with your organization id filled in. */
|
|
1081
|
+
links: { corridors: string; events: string; balanceTransactions: string };
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
export interface LedgerBalance {
|
|
1085
|
+
currency: string;
|
|
1086
|
+
/** What a payout can draw on right now. */
|
|
1087
|
+
available: string;
|
|
1088
|
+
/** Reserved by holds not yet converted to payouts or released. */
|
|
1089
|
+
held: string;
|
|
1090
|
+
/** `available` + `held`. */
|
|
1091
|
+
total: string;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
/** One USD stablecoin position in your own wallet, on one chain. */
|
|
1095
|
+
export interface WalletBalance {
|
|
1096
|
+
currency: 'USDC' | 'USDT';
|
|
1097
|
+
/** Chain name: Ethereum, Base, Arbitrum, Optimism, Solana. */
|
|
1098
|
+
network: string;
|
|
1099
|
+
/** Token units, up to six decimals. Counted into `balances` at face value. */
|
|
1100
|
+
amount: string;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
export type BalanceTransactionType =
|
|
1104
|
+
| 'funding'
|
|
1105
|
+
| 'payout'
|
|
1106
|
+
| 'payout_return'
|
|
1107
|
+
| 'hold'
|
|
1108
|
+
| 'hold_release'
|
|
1109
|
+
| 'adjustment';
|
|
1110
|
+
|
|
1111
|
+
export interface BalanceTransactionFilters {
|
|
1112
|
+
/** One type, several, or a comma-separated string. Unknown values are a 400. */
|
|
1113
|
+
type?: BalanceTransactionType | BalanceTransactionType[] | string;
|
|
1114
|
+
/** Everything that moved for one payout. */
|
|
1115
|
+
orderId?: string;
|
|
1116
|
+
currency?: string;
|
|
1117
|
+
/** Inclusive, ISO-8601 with a timezone. */
|
|
1118
|
+
createdAfter?: string;
|
|
1119
|
+
/** Inclusive, ISO-8601 with a timezone. */
|
|
1120
|
+
createdBefore?: string;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* One append-only change to what you can spend. `amount` is signed and always
|
|
1125
|
+
* means "how this row changed `available`".
|
|
1126
|
+
*/
|
|
1127
|
+
export interface BalanceTransaction {
|
|
1128
|
+
/** Monotonic, and the cursor. A string: it can exceed 2^53. */
|
|
1129
|
+
id: string;
|
|
1130
|
+
type: BalanceTransactionType;
|
|
1131
|
+
amount: string;
|
|
1132
|
+
/** Fee portion of `amount`. Null means not known, which is not zero. */
|
|
1133
|
+
fee: string | null;
|
|
1134
|
+
/** The amount less the fee, carrying the amount's sign. Absent when `fee` is null. */
|
|
1135
|
+
net?: string;
|
|
1136
|
+
currency: string;
|
|
1137
|
+
/** `available` after this row. */
|
|
1138
|
+
balanceAfter: string;
|
|
1139
|
+
orderId: string | null;
|
|
1140
|
+
/**
|
|
1141
|
+
* The quote snapshot that sized this row. A `hold` has no `orderId` (it is
|
|
1142
|
+
* placed before the network answers); its `hold_release` and `payout` rows
|
|
1143
|
+
* share this `snapshotId`, which is the join. Null on `funding`/`adjustment`.
|
|
1144
|
+
*/
|
|
1145
|
+
snapshotId: string | null;
|
|
1146
|
+
batchId: string | null;
|
|
1147
|
+
reference: string | null;
|
|
1148
|
+
endUserId: string | null;
|
|
1149
|
+
reason: string | null;
|
|
1150
|
+
description: string | null;
|
|
1151
|
+
createdAt: string;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* Every event the feed and the webhooks carry. `payout.returned` is its OWN
|
|
1156
|
+
* type, not a flavour of `payout.failed` — it is the one event that reverses
|
|
1157
|
+
* something you already booked. New types are added without a major version;
|
|
1158
|
+
* ignore ones you do not handle.
|
|
1159
|
+
*/
|
|
1160
|
+
export type PayoutEventType =
|
|
1161
|
+
| 'payout.pending'
|
|
1162
|
+
| 'payout.processing'
|
|
1163
|
+
| 'payout.completed'
|
|
1164
|
+
| 'payout.failed'
|
|
1165
|
+
| 'payout.returned'
|
|
1166
|
+
| 'payout.canceled'
|
|
1167
|
+
| 'payout_batch.awaiting_confirmation'
|
|
1168
|
+
| 'payout_batch.completed'
|
|
1169
|
+
| 'payout_batch.canceled'
|
|
1170
|
+
| 'payout_batch.failed'
|
|
1171
|
+
| 'payout_approval.pending'
|
|
1172
|
+
| 'payout_approval.approved'
|
|
1173
|
+
| 'payout_approval.rejected'
|
|
1174
|
+
| 'payout_approval.expired'
|
|
1175
|
+
| 'payout_approval.executed'
|
|
1176
|
+
| 'payout_approval.execution_failed'
|
|
1177
|
+
| 'webhook_endpoint.disabled'
|
|
1178
|
+
| (string & {});
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* The `data` of an event, by family. Discriminate on the row's `type`:
|
|
1182
|
+
* `payout.*` → `WebhookPayout`, `payout_batch.*` → `PayoutBatch`,
|
|
1183
|
+
* `payout_approval.*` → `PayoutApprovalEvent`, `webhook_endpoint.*` →
|
|
1184
|
+
* `WebhookEndpointDisabled`.
|
|
1185
|
+
*/
|
|
1186
|
+
export type EventData =
|
|
1187
|
+
| WebhookPayout
|
|
1188
|
+
| PayoutBatch
|
|
1189
|
+
| PayoutApprovalEvent
|
|
1190
|
+
| WebhookEndpointDisabled;
|
|
1191
|
+
|
|
583
1192
|
export interface PayoutEvent {
|
|
584
|
-
/** Stable. Dedupe on this — the feed is at-least-once. */
|
|
1193
|
+
/** Stable. Dedupe on this — the feed is at-least-once. Equals the webhook `svix-id`. */
|
|
585
1194
|
id: string;
|
|
586
1195
|
/**
|
|
587
1196
|
* The cursor, as a decimal STRING. A 64-bit sequence past 2^53 is not
|
|
@@ -589,23 +1198,121 @@ export interface PayoutEvent {
|
|
|
589
1198
|
* unrecoverable.
|
|
590
1199
|
*/
|
|
591
1200
|
sequence: string;
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
| 'payout.processing'
|
|
600
|
-
| 'payout.completed'
|
|
601
|
-
| 'payout.failed'
|
|
602
|
-
| 'payout.returned'
|
|
603
|
-
| (string & {});
|
|
604
|
-
payoutId: string;
|
|
605
|
-
status: PayoutStatus;
|
|
1201
|
+
type: PayoutEventType;
|
|
1202
|
+
/** Null on batch, approval and endpoint events. */
|
|
1203
|
+
payoutId: string | null;
|
|
1204
|
+
/** Set on `payout_batch.*` rows and on a batch approval. */
|
|
1205
|
+
batchId: string | null;
|
|
1206
|
+
/** The resource's status after this transition; a `PayoutStatus` on `payout.*` rows. */
|
|
1207
|
+
status: PayoutStatus | string;
|
|
606
1208
|
failureCode?: PayoutFailureCode;
|
|
607
1209
|
fundsReturned?: boolean;
|
|
608
1210
|
createdAt: string;
|
|
1211
|
+
/** The `data` shape version. Same value as the `Avvio-Webhook-Version` header. */
|
|
1212
|
+
apiVersion: number;
|
|
1213
|
+
/** The webhook body for this event, verbatim. */
|
|
1214
|
+
data: EventData;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
export type PayoutApprovalStatus =
|
|
1218
|
+
| 'pending'
|
|
1219
|
+
| 'approved'
|
|
1220
|
+
| 'rejected'
|
|
1221
|
+
| 'expired'
|
|
1222
|
+
| 'executing'
|
|
1223
|
+
| 'executed'
|
|
1224
|
+
| 'execution_failed'
|
|
1225
|
+
| 'execution_unknown';
|
|
1226
|
+
|
|
1227
|
+
/** One request for M-of-N human approval. A PRE-payout resource, not a payout status. */
|
|
1228
|
+
export interface PayoutApproval {
|
|
1229
|
+
id: string;
|
|
1230
|
+
kind: 'payout' | 'payout_batch';
|
|
1231
|
+
status: PayoutApprovalStatus;
|
|
1232
|
+
/** M, snapshotted when the request was created. */
|
|
1233
|
+
requiredApprovals: number;
|
|
1234
|
+
/** Approve votes so far. */
|
|
1235
|
+
approvals: number;
|
|
1236
|
+
/** Present once a `payout` approval is `executed` — the payout it became. */
|
|
1237
|
+
payoutId?: string;
|
|
1238
|
+
/** Present on `payout_batch` approvals. */
|
|
1239
|
+
batchId?: string;
|
|
1240
|
+
amount: string | null;
|
|
1241
|
+
currency: string | null;
|
|
1242
|
+
destinationAccountId?: string;
|
|
1243
|
+
/** Present on `execution_failed`. */
|
|
1244
|
+
error?: string;
|
|
1245
|
+
createdAt: string;
|
|
1246
|
+
/** A `pending` request expires 24 hours after creation. */
|
|
1247
|
+
expiresAt: string | null;
|
|
1248
|
+
updatedAt: string;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/** The `data` of a `payout_approval.*` event. */
|
|
1252
|
+
export interface PayoutApprovalEvent {
|
|
1253
|
+
approval: PayoutApproval;
|
|
1254
|
+
/** On `payout_approval.executed` — the payout the approval became. */
|
|
1255
|
+
payoutId?: string;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/** The `data` of `webhook_endpoint.disabled`, delivered to your OTHER endpoints. */
|
|
1259
|
+
export interface WebhookEndpointDisabled {
|
|
1260
|
+
endpointId: string;
|
|
1261
|
+
url: string;
|
|
1262
|
+
reason: 'auto_disabled_after_failures';
|
|
1263
|
+
consecutiveFailures: number;
|
|
1264
|
+
lastSuccessAt: string | null;
|
|
1265
|
+
disabledAt: string;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* The 202 body from `payout()` and `confirmPayoutBatch()` when the
|
|
1270
|
+
* organization's policy holds the instruction for its approvers. Nothing was
|
|
1271
|
+
* priced or sent.
|
|
1272
|
+
*/
|
|
1273
|
+
export interface PendingApproval {
|
|
1274
|
+
status: 'pending_approval';
|
|
1275
|
+
approvalId: string;
|
|
1276
|
+
/** Same value as `approvalId`; kept for the dashboard client. */
|
|
1277
|
+
approvalRequestId?: string;
|
|
1278
|
+
requiredApprovals: number;
|
|
1279
|
+
expiresAt: string;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
export interface AuditEventFilters {
|
|
1283
|
+
/** One action, e.g. `payout.create`. */
|
|
1284
|
+
action?: string;
|
|
1285
|
+
/** Everything done to one payout, batch, approval, beneficiary, key or endpoint. */
|
|
1286
|
+
resourceId?: string;
|
|
1287
|
+
/** A key prefix. An unknown prefix is an empty page, not a 404. */
|
|
1288
|
+
apiKey?: string;
|
|
1289
|
+
actorUserId?: string;
|
|
1290
|
+
/** Inclusive, ISO-8601 with a timezone. */
|
|
1291
|
+
createdAfter?: string;
|
|
1292
|
+
/** Inclusive, ISO-8601 with a timezone. */
|
|
1293
|
+
createdBefore?: string;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/** One audited mutation. Append-only; never updated. */
|
|
1297
|
+
export interface AuditEvent {
|
|
1298
|
+
/** Monotonic, and the cursor. A decimal string. */
|
|
1299
|
+
id: string;
|
|
1300
|
+
/** e.g. `payout.create`, `payout_batch.confirm`, `recipient.delete`, `api_key.rotate`. New actions are added without a version. */
|
|
1301
|
+
action: string;
|
|
1302
|
+
resourceType: string;
|
|
1303
|
+
/** Null when the request was refused before a resource existed. */
|
|
1304
|
+
resourceId: string | null;
|
|
1305
|
+
/** The key's prefix as you named it. Null for a dashboard action. */
|
|
1306
|
+
apiKeyPrefix: string | null;
|
|
1307
|
+
/** The dashboard user. Null for an API-key action. */
|
|
1308
|
+
actorUserId: string | null;
|
|
1309
|
+
ip: string | null;
|
|
1310
|
+
/** The `x-request-id` of that request; joins to `BalanceTransaction.requestId`. */
|
|
1311
|
+
requestId: string | null;
|
|
1312
|
+
outcome: 'ok' | 'error';
|
|
1313
|
+
/** The error `type` when `outcome` is `error`. */
|
|
1314
|
+
errorType: string | null;
|
|
1315
|
+
createdAt: string;
|
|
609
1316
|
}
|
|
610
1317
|
|
|
611
1318
|
export interface WebhookPayout {
|
|
@@ -628,25 +1335,29 @@ export interface WebhookPayout {
|
|
|
628
1335
|
completedAt: string | null;
|
|
629
1336
|
}
|
|
630
1337
|
|
|
1338
|
+
/**
|
|
1339
|
+
* A signed delivery. The envelope is the feed row: the same `id`, `sequence`,
|
|
1340
|
+
* `type`, `createdAt`, `apiVersion` and `data` come back from `listEvents()`,
|
|
1341
|
+
* so a delivery is the trigger to read the feed from the right place.
|
|
1342
|
+
*/
|
|
631
1343
|
export interface WebhookEvent {
|
|
632
|
-
/**
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
*
|
|
638
|
-
* and
|
|
639
|
-
*
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
data: WebhookPayout;
|
|
1344
|
+
/** The event id. Equals the `svix-id` header and the feed row's `id`. Dedupe on it. */
|
|
1345
|
+
id: string;
|
|
1346
|
+
/** The feed cursor for this event, as a decimal string. */
|
|
1347
|
+
sequence: string;
|
|
1348
|
+
/**
|
|
1349
|
+
* Every type actually delivered. An earlier version omitted `payout.returned`,
|
|
1350
|
+
* `payout.canceled` and `payout.processing`, all three of which arrive; the
|
|
1351
|
+
* `(string & {})` escape made the omission invisible. Return 2xx for types
|
|
1352
|
+
* you do not handle.
|
|
1353
|
+
*/
|
|
1354
|
+
type: PayoutEventType;
|
|
1355
|
+
createdAt: string;
|
|
1356
|
+
/** Which body shape `data` is. Also the `Avvio-Webhook-Version` header. */
|
|
1357
|
+
apiVersion: number;
|
|
1358
|
+
/** False from a sandbox organization's endpoint. */
|
|
1359
|
+
livemode: boolean;
|
|
1360
|
+
data: EventData;
|
|
650
1361
|
}
|
|
651
1362
|
|
|
652
1363
|
/**
|
|
@@ -678,3 +1389,11 @@ export declare function createWebhookHandler(opts: {
|
|
|
678
1389
|
/** Reject timestamps outside this window. Defaults to 300. */
|
|
679
1390
|
toleranceSeconds?: number;
|
|
680
1391
|
}): (req: any, res: any) => Promise<void>;
|
|
1392
|
+
|
|
1393
|
+
// PARKED request-signing helper. The runtime implementation remains available
|
|
1394
|
+
// for a coordinated restoration, but it is intentionally absent from the
|
|
1395
|
+
// current bearer-key type surface.
|
|
1396
|
+
// export function generateSigningKeyPair(): {
|
|
1397
|
+
// publicKeyPem: string;
|
|
1398
|
+
// privateKeyPem: string;
|
|
1399
|
+
// };
|