@codespar/sdk 0.12.0 → 0.14.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/dist/__tests__/api-client.test.js +15 -2
- package/dist/__tests__/api-client.test.js.map +1 -1
- package/dist/generated/openapi.d.ts +1833 -175
- package/dist/generated/openapi.d.ts.map +1 -1
- package/dist/generated/operations.d.ts +60 -0
- package/dist/generated/operations.d.ts.map +1 -1
- package/dist/generated/operations.js +12 -0
- package/dist/generated/operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -427,6 +427,114 @@ export interface paths {
|
|
|
427
427
|
patch?: never;
|
|
428
428
|
trace?: never;
|
|
429
429
|
};
|
|
430
|
+
"/meta-tools.json": {
|
|
431
|
+
parameters: {
|
|
432
|
+
query?: never;
|
|
433
|
+
header?: never;
|
|
434
|
+
path?: never;
|
|
435
|
+
cookie?: never;
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* The tool catalogue the execute operation dispatches
|
|
439
|
+
* @description THE LEGAL VALUES OF `tool`, and what each one accepts. `POST /v1/sessions/{id}/execute` names a tool by string; this is the document that gives those strings meaning, one entry per tool with a JSON Schema for its input.
|
|
440
|
+
*
|
|
441
|
+
* Served with no credential, `Access-Control-Allow-Origin: *`, cached for five minutes. It carries no tenant data: names, descriptions and schemas, identical for every caller. `/meta-tools.json` and `/v1/meta-tools.json` return the same bytes.
|
|
442
|
+
*
|
|
443
|
+
* READ IT BEFORE CONCLUDING A CAPABILITY IS MISSING. The tool descriptions and their schemas carry contracts this OpenAPI document does not repeat — which `action` values exist, which arguments are mandatory for which combination, and what a create answers when the instrument is not ready yet. A capability can be fully implemented and still read as absent to someone holding only this document.
|
|
444
|
+
*/
|
|
445
|
+
get: {
|
|
446
|
+
parameters: {
|
|
447
|
+
query?: never;
|
|
448
|
+
header?: never;
|
|
449
|
+
path?: never;
|
|
450
|
+
cookie?: never;
|
|
451
|
+
};
|
|
452
|
+
requestBody?: never;
|
|
453
|
+
responses: {
|
|
454
|
+
/** @description OK */
|
|
455
|
+
200: {
|
|
456
|
+
headers: {
|
|
457
|
+
[name: string]: unknown;
|
|
458
|
+
};
|
|
459
|
+
content: {
|
|
460
|
+
"application/json": {
|
|
461
|
+
/**
|
|
462
|
+
* @description Names the source so the reader does not have to take the document's word for it: this is the same output the MCP transport answers `tools/list` with, not a second reading of the catalogue that could drift from it.
|
|
463
|
+
* @enum {string}
|
|
464
|
+
*/
|
|
465
|
+
generated_from: "tools/list";
|
|
466
|
+
tools: {
|
|
467
|
+
/** @description The value to send as `tool` on the execute operation. */
|
|
468
|
+
name: string;
|
|
469
|
+
description: string;
|
|
470
|
+
/** @description JSON Schema for that tool's input, which is what goes in `params`. */
|
|
471
|
+
inputSchema: Record<string, never>;
|
|
472
|
+
}[];
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
put?: never;
|
|
479
|
+
post?: never;
|
|
480
|
+
delete?: never;
|
|
481
|
+
options?: never;
|
|
482
|
+
head?: never;
|
|
483
|
+
patch?: never;
|
|
484
|
+
trace?: never;
|
|
485
|
+
};
|
|
486
|
+
"/v1/meta-tools.json": {
|
|
487
|
+
parameters: {
|
|
488
|
+
query?: never;
|
|
489
|
+
header?: never;
|
|
490
|
+
path?: never;
|
|
491
|
+
cookie?: never;
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* The tool catalogue, under the /v1 mount
|
|
495
|
+
* @description Identical to `/meta-tools.json`, for a caller already pointed at the versioned prefix. Same bytes, same absence of a credential.
|
|
496
|
+
*/
|
|
497
|
+
get: {
|
|
498
|
+
parameters: {
|
|
499
|
+
query?: never;
|
|
500
|
+
header?: never;
|
|
501
|
+
path?: never;
|
|
502
|
+
cookie?: never;
|
|
503
|
+
};
|
|
504
|
+
requestBody?: never;
|
|
505
|
+
responses: {
|
|
506
|
+
/** @description OK */
|
|
507
|
+
200: {
|
|
508
|
+
headers: {
|
|
509
|
+
[name: string]: unknown;
|
|
510
|
+
};
|
|
511
|
+
content: {
|
|
512
|
+
"application/json": {
|
|
513
|
+
/**
|
|
514
|
+
* @description Names the source so the reader does not have to take the document's word for it: this is the same output the MCP transport answers `tools/list` with, not a second reading of the catalogue that could drift from it.
|
|
515
|
+
* @enum {string}
|
|
516
|
+
*/
|
|
517
|
+
generated_from: "tools/list";
|
|
518
|
+
tools: {
|
|
519
|
+
/** @description The value to send as `tool` on the execute operation. */
|
|
520
|
+
name: string;
|
|
521
|
+
description: string;
|
|
522
|
+
/** @description JSON Schema for that tool's input, which is what goes in `params`. */
|
|
523
|
+
inputSchema: Record<string, never>;
|
|
524
|
+
}[];
|
|
525
|
+
};
|
|
526
|
+
};
|
|
527
|
+
};
|
|
528
|
+
};
|
|
529
|
+
};
|
|
530
|
+
put?: never;
|
|
531
|
+
post?: never;
|
|
532
|
+
delete?: never;
|
|
533
|
+
options?: never;
|
|
534
|
+
head?: never;
|
|
535
|
+
patch?: never;
|
|
536
|
+
trace?: never;
|
|
537
|
+
};
|
|
430
538
|
"/v1/providers": {
|
|
431
539
|
parameters: {
|
|
432
540
|
query?: never;
|
|
@@ -2759,7 +2867,7 @@ export interface paths {
|
|
|
2759
2867
|
*
|
|
2760
2868
|
* `tool_input` IS NOT THE CALL. It is what the lane that raised the hold recorded, and two things happen to it on the way in. A hold raised on the session execute path carries `{}`, because that path hands the policy engine no tool input at all and the engine stores an empty object when it gets none. A hold raised on the proxy path carries `{ server, method, endpoint, body, params, headers }`, with the `authorization` and `cookie` request headers removed before the row is written. So an empty object here means 'this lane records nothing', not 'the agent sent nothing'.
|
|
2761
2869
|
*
|
|
2762
|
-
* `tool_name` HAS NO SINGLE FORMAT, because four lanes write it. The proxy path writes `<server>:<method>:<endpoint>` with the leading slash dropped and the remaining slashes turned into colons (`asaas`, `POST`, `/payments/create` becomes `asaas:post:payments:create`). The session execute path writes the caller's own `tool` string verbatim, which is any non-empty string that caller chose. The over-cap settlement lane writes `codespar_pay`. The operator account-status lane writes `admin:account_status_set`. Match on it only knowing which lane you are reading.
|
|
2870
|
+
* `tool_name` HAS NO SINGLE FORMAT, because four lanes write it. The proxy path writes `<server>:<method>:<endpoint>` with the leading slash dropped and the remaining slashes turned into colons (`asaas`, `POST`, `/payments/create` becomes `asaas:post:payments:create`). The session execute path writes the caller's own `tool` string verbatim, which is any non-empty string that caller chose. The over-cap settlement lane writes `codespar_pay`. The operator account-status lane writes `admin:account_status_set` and the operator withdrawal-resolution lane `admin:withdrawal_resolve`. Match on it only knowing which lane you are reading.
|
|
2763
2871
|
*
|
|
2764
2872
|
* `expires_at` is the end of the hold, not a display hint: once it passes, the row stops being decidable and the expiry sweep moves it to `expired`.
|
|
2765
2873
|
*
|
|
@@ -3907,7 +4015,7 @@ export interface paths {
|
|
|
3907
4015
|
* Which rate-card lanes are measured and charged for this org
|
|
3908
4016
|
* @description The public rate card has four lanes, told apart by the direction of the money: MOVIMENTAR (money leaving under a mandate, 10 bps), FATURAR (money being born in the receiver's account, 1%), GOVERNAR (account governance, per governed account) and OPERAR (non-monetary outcomes). A published price is not the same thing as a measured one, and this answer keeps the two apart per lane so a client never shows a figure the platform is not computing.
|
|
3909
4017
|
*
|
|
3910
|
-
* `computed` says whether this build measures the lane from the organization's own ledger; `charging` says whether the organization is actually invoiced for it; `latest` is the last computed period and is only ever non-null on a computed lane (its shape is the one `GET /v1/fees/movimentar`
|
|
4018
|
+
* `computed` says whether this build measures the lane from the organization's own ledger; `charging` says whether the organization is actually invoiced for it; `latest` is the last computed period and is only ever non-null on a computed lane (its shape is the one the lane's own read returns: `GET /v1/fees/movimentar`, `GET /v1/fees/governar`). Today MOVIMENTAR and GOVERNAR are the computed lanes; FATURAR and OPERAR are not measured and always answer `latest: null`. `charging` is each lane's own switch: an organization can be charged for one lane and not the other. `period` is the current calendar month in Sao Paulo time.
|
|
3911
4019
|
*
|
|
3912
4020
|
* Scope: `fees:read`.
|
|
3913
4021
|
*/
|
|
@@ -3951,36 +4059,16 @@ export interface paths {
|
|
|
3951
4059
|
faturar: {
|
|
3952
4060
|
computed: boolean;
|
|
3953
4061
|
charging: boolean;
|
|
3954
|
-
latest:
|
|
3955
|
-
period: string;
|
|
3956
|
-
consumerCount: number;
|
|
3957
|
-
movedMinor: number;
|
|
3958
|
-
freeTierAppliedMinor: number;
|
|
3959
|
-
billableMinor: number;
|
|
3960
|
-
refundCreditMinor: number;
|
|
3961
|
-
refundedCount: number;
|
|
3962
|
-
feeMinor: number;
|
|
3963
|
-
/** @enum {string} */
|
|
3964
|
-
rateTier: "self_serve" | "commit_8bps" | "commit_6bps";
|
|
3965
|
-
/** Format: date-time */
|
|
3966
|
-
computedAt: string;
|
|
3967
|
-
invoiced: boolean;
|
|
3968
|
-
} | null;
|
|
4062
|
+
latest: null;
|
|
3969
4063
|
};
|
|
3970
4064
|
governar: {
|
|
3971
4065
|
computed: boolean;
|
|
3972
4066
|
charging: boolean;
|
|
3973
4067
|
latest: {
|
|
3974
4068
|
period: string;
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
freeTierAppliedMinor: number;
|
|
3978
|
-
billableMinor: number;
|
|
3979
|
-
refundCreditMinor: number;
|
|
3980
|
-
refundedCount: number;
|
|
4069
|
+
governedAccountsCount: number;
|
|
4070
|
+
consumerIdsSha256: string;
|
|
3981
4071
|
feeMinor: number;
|
|
3982
|
-
/** @enum {string} */
|
|
3983
|
-
rateTier: "self_serve" | "commit_8bps" | "commit_6bps";
|
|
3984
4072
|
/** Format: date-time */
|
|
3985
4073
|
computedAt: string;
|
|
3986
4074
|
invoiced: boolean;
|
|
@@ -3989,21 +4077,7 @@ export interface paths {
|
|
|
3989
4077
|
operar: {
|
|
3990
4078
|
computed: boolean;
|
|
3991
4079
|
charging: boolean;
|
|
3992
|
-
latest:
|
|
3993
|
-
period: string;
|
|
3994
|
-
consumerCount: number;
|
|
3995
|
-
movedMinor: number;
|
|
3996
|
-
freeTierAppliedMinor: number;
|
|
3997
|
-
billableMinor: number;
|
|
3998
|
-
refundCreditMinor: number;
|
|
3999
|
-
refundedCount: number;
|
|
4000
|
-
feeMinor: number;
|
|
4001
|
-
/** @enum {string} */
|
|
4002
|
-
rateTier: "self_serve" | "commit_8bps" | "commit_6bps";
|
|
4003
|
-
/** Format: date-time */
|
|
4004
|
-
computedAt: string;
|
|
4005
|
-
invoiced: boolean;
|
|
4006
|
-
} | null;
|
|
4080
|
+
latest: null;
|
|
4007
4081
|
};
|
|
4008
4082
|
};
|
|
4009
4083
|
};
|
|
@@ -4078,6 +4152,61 @@ export interface paths {
|
|
|
4078
4152
|
patch?: never;
|
|
4079
4153
|
trace?: never;
|
|
4080
4154
|
};
|
|
4155
|
+
"/v1/fees/governar": {
|
|
4156
|
+
parameters: {
|
|
4157
|
+
query?: never;
|
|
4158
|
+
header?: never;
|
|
4159
|
+
path?: never;
|
|
4160
|
+
cookie?: never;
|
|
4161
|
+
};
|
|
4162
|
+
/**
|
|
4163
|
+
* The org's latest GOVERNAR-lane fee period (rate card v1)
|
|
4164
|
+
* @description What the calling credential's organization owes CodeSpar for the most recently computed calendar month (Sao Paulo time) under the GOVERNAR lane of the public rate card (Account governance): R$4,90 per governed account active in the month. A governed account active in the month is a holder that had a consumer mandate active at some instant of the month AND at least one outcome settled under one of their mandates in the month (a debit in the wallet ledger, or a receipt sealed). A holder with mandates and no settled outcome in the month costs nothing; a holder with three mandates is one account; the population resets every month.
|
|
4165
|
+
*
|
|
4166
|
+
* This lane prices the ACCOUNT, not the outcome. The same debit that pays 10 bps under MOVIMENTAR is what shows the account was alive in the month; it is not priced twice, because the two lines price two different things.
|
|
4167
|
+
*
|
|
4168
|
+
* HOW TO READ THE NUMBERS. `governedAccountsCount` is how many holders were counted; `feeMinor` is that count times R$4,90, in centavos; `consumerIdsSha256` is the SHA-256 (hex) of the counted consumer ids sorted and joined by a newline, so a client can verify its own list of accounts against the figure; the ids themselves stay on the platform's row for audit. `invoiced` says whether the period has been invoiced; a period is invoiced at most once.
|
|
4169
|
+
*
|
|
4170
|
+
* `null` (200) when no period has been computed for the organization yet. The period is computed by the platform, not on this read; `computedAt` says when.
|
|
4171
|
+
*
|
|
4172
|
+
* Scope: `fees:read`.
|
|
4173
|
+
*/
|
|
4174
|
+
get: {
|
|
4175
|
+
parameters: {
|
|
4176
|
+
query?: never;
|
|
4177
|
+
header?: never;
|
|
4178
|
+
path?: never;
|
|
4179
|
+
cookie?: never;
|
|
4180
|
+
};
|
|
4181
|
+
requestBody?: never;
|
|
4182
|
+
responses: {
|
|
4183
|
+
/** @description OK */
|
|
4184
|
+
200: {
|
|
4185
|
+
headers: {
|
|
4186
|
+
[name: string]: unknown;
|
|
4187
|
+
};
|
|
4188
|
+
content: {
|
|
4189
|
+
"application/json": {
|
|
4190
|
+
period: string;
|
|
4191
|
+
governedAccountsCount: number;
|
|
4192
|
+
consumerIdsSha256: string;
|
|
4193
|
+
feeMinor: number;
|
|
4194
|
+
/** Format: date-time */
|
|
4195
|
+
computedAt: string;
|
|
4196
|
+
invoiced: boolean;
|
|
4197
|
+
} | null;
|
|
4198
|
+
};
|
|
4199
|
+
};
|
|
4200
|
+
};
|
|
4201
|
+
};
|
|
4202
|
+
put?: never;
|
|
4203
|
+
post?: never;
|
|
4204
|
+
delete?: never;
|
|
4205
|
+
options?: never;
|
|
4206
|
+
head?: never;
|
|
4207
|
+
patch?: never;
|
|
4208
|
+
trace?: never;
|
|
4209
|
+
};
|
|
4081
4210
|
"/v1/cart/meli/connect/start": {
|
|
4082
4211
|
parameters: {
|
|
4083
4212
|
query?: never;
|
|
@@ -4502,9 +4631,10 @@ export interface paths {
|
|
|
4502
4631
|
};
|
|
4503
4632
|
/**
|
|
4504
4633
|
* Read the credential form a provider needs, without reading any credential
|
|
4634
|
+
* @deprecated
|
|
4505
4635
|
* @description What to ask an operator for before connecting this provider, and where the request will go once connected. It NEVER returns a stored secret: the vault is write-only from this side, and `fields` describes inputs to collect, not values that exist.
|
|
4506
4636
|
*
|
|
4507
|
-
* AN EMPTY `fields` DOES NOT MEAN NOTHING TO DO, and four auth types produce one. `oauth` collects nothing here because the browser leg starts at `POST /v1/connections/start` instead. `none` needs no credential. And `jwt_ecdsa` and `cdp` reach no field-building branch at all, so they come back empty while still needing operator-issued material: read that pair as unsupported by this form rather than as ready to connect. The
|
|
4637
|
+
* AN EMPTY `fields` DOES NOT MEAN NOTHING TO DO, and four of the auth types produce one. `oauth` collects nothing here because the browser leg starts at `POST /v1/connections/start` instead. `none` needs no credential. And `jwt_ecdsa` and `cdp` reach no field-building branch at all, so they come back empty while still needing operator-issued material: read that pair as unsupported by this form rather than as ready to connect. The rest all return at least one field, `cert` included.
|
|
4508
4638
|
*
|
|
4509
4639
|
* `base_url` IS ENVIRONMENT-RESOLVED against the credential in hand: a test key sees the provider's test host when the catalog declares one, and the live host otherwise. It is the empty string when the provider has no endpoint row, which is a catalog gap rather than a value to dial.
|
|
4510
4640
|
*
|
|
@@ -4664,6 +4794,7 @@ export interface paths {
|
|
|
4664
4794
|
put?: never;
|
|
4665
4795
|
/**
|
|
4666
4796
|
* Ask the provider whether this project's stored credential still works
|
|
4797
|
+
* @deprecated
|
|
4667
4798
|
* @description Issues ONE safe read against the provider using the credential this project has stored for it, and reports what came back. POST because it leaves the process and spends a provider call, not because it changes anything here: no state of yours is altered by it. It takes NO REQUEST BODY, and anything sent is ignored.
|
|
4668
4799
|
*
|
|
4669
4800
|
* WHICH READ depends on the provider. A handful ship a bespoke recipe, and those are the ones that can return an `account` summary. Everything else re-runs the provider's declared functional probe, the same authenticated read used to confirm a sandbox works when it is first set up; that path returns no `account`. A provider with neither answers 501.
|
|
@@ -4778,6 +4909,24 @@ export interface paths {
|
|
|
4778
4909
|
};
|
|
4779
4910
|
};
|
|
4780
4911
|
};
|
|
4912
|
+
/** @description `test_venue_unavailable`. The project is in `environment="test"` and this provider cannot be exercised there: its catalog entry classifies `test_venue` as `none` (the provider runs no test environment, so a call would land on production with a real effect) or `unclassified` (nobody has established what it does in test). Not a verdict on the credential and not retryable — the identical request from a `live` project reaches the provider (ent#722). */
|
|
4913
|
+
422: {
|
|
4914
|
+
headers: {
|
|
4915
|
+
[name: string]: unknown;
|
|
4916
|
+
};
|
|
4917
|
+
content: {
|
|
4918
|
+
"application/json": {
|
|
4919
|
+
/** @enum {boolean} */
|
|
4920
|
+
ok: false;
|
|
4921
|
+
/** @description The provider id from the path. */
|
|
4922
|
+
provider: string;
|
|
4923
|
+
/** @enum {string} */
|
|
4924
|
+
error: "test_venue_unavailable";
|
|
4925
|
+
/** @description A CodeSpar-authored sentence naming the catalog file and the field to declare. Never provider text — no round trip was made. */
|
|
4926
|
+
detail: string;
|
|
4927
|
+
};
|
|
4928
|
+
};
|
|
4929
|
+
};
|
|
4781
4930
|
/** @description `not_connected`. There is nothing to verify: either no active connection exists for this project and provider, or one exists and its stored credential did not resolve to a value. Connect the provider, or reconnect it. */
|
|
4782
4931
|
424: {
|
|
4783
4932
|
headers: {
|
|
@@ -5967,8 +6116,8 @@ export interface paths {
|
|
|
5967
6116
|
ok: false;
|
|
5968
6117
|
provider: string;
|
|
5969
6118
|
/** @enum {string} */
|
|
5970
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
5971
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6119
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6120
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
5972
6121
|
detail?: string;
|
|
5973
6122
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
5974
6123
|
status?: number;
|
|
@@ -6000,8 +6149,8 @@ export interface paths {
|
|
|
6000
6149
|
ok: false;
|
|
6001
6150
|
provider: string;
|
|
6002
6151
|
/** @enum {string} */
|
|
6003
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6004
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6152
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6153
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6005
6154
|
detail?: string;
|
|
6006
6155
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6007
6156
|
status?: number;
|
|
@@ -6028,8 +6177,8 @@ export interface paths {
|
|
|
6028
6177
|
ok: false;
|
|
6029
6178
|
provider: string;
|
|
6030
6179
|
/** @enum {string} */
|
|
6031
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6032
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6180
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6181
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6033
6182
|
detail?: string;
|
|
6034
6183
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6035
6184
|
status?: number;
|
|
@@ -6056,8 +6205,8 @@ export interface paths {
|
|
|
6056
6205
|
ok: false;
|
|
6057
6206
|
provider: string;
|
|
6058
6207
|
/** @enum {string} */
|
|
6059
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6060
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6208
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6209
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6061
6210
|
detail?: string;
|
|
6062
6211
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6063
6212
|
status?: number;
|
|
@@ -6084,8 +6233,8 @@ export interface paths {
|
|
|
6084
6233
|
ok: false;
|
|
6085
6234
|
provider: string;
|
|
6086
6235
|
/** @enum {string} */
|
|
6087
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6088
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6236
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6237
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6089
6238
|
detail?: string;
|
|
6090
6239
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6091
6240
|
status?: number;
|
|
@@ -6112,8 +6261,8 @@ export interface paths {
|
|
|
6112
6261
|
ok: false;
|
|
6113
6262
|
provider: string;
|
|
6114
6263
|
/** @enum {string} */
|
|
6115
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6116
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6264
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6265
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6117
6266
|
detail?: string;
|
|
6118
6267
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6119
6268
|
status?: number;
|
|
@@ -6140,8 +6289,8 @@ export interface paths {
|
|
|
6140
6289
|
ok: false;
|
|
6141
6290
|
provider: string;
|
|
6142
6291
|
/** @enum {string} */
|
|
6143
|
-
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing";
|
|
6144
|
-
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. */
|
|
6292
|
+
error: "server_unknown" | "verify_unsupported" | "not_connected" | "provider_rejected" | "provider_unreachable" | "redirect_not_followed" | "endpoint_missing" | "test_venue_unavailable";
|
|
6293
|
+
/** @description Whose sentence this is depends on the code, and the difference matters. On `provider_rejected` and `provider_unreachable` it is up to 256 characters of the PROVIDER's own response body, or the transport error. On the others it is text we wrote, naming what is missing on our side. It is absent on `redirect_not_followed`, and on the `server_unknown` and `endpoint_missing` refusals that carry nothing but the code. On `test_venue_unavailable` it names the catalog file and the field to declare, and it is the one refusal here that is about the project's ENVIRONMENT rather than its connection: the identical request from a `live` project reaches the provider. */
|
|
6145
6294
|
detail?: string;
|
|
6146
6295
|
/** @description The provider's HTTP status, present only when a round trip completed: on `provider_rejected`, `redirect_not_followed`, and the `provider_unreachable` that came from a response rather than from a transport failure. Its ABSENCE on a 502 is the signal that nothing was reached at all. */
|
|
6147
6296
|
status?: number;
|
|
@@ -6875,6 +7024,23 @@ export interface paths {
|
|
|
6875
7024
|
};
|
|
6876
7025
|
};
|
|
6877
7026
|
};
|
|
7027
|
+
/** @description The project is in `environment="test"` and this provider has no test venue, so the flow is refused BEFORE a state token is minted — a refused start leaves no half-begun link behind. Sending a test project to the provider's LIVE consent screen would have it authorise a real account and vault a real token under a project that is not supposed to hold one (ent#722). Not retryable; the same call from a `live` project succeeds. */
|
|
7028
|
+
422: {
|
|
7029
|
+
headers: {
|
|
7030
|
+
[name: string]: unknown;
|
|
7031
|
+
};
|
|
7032
|
+
content: {
|
|
7033
|
+
"application/json": {
|
|
7034
|
+
/** @enum {string} */
|
|
7035
|
+
error: "test_venue_unavailable";
|
|
7036
|
+
server_id: string;
|
|
7037
|
+
/** @enum {string} */
|
|
7038
|
+
environment: "live" | "test";
|
|
7039
|
+
/** @description Names the catalog file and the field to declare. */
|
|
7040
|
+
detail: string;
|
|
7041
|
+
};
|
|
7042
|
+
};
|
|
7043
|
+
};
|
|
6878
7044
|
/** @description The platform's OAuth client credential is not seeded for this provider. A configuration defect on our side. */
|
|
6879
7045
|
500: {
|
|
6880
7046
|
headers: {
|
|
@@ -7968,6 +8134,7 @@ export interface paths {
|
|
|
7968
8134
|
};
|
|
7969
8135
|
/**
|
|
7970
8136
|
* Browse the audit chain (alias path)
|
|
8137
|
+
* @deprecated
|
|
7971
8138
|
* @description A read-only page of the caller's own tamper-evident chain, newest first.
|
|
7972
8139
|
*
|
|
7973
8140
|
* THIS IS AN ALIAS OF `GET /v1/audit-events`, NOT A SECOND RESOURCE. One handler serves both paths, so the query, the body and every refusal are identical and there is nothing to choose between them. It is described separately only because a generated client sees two operations; pick one spelling and stay on it. Note that the OTHER audit operations — the chain's health report, its incidents, its configuration — have no twin under this prefix and live only under `/v1/audit-events`.
|
|
@@ -8525,8 +8692,12 @@ export interface paths {
|
|
|
8525
8692
|
counterparty_id: string;
|
|
8526
8693
|
/** @enum {string} */
|
|
8527
8694
|
kind: "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other";
|
|
8528
|
-
/** @description Minor units.
|
|
8695
|
+
/** @description Minor units (cents). The row is STORED in the currency's native unit, BRL centavos and USDC 10^-6 (ent#1203), and rendered here in cents rounded away from zero, so a USDC row of 0.001 reads as 1 and never as 0. `amount_native` carries the exact figure. Null unless `currency` is also set. */
|
|
8529
8696
|
amount_minor: number | null;
|
|
8697
|
+
/** @description The stored figure, exact, in the currency's NATIVE unit as a decimal string: BRL centavos, USDC 10^-6. This is the unit the wallet ledger holds, so it joins to `wallet_ledger.amount_minor` without conversion. Null when `amount_minor` is. */
|
|
8698
|
+
amount_native: string | null;
|
|
8699
|
+
/** @description The same figure in major units as a decimal string (`"0.001"`, `"19.99"`), for display. */
|
|
8700
|
+
amount: string | null;
|
|
8530
8701
|
currency: string | null;
|
|
8531
8702
|
/** Format: date-time */
|
|
8532
8703
|
occurred_at: string;
|
|
@@ -8590,7 +8761,7 @@ export interface paths {
|
|
|
8590
8761
|
counterparty_id: string;
|
|
8591
8762
|
/** @enum {string} */
|
|
8592
8763
|
kind: "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other";
|
|
8593
|
-
/** @description Minor units. Set it together with `currency` or omit both. */
|
|
8764
|
+
/** @description Minor units (cents). Stored in the currency's native unit (USDC x10^4, BRL as is), so this field cannot carry a sub-cent USDC figure. Set it together with `currency` or omit both. */
|
|
8594
8765
|
amount_minor?: number;
|
|
8595
8766
|
currency?: string;
|
|
8596
8767
|
/**
|
|
@@ -8628,8 +8799,12 @@ export interface paths {
|
|
|
8628
8799
|
counterparty_id: string;
|
|
8629
8800
|
/** @enum {string} */
|
|
8630
8801
|
kind: "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other";
|
|
8631
|
-
/** @description Minor units.
|
|
8802
|
+
/** @description Minor units (cents). The row is STORED in the currency's native unit, BRL centavos and USDC 10^-6 (ent#1203), and rendered here in cents rounded away from zero, so a USDC row of 0.001 reads as 1 and never as 0. `amount_native` carries the exact figure. Null unless `currency` is also set. */
|
|
8632
8803
|
amount_minor: number | null;
|
|
8804
|
+
/** @description The stored figure, exact, in the currency's NATIVE unit as a decimal string: BRL centavos, USDC 10^-6. This is the unit the wallet ledger holds, so it joins to `wallet_ledger.amount_minor` without conversion. Null when `amount_minor` is. */
|
|
8805
|
+
amount_native: string | null;
|
|
8806
|
+
/** @description The same figure in major units as a decimal string (`"0.001"`, `"19.99"`), for display. */
|
|
8807
|
+
amount: string | null;
|
|
8633
8808
|
currency: string | null;
|
|
8634
8809
|
/** Format: date-time */
|
|
8635
8810
|
occurred_at: string;
|
|
@@ -8657,8 +8832,12 @@ export interface paths {
|
|
|
8657
8832
|
counterparty_id: string;
|
|
8658
8833
|
/** @enum {string} */
|
|
8659
8834
|
kind: "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other";
|
|
8660
|
-
/** @description Minor units.
|
|
8835
|
+
/** @description Minor units (cents). The row is STORED in the currency's native unit, BRL centavos and USDC 10^-6 (ent#1203), and rendered here in cents rounded away from zero, so a USDC row of 0.001 reads as 1 and never as 0. `amount_native` carries the exact figure. Null unless `currency` is also set. */
|
|
8661
8836
|
amount_minor: number | null;
|
|
8837
|
+
/** @description The stored figure, exact, in the currency's NATIVE unit as a decimal string: BRL centavos, USDC 10^-6. This is the unit the wallet ledger holds, so it joins to `wallet_ledger.amount_minor` without conversion. Null when `amount_minor` is. */
|
|
8838
|
+
amount_native: string | null;
|
|
8839
|
+
/** @description The same figure in major units as a decimal string (`"0.001"`, `"19.99"`), for display. */
|
|
8840
|
+
amount: string | null;
|
|
8662
8841
|
currency: string | null;
|
|
8663
8842
|
/** Format: date-time */
|
|
8664
8843
|
occurred_at: string;
|
|
@@ -9223,7 +9402,7 @@ export interface paths {
|
|
|
9223
9402
|
interaction_count: number;
|
|
9224
9403
|
/** @description Of those, the ones with `kind: payment`. */
|
|
9225
9404
|
payment_count: number;
|
|
9226
|
-
/** @description Sum
|
|
9405
|
+
/** @description Sum over the window's PAYMENT interactions only, ACROSS CURRENCIES, in cents: each row is converted from its currency's native unit before the sum and the total is rounded up once. Read `currencies` before reading this as an amount. */
|
|
9227
9406
|
total_payment_minor: number;
|
|
9228
9407
|
/** @description Distinct non null currencies over the window's interactions of EVERY kind, not only the payments the total is built from. It is therefore an UPPER BOUND on the currencies inside `total_payment_minor` and never a smaller set: an invoice priced in USD puts USD here while the total stays pure BRL. One entry (or none) does bound the total to a single currency; two or more do not prove it mixes. */
|
|
9229
9408
|
currencies: string[];
|
|
@@ -9411,7 +9590,7 @@ export interface paths {
|
|
|
9411
9590
|
/** @enum {string} */
|
|
9412
9591
|
kind: "supplier" | "customer" | "agent_peer";
|
|
9413
9592
|
payment_count: number;
|
|
9414
|
-
/** @description Sum
|
|
9593
|
+
/** @description Sum over the window's payment interactions, ACROSS CURRENCIES, in cents: each row converted from its currency's native unit before the sum, the total rounded up once. */
|
|
9415
9594
|
total_payment_minor: number;
|
|
9416
9595
|
/** @description The most frequent currency over ALL of this counterparty's payment interactions, ignoring `since` and `until`, so it can name a currency the window itself never saw. */
|
|
9417
9596
|
dominant_currency: string | null;
|
|
@@ -10210,6 +10389,23 @@ export interface paths {
|
|
|
10210
10389
|
};
|
|
10211
10390
|
};
|
|
10212
10391
|
};
|
|
10392
|
+
/** @description The project is in `environment="test"` and this provider has no test venue, so the flow is refused BEFORE a state token is minted — a refused start leaves no half-begun link behind. Sending a test project to the provider's LIVE consent screen would have it authorise a real account and vault a real token under a project that is not supposed to hold one (ent#722). Not retryable; the same call from a `live` project succeeds. */
|
|
10393
|
+
422: {
|
|
10394
|
+
headers: {
|
|
10395
|
+
[name: string]: unknown;
|
|
10396
|
+
};
|
|
10397
|
+
content: {
|
|
10398
|
+
"application/json": {
|
|
10399
|
+
/** @enum {string} */
|
|
10400
|
+
error: "test_venue_unavailable";
|
|
10401
|
+
server_id: string;
|
|
10402
|
+
/** @enum {string} */
|
|
10403
|
+
environment: "live" | "test";
|
|
10404
|
+
/** @description Names the catalog file and the field to declare. */
|
|
10405
|
+
detail: string;
|
|
10406
|
+
};
|
|
10407
|
+
};
|
|
10408
|
+
};
|
|
10213
10409
|
/** @description The platform's OAuth client credential is not seeded for this provider. A configuration defect on our side. */
|
|
10214
10410
|
500: {
|
|
10215
10411
|
headers: {
|
|
@@ -10225,39 +10421,1269 @@ export interface paths {
|
|
|
10225
10421
|
};
|
|
10226
10422
|
};
|
|
10227
10423
|
};
|
|
10228
|
-
delete?: never;
|
|
10229
|
-
options?: never;
|
|
10230
|
-
head?: never;
|
|
10231
|
-
patch?: never;
|
|
10232
|
-
trace?: never;
|
|
10233
|
-
};
|
|
10234
|
-
"/v1/connections/engine/{run_id}/status": {
|
|
10235
|
-
parameters: {
|
|
10236
|
-
query?: never;
|
|
10237
|
-
header?: never;
|
|
10238
|
-
path?: never;
|
|
10239
|
-
cookie?: never;
|
|
10240
|
-
};
|
|
10424
|
+
delete?: never;
|
|
10425
|
+
options?: never;
|
|
10426
|
+
head?: never;
|
|
10427
|
+
patch?: never;
|
|
10428
|
+
trace?: never;
|
|
10429
|
+
};
|
|
10430
|
+
"/v1/connections/engine/{run_id}/status": {
|
|
10431
|
+
parameters: {
|
|
10432
|
+
query?: never;
|
|
10433
|
+
header?: never;
|
|
10434
|
+
path?: never;
|
|
10435
|
+
cookie?: never;
|
|
10436
|
+
};
|
|
10437
|
+
/**
|
|
10438
|
+
* Poll a browser-driven signup run
|
|
10439
|
+
* @description Read-only. The run resolves only inside the calling credential's org and project, so a run id from another tenant is 404 rather than 403.
|
|
10440
|
+
*
|
|
10441
|
+
* Poll this while `status` is `running`. When it becomes `needs_verification` the customer has to clear the provider's email gate, and `verification.mechanism` says how: `code` means a one-time code to relay, `link` means a link to click in their own inbox. Branch on the mechanism, never on the provider name. A paused run that has expired answers 410 `run_stale` and cannot be resumed.
|
|
10442
|
+
*
|
|
10443
|
+
* On `provisioned`, `connection_id` names the connection the run produced, which then behaves like any other row on this resource. On `failed`, `code` is drawn from a closed first-party vocabulary and `failed_step_id` names the step, when the run recorded one; a failed run that recorded no reason reports its status alone. The bounded failure detail, the page URL and the screenshot references are deliberately not selected by this query, so they cannot leak from it.
|
|
10444
|
+
*
|
|
10445
|
+
* The 404 body here is `{ error: { code, message } }` with no `request_id`, unlike the 410 beside it.
|
|
10446
|
+
*/
|
|
10447
|
+
get: {
|
|
10448
|
+
parameters: {
|
|
10449
|
+
query?: never;
|
|
10450
|
+
header?: never;
|
|
10451
|
+
path: {
|
|
10452
|
+
run_id: string;
|
|
10453
|
+
};
|
|
10454
|
+
cookie?: never;
|
|
10455
|
+
};
|
|
10456
|
+
requestBody?: never;
|
|
10457
|
+
responses: {
|
|
10458
|
+
/** @description OK */
|
|
10459
|
+
200: {
|
|
10460
|
+
headers: {
|
|
10461
|
+
[name: string]: unknown;
|
|
10462
|
+
};
|
|
10463
|
+
content: {
|
|
10464
|
+
"application/json": {
|
|
10465
|
+
/** @enum {string} */
|
|
10466
|
+
status: "running" | "needs_verification" | "provisioned" | "failed";
|
|
10467
|
+
/** @description Present while the run waits on the customer. Fallback copy when the modal has none of its own. */
|
|
10468
|
+
prompt?: string;
|
|
10469
|
+
/** @description Resolved from the provider's public descriptor. Present only while `status` is `needs_verification`. */
|
|
10470
|
+
verification?: {
|
|
10471
|
+
/**
|
|
10472
|
+
* @description `code` means the provider mailed a one-time code to type; `link` means it mailed an activation link to click.
|
|
10473
|
+
* @enum {string}
|
|
10474
|
+
*/
|
|
10475
|
+
mechanism: "code" | "link";
|
|
10476
|
+
resend?: boolean;
|
|
10477
|
+
};
|
|
10478
|
+
/** @description Result of the post-provision reachability probe, when one ran. */
|
|
10479
|
+
probe_result?: unknown;
|
|
10480
|
+
/** @description The `ca_` id of the connection the run produced. Present once the run reaches `provisioned`. */
|
|
10481
|
+
connection_id?: string;
|
|
10482
|
+
/**
|
|
10483
|
+
* @description Why the run failed. A stored value outside this vocabulary is reported as absent rather than passed through, so a failed run can render as its status alone.
|
|
10484
|
+
* @enum {string}
|
|
10485
|
+
*/
|
|
10486
|
+
code?: "flow_failed" | "capacity" | "no_credential_captured" | "probe_failed" | "drive_deadline_exceeded" | "provider_account_not_registered" | "drive_stalled" | "resume_inputs_unavailable";
|
|
10487
|
+
failed_step_id?: string;
|
|
10488
|
+
};
|
|
10489
|
+
};
|
|
10490
|
+
};
|
|
10491
|
+
/** @description No run with that id inside the caller's org and project. */
|
|
10492
|
+
404: {
|
|
10493
|
+
headers: {
|
|
10494
|
+
[name: string]: unknown;
|
|
10495
|
+
};
|
|
10496
|
+
content: {
|
|
10497
|
+
"application/json": {
|
|
10498
|
+
error: {
|
|
10499
|
+
/** @enum {string} */
|
|
10500
|
+
code: "not_found";
|
|
10501
|
+
message: string;
|
|
10502
|
+
};
|
|
10503
|
+
};
|
|
10504
|
+
};
|
|
10505
|
+
};
|
|
10506
|
+
/** @description The paused run expired before it was resumed. */
|
|
10507
|
+
410: {
|
|
10508
|
+
headers: {
|
|
10509
|
+
[name: string]: unknown;
|
|
10510
|
+
};
|
|
10511
|
+
content: {
|
|
10512
|
+
"application/json": {
|
|
10513
|
+
error: {
|
|
10514
|
+
/** @enum {string} */
|
|
10515
|
+
code: "run_stale";
|
|
10516
|
+
message: string;
|
|
10517
|
+
details?: {
|
|
10518
|
+
[key: string]: unknown;
|
|
10519
|
+
};
|
|
10520
|
+
};
|
|
10521
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10522
|
+
request_id: string | null;
|
|
10523
|
+
};
|
|
10524
|
+
};
|
|
10525
|
+
};
|
|
10526
|
+
};
|
|
10527
|
+
};
|
|
10528
|
+
put?: never;
|
|
10529
|
+
post?: never;
|
|
10530
|
+
delete?: never;
|
|
10531
|
+
options?: never;
|
|
10532
|
+
head?: never;
|
|
10533
|
+
patch?: never;
|
|
10534
|
+
trace?: never;
|
|
10535
|
+
};
|
|
10536
|
+
"/v1/connections/subaccount/{id}/revoke": {
|
|
10537
|
+
parameters: {
|
|
10538
|
+
query?: never;
|
|
10539
|
+
header?: never;
|
|
10540
|
+
path?: never;
|
|
10541
|
+
cookie?: never;
|
|
10542
|
+
};
|
|
10543
|
+
get?: never;
|
|
10544
|
+
put?: never;
|
|
10545
|
+
/**
|
|
10546
|
+
* Revoke a provisioned subaccount and try to delete it upstream
|
|
10547
|
+
* @description The revoke for accounts this platform minted on the customer's behalf. It is not `POST /v1/connections/{id}/revoke`: the generic purge targets the ref keyed on the server id, which is the wrong ref for a per-account subaccount credential, and it touches neither the provisioning record nor the account at the provider.
|
|
10548
|
+
*
|
|
10549
|
+
* Local teardown first, atomically: the connection projection flips, the provisioning record flips, and the correct per-account vault ref is purged. A failure in that phase changes nothing and answers 503, so a retry is safe. Only then is a delete attempted at the provider.
|
|
10550
|
+
*
|
|
10551
|
+
* READ `upstream` BEFORE TREATING THIS AS FINISHED. `deleted` means the account is gone at the provider. `not_applicable` means the lane has no delete to make. `delete_failed` and `orphaned` mean the credential is destroyed on our side but an account may still exist upstream, and closing it is a manual step. All four come back with 200, because the local teardown did succeed.
|
|
10552
|
+
*
|
|
10553
|
+
* `{id}` is a connection id for the customer path, matched only inside the caller's own org and project. It is a provisioning record id for the operator-internal path, which additionally requires service auth. A customer credential can never reach an operator-internal record: it misses the connection lookup and gets 404, never a 403 that would confirm the id exists. A repeated revoke returns `already: true` and changes nothing.
|
|
10554
|
+
*/
|
|
10555
|
+
post: {
|
|
10556
|
+
parameters: {
|
|
10557
|
+
query?: never;
|
|
10558
|
+
header?: never;
|
|
10559
|
+
path: {
|
|
10560
|
+
/** @description A `ca_` connection id, or a `pr_` provisioning record id on the operator-internal path. */
|
|
10561
|
+
id: string;
|
|
10562
|
+
};
|
|
10563
|
+
cookie?: never;
|
|
10564
|
+
};
|
|
10565
|
+
requestBody?: never;
|
|
10566
|
+
responses: {
|
|
10567
|
+
/** @description OK */
|
|
10568
|
+
200: {
|
|
10569
|
+
headers: {
|
|
10570
|
+
[name: string]: unknown;
|
|
10571
|
+
};
|
|
10572
|
+
content: {
|
|
10573
|
+
"application/json": {
|
|
10574
|
+
/** @enum {string} */
|
|
10575
|
+
status: "revoked";
|
|
10576
|
+
record_id: string;
|
|
10577
|
+
/** @description The connection projection's id, or the provisioning record's id when there is no projection. */
|
|
10578
|
+
connection_id: string;
|
|
10579
|
+
/**
|
|
10580
|
+
* @description What happened at the provider. `delete_failed` and `orphaned` mean an account may still exist there; the local credential is gone either way.
|
|
10581
|
+
* @enum {string}
|
|
10582
|
+
*/
|
|
10583
|
+
upstream: "deleted" | "delete_failed" | "not_applicable" | "orphaned";
|
|
10584
|
+
/**
|
|
10585
|
+
* @description Present when the subaccount was already revoked. Nothing changed.
|
|
10586
|
+
* @enum {boolean}
|
|
10587
|
+
*/
|
|
10588
|
+
already?: true;
|
|
10589
|
+
};
|
|
10590
|
+
};
|
|
10591
|
+
};
|
|
10592
|
+
/** @description This is a write, so it carries a role floor: a service-auth caller must send `x-codespar-user` and hold admin or above. */
|
|
10593
|
+
403: {
|
|
10594
|
+
headers: {
|
|
10595
|
+
[name: string]: unknown;
|
|
10596
|
+
};
|
|
10597
|
+
content: {
|
|
10598
|
+
"application/json": {
|
|
10599
|
+
error: {
|
|
10600
|
+
/** @enum {string} */
|
|
10601
|
+
code: "insufficient_role";
|
|
10602
|
+
message: string;
|
|
10603
|
+
details?: {
|
|
10604
|
+
[key: string]: unknown;
|
|
10605
|
+
};
|
|
10606
|
+
};
|
|
10607
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10608
|
+
request_id: string | null;
|
|
10609
|
+
};
|
|
10610
|
+
};
|
|
10611
|
+
};
|
|
10612
|
+
/** @description No connection or operator-internal record with that id is reachable by this caller. */
|
|
10613
|
+
404: {
|
|
10614
|
+
headers: {
|
|
10615
|
+
[name: string]: unknown;
|
|
10616
|
+
};
|
|
10617
|
+
content: {
|
|
10618
|
+
"application/json": {
|
|
10619
|
+
error: {
|
|
10620
|
+
/** @enum {string} */
|
|
10621
|
+
code: "not_found";
|
|
10622
|
+
message: string;
|
|
10623
|
+
};
|
|
10624
|
+
};
|
|
10625
|
+
};
|
|
10626
|
+
};
|
|
10627
|
+
/** @description The revoke threw unexpectedly. */
|
|
10628
|
+
500: {
|
|
10629
|
+
headers: {
|
|
10630
|
+
[name: string]: unknown;
|
|
10631
|
+
};
|
|
10632
|
+
content: {
|
|
10633
|
+
"application/json": {
|
|
10634
|
+
error: {
|
|
10635
|
+
/** @enum {string} */
|
|
10636
|
+
code: "revoke_failed";
|
|
10637
|
+
message: string;
|
|
10638
|
+
details?: {
|
|
10639
|
+
[key: string]: unknown;
|
|
10640
|
+
};
|
|
10641
|
+
};
|
|
10642
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10643
|
+
request_id: string | null;
|
|
10644
|
+
};
|
|
10645
|
+
};
|
|
10646
|
+
};
|
|
10647
|
+
/** @description The internal phase failed and left nothing changed. Retry. */
|
|
10648
|
+
503: {
|
|
10649
|
+
headers: {
|
|
10650
|
+
[name: string]: unknown;
|
|
10651
|
+
};
|
|
10652
|
+
content: {
|
|
10653
|
+
"application/json": {
|
|
10654
|
+
error: {
|
|
10655
|
+
/** @enum {string} */
|
|
10656
|
+
code: "revoke_failed";
|
|
10657
|
+
message: string;
|
|
10658
|
+
details?: {
|
|
10659
|
+
[key: string]: unknown;
|
|
10660
|
+
};
|
|
10661
|
+
};
|
|
10662
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10663
|
+
request_id: string | null;
|
|
10664
|
+
};
|
|
10665
|
+
};
|
|
10666
|
+
};
|
|
10667
|
+
};
|
|
10668
|
+
};
|
|
10669
|
+
delete?: never;
|
|
10670
|
+
options?: never;
|
|
10671
|
+
head?: never;
|
|
10672
|
+
patch?: never;
|
|
10673
|
+
trace?: never;
|
|
10674
|
+
};
|
|
10675
|
+
"/v1/connections/subaccount/{id}/status": {
|
|
10676
|
+
parameters: {
|
|
10677
|
+
query?: never;
|
|
10678
|
+
header?: never;
|
|
10679
|
+
path?: never;
|
|
10680
|
+
cookie?: never;
|
|
10681
|
+
};
|
|
10682
|
+
/**
|
|
10683
|
+
* Read whether a provisioned subaccount can transact yet
|
|
10684
|
+
* @description Read-only, with one live call to the provider. It writes nothing and changes no state.
|
|
10685
|
+
*
|
|
10686
|
+
* `charges_enabled` is what the provider says right now, not a cached flag, which is why a provider that is unreachable answers 502 rather than a stale `false`. The one exception is a revoked record: it short-circuits to `status: "revoked"` and `charges_enabled: false` without calling the provider at all, since there is nothing left to poll. A confirmed account that never reached an upstream account ref reports not-yet-chargeable for the same reason.
|
|
10687
|
+
*
|
|
10688
|
+
* `capabilities` carries the provider's per-capability activation states when it reports them, and is absent when it does not. An account can be provisioned and still not chargeable; gate any money movement on `charges_enabled`, not on the existence of the connection.
|
|
10689
|
+
*
|
|
10690
|
+
* Same dual-id resolution and same cross-tenant 404 as the revoke beside it, minus its admin floor: a read does not need one.
|
|
10691
|
+
*/
|
|
10692
|
+
get: {
|
|
10693
|
+
parameters: {
|
|
10694
|
+
query?: never;
|
|
10695
|
+
header?: never;
|
|
10696
|
+
path: {
|
|
10697
|
+
/** @description A `ca_` connection id, or a `pr_` provisioning record id on the operator-internal path. */
|
|
10698
|
+
id: string;
|
|
10699
|
+
};
|
|
10700
|
+
cookie?: never;
|
|
10701
|
+
};
|
|
10702
|
+
requestBody?: never;
|
|
10703
|
+
responses: {
|
|
10704
|
+
/** @description OK */
|
|
10705
|
+
200: {
|
|
10706
|
+
headers: {
|
|
10707
|
+
[name: string]: unknown;
|
|
10708
|
+
};
|
|
10709
|
+
content: {
|
|
10710
|
+
"application/json": {
|
|
10711
|
+
/** @enum {string} */
|
|
10712
|
+
status: "provisioned" | "revoked";
|
|
10713
|
+
charges_enabled: boolean;
|
|
10714
|
+
/** @description Per-capability activation states as the provider reports them, for example `card_payments: "active"`. */
|
|
10715
|
+
capabilities?: {
|
|
10716
|
+
[key: string]: string;
|
|
10717
|
+
};
|
|
10718
|
+
/** @description The upstream account identifier. Empty string when the record never reached one. */
|
|
10719
|
+
account_ref: string;
|
|
10720
|
+
};
|
|
10721
|
+
};
|
|
10722
|
+
};
|
|
10723
|
+
/** @description No connection or operator-internal record with that id is reachable by this caller. */
|
|
10724
|
+
404: {
|
|
10725
|
+
headers: {
|
|
10726
|
+
[name: string]: unknown;
|
|
10727
|
+
};
|
|
10728
|
+
content: {
|
|
10729
|
+
"application/json": {
|
|
10730
|
+
error: {
|
|
10731
|
+
/** @enum {string} */
|
|
10732
|
+
code: "not_found";
|
|
10733
|
+
message: string;
|
|
10734
|
+
};
|
|
10735
|
+
};
|
|
10736
|
+
};
|
|
10737
|
+
};
|
|
10738
|
+
/** @description The status read threw unexpectedly. */
|
|
10739
|
+
500: {
|
|
10740
|
+
headers: {
|
|
10741
|
+
[name: string]: unknown;
|
|
10742
|
+
};
|
|
10743
|
+
content: {
|
|
10744
|
+
"application/json": {
|
|
10745
|
+
error: {
|
|
10746
|
+
/** @enum {string} */
|
|
10747
|
+
code: "status_failed";
|
|
10748
|
+
message: string;
|
|
10749
|
+
details?: {
|
|
10750
|
+
[key: string]: unknown;
|
|
10751
|
+
};
|
|
10752
|
+
};
|
|
10753
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10754
|
+
request_id: string | null;
|
|
10755
|
+
};
|
|
10756
|
+
};
|
|
10757
|
+
};
|
|
10758
|
+
/** @description The provider read did not produce a status. Usually the live call failed or timed out, and a retry is the right response. TWO OF THE CASES BEHIND THIS CODE ARE NOT TRANSIENT and retrying never clears them: the provider has no subaccount descriptor in this deployment, and no platform account credential is registered for it. Both are configuration defects on our side; `error.message` distinguishes them from a provider outage. */
|
|
10759
|
+
502: {
|
|
10760
|
+
headers: {
|
|
10761
|
+
[name: string]: unknown;
|
|
10762
|
+
};
|
|
10763
|
+
content: {
|
|
10764
|
+
"application/json": {
|
|
10765
|
+
error: {
|
|
10766
|
+
/** @enum {string} */
|
|
10767
|
+
code: "status_failed";
|
|
10768
|
+
message: string;
|
|
10769
|
+
details?: {
|
|
10770
|
+
[key: string]: unknown;
|
|
10771
|
+
};
|
|
10772
|
+
};
|
|
10773
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10774
|
+
request_id: string | null;
|
|
10775
|
+
};
|
|
10776
|
+
};
|
|
10777
|
+
};
|
|
10778
|
+
};
|
|
10779
|
+
};
|
|
10780
|
+
put?: never;
|
|
10781
|
+
post?: never;
|
|
10782
|
+
delete?: never;
|
|
10783
|
+
options?: never;
|
|
10784
|
+
head?: never;
|
|
10785
|
+
patch?: never;
|
|
10786
|
+
trace?: never;
|
|
10787
|
+
};
|
|
10788
|
+
"/v1/consents": {
|
|
10789
|
+
parameters: {
|
|
10790
|
+
query?: never;
|
|
10791
|
+
header?: never;
|
|
10792
|
+
path?: never;
|
|
10793
|
+
cookie?: never;
|
|
10794
|
+
};
|
|
10795
|
+
get?: never;
|
|
10796
|
+
put?: never;
|
|
10797
|
+
/**
|
|
10798
|
+
* Start a hosted consent
|
|
10799
|
+
* @description Starts a hosted consent for a consumer mandate. The partner's backend calls this with its API key and gets a one-shot token carrying the intent the consumer is about to authorize (purpose, total and per-transaction caps, currency, mandate TTL and the merchant, withdrawal and DDA allowlists that will be signed into the mandate). The partner composes the URL of the hosted consent page from the token and hands it to the consumer.
|
|
10800
|
+
*
|
|
10801
|
+
* The consumer signs on the hosted page. The mandate is created server-side when the consumer submits there: the consumer's secret is provisioned, the mandate is signed with it, the funding source and the consent record are written and the token is consumed, in one transaction. The API key never signs, and the page's own calls are not operations of this document: nothing a partner can call with a key produces a signed mandate.
|
|
10802
|
+
*
|
|
10803
|
+
* `intent.merchant_allowlist` defaults to `["*"]`, an explicit wildcard bounded by the caps, purpose and expiry; pass concrete Pix keys to narrow it. `intent.withdrawal_allowlist` and `intent.dda_allowlist` are deliberately NOT defaulted: absent means the mandate authorizes no cash-out and no DDA registration, which is a different thing from a wildcard, and `"*"` is refused in both. `callback_url`, when given, is returned to the hosted page at submit time so the partner's backend can receive the signed mandate.
|
|
10804
|
+
*
|
|
10805
|
+
* The token is stamped with the credential's project, and that stamp is what scopes the funding source the consumer's submission later creates.
|
|
10806
|
+
*
|
|
10807
|
+
* Requires the `consents:write` scope.
|
|
10808
|
+
*/
|
|
10809
|
+
post: {
|
|
10810
|
+
parameters: {
|
|
10811
|
+
query?: never;
|
|
10812
|
+
header?: never;
|
|
10813
|
+
path?: never;
|
|
10814
|
+
cookie?: never;
|
|
10815
|
+
};
|
|
10816
|
+
requestBody?: {
|
|
10817
|
+
content: {
|
|
10818
|
+
"application/json": {
|
|
10819
|
+
agent_id: string;
|
|
10820
|
+
/** Format: email */
|
|
10821
|
+
consumer_email_hint?: string;
|
|
10822
|
+
intent: {
|
|
10823
|
+
purpose: string;
|
|
10824
|
+
cap_minor: number;
|
|
10825
|
+
per_tx_cap_minor: number;
|
|
10826
|
+
/** @enum {string} */
|
|
10827
|
+
currency: "BRL" | "USD" | "MXN" | "COP" | "ARS" | "USDC" | "BRLA";
|
|
10828
|
+
mandate_ttl_seconds: number;
|
|
10829
|
+
/**
|
|
10830
|
+
* @default [
|
|
10831
|
+
* "*"
|
|
10832
|
+
* ]
|
|
10833
|
+
*/
|
|
10834
|
+
merchant_allowlist?: string[];
|
|
10835
|
+
/**
|
|
10836
|
+
* @default pix-key
|
|
10837
|
+
* @enum {string}
|
|
10838
|
+
*/
|
|
10839
|
+
merchant_pin_kind?: "pix-key" | "merchant-id" | "mcc";
|
|
10840
|
+
withdrawal_allowlist?: string[];
|
|
10841
|
+
dda_allowlist?: string[];
|
|
10842
|
+
slots?: {
|
|
10843
|
+
/** @enum {string} */
|
|
10844
|
+
currency: "BRL" | "USD" | "MXN" | "COP" | "ARS" | "USDC" | "BRLA";
|
|
10845
|
+
rail: string;
|
|
10846
|
+
cap_minor: number;
|
|
10847
|
+
per_tx_cap_minor: number;
|
|
10848
|
+
}[];
|
|
10849
|
+
display_name?: string;
|
|
10850
|
+
intent_note?: string;
|
|
10851
|
+
shipping?: {
|
|
10852
|
+
[key: string]: unknown;
|
|
10853
|
+
};
|
|
10854
|
+
};
|
|
10855
|
+
/** Format: uri */
|
|
10856
|
+
callback_url?: string;
|
|
10857
|
+
};
|
|
10858
|
+
};
|
|
10859
|
+
};
|
|
10860
|
+
responses: {
|
|
10861
|
+
/** @description Created. The consent is pending until the consumer signs on the hosted page or the token expires. */
|
|
10862
|
+
201: {
|
|
10863
|
+
headers: {
|
|
10864
|
+
[name: string]: unknown;
|
|
10865
|
+
};
|
|
10866
|
+
content: {
|
|
10867
|
+
"application/json": {
|
|
10868
|
+
/** @description One-shot, `ctk_`-prefixed, unguessable. Put it in the URL of the hosted consent page and hand that URL to the consumer. It is consumed by the consumer's submission and cannot be replayed. */
|
|
10869
|
+
token: string;
|
|
10870
|
+
/** @description ISO 8601. The token expires 24 hours after this call; a consumer opening the link after that sees an expired consent and nothing is created. This is the TOKEN's TTL, not the mandate's: the mandate's own TTL is `intent.mandate_ttl_seconds`, counted from the moment the consumer signs. */
|
|
10871
|
+
expires_at: string;
|
|
10872
|
+
};
|
|
10873
|
+
};
|
|
10874
|
+
};
|
|
10875
|
+
/** @description The body did not match the schema. `details.issues` carries the Zod issues; the refusals with their own message are a `"*"` entry in `intent.withdrawal_allowlist` and a `intent.dda_allowlist` entry that is not a CPF (11 digits) or a CNPJ (14 digits). */
|
|
10876
|
+
400: {
|
|
10877
|
+
headers: {
|
|
10878
|
+
[name: string]: unknown;
|
|
10879
|
+
};
|
|
10880
|
+
content: {
|
|
10881
|
+
"application/json": {
|
|
10882
|
+
error: {
|
|
10883
|
+
/** @enum {string} */
|
|
10884
|
+
code: "invalid_body";
|
|
10885
|
+
message: string;
|
|
10886
|
+
details?: {
|
|
10887
|
+
[key: string]: unknown;
|
|
10888
|
+
};
|
|
10889
|
+
};
|
|
10890
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
10891
|
+
request_id: string | null;
|
|
10892
|
+
};
|
|
10893
|
+
};
|
|
10894
|
+
};
|
|
10895
|
+
};
|
|
10896
|
+
};
|
|
10897
|
+
delete?: never;
|
|
10898
|
+
options?: never;
|
|
10899
|
+
head?: never;
|
|
10900
|
+
patch?: never;
|
|
10901
|
+
trace?: never;
|
|
10902
|
+
};
|
|
10903
|
+
"/v1/consents/init": {
|
|
10904
|
+
parameters: {
|
|
10905
|
+
query?: never;
|
|
10906
|
+
header?: never;
|
|
10907
|
+
path?: never;
|
|
10908
|
+
cookie?: never;
|
|
10909
|
+
};
|
|
10910
|
+
get?: never;
|
|
10911
|
+
put?: never;
|
|
10912
|
+
/**
|
|
10913
|
+
* Start a hosted consent
|
|
10914
|
+
* @deprecated
|
|
10915
|
+
* @description DEPRECATED alias of `POST /v1/consents` (ent#979), kept for two releases. Same handler, same required scope, same request and same responses; switch the path and nothing else changes. The canonical path is described in this document too.
|
|
10916
|
+
*
|
|
10917
|
+
* Starts a hosted consent for a consumer mandate. The partner's backend calls this with its API key and gets a one-shot token carrying the intent the consumer is about to authorize (purpose, total and per-transaction caps, currency, mandate TTL and the merchant, withdrawal and DDA allowlists that will be signed into the mandate). The partner composes the URL of the hosted consent page from the token and hands it to the consumer.
|
|
10918
|
+
*
|
|
10919
|
+
* The consumer signs on the hosted page. The mandate is created server-side when the consumer submits there: the consumer's secret is provisioned, the mandate is signed with it, the funding source and the consent record are written and the token is consumed, in one transaction. The API key never signs, and the page's own calls are not operations of this document: nothing a partner can call with a key produces a signed mandate.
|
|
10920
|
+
*
|
|
10921
|
+
* `intent.merchant_allowlist` defaults to `["*"]`, an explicit wildcard bounded by the caps, purpose and expiry; pass concrete Pix keys to narrow it. `intent.withdrawal_allowlist` and `intent.dda_allowlist` are deliberately NOT defaulted: absent means the mandate authorizes no cash-out and no DDA registration, which is a different thing from a wildcard, and `"*"` is refused in both. `callback_url`, when given, is returned to the hosted page at submit time so the partner's backend can receive the signed mandate.
|
|
10922
|
+
*
|
|
10923
|
+
* The token is stamped with the credential's project, and that stamp is what scopes the funding source the consumer's submission later creates.
|
|
10924
|
+
*
|
|
10925
|
+
* Requires the `consents:write` scope.
|
|
10926
|
+
*/
|
|
10927
|
+
post: {
|
|
10928
|
+
parameters: {
|
|
10929
|
+
query?: never;
|
|
10930
|
+
header?: never;
|
|
10931
|
+
path?: never;
|
|
10932
|
+
cookie?: never;
|
|
10933
|
+
};
|
|
10934
|
+
requestBody?: {
|
|
10935
|
+
content: {
|
|
10936
|
+
"application/json": {
|
|
10937
|
+
agent_id: string;
|
|
10938
|
+
/** Format: email */
|
|
10939
|
+
consumer_email_hint?: string;
|
|
10940
|
+
intent: {
|
|
10941
|
+
purpose: string;
|
|
10942
|
+
cap_minor: number;
|
|
10943
|
+
per_tx_cap_minor: number;
|
|
10944
|
+
/** @enum {string} */
|
|
10945
|
+
currency: "BRL" | "USD" | "MXN" | "COP" | "ARS" | "USDC" | "BRLA";
|
|
10946
|
+
mandate_ttl_seconds: number;
|
|
10947
|
+
/**
|
|
10948
|
+
* @default [
|
|
10949
|
+
* "*"
|
|
10950
|
+
* ]
|
|
10951
|
+
*/
|
|
10952
|
+
merchant_allowlist?: string[];
|
|
10953
|
+
/**
|
|
10954
|
+
* @default pix-key
|
|
10955
|
+
* @enum {string}
|
|
10956
|
+
*/
|
|
10957
|
+
merchant_pin_kind?: "pix-key" | "merchant-id" | "mcc";
|
|
10958
|
+
withdrawal_allowlist?: string[];
|
|
10959
|
+
dda_allowlist?: string[];
|
|
10960
|
+
slots?: {
|
|
10961
|
+
/** @enum {string} */
|
|
10962
|
+
currency: "BRL" | "USD" | "MXN" | "COP" | "ARS" | "USDC" | "BRLA";
|
|
10963
|
+
rail: string;
|
|
10964
|
+
cap_minor: number;
|
|
10965
|
+
per_tx_cap_minor: number;
|
|
10966
|
+
}[];
|
|
10967
|
+
display_name?: string;
|
|
10968
|
+
intent_note?: string;
|
|
10969
|
+
shipping?: {
|
|
10970
|
+
[key: string]: unknown;
|
|
10971
|
+
};
|
|
10972
|
+
};
|
|
10973
|
+
/** Format: uri */
|
|
10974
|
+
callback_url?: string;
|
|
10975
|
+
};
|
|
10976
|
+
};
|
|
10977
|
+
};
|
|
10978
|
+
responses: {
|
|
10979
|
+
/** @description Created. The consent is pending until the consumer signs on the hosted page or the token expires. */
|
|
10980
|
+
201: {
|
|
10981
|
+
headers: {
|
|
10982
|
+
[name: string]: unknown;
|
|
10983
|
+
};
|
|
10984
|
+
content: {
|
|
10985
|
+
"application/json": {
|
|
10986
|
+
/** @description One-shot, `ctk_`-prefixed, unguessable. Put it in the URL of the hosted consent page and hand that URL to the consumer. It is consumed by the consumer's submission and cannot be replayed. */
|
|
10987
|
+
token: string;
|
|
10988
|
+
/** @description ISO 8601. The token expires 24 hours after this call; a consumer opening the link after that sees an expired consent and nothing is created. This is the TOKEN's TTL, not the mandate's: the mandate's own TTL is `intent.mandate_ttl_seconds`, counted from the moment the consumer signs. */
|
|
10989
|
+
expires_at: string;
|
|
10990
|
+
};
|
|
10991
|
+
};
|
|
10992
|
+
};
|
|
10993
|
+
/** @description The body did not match the schema. `details.issues` carries the Zod issues; the refusals with their own message are a `"*"` entry in `intent.withdrawal_allowlist` and a `intent.dda_allowlist` entry that is not a CPF (11 digits) or a CNPJ (14 digits). */
|
|
10994
|
+
400: {
|
|
10995
|
+
headers: {
|
|
10996
|
+
[name: string]: unknown;
|
|
10997
|
+
};
|
|
10998
|
+
content: {
|
|
10999
|
+
"application/json": {
|
|
11000
|
+
error: {
|
|
11001
|
+
/** @enum {string} */
|
|
11002
|
+
code: "invalid_body";
|
|
11003
|
+
message: string;
|
|
11004
|
+
details?: {
|
|
11005
|
+
[key: string]: unknown;
|
|
11006
|
+
};
|
|
11007
|
+
};
|
|
11008
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11009
|
+
request_id: string | null;
|
|
11010
|
+
};
|
|
11011
|
+
};
|
|
11012
|
+
};
|
|
11013
|
+
};
|
|
11014
|
+
};
|
|
11015
|
+
delete?: never;
|
|
11016
|
+
options?: never;
|
|
11017
|
+
head?: never;
|
|
11018
|
+
patch?: never;
|
|
11019
|
+
trace?: never;
|
|
11020
|
+
};
|
|
11021
|
+
"/v1/consumers/mandates/{id}/spend": {
|
|
11022
|
+
parameters: {
|
|
11023
|
+
query?: never;
|
|
11024
|
+
header?: never;
|
|
11025
|
+
path?: never;
|
|
11026
|
+
cookie?: never;
|
|
11027
|
+
};
|
|
11028
|
+
get?: never;
|
|
11029
|
+
put?: never;
|
|
11030
|
+
/**
|
|
11031
|
+
* Spend under a mandate already projected here
|
|
11032
|
+
* @description Moves money out under a mandate already projected into this organization, addressed by id. This is the path the `codespar_pay` meta-tool takes internally, so the behaviour here is the behaviour an agent gets; the route exists so a caller who does not use the SDK reaches the same place.
|
|
11033
|
+
*
|
|
11034
|
+
* With `ted` present the provider leg is a real bank transfer, debited from the consumer's own sub-account. Without `ted`, `payee` is a Pix key or a copy-and-paste string.
|
|
11035
|
+
*
|
|
11036
|
+
* **TED carries three requirements the other payment methods do not, and all three bind BEFORE any money step:**
|
|
11037
|
+
*
|
|
11038
|
+
* 1. `attempt_id` is MANDATORY. A TED has no copy-and-paste string and no nonce to derive correlation from, and two TEDs under the same mandate must never collide on a derived id.
|
|
11039
|
+
* 2. `payee` must EQUAL the destination's canonical string, `ted:<ispb>:<branch>:<account>`, alphanumerics only and upper-cased. The comparison normalizes whitespace and nothing else, so an entry carrying a dot or a hyphen does NOT match. The rule is what makes the signed-allowlist pin and the wire name the SAME destination: without it, an approved payee fronts for a different bank account.
|
|
11040
|
+
* 3. The destination must be NAMED in a signed list of the mandate, and a merchant-list wildcard `"*"` NEVER authorizes money out. Which list is accepted is mid-rollout, so read this one carefully: the target rule is `withdrawal_allowlist` alone, and while the rollout flag is off a destination named explicitly in the signed `merchant_allowlist` is ALSO accepted, with the stricter rule's refusal recorded rather than applied. Tolerance never widens what passes: a wildcard is refused on both paths, and a destination in neither list is refused with its own code. Build against `withdrawal_allowlist`: it is the list that keeps working when the flag turns on.
|
|
11041
|
+
*
|
|
11042
|
+
* The cumulative cap is checked and CONSUMED under an advisory lock, and the wallet hold is taken inside that same lock. The lock is released before the provider call, so a slow provider does not serialize everyone else.
|
|
11043
|
+
*
|
|
11044
|
+
* **There is no read route for the outcome.** An `attempt_id` that answered `psp_dispatch_uncertain` has no endpoint to ask about afterwards. Keep the `attempt_id` and present it again: the lifecycle is idempotent on it and answers the state that attempt stopped in, instead of firing a second one. Do NOT restart the same intent under a fresh `attempt_id`. That is how a payment gets made twice.
|
|
11045
|
+
*/
|
|
11046
|
+
post: {
|
|
11047
|
+
parameters: {
|
|
11048
|
+
query?: never;
|
|
11049
|
+
header?: never;
|
|
11050
|
+
path: {
|
|
11051
|
+
/** @description The mandate's id. */
|
|
11052
|
+
id: string;
|
|
11053
|
+
};
|
|
11054
|
+
cookie?: never;
|
|
11055
|
+
};
|
|
11056
|
+
requestBody?: {
|
|
11057
|
+
content: {
|
|
11058
|
+
"application/json": {
|
|
11059
|
+
/** @description Amount in minor units. */
|
|
11060
|
+
amount_minor: number;
|
|
11061
|
+
/** @description A Pix key, a copy-and-paste string, or, for TED, the destination's canonical string. The 1024 limit is there to fit a copy-and-paste string. */
|
|
11062
|
+
payee: string;
|
|
11063
|
+
agent_id?: string;
|
|
11064
|
+
/** @description Mandatory when `ted` is present. Present the same one again on every retry. */
|
|
11065
|
+
attempt_id?: string;
|
|
11066
|
+
ted?: components["schemas"]["TedDestination"];
|
|
11067
|
+
quote?: components["schemas"]["SpendQuote"];
|
|
11068
|
+
};
|
|
11069
|
+
};
|
|
11070
|
+
};
|
|
11071
|
+
responses: {
|
|
11072
|
+
/** @description OK */
|
|
11073
|
+
200: {
|
|
11074
|
+
headers: {
|
|
11075
|
+
[name: string]: unknown;
|
|
11076
|
+
};
|
|
11077
|
+
content: {
|
|
11078
|
+
"application/json": components["schemas"]["SpendOutcome"];
|
|
11079
|
+
};
|
|
11080
|
+
};
|
|
11081
|
+
/** @description The body did not match the schema. */
|
|
11082
|
+
400: {
|
|
11083
|
+
headers: {
|
|
11084
|
+
[name: string]: unknown;
|
|
11085
|
+
};
|
|
11086
|
+
content: {
|
|
11087
|
+
"application/json": {
|
|
11088
|
+
error: {
|
|
11089
|
+
/** @enum {string} */
|
|
11090
|
+
code: "invalid_body";
|
|
11091
|
+
message: string;
|
|
11092
|
+
details?: {
|
|
11093
|
+
[key: string]: unknown;
|
|
11094
|
+
};
|
|
11095
|
+
};
|
|
11096
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11097
|
+
request_id: string | null;
|
|
11098
|
+
};
|
|
11099
|
+
};
|
|
11100
|
+
};
|
|
11101
|
+
/** @description The destination is not on the mandate's signed withdrawal allowlist. Nothing was sent to the provider. The response carries the next consent step. */
|
|
11102
|
+
403: {
|
|
11103
|
+
headers: {
|
|
11104
|
+
[name: string]: unknown;
|
|
11105
|
+
};
|
|
11106
|
+
content: {
|
|
11107
|
+
"application/json": {
|
|
11108
|
+
error: {
|
|
11109
|
+
/** @enum {string} */
|
|
11110
|
+
code: "withdrawal_pin";
|
|
11111
|
+
message: string;
|
|
11112
|
+
details?: {
|
|
11113
|
+
[key: string]: unknown;
|
|
11114
|
+
};
|
|
11115
|
+
};
|
|
11116
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11117
|
+
request_id: string | null;
|
|
11118
|
+
};
|
|
11119
|
+
};
|
|
11120
|
+
};
|
|
11121
|
+
/** @description No mandate with that id exists in this organization. */
|
|
11122
|
+
404: {
|
|
11123
|
+
headers: {
|
|
11124
|
+
[name: string]: unknown;
|
|
11125
|
+
};
|
|
11126
|
+
content: {
|
|
11127
|
+
"application/json": {
|
|
11128
|
+
error: {
|
|
11129
|
+
/** @enum {string} */
|
|
11130
|
+
code: "mandate_not_found";
|
|
11131
|
+
message: string;
|
|
11132
|
+
details?: {
|
|
11133
|
+
[key: string]: unknown;
|
|
11134
|
+
};
|
|
11135
|
+
};
|
|
11136
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11137
|
+
request_id: string | null;
|
|
11138
|
+
};
|
|
11139
|
+
};
|
|
11140
|
+
};
|
|
11141
|
+
/** @description Local state refuses. `psp_attempt_in_flight`: the same attempt is already in flight. `psp_attempt_uncertain`: an earlier attempt ended with an unknown outcome and this intent is PINNED to it, so present the same `attempt_id` again, never a new one. `psp_attempt_conflict`: the earlier attempt was already compensated. */
|
|
11142
|
+
409: {
|
|
11143
|
+
headers: {
|
|
11144
|
+
[name: string]: unknown;
|
|
11145
|
+
};
|
|
11146
|
+
content: {
|
|
11147
|
+
"application/json": {
|
|
11148
|
+
error: {
|
|
11149
|
+
/** @enum {string} */
|
|
11150
|
+
code: "psp_attempt_in_flight" | "psp_attempt_uncertain" | "psp_attempt_conflict";
|
|
11151
|
+
message: string;
|
|
11152
|
+
details?: {
|
|
11153
|
+
[key: string]: unknown;
|
|
11154
|
+
};
|
|
11155
|
+
};
|
|
11156
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11157
|
+
request_id: string | null;
|
|
11158
|
+
};
|
|
11159
|
+
};
|
|
11160
|
+
};
|
|
11161
|
+
/** @description The mandate refuses. `mandate_verify`: signature, agent, purpose or payee do not check out. `mandate_projection_mismatch`: the signature presented differs from the stored one, or the mandate is not active. `no_funding_source`: the consumer has no funding source that serves this rail; TED requires a registered bank account. */
|
|
11162
|
+
422: {
|
|
11163
|
+
headers: {
|
|
11164
|
+
[name: string]: unknown;
|
|
11165
|
+
};
|
|
11166
|
+
content: {
|
|
11167
|
+
"application/json": {
|
|
11168
|
+
error: {
|
|
11169
|
+
/** @enum {string} */
|
|
11170
|
+
code: "mandate_verify" | "mandate_projection_mismatch" | "no_funding_source";
|
|
11171
|
+
message: string;
|
|
11172
|
+
details?: {
|
|
11173
|
+
[key: string]: unknown;
|
|
11174
|
+
};
|
|
11175
|
+
};
|
|
11176
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11177
|
+
request_id: string | null;
|
|
11178
|
+
};
|
|
11179
|
+
};
|
|
11180
|
+
};
|
|
11181
|
+
/** @description The verifier answered without resolving the cumulative cap, so the re-check under the lock would have no limit to compare against. A deliberate refusal: nothing is debited. */
|
|
11182
|
+
500: {
|
|
11183
|
+
headers: {
|
|
11184
|
+
[name: string]: unknown;
|
|
11185
|
+
};
|
|
11186
|
+
content: {
|
|
11187
|
+
"application/json": {
|
|
11188
|
+
error: {
|
|
11189
|
+
/** @enum {string} */
|
|
11190
|
+
code: "mandate_cap_unresolved";
|
|
11191
|
+
message: string;
|
|
11192
|
+
details?: {
|
|
11193
|
+
[key: string]: unknown;
|
|
11194
|
+
};
|
|
11195
|
+
};
|
|
11196
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11197
|
+
request_id: string | null;
|
|
11198
|
+
};
|
|
11199
|
+
};
|
|
11200
|
+
};
|
|
11201
|
+
/** @description The provider refused or did not answer. `psp_dispatch_failed`: a known refusal, nothing left. `psp_dispatch_uncertain`: it is NOT known whether anything left, so the hold stands and the attempt stays pinned. */
|
|
11202
|
+
502: {
|
|
11203
|
+
headers: {
|
|
11204
|
+
[name: string]: unknown;
|
|
11205
|
+
};
|
|
11206
|
+
content: {
|
|
11207
|
+
"application/json": {
|
|
11208
|
+
error: {
|
|
11209
|
+
/** @enum {string} */
|
|
11210
|
+
code: "psp_dispatch_failed" | "psp_dispatch_uncertain";
|
|
11211
|
+
message: string;
|
|
11212
|
+
details?: {
|
|
11213
|
+
[key: string]: unknown;
|
|
11214
|
+
};
|
|
11215
|
+
};
|
|
11216
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11217
|
+
request_id: string | null;
|
|
11218
|
+
};
|
|
11219
|
+
};
|
|
11220
|
+
};
|
|
11221
|
+
};
|
|
11222
|
+
};
|
|
11223
|
+
delete?: never;
|
|
11224
|
+
options?: never;
|
|
11225
|
+
head?: never;
|
|
11226
|
+
patch?: never;
|
|
11227
|
+
trace?: never;
|
|
11228
|
+
};
|
|
11229
|
+
"/v1/consumer-payments/execute": {
|
|
11230
|
+
parameters: {
|
|
11231
|
+
query?: never;
|
|
11232
|
+
header?: never;
|
|
11233
|
+
path?: never;
|
|
11234
|
+
cookie?: never;
|
|
11235
|
+
};
|
|
11236
|
+
get?: never;
|
|
11237
|
+
put?: never;
|
|
11238
|
+
/**
|
|
11239
|
+
* Spend by presenting the signed mandate
|
|
11240
|
+
* @description The same lifecycle as the by-id route, for a caller who carries the signed envelope instead of a mandate already projected here. Use this one when the mandate arrives from the consumer at call time; use `/consumers/mandates/{id}/spend` when it is already registered here.
|
|
11241
|
+
*
|
|
11242
|
+
* `signature` is the 64-character hexadecimal HMAC over the canonical mandate. The body's `agent_id` is checked against the SIGNED one: attribution of the spend belongs to the mandate, not to the caller.
|
|
11243
|
+
*
|
|
11244
|
+
* **TED carries three requirements the other payment methods do not, and all three bind BEFORE any money step:**
|
|
11245
|
+
*
|
|
11246
|
+
* 1. `attempt_id` is MANDATORY. A TED has no copy-and-paste string and no nonce to derive correlation from, and two TEDs under the same mandate must never collide on a derived id.
|
|
11247
|
+
* 2. `payee` must EQUAL the destination's canonical string, `ted:<ispb>:<branch>:<account>`, alphanumerics only and upper-cased. The comparison normalizes whitespace and nothing else, so an entry carrying a dot or a hyphen does NOT match. The rule is what makes the signed-allowlist pin and the wire name the SAME destination: without it, an approved payee fronts for a different bank account.
|
|
11248
|
+
* 3. The destination must be NAMED in a signed list of the mandate, and a merchant-list wildcard `"*"` NEVER authorizes money out. Which list is accepted is mid-rollout, so read this one carefully: the target rule is `withdrawal_allowlist` alone, and while the rollout flag is off a destination named explicitly in the signed `merchant_allowlist` is ALSO accepted, with the stricter rule's refusal recorded rather than applied. Tolerance never widens what passes: a wildcard is refused on both paths, and a destination in neither list is refused with its own code. Build against `withdrawal_allowlist`: it is the list that keeps working when the flag turns on.
|
|
11249
|
+
*
|
|
11250
|
+
* **There is no read route for the outcome.** An `attempt_id` that answered `psp_dispatch_uncertain` has no endpoint to ask about afterwards. Keep the `attempt_id` and present it again: the lifecycle is idempotent on it and answers the state that attempt stopped in, instead of firing a second one. Do NOT restart the same intent under a fresh `attempt_id`. That is how a payment gets made twice.
|
|
11251
|
+
*/
|
|
11252
|
+
post: {
|
|
11253
|
+
parameters: {
|
|
11254
|
+
query?: never;
|
|
11255
|
+
header?: never;
|
|
11256
|
+
path?: never;
|
|
11257
|
+
cookie?: never;
|
|
11258
|
+
};
|
|
11259
|
+
requestBody?: {
|
|
11260
|
+
content: {
|
|
11261
|
+
"application/json": {
|
|
11262
|
+
/** @description The canonical mandate, in the form it was signed in. */
|
|
11263
|
+
mandate?: unknown;
|
|
11264
|
+
/** @description HMAC in hexadecimal, 64 characters. */
|
|
11265
|
+
signature: string;
|
|
11266
|
+
amount_minor: number;
|
|
11267
|
+
purpose: string;
|
|
11268
|
+
agent_id: string;
|
|
11269
|
+
payee: string;
|
|
11270
|
+
attempt_id?: string;
|
|
11271
|
+
ted?: components["schemas"]["TedDestination"];
|
|
11272
|
+
quote?: components["schemas"]["SpendQuote"];
|
|
11273
|
+
};
|
|
11274
|
+
};
|
|
11275
|
+
};
|
|
11276
|
+
responses: {
|
|
11277
|
+
/** @description OK */
|
|
11278
|
+
200: {
|
|
11279
|
+
headers: {
|
|
11280
|
+
[name: string]: unknown;
|
|
11281
|
+
};
|
|
11282
|
+
content: {
|
|
11283
|
+
"application/json": components["schemas"]["SpendOutcome"];
|
|
11284
|
+
};
|
|
11285
|
+
};
|
|
11286
|
+
/** @description The body did not match the schema. */
|
|
11287
|
+
400: {
|
|
11288
|
+
headers: {
|
|
11289
|
+
[name: string]: unknown;
|
|
11290
|
+
};
|
|
11291
|
+
content: {
|
|
11292
|
+
"application/json": {
|
|
11293
|
+
error: {
|
|
11294
|
+
/** @enum {string} */
|
|
11295
|
+
code: "invalid_body";
|
|
11296
|
+
message: string;
|
|
11297
|
+
details?: {
|
|
11298
|
+
[key: string]: unknown;
|
|
11299
|
+
};
|
|
11300
|
+
};
|
|
11301
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11302
|
+
request_id: string | null;
|
|
11303
|
+
};
|
|
11304
|
+
};
|
|
11305
|
+
};
|
|
11306
|
+
/** @description The destination is not on the signed withdrawal allowlist. Nothing was sent to the provider. */
|
|
11307
|
+
403: {
|
|
11308
|
+
headers: {
|
|
11309
|
+
[name: string]: unknown;
|
|
11310
|
+
};
|
|
11311
|
+
content: {
|
|
11312
|
+
"application/json": {
|
|
11313
|
+
error: {
|
|
11314
|
+
/** @enum {string} */
|
|
11315
|
+
code: "withdrawal_pin";
|
|
11316
|
+
message: string;
|
|
11317
|
+
details?: {
|
|
11318
|
+
[key: string]: unknown;
|
|
11319
|
+
};
|
|
11320
|
+
};
|
|
11321
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11322
|
+
request_id: string | null;
|
|
11323
|
+
};
|
|
11324
|
+
};
|
|
11325
|
+
};
|
|
11326
|
+
/** @description Local state refuses, on the same three conditions as the by-id route. */
|
|
11327
|
+
409: {
|
|
11328
|
+
headers: {
|
|
11329
|
+
[name: string]: unknown;
|
|
11330
|
+
};
|
|
11331
|
+
content: {
|
|
11332
|
+
"application/json": {
|
|
11333
|
+
error: {
|
|
11334
|
+
/** @enum {string} */
|
|
11335
|
+
code: "psp_attempt_in_flight" | "psp_attempt_uncertain" | "psp_attempt_conflict";
|
|
11336
|
+
message: string;
|
|
11337
|
+
details?: {
|
|
11338
|
+
[key: string]: unknown;
|
|
11339
|
+
};
|
|
11340
|
+
};
|
|
11341
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11342
|
+
request_id: string | null;
|
|
11343
|
+
};
|
|
11344
|
+
};
|
|
11345
|
+
};
|
|
11346
|
+
/** @description The mandate refuses, or the consumer has no funding source for this rail. */
|
|
11347
|
+
422: {
|
|
11348
|
+
headers: {
|
|
11349
|
+
[name: string]: unknown;
|
|
11350
|
+
};
|
|
11351
|
+
content: {
|
|
11352
|
+
"application/json": {
|
|
11353
|
+
error: {
|
|
11354
|
+
/** @enum {string} */
|
|
11355
|
+
code: "mandate_verify" | "mandate_projection_mismatch" | "no_funding_source";
|
|
11356
|
+
message: string;
|
|
11357
|
+
details?: {
|
|
11358
|
+
[key: string]: unknown;
|
|
11359
|
+
};
|
|
11360
|
+
};
|
|
11361
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11362
|
+
request_id: string | null;
|
|
11363
|
+
};
|
|
11364
|
+
};
|
|
11365
|
+
};
|
|
11366
|
+
/** @description The cumulative cap was not resolved by the verifier. Nothing is debited. */
|
|
11367
|
+
500: {
|
|
11368
|
+
headers: {
|
|
11369
|
+
[name: string]: unknown;
|
|
11370
|
+
};
|
|
11371
|
+
content: {
|
|
11372
|
+
"application/json": {
|
|
11373
|
+
error: {
|
|
11374
|
+
/** @enum {string} */
|
|
11375
|
+
code: "mandate_cap_unresolved";
|
|
11376
|
+
message: string;
|
|
11377
|
+
details?: {
|
|
11378
|
+
[key: string]: unknown;
|
|
11379
|
+
};
|
|
11380
|
+
};
|
|
11381
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11382
|
+
request_id: string | null;
|
|
11383
|
+
};
|
|
11384
|
+
};
|
|
11385
|
+
};
|
|
11386
|
+
/** @description The provider refused, or the outcome is unknown. */
|
|
11387
|
+
502: {
|
|
11388
|
+
headers: {
|
|
11389
|
+
[name: string]: unknown;
|
|
11390
|
+
};
|
|
11391
|
+
content: {
|
|
11392
|
+
"application/json": {
|
|
11393
|
+
error: {
|
|
11394
|
+
/** @enum {string} */
|
|
11395
|
+
code: "psp_dispatch_failed" | "psp_dispatch_uncertain";
|
|
11396
|
+
message: string;
|
|
11397
|
+
details?: {
|
|
11398
|
+
[key: string]: unknown;
|
|
11399
|
+
};
|
|
11400
|
+
};
|
|
11401
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11402
|
+
request_id: string | null;
|
|
11403
|
+
};
|
|
11404
|
+
};
|
|
11405
|
+
};
|
|
11406
|
+
};
|
|
11407
|
+
};
|
|
11408
|
+
delete?: never;
|
|
11409
|
+
options?: never;
|
|
11410
|
+
head?: never;
|
|
11411
|
+
patch?: never;
|
|
11412
|
+
trace?: never;
|
|
11413
|
+
};
|
|
11414
|
+
"/v1/consumer-payments/execute-stream": {
|
|
11415
|
+
parameters: {
|
|
11416
|
+
query?: never;
|
|
11417
|
+
header?: never;
|
|
11418
|
+
path?: never;
|
|
11419
|
+
cookie?: never;
|
|
11420
|
+
};
|
|
11421
|
+
get?: never;
|
|
11422
|
+
put?: never;
|
|
11423
|
+
/**
|
|
11424
|
+
* Spend by presenting the mandate, with the steps streamed
|
|
11425
|
+
* @description Same body and same gates as `/v1/consumer-payments/execute`. Only the response transport differs: the lifecycle steps (mandate verification, funding-source routing, hold, provider debit, receipt seal) arrive as `text/event-stream` events as they happen, instead of one JSON at the end.
|
|
11426
|
+
*
|
|
11427
|
+
* The outcome is the same object the sibling route returns, carried on the last event. A client that does not need to follow progress should use `/execute`: streaming does not make settlement faster, it makes it observable while it runs.
|
|
11428
|
+
*
|
|
11429
|
+
* **There is no read route for the outcome.** An `attempt_id` that answered `psp_dispatch_uncertain` has no endpoint to ask about afterwards. Keep the `attempt_id` and present it again: the lifecycle is idempotent on it and answers the state that attempt stopped in, instead of firing a second one. Do NOT restart the same intent under a fresh `attempt_id`. That is how a payment gets made twice.
|
|
11430
|
+
*/
|
|
11431
|
+
post: {
|
|
11432
|
+
parameters: {
|
|
11433
|
+
query?: never;
|
|
11434
|
+
header?: never;
|
|
11435
|
+
path?: never;
|
|
11436
|
+
cookie?: never;
|
|
11437
|
+
};
|
|
11438
|
+
requestBody?: {
|
|
11439
|
+
content: {
|
|
11440
|
+
"application/json": {
|
|
11441
|
+
mandate?: unknown;
|
|
11442
|
+
signature: string;
|
|
11443
|
+
amount_minor: number;
|
|
11444
|
+
purpose: string;
|
|
11445
|
+
agent_id: string;
|
|
11446
|
+
payee: string;
|
|
11447
|
+
attempt_id?: string;
|
|
11448
|
+
ted?: components["schemas"]["TedDestination"];
|
|
11449
|
+
quote?: components["schemas"]["SpendQuote"];
|
|
11450
|
+
};
|
|
11451
|
+
};
|
|
11452
|
+
};
|
|
11453
|
+
responses: {
|
|
11454
|
+
/** @description An event stream. Each event is one lifecycle step; the last one carries the same outcome object `/execute` returns. */
|
|
11455
|
+
200: {
|
|
11456
|
+
headers: {
|
|
11457
|
+
[name: string]: unknown;
|
|
11458
|
+
};
|
|
11459
|
+
content: {
|
|
11460
|
+
"text/event-stream": string;
|
|
11461
|
+
};
|
|
11462
|
+
};
|
|
11463
|
+
/** @description The body did not match the schema. */
|
|
11464
|
+
400: {
|
|
11465
|
+
headers: {
|
|
11466
|
+
[name: string]: unknown;
|
|
11467
|
+
};
|
|
11468
|
+
content: {
|
|
11469
|
+
"application/json": {
|
|
11470
|
+
error: {
|
|
11471
|
+
/** @enum {string} */
|
|
11472
|
+
code: "invalid_body";
|
|
11473
|
+
message: string;
|
|
11474
|
+
details?: {
|
|
11475
|
+
[key: string]: unknown;
|
|
11476
|
+
};
|
|
11477
|
+
};
|
|
11478
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11479
|
+
request_id: string | null;
|
|
11480
|
+
};
|
|
11481
|
+
};
|
|
11482
|
+
};
|
|
11483
|
+
/** @description The destination is not on the signed withdrawal allowlist. */
|
|
11484
|
+
403: {
|
|
11485
|
+
headers: {
|
|
11486
|
+
[name: string]: unknown;
|
|
11487
|
+
};
|
|
11488
|
+
content: {
|
|
11489
|
+
"application/json": {
|
|
11490
|
+
error: {
|
|
11491
|
+
/** @enum {string} */
|
|
11492
|
+
code: "withdrawal_pin";
|
|
11493
|
+
message: string;
|
|
11494
|
+
details?: {
|
|
11495
|
+
[key: string]: unknown;
|
|
11496
|
+
};
|
|
11497
|
+
};
|
|
11498
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11499
|
+
request_id: string | null;
|
|
11500
|
+
};
|
|
11501
|
+
};
|
|
11502
|
+
};
|
|
11503
|
+
/** @description The mandate refuses, or there is no funding source for this rail. */
|
|
11504
|
+
422: {
|
|
11505
|
+
headers: {
|
|
11506
|
+
[name: string]: unknown;
|
|
11507
|
+
};
|
|
11508
|
+
content: {
|
|
11509
|
+
"application/json": {
|
|
11510
|
+
error: {
|
|
11511
|
+
/** @enum {string} */
|
|
11512
|
+
code: "mandate_verify" | "mandate_projection_mismatch" | "no_funding_source";
|
|
11513
|
+
message: string;
|
|
11514
|
+
details?: {
|
|
11515
|
+
[key: string]: unknown;
|
|
11516
|
+
};
|
|
11517
|
+
};
|
|
11518
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11519
|
+
request_id: string | null;
|
|
11520
|
+
};
|
|
11521
|
+
};
|
|
11522
|
+
};
|
|
11523
|
+
/** @description The provider refused, or the outcome is unknown. */
|
|
11524
|
+
502: {
|
|
11525
|
+
headers: {
|
|
11526
|
+
[name: string]: unknown;
|
|
11527
|
+
};
|
|
11528
|
+
content: {
|
|
11529
|
+
"application/json": {
|
|
11530
|
+
error: {
|
|
11531
|
+
/** @enum {string} */
|
|
11532
|
+
code: "psp_dispatch_failed" | "psp_dispatch_uncertain";
|
|
11533
|
+
message: string;
|
|
11534
|
+
details?: {
|
|
11535
|
+
[key: string]: unknown;
|
|
11536
|
+
};
|
|
11537
|
+
};
|
|
11538
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11539
|
+
request_id: string | null;
|
|
11540
|
+
};
|
|
11541
|
+
};
|
|
11542
|
+
};
|
|
11543
|
+
};
|
|
11544
|
+
};
|
|
11545
|
+
delete?: never;
|
|
11546
|
+
options?: never;
|
|
11547
|
+
head?: never;
|
|
11548
|
+
patch?: never;
|
|
11549
|
+
trace?: never;
|
|
11550
|
+
};
|
|
11551
|
+
"/v1/charges": {
|
|
11552
|
+
parameters: {
|
|
11553
|
+
query?: never;
|
|
11554
|
+
header?: never;
|
|
11555
|
+
path?: never;
|
|
11556
|
+
cookie?: never;
|
|
11557
|
+
};
|
|
11558
|
+
/**
|
|
11559
|
+
* List charges
|
|
11560
|
+
* @description The charges this project issued, newest first. Page with `limit` (1 to 200, default 50) and `cursor`, which is the `created_at` of the last row you saw; `next_cursor` comes back null when the page is the last one.
|
|
11561
|
+
*
|
|
11562
|
+
* **The `settlement` here is the LAST KNOWN, and the one on the by-id read is the one from now.** The by-id read calls the issuer and compares; a list cannot do that per row, because 200 rows would be 200 provider calls and paging would become a flood. So every item carries `settlement_as_of`: when we last knew the issuer's state for that charge, or null if we never did.
|
|
11563
|
+
*
|
|
11564
|
+
* The same charge can therefore answer a different `settlement` here and there. That is the age of the data, not a defect, which is why the freshness field is required rather than optional. A charge we never read carries `settlement_as_of: null` and can never be `unconfirmable` on this list, because there is nothing to conflict with.
|
|
11565
|
+
*
|
|
11566
|
+
* `settlement=none` selects the charge with no settlement to report: nobody paid it, so there is no pending settlement, only an open receivable. It is not the same as omitting the filter.
|
|
11567
|
+
*/
|
|
11568
|
+
get: {
|
|
11569
|
+
parameters: {
|
|
11570
|
+
query?: {
|
|
11571
|
+
/** @description Our own row status: `pending`, `settled`, `expired`. */
|
|
11572
|
+
status?: string;
|
|
11573
|
+
/** @description Filters on the same three facts the field is derived from, in SQL. */
|
|
11574
|
+
settlement?: "confirmed" | "pending" | "unconfirmable" | "none";
|
|
11575
|
+
limit?: string;
|
|
11576
|
+
cursor?: string;
|
|
11577
|
+
};
|
|
11578
|
+
header?: never;
|
|
11579
|
+
path?: never;
|
|
11580
|
+
cookie?: never;
|
|
11581
|
+
};
|
|
11582
|
+
requestBody?: never;
|
|
11583
|
+
responses: {
|
|
11584
|
+
/** @description OK */
|
|
11585
|
+
200: {
|
|
11586
|
+
headers: {
|
|
11587
|
+
[name: string]: unknown;
|
|
11588
|
+
};
|
|
11589
|
+
content: {
|
|
11590
|
+
"application/json": {
|
|
11591
|
+
data: {
|
|
11592
|
+
id: string | null;
|
|
11593
|
+
status: string;
|
|
11594
|
+
local_status: string;
|
|
11595
|
+
status_conflict: boolean;
|
|
11596
|
+
currency: string;
|
|
11597
|
+
amount_minor: number;
|
|
11598
|
+
due_date: string | null;
|
|
11599
|
+
created_at: string;
|
|
11600
|
+
/** @enum {string|null} */
|
|
11601
|
+
settlement: "confirmed" | "pending" | "unconfirmable" | null;
|
|
11602
|
+
/** @description When we last knew the issuer's state. Null means we never did. */
|
|
11603
|
+
settlement_as_of: string | null;
|
|
11604
|
+
}[];
|
|
11605
|
+
next_cursor: string | null;
|
|
11606
|
+
};
|
|
11607
|
+
};
|
|
11608
|
+
};
|
|
11609
|
+
/** @description The query is malformed, or the credential names no project. */
|
|
11610
|
+
400: {
|
|
11611
|
+
headers: {
|
|
11612
|
+
[name: string]: unknown;
|
|
11613
|
+
};
|
|
11614
|
+
content: {
|
|
11615
|
+
"application/json": {
|
|
11616
|
+
error: {
|
|
11617
|
+
/** @enum {string} */
|
|
11618
|
+
code: "project_scope_missing" | "invalid_settlement_filter" | "invalid_limit";
|
|
11619
|
+
message: string;
|
|
11620
|
+
details?: {
|
|
11621
|
+
[key: string]: unknown;
|
|
11622
|
+
};
|
|
11623
|
+
};
|
|
11624
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11625
|
+
request_id: string | null;
|
|
11626
|
+
};
|
|
11627
|
+
};
|
|
11628
|
+
};
|
|
11629
|
+
};
|
|
11630
|
+
};
|
|
11631
|
+
put?: never;
|
|
10241
11632
|
/**
|
|
10242
|
-
*
|
|
10243
|
-
* @description
|
|
11633
|
+
* Issue a charge
|
|
11634
|
+
* @description Issues an inbound charge: the buyer pays the merchant. The RAIL IS A FIELD, not a path. `method: "pix"` mints an immediate Pix that hands back its copy-and-paste string right away and expires in about an hour. `method: "boleto"` WITH a `due_date` issues a cobrança com vencimento: ONE receivable the payer settles either as a boleto (barcode and linha digitável) or by Pix. One debt, two payable legs, never two documents.
|
|
10244
11635
|
*
|
|
10245
|
-
*
|
|
11636
|
+
* **The cobrança com vencimento answers `PROCESSING` with `payable: false` and no document.** The instrument registers with the clearing house first. Subscribe to `commerce.charge.created` rather than polling for a barcode that is not late, only not made yet. `commerce.charge.paid` is the event that means the funds arrived, by either leg.
|
|
10246
11637
|
*
|
|
10247
|
-
*
|
|
11638
|
+
* **`idempotency_key` is REQUIRED for that combination**, and it is checked before anything reaches the issuer. A repeat with the same key returns the charge already issued, or its still-open reservation, instead of a second receivable the same debtor could pay twice. Send it as the `Idempotency-Key` header, as the body's `idempotency_key`, or as both with the SAME value; two different values are refused rather than one silently winning.
|
|
10248
11639
|
*
|
|
10249
|
-
*
|
|
11640
|
+
* An agreement in N instalments is N cobranças, one per parcela, each with its own `due_date` and its own key. There is no single instalment charge.
|
|
11641
|
+
*
|
|
11642
|
+
* **Each refusal names a `reason`, and the reason is what to branch on.** The two error `code` values (`invalid_args`, `provider_error`) are too coarse: they cover six different situations, and reading them as one would turn `not found` into `bad request`.
|
|
11643
|
+
*
|
|
11644
|
+
* | reason | status | what it means |
|
|
11645
|
+
* |---|---|---|
|
|
11646
|
+
* | `charge_id_missing` | 400 | the call named no charge |
|
|
11647
|
+
* | `project_scope_missing` | 400 | the credential is not project-scoped, and a charge belongs to one project |
|
|
11648
|
+
* | `charge_not_found` | 404 | no charge under that id FOR THIS TENANT |
|
|
11649
|
+
* | `issuance_unconfirmed` | 409 | the key holds a reservation whose create never got an answer |
|
|
11650
|
+
* | `already_payment_notified` | 409 | the clearing house already notified a payment |
|
|
11651
|
+
* | `not_cancellable_in_this_state` | 409 | the issuer accepts a cancellation only in some states |
|
|
11652
|
+
* | `provider_status_unreadable` | 502 | the issuer did not answer the read |
|
|
11653
|
+
* | `provider_cancel_failed` | 502 | the issuer refused the withdrawal |
|
|
11654
|
+
*
|
|
11655
|
+
* `charge_not_found` is deliberately the SAME answer for an id that belongs to another project and for an id that exists nowhere. Telling those apart would be an oracle about another tenant over a string anyone can guess.
|
|
10250
11656
|
*/
|
|
10251
|
-
|
|
11657
|
+
post: {
|
|
10252
11658
|
parameters: {
|
|
10253
11659
|
query?: never;
|
|
10254
11660
|
header?: never;
|
|
10255
|
-
path
|
|
10256
|
-
run_id: string;
|
|
10257
|
-
};
|
|
11661
|
+
path?: never;
|
|
10258
11662
|
cookie?: never;
|
|
10259
11663
|
};
|
|
10260
|
-
requestBody?:
|
|
11664
|
+
requestBody?: {
|
|
11665
|
+
content: {
|
|
11666
|
+
"application/json": {
|
|
11667
|
+
/** @description In minor units. */
|
|
11668
|
+
amount: number;
|
|
11669
|
+
currency: string;
|
|
11670
|
+
/** @description `pix`, `boleto`, `card` or `wallet`. */
|
|
11671
|
+
method: string;
|
|
11672
|
+
description?: string;
|
|
11673
|
+
buyer?: {
|
|
11674
|
+
[key: string]: unknown;
|
|
11675
|
+
};
|
|
11676
|
+
/** @description `YYYY-MM-DD`. With `method: "boleto"` this is what makes it a cobrança com vencimento; an immediate Pix has no due date and refuses one. */
|
|
11677
|
+
due_date?: string;
|
|
11678
|
+
/** @description Required for a cobrança com vencimento. Stable per debt: it is what makes a retry the SAME charge instead of a second one. */
|
|
11679
|
+
idempotency_key?: string;
|
|
11680
|
+
country?: string;
|
|
11681
|
+
metadata?: {
|
|
11682
|
+
[key: string]: unknown;
|
|
11683
|
+
};
|
|
11684
|
+
};
|
|
11685
|
+
};
|
|
11686
|
+
};
|
|
10261
11687
|
responses: {
|
|
10262
11688
|
/** @description OK */
|
|
10263
11689
|
200: {
|
|
@@ -10266,34 +11692,45 @@ export interface paths {
|
|
|
10266
11692
|
};
|
|
10267
11693
|
content: {
|
|
10268
11694
|
"application/json": {
|
|
10269
|
-
/** @
|
|
10270
|
-
|
|
10271
|
-
/** @description
|
|
10272
|
-
|
|
10273
|
-
/** @description
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
/** @description
|
|
10285
|
-
|
|
11695
|
+
/** @description The issuer's charge id. Null while the issuance is unconfirmed. */
|
|
11696
|
+
id: string | null;
|
|
11697
|
+
/** @description The provider's state as far as we know it, normalized. Forced to PROCESSING until the issuance is confirmed. */
|
|
11698
|
+
status: string;
|
|
11699
|
+
/** @description What CodeSpar recorded, which is a different question from `status`. */
|
|
11700
|
+
local_status: string;
|
|
11701
|
+
/** @description True when the two disagree terminally, instead of one of them silently winning. */
|
|
11702
|
+
status_conflict: boolean;
|
|
11703
|
+
method: string;
|
|
11704
|
+
currency: string;
|
|
11705
|
+
/** @description In units. */
|
|
11706
|
+
amount: number;
|
|
11707
|
+
/** @description In minor units. */
|
|
11708
|
+
amount_minor: number;
|
|
11709
|
+
due_date: string | null;
|
|
11710
|
+
/** @description True only when all four hold: the issuance is confirmed, our row is still open, the provider says PENDING, and at least one document exists. This is the field to branch on, not `status`. */
|
|
11711
|
+
payable: boolean;
|
|
11712
|
+
boleto_bar_code: string | null;
|
|
11713
|
+
boleto_bank_line: string | null;
|
|
11714
|
+
/** @description The Pix leg of the same debt. One receivable, two payable legs. */
|
|
11715
|
+
pix_copy_paste: string | null;
|
|
11716
|
+
/** @description Whether an inbound Pix on this charge's Pix leg can resolve a wallet on its own. False until registration hands us the leg's identifier. */
|
|
11717
|
+
credit_correlation_armed: boolean;
|
|
11718
|
+
/** @description True when a payment was notified and the receivable is still open. Read this before you write anything off: the issuer can answer EXPIRED for a boleto it already told us was paid, because the baixa happened before the due date and the credit lands on the next business day. */
|
|
11719
|
+
payment_in_flight: boolean;
|
|
10286
11720
|
/**
|
|
10287
|
-
* @description
|
|
10288
|
-
*
|
|
11721
|
+
* @description The settlement tri-state (decision 10b of the canonical matrix). `confirmed`: the money is in the account. `pending`: the clearing house notified a payment and the credit has not landed, which is the D+1 window. `unconfirmable`: our terminal state disagrees with the issuer's, so settlement cannot be established.
|
|
11722
|
+
*
|
|
11723
|
+
* NULL MEANS NOT APPLICABLE, never `pending`. A charge nobody paid has no pending settlement: it has an open receivable. Reading null as pending would tell you money is on its way.
|
|
11724
|
+
* @enum {string|null}
|
|
10289
11725
|
*/
|
|
10290
|
-
|
|
10291
|
-
|
|
11726
|
+
settlement: "confirmed" | "pending" | "unconfirmable" | null;
|
|
11727
|
+
/** @description True while the row is a reservation with no charge id: the issuer's answer to the create was lost, or a create is in flight elsewhere under the same key. Nothing is payable and nothing was duplicated. */
|
|
11728
|
+
issuance_unconfirmed: boolean;
|
|
10292
11729
|
};
|
|
10293
11730
|
};
|
|
10294
11731
|
};
|
|
10295
|
-
/** @description
|
|
10296
|
-
|
|
11732
|
+
/** @description The call is malformed, or the two idempotency keys disagree. */
|
|
11733
|
+
400: {
|
|
10297
11734
|
headers: {
|
|
10298
11735
|
[name: string]: unknown;
|
|
10299
11736
|
};
|
|
@@ -10301,14 +11738,19 @@ export interface paths {
|
|
|
10301
11738
|
"application/json": {
|
|
10302
11739
|
error: {
|
|
10303
11740
|
/** @enum {string} */
|
|
10304
|
-
code: "
|
|
11741
|
+
code: "charge_idempotency_key_required" | "idempotency_key_conflict";
|
|
10305
11742
|
message: string;
|
|
11743
|
+
details?: {
|
|
11744
|
+
[key: string]: unknown;
|
|
11745
|
+
};
|
|
10306
11746
|
};
|
|
11747
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11748
|
+
request_id: string | null;
|
|
10307
11749
|
};
|
|
10308
11750
|
};
|
|
10309
11751
|
};
|
|
10310
|
-
/** @description The
|
|
10311
|
-
|
|
11752
|
+
/** @description The idempotency slot is held by a row this project cannot read. */
|
|
11753
|
+
409: {
|
|
10312
11754
|
headers: {
|
|
10313
11755
|
[name: string]: unknown;
|
|
10314
11756
|
};
|
|
@@ -10316,7 +11758,27 @@ export interface paths {
|
|
|
10316
11758
|
"application/json": {
|
|
10317
11759
|
error: {
|
|
10318
11760
|
/** @enum {string} */
|
|
10319
|
-
code: "
|
|
11761
|
+
code: "charge_idempotency_slot_unreadable";
|
|
11762
|
+
message: string;
|
|
11763
|
+
details?: {
|
|
11764
|
+
[key: string]: unknown;
|
|
11765
|
+
};
|
|
11766
|
+
};
|
|
11767
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11768
|
+
request_id: string | null;
|
|
11769
|
+
};
|
|
11770
|
+
};
|
|
11771
|
+
};
|
|
11772
|
+
/** @description The slot could not be reserved, or the issuer refused. Nothing was sent. */
|
|
11773
|
+
502: {
|
|
11774
|
+
headers: {
|
|
11775
|
+
[name: string]: unknown;
|
|
11776
|
+
};
|
|
11777
|
+
content: {
|
|
11778
|
+
"application/json": {
|
|
11779
|
+
error: {
|
|
11780
|
+
/** @enum {string} */
|
|
11781
|
+
code: "charge_idempotency_reserve_failed";
|
|
10320
11782
|
message: string;
|
|
10321
11783
|
details?: {
|
|
10322
11784
|
[key: string]: unknown;
|
|
@@ -10329,40 +11791,48 @@ export interface paths {
|
|
|
10329
11791
|
};
|
|
10330
11792
|
};
|
|
10331
11793
|
};
|
|
10332
|
-
put?: never;
|
|
10333
|
-
post?: never;
|
|
10334
11794
|
delete?: never;
|
|
10335
11795
|
options?: never;
|
|
10336
11796
|
head?: never;
|
|
10337
11797
|
patch?: never;
|
|
10338
11798
|
trace?: never;
|
|
10339
11799
|
};
|
|
10340
|
-
"/v1/
|
|
11800
|
+
"/v1/charges/{chargeId}": {
|
|
10341
11801
|
parameters: {
|
|
10342
11802
|
query?: never;
|
|
10343
11803
|
header?: never;
|
|
10344
11804
|
path?: never;
|
|
10345
11805
|
cookie?: never;
|
|
10346
11806
|
};
|
|
10347
|
-
get?: never;
|
|
10348
|
-
put?: never;
|
|
10349
11807
|
/**
|
|
10350
|
-
*
|
|
10351
|
-
* @description
|
|
11808
|
+
* Read a charge
|
|
11809
|
+
* @description Reads a charge this project issued. `chargeId` accepts EITHER the id the create returned OR the caller's own `idempotency_key` — the row is resolved under this credential's org and project, which is what makes another tenant's id simply not found.
|
|
10352
11810
|
*
|
|
10353
|
-
*
|
|
11811
|
+
* **Branch on `payable`, not on `status`.** `payable` is true only when the issuance is confirmed, our row is still open, the provider says PENDING, and at least one payable document exists. A cobrança com vencimento answers PROCESSING with `payable: false` and no document at first, because the instrument registers with the clearing house before it can be paid.
|
|
10354
11812
|
*
|
|
10355
|
-
*
|
|
11813
|
+
* This read also ARMS the Pix leg's correlation when the provider's answer carries it, which is why `credit_correlation_armed` can flip from a read. Nothing else about it writes: no ledger row, no money.
|
|
10356
11814
|
*
|
|
10357
|
-
*
|
|
11815
|
+
* **Each refusal names a `reason`, and the reason is what to branch on.** The two error `code` values (`invalid_args`, `provider_error`) are too coarse: they cover six different situations, and reading them as one would turn `not found` into `bad request`.
|
|
11816
|
+
*
|
|
11817
|
+
* | reason | status | what it means |
|
|
11818
|
+
* |---|---|---|
|
|
11819
|
+
* | `charge_id_missing` | 400 | the call named no charge |
|
|
11820
|
+
* | `project_scope_missing` | 400 | the credential is not project-scoped, and a charge belongs to one project |
|
|
11821
|
+
* | `charge_not_found` | 404 | no charge under that id FOR THIS TENANT |
|
|
11822
|
+
* | `issuance_unconfirmed` | 409 | the key holds a reservation whose create never got an answer |
|
|
11823
|
+
* | `already_payment_notified` | 409 | the clearing house already notified a payment |
|
|
11824
|
+
* | `not_cancellable_in_this_state` | 409 | the issuer accepts a cancellation only in some states |
|
|
11825
|
+
* | `provider_status_unreadable` | 502 | the issuer did not answer the read |
|
|
11826
|
+
* | `provider_cancel_failed` | 502 | the issuer refused the withdrawal |
|
|
11827
|
+
*
|
|
11828
|
+
* `charge_not_found` is deliberately the SAME answer for an id that belongs to another project and for an id that exists nowhere. Telling those apart would be an oracle about another tenant over a string anyone can guess.
|
|
10358
11829
|
*/
|
|
10359
|
-
|
|
11830
|
+
get: {
|
|
10360
11831
|
parameters: {
|
|
10361
11832
|
query?: never;
|
|
10362
11833
|
header?: never;
|
|
10363
11834
|
path: {
|
|
10364
|
-
|
|
10365
|
-
id: string;
|
|
11835
|
+
chargeId: string;
|
|
10366
11836
|
};
|
|
10367
11837
|
cookie?: never;
|
|
10368
11838
|
};
|
|
@@ -10375,26 +11845,45 @@ export interface paths {
|
|
|
10375
11845
|
};
|
|
10376
11846
|
content: {
|
|
10377
11847
|
"application/json": {
|
|
10378
|
-
/** @
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
11848
|
+
/** @description The issuer's charge id. Null while the issuance is unconfirmed. */
|
|
11849
|
+
id: string | null;
|
|
11850
|
+
/** @description The provider's state as far as we know it, normalized. Forced to PROCESSING until the issuance is confirmed. */
|
|
11851
|
+
status: string;
|
|
11852
|
+
/** @description What CodeSpar recorded, which is a different question from `status`. */
|
|
11853
|
+
local_status: string;
|
|
11854
|
+
/** @description True when the two disagree terminally, instead of one of them silently winning. */
|
|
11855
|
+
status_conflict: boolean;
|
|
11856
|
+
method: string;
|
|
11857
|
+
currency: string;
|
|
11858
|
+
/** @description In units. */
|
|
11859
|
+
amount: number;
|
|
11860
|
+
/** @description In minor units. */
|
|
11861
|
+
amount_minor: number;
|
|
11862
|
+
due_date: string | null;
|
|
11863
|
+
/** @description True only when all four hold: the issuance is confirmed, our row is still open, the provider says PENDING, and at least one document exists. This is the field to branch on, not `status`. */
|
|
11864
|
+
payable: boolean;
|
|
11865
|
+
boleto_bar_code: string | null;
|
|
11866
|
+
boleto_bank_line: string | null;
|
|
11867
|
+
/** @description The Pix leg of the same debt. One receivable, two payable legs. */
|
|
11868
|
+
pix_copy_paste: string | null;
|
|
11869
|
+
/** @description Whether an inbound Pix on this charge's Pix leg can resolve a wallet on its own. False until registration hands us the leg's identifier. */
|
|
11870
|
+
credit_correlation_armed: boolean;
|
|
11871
|
+
/** @description True when a payment was notified and the receivable is still open. Read this before you write anything off: the issuer can answer EXPIRED for a boleto it already told us was paid, because the baixa happened before the due date and the credit lands on the next business day. */
|
|
11872
|
+
payment_in_flight: boolean;
|
|
10388
11873
|
/**
|
|
10389
|
-
* @description
|
|
10390
|
-
*
|
|
11874
|
+
* @description The settlement tri-state (decision 10b of the canonical matrix). `confirmed`: the money is in the account. `pending`: the clearing house notified a payment and the credit has not landed, which is the D+1 window. `unconfirmable`: our terminal state disagrees with the issuer's, so settlement cannot be established.
|
|
11875
|
+
*
|
|
11876
|
+
* NULL MEANS NOT APPLICABLE, never `pending`. A charge nobody paid has no pending settlement: it has an open receivable. Reading null as pending would tell you money is on its way.
|
|
11877
|
+
* @enum {string|null}
|
|
10391
11878
|
*/
|
|
10392
|
-
|
|
11879
|
+
settlement: "confirmed" | "pending" | "unconfirmable" | null;
|
|
11880
|
+
/** @description True while the row is a reservation with no charge id: the issuer's answer to the create was lost, or a create is in flight elsewhere under the same key. Nothing is payable and nothing was duplicated. */
|
|
11881
|
+
issuance_unconfirmed: boolean;
|
|
10393
11882
|
};
|
|
10394
11883
|
};
|
|
10395
11884
|
};
|
|
10396
|
-
/** @description
|
|
10397
|
-
|
|
11885
|
+
/** @description The call is malformed. `reason` says which half. */
|
|
11886
|
+
400: {
|
|
10398
11887
|
headers: {
|
|
10399
11888
|
[name: string]: unknown;
|
|
10400
11889
|
};
|
|
@@ -10402,7 +11891,7 @@ export interface paths {
|
|
|
10402
11891
|
"application/json": {
|
|
10403
11892
|
error: {
|
|
10404
11893
|
/** @enum {string} */
|
|
10405
|
-
code: "
|
|
11894
|
+
code: "charge_id_missing" | "project_scope_missing";
|
|
10406
11895
|
message: string;
|
|
10407
11896
|
details?: {
|
|
10408
11897
|
[key: string]: unknown;
|
|
@@ -10413,7 +11902,7 @@ export interface paths {
|
|
|
10413
11902
|
};
|
|
10414
11903
|
};
|
|
10415
11904
|
};
|
|
10416
|
-
/** @description No
|
|
11905
|
+
/** @description No charge under that id for this tenant. */
|
|
10417
11906
|
404: {
|
|
10418
11907
|
headers: {
|
|
10419
11908
|
[name: string]: unknown;
|
|
@@ -10422,14 +11911,19 @@ export interface paths {
|
|
|
10422
11911
|
"application/json": {
|
|
10423
11912
|
error: {
|
|
10424
11913
|
/** @enum {string} */
|
|
10425
|
-
code: "
|
|
11914
|
+
code: "charge_not_found";
|
|
10426
11915
|
message: string;
|
|
11916
|
+
details?: {
|
|
11917
|
+
[key: string]: unknown;
|
|
11918
|
+
};
|
|
10427
11919
|
};
|
|
11920
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
11921
|
+
request_id: string | null;
|
|
10428
11922
|
};
|
|
10429
11923
|
};
|
|
10430
11924
|
};
|
|
10431
|
-
/** @description The
|
|
10432
|
-
|
|
11925
|
+
/** @description The charge exists and is not readable in this state. */
|
|
11926
|
+
409: {
|
|
10433
11927
|
headers: {
|
|
10434
11928
|
[name: string]: unknown;
|
|
10435
11929
|
};
|
|
@@ -10437,7 +11931,7 @@ export interface paths {
|
|
|
10437
11931
|
"application/json": {
|
|
10438
11932
|
error: {
|
|
10439
11933
|
/** @enum {string} */
|
|
10440
|
-
code: "
|
|
11934
|
+
code: "issuance_unconfirmed";
|
|
10441
11935
|
message: string;
|
|
10442
11936
|
details?: {
|
|
10443
11937
|
[key: string]: unknown;
|
|
@@ -10448,8 +11942,8 @@ export interface paths {
|
|
|
10448
11942
|
};
|
|
10449
11943
|
};
|
|
10450
11944
|
};
|
|
10451
|
-
/** @description The
|
|
10452
|
-
|
|
11945
|
+
/** @description The issuer did not answer. */
|
|
11946
|
+
502: {
|
|
10453
11947
|
headers: {
|
|
10454
11948
|
[name: string]: unknown;
|
|
10455
11949
|
};
|
|
@@ -10457,7 +11951,7 @@ export interface paths {
|
|
|
10457
11951
|
"application/json": {
|
|
10458
11952
|
error: {
|
|
10459
11953
|
/** @enum {string} */
|
|
10460
|
-
code: "
|
|
11954
|
+
code: "provider_status_unreadable";
|
|
10461
11955
|
message: string;
|
|
10462
11956
|
details?: {
|
|
10463
11957
|
[key: string]: unknown;
|
|
@@ -10470,36 +11964,52 @@ export interface paths {
|
|
|
10470
11964
|
};
|
|
10471
11965
|
};
|
|
10472
11966
|
};
|
|
11967
|
+
put?: never;
|
|
11968
|
+
post?: never;
|
|
10473
11969
|
delete?: never;
|
|
10474
11970
|
options?: never;
|
|
10475
11971
|
head?: never;
|
|
10476
11972
|
patch?: never;
|
|
10477
11973
|
trace?: never;
|
|
10478
11974
|
};
|
|
10479
|
-
"/v1/
|
|
11975
|
+
"/v1/charges/{chargeId}/cancel": {
|
|
10480
11976
|
parameters: {
|
|
10481
11977
|
query?: never;
|
|
10482
11978
|
header?: never;
|
|
10483
11979
|
path?: never;
|
|
10484
11980
|
cookie?: never;
|
|
10485
11981
|
};
|
|
11982
|
+
get?: never;
|
|
11983
|
+
put?: never;
|
|
10486
11984
|
/**
|
|
10487
|
-
*
|
|
10488
|
-
* @description
|
|
11985
|
+
* Withdraw a charge
|
|
11986
|
+
* @description Withdraws a charge that has not been paid. Takes no body: the id is the whole request, and it accepts the same two forms the read does.
|
|
10489
11987
|
*
|
|
10490
|
-
*
|
|
11988
|
+
* **This never moves money.** It is not a refund: an unpaid receivable is withdrawn, and a charge whose payment the clearing house already notified is REFUSED with `already_payment_notified` rather than withdrawn. That refusal is the D+1 guard: a boleto paid after the convênio's cut-off is notified on one day and credited on the next business day, so the due date can fall between the two, and withdrawing there would write off a receivable somebody paid.
|
|
10491
11989
|
*
|
|
10492
|
-
*
|
|
11990
|
+
* A charge the issuer already reports as cancelled is a no-op that closes our row, not a second withdrawal.
|
|
10493
11991
|
*
|
|
10494
|
-
*
|
|
11992
|
+
* **Each refusal names a `reason`, and the reason is what to branch on.** The two error `code` values (`invalid_args`, `provider_error`) are too coarse: they cover six different situations, and reading them as one would turn `not found` into `bad request`.
|
|
11993
|
+
*
|
|
11994
|
+
* | reason | status | what it means |
|
|
11995
|
+
* |---|---|---|
|
|
11996
|
+
* | `charge_id_missing` | 400 | the call named no charge |
|
|
11997
|
+
* | `project_scope_missing` | 400 | the credential is not project-scoped, and a charge belongs to one project |
|
|
11998
|
+
* | `charge_not_found` | 404 | no charge under that id FOR THIS TENANT |
|
|
11999
|
+
* | `issuance_unconfirmed` | 409 | the key holds a reservation whose create never got an answer |
|
|
12000
|
+
* | `already_payment_notified` | 409 | the clearing house already notified a payment |
|
|
12001
|
+
* | `not_cancellable_in_this_state` | 409 | the issuer accepts a cancellation only in some states |
|
|
12002
|
+
* | `provider_status_unreadable` | 502 | the issuer did not answer the read |
|
|
12003
|
+
* | `provider_cancel_failed` | 502 | the issuer refused the withdrawal |
|
|
12004
|
+
*
|
|
12005
|
+
* `charge_not_found` is deliberately the SAME answer for an id that belongs to another project and for an id that exists nowhere. Telling those apart would be an oracle about another tenant over a string anyone can guess.
|
|
10495
12006
|
*/
|
|
10496
|
-
|
|
12007
|
+
post: {
|
|
10497
12008
|
parameters: {
|
|
10498
12009
|
query?: never;
|
|
10499
12010
|
header?: never;
|
|
10500
12011
|
path: {
|
|
10501
|
-
|
|
10502
|
-
id: string;
|
|
12012
|
+
chargeId: string;
|
|
10503
12013
|
};
|
|
10504
12014
|
cookie?: never;
|
|
10505
12015
|
};
|
|
@@ -10512,19 +12022,64 @@ export interface paths {
|
|
|
10512
12022
|
};
|
|
10513
12023
|
content: {
|
|
10514
12024
|
"application/json": {
|
|
10515
|
-
/** @
|
|
10516
|
-
|
|
10517
|
-
|
|
10518
|
-
|
|
10519
|
-
|
|
10520
|
-
|
|
12025
|
+
/** @description The issuer's charge id. Null while the issuance is unconfirmed. */
|
|
12026
|
+
id: string | null;
|
|
12027
|
+
/** @description The provider's state as far as we know it, normalized. Forced to PROCESSING until the issuance is confirmed. */
|
|
12028
|
+
status: string;
|
|
12029
|
+
/** @description What CodeSpar recorded, which is a different question from `status`. */
|
|
12030
|
+
local_status: string;
|
|
12031
|
+
/** @description True when the two disagree terminally, instead of one of them silently winning. */
|
|
12032
|
+
status_conflict: boolean;
|
|
12033
|
+
method: string;
|
|
12034
|
+
currency: string;
|
|
12035
|
+
/** @description In units. */
|
|
12036
|
+
amount: number;
|
|
12037
|
+
/** @description In minor units. */
|
|
12038
|
+
amount_minor: number;
|
|
12039
|
+
due_date: string | null;
|
|
12040
|
+
/** @description True only when all four hold: the issuance is confirmed, our row is still open, the provider says PENDING, and at least one document exists. This is the field to branch on, not `status`. */
|
|
12041
|
+
payable: boolean;
|
|
12042
|
+
boleto_bar_code: string | null;
|
|
12043
|
+
boleto_bank_line: string | null;
|
|
12044
|
+
/** @description The Pix leg of the same debt. One receivable, two payable legs. */
|
|
12045
|
+
pix_copy_paste: string | null;
|
|
12046
|
+
/** @description Whether an inbound Pix on this charge's Pix leg can resolve a wallet on its own. False until registration hands us the leg's identifier. */
|
|
12047
|
+
credit_correlation_armed: boolean;
|
|
12048
|
+
/** @description True when a payment was notified and the receivable is still open. Read this before you write anything off: the issuer can answer EXPIRED for a boleto it already told us was paid, because the baixa happened before the due date and the credit lands on the next business day. */
|
|
12049
|
+
payment_in_flight: boolean;
|
|
12050
|
+
/**
|
|
12051
|
+
* @description The settlement tri-state (decision 10b of the canonical matrix). `confirmed`: the money is in the account. `pending`: the clearing house notified a payment and the credit has not landed, which is the D+1 window. `unconfirmable`: our terminal state disagrees with the issuer's, so settlement cannot be established.
|
|
12052
|
+
*
|
|
12053
|
+
* NULL MEANS NOT APPLICABLE, never `pending`. A charge nobody paid has no pending settlement: it has an open receivable. Reading null as pending would tell you money is on its way.
|
|
12054
|
+
* @enum {string|null}
|
|
12055
|
+
*/
|
|
12056
|
+
settlement: "confirmed" | "pending" | "unconfirmable" | null;
|
|
12057
|
+
/** @description True while the row is a reservation with no charge id: the issuer's answer to the create was lost, or a create is in flight elsewhere under the same key. Nothing is payable and nothing was duplicated. */
|
|
12058
|
+
issuance_unconfirmed: boolean;
|
|
12059
|
+
};
|
|
12060
|
+
};
|
|
12061
|
+
};
|
|
12062
|
+
/** @description The call is malformed. */
|
|
12063
|
+
400: {
|
|
12064
|
+
headers: {
|
|
12065
|
+
[name: string]: unknown;
|
|
12066
|
+
};
|
|
12067
|
+
content: {
|
|
12068
|
+
"application/json": {
|
|
12069
|
+
error: {
|
|
12070
|
+
/** @enum {string} */
|
|
12071
|
+
code: "charge_id_missing" | "project_scope_missing";
|
|
12072
|
+
message: string;
|
|
12073
|
+
details?: {
|
|
12074
|
+
[key: string]: unknown;
|
|
12075
|
+
};
|
|
10521
12076
|
};
|
|
10522
|
-
/** @description
|
|
10523
|
-
|
|
12077
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
12078
|
+
request_id: string | null;
|
|
10524
12079
|
};
|
|
10525
12080
|
};
|
|
10526
12081
|
};
|
|
10527
|
-
/** @description No
|
|
12082
|
+
/** @description No charge under that id for this tenant. */
|
|
10528
12083
|
404: {
|
|
10529
12084
|
headers: {
|
|
10530
12085
|
[name: string]: unknown;
|
|
@@ -10533,14 +12088,19 @@ export interface paths {
|
|
|
10533
12088
|
"application/json": {
|
|
10534
12089
|
error: {
|
|
10535
12090
|
/** @enum {string} */
|
|
10536
|
-
code: "
|
|
12091
|
+
code: "charge_not_found";
|
|
10537
12092
|
message: string;
|
|
12093
|
+
details?: {
|
|
12094
|
+
[key: string]: unknown;
|
|
12095
|
+
};
|
|
10538
12096
|
};
|
|
12097
|
+
/** @description Echoes the `X-Request-Id` header when the request carried one. */
|
|
12098
|
+
request_id: string | null;
|
|
10539
12099
|
};
|
|
10540
12100
|
};
|
|
10541
12101
|
};
|
|
10542
|
-
/** @description The
|
|
10543
|
-
|
|
12102
|
+
/** @description The charge exists and this state does not accept a withdrawal. `already_payment_notified` is the D+1 guard and is never a retry case. */
|
|
12103
|
+
409: {
|
|
10544
12104
|
headers: {
|
|
10545
12105
|
[name: string]: unknown;
|
|
10546
12106
|
};
|
|
@@ -10548,7 +12108,7 @@ export interface paths {
|
|
|
10548
12108
|
"application/json": {
|
|
10549
12109
|
error: {
|
|
10550
12110
|
/** @enum {string} */
|
|
10551
|
-
code: "
|
|
12111
|
+
code: "issuance_unconfirmed" | "already_payment_notified" | "not_cancellable_in_this_state";
|
|
10552
12112
|
message: string;
|
|
10553
12113
|
details?: {
|
|
10554
12114
|
[key: string]: unknown;
|
|
@@ -10559,7 +12119,7 @@ export interface paths {
|
|
|
10559
12119
|
};
|
|
10560
12120
|
};
|
|
10561
12121
|
};
|
|
10562
|
-
/** @description The
|
|
12122
|
+
/** @description The issuer refused the withdrawal, or did not answer. */
|
|
10563
12123
|
502: {
|
|
10564
12124
|
headers: {
|
|
10565
12125
|
[name: string]: unknown;
|
|
@@ -10568,7 +12128,7 @@ export interface paths {
|
|
|
10568
12128
|
"application/json": {
|
|
10569
12129
|
error: {
|
|
10570
12130
|
/** @enum {string} */
|
|
10571
|
-
code: "
|
|
12131
|
+
code: "provider_cancel_failed" | "provider_status_unreadable";
|
|
10572
12132
|
message: string;
|
|
10573
12133
|
details?: {
|
|
10574
12134
|
[key: string]: unknown;
|
|
@@ -10581,8 +12141,6 @@ export interface paths {
|
|
|
10581
12141
|
};
|
|
10582
12142
|
};
|
|
10583
12143
|
};
|
|
10584
|
-
put?: never;
|
|
10585
|
-
post?: never;
|
|
10586
12144
|
delete?: never;
|
|
10587
12145
|
options?: never;
|
|
10588
12146
|
head?: never;
|
|
@@ -17972,7 +19530,7 @@ export interface paths {
|
|
|
17972
19530
|
*
|
|
17973
19531
|
* `linked_consumer_id` is set on first write and then kept: a later call that sends a different one does not overwrite it. The other KYB fields are overwritten by the re-POST.
|
|
17974
19532
|
*
|
|
17975
|
-
* `document_number` is stored with every non-digit stripped. A value that survives the schema but contains no digits at all leaves nothing to store, and that surfaces as 502 `seller_document_required`, not as 400: the check lives in the provisioning flow, past the point where the body was validated.
|
|
19533
|
+
* `document_number` must be a CPF (11 digits) or a CNPJ (14 characters, letters allowed in the twelve base positions per IN RFB 2229/2024) whose check digits verify, and `document_type` / `document_tax_type` must agree with it (CPF ↔ PF, CNPJ ↔ PJ | MEI | ME); any of those failing is 400 `invalid_body` with the offending field in `issues[].path`, before Rinne is reached. It is then stored with every non-digit stripped. A value that survives the schema but contains no digits at all leaves nothing to store, and that surfaces as 502 `seller_document_required`, not as 400: the check lives in the provisioning flow, past the point where the body was validated.
|
|
17976
19534
|
*
|
|
17977
19535
|
* The response is the seller row, not Rinne's. `status` and `affiliation_status` reflect whatever the affiliation was at that instant, which for a fresh onboarding is normally pending rather than active.
|
|
17978
19536
|
*/
|
|
@@ -19376,6 +20934,18 @@ export interface paths {
|
|
|
19376
20934
|
* Three refusals arrive IN BAND on the catalog branch, as a 200 whose `error` starts with `policy_denied: `, `approval_required: ` or `policy_engine_error: `. The policy 403 and the policy 503 below are the same decisions taken one layer earlier, by the route's guard, before the handler runs. A caller that only checks the status code will read an in-band refusal as a successful request.
|
|
19377
20935
|
*
|
|
19378
20936
|
* 413 is absent from this operation on purpose: the guard here does not hand the caller's tool input to the policy engine, so the engine's payload cap cannot fire. `POST /v1/sessions/{id}/proxy_execute` does hand it over, and does answer 413.
|
|
20937
|
+
*
|
|
20938
|
+
* WHICH STRINGS ARE LEGAL IN `tool`. This operation takes the name opaquely and this document does not enumerate it. `GET /v1/meta-tools.json` does: one entry per tool, each with a JSON Schema for what goes in `params`, served with no credential. Read that before hardcoding a name or concluding a capability is missing, because the per-tool contracts live there and not here.
|
|
20939
|
+
*
|
|
20940
|
+
* SEVERAL OF THOSE TOOLS MOVE MONEY, and the envelope above shows none of what they require. `codespar_pay` spends outbound under a mandate; `codespar_charge` issues an inbound receivable. Both answer in this same 200 envelope, so `success` is the field that says whether the money instruction was accepted, and a refusal that starts with `policy_denied: ` or `approval_required: ` is a refusal even though the status is 200.
|
|
20941
|
+
*
|
|
20942
|
+
* THE COBRANÇA COM VENCIMENTO IS THE ONE THAT SURPRISES CALLERS. `codespar_charge` with `action: "create"`, `method: "boleto"` and a `due_date` issues ONE receivable the payer settles EITHER as a boleto (barcode and linha digitável) OR by Pix — one debt, two payable legs, never two documents. Three properties of it are not visible from this envelope and each one costs money to learn late:
|
|
20943
|
+
*
|
|
20944
|
+
* 1. `idempotency_key` is REQUIRED for that combination. A create without one is refused before anything reaches the provider, and a repeat with the same key returns the charge already issued rather than a second document for the same debt. An agent that retries on a timeout without it bills the payer twice.
|
|
20945
|
+
* 2. The create answers `status: "PROCESSING"` with `payable: false` and NO document. The instrument registers with the clearing house first. Subscribe to `commerce.charge.created` instead of polling for a barcode that is not late, only not made yet.
|
|
20946
|
+
* 3. `commerce.charge.paid` is the event that means the funds arrived, by either leg. A boleto payment can be preceded by `commerce.charge.payment_notified`, which is the clearing house posting its operational baixa and which the issuer states is not proof of payment; every convênio has a daily cut-off, so a boleto paid after it is notified on one day and credited on the next business day. Ship on `paid`.
|
|
20947
|
+
*
|
|
20948
|
+
* An agreement in N instalments is N cobranças, one per parcela, each with its own `due_date` and its own `idempotency_key`. There is no single instalment charge.
|
|
19379
20949
|
*/
|
|
19380
20950
|
post: {
|
|
19381
20951
|
parameters: {
|
|
@@ -19685,6 +21255,23 @@ export interface paths {
|
|
|
19685
21255
|
};
|
|
19686
21256
|
};
|
|
19687
21257
|
};
|
|
21258
|
+
/** @description Unprocessable — the project is in `environment="test"` and this server cannot be exercised there. `reason` is the provider's `test_venue` classification: `none` means the provider runs no test environment at all, so the call would land on production with a real effect (a Z-API WhatsApp message goes to a real number); `unclassified` means nobody has established what it does in test. Answered whether or not `PROXY_REQUIRE_CONNECTION` is set, because it is about the environment and not about a missing connection, and not retryable — the same call from a `live` project reaches the provider (ent#722). */
|
|
21259
|
+
422: {
|
|
21260
|
+
headers: {
|
|
21261
|
+
[name: string]: unknown;
|
|
21262
|
+
};
|
|
21263
|
+
content: {
|
|
21264
|
+
"application/json": {
|
|
21265
|
+
/** @enum {string} */
|
|
21266
|
+
error: "test_venue_unavailable";
|
|
21267
|
+
/** @enum {string} */
|
|
21268
|
+
reason: "none" | "unclassified" | "separate_host";
|
|
21269
|
+
server: string;
|
|
21270
|
+
/** @description Names the catalog file and the field to declare. */
|
|
21271
|
+
message: string;
|
|
21272
|
+
};
|
|
21273
|
+
};
|
|
21274
|
+
};
|
|
19688
21275
|
/** @description Failed Dependency — no usable credential for this server. `reason` is the resolver's own outcome. */
|
|
19689
21276
|
424: {
|
|
19690
21277
|
headers: {
|
|
@@ -21992,6 +23579,77 @@ export interface components {
|
|
|
21992
23579
|
*/
|
|
21993
23580
|
engine_status: "none" | "available" | "quarantined";
|
|
21994
23581
|
};
|
|
23582
|
+
SpendOutcome: {
|
|
23583
|
+
/** @enum {string} */
|
|
23584
|
+
status: "completed";
|
|
23585
|
+
requestId: string;
|
|
23586
|
+
mandate: {
|
|
23587
|
+
consumer_id: string;
|
|
23588
|
+
purpose: string;
|
|
23589
|
+
currency: string;
|
|
23590
|
+
};
|
|
23591
|
+
payment: {
|
|
23592
|
+
transactionId: string;
|
|
23593
|
+
/** @description The Pix endToEndId when the rail produces one. Null for rails that have none, TED included. */
|
|
23594
|
+
endToEndId: string | null;
|
|
23595
|
+
amountMinor: number;
|
|
23596
|
+
rail: string;
|
|
23597
|
+
provider: string;
|
|
23598
|
+
/** @description False when the adapter is a mock or a staging stub. True when real money left. */
|
|
23599
|
+
moneyMoved: boolean;
|
|
23600
|
+
adapter: string;
|
|
23601
|
+
};
|
|
23602
|
+
wallet: {
|
|
23603
|
+
walletId: string;
|
|
23604
|
+
holdEntryId: string;
|
|
23605
|
+
fundEntryId: string | null;
|
|
23606
|
+
debitEntryId: string | null;
|
|
23607
|
+
};
|
|
23608
|
+
/** @description The sealed Control Record. Null when there was no consumer secret to sign it with. */
|
|
23609
|
+
receipt: {
|
|
23610
|
+
id: string;
|
|
23611
|
+
/** @enum {string} */
|
|
23612
|
+
state: "paid" | "exception" | "delivered";
|
|
23613
|
+
chain: string;
|
|
23614
|
+
exceptions: unknown[];
|
|
23615
|
+
} | null;
|
|
23616
|
+
/** @description The lifecycle steps, in order, each with a timestamp and an outcome. */
|
|
23617
|
+
audit: unknown[];
|
|
23618
|
+
};
|
|
23619
|
+
/** @description The destination of a TED, the Brazilian same-day bank wire. Present this object on a spend to send a wire instead of a Pix: its presence is what switches the rail, and what makes the three TED requirements on those operations bind. Money leaves the consumer's own sub-account, never a pooled one. */
|
|
23620
|
+
TedDestination: {
|
|
23621
|
+
/** @description ISPB of the destination institution, digits only. */
|
|
23622
|
+
bank: string;
|
|
23623
|
+
/** @description Branch, with no separate check digit. */
|
|
23624
|
+
branch: string;
|
|
23625
|
+
/** @description Account, including the check digit. */
|
|
23626
|
+
account: string;
|
|
23627
|
+
/** @description CPF or CNPJ of the destination account holder. */
|
|
23628
|
+
tax_id: string;
|
|
23629
|
+
/** @description Name of the destination account holder. */
|
|
23630
|
+
name: string;
|
|
23631
|
+
/**
|
|
23632
|
+
* @description Checking, investment, payment or savings. This is the TED product's OWN enum, different from the Pix account enum (`CACC`, `SLRY`, `SVGS`, `TRAN`): they are distinct endpoints and distinct products at the provider.
|
|
23633
|
+
* @enum {string}
|
|
23634
|
+
*/
|
|
23635
|
+
account_type?: "CC" | "CI" | "PG" | "PP";
|
|
23636
|
+
/**
|
|
23637
|
+
* @description A natural person or a legal entity.
|
|
23638
|
+
* @enum {string}
|
|
23639
|
+
*/
|
|
23640
|
+
person_type?: "F" | "J";
|
|
23641
|
+
/** @description The banking partner's purpose code. Defaults to `1`, a generic transfer. */
|
|
23642
|
+
client_finality?: string;
|
|
23643
|
+
};
|
|
23644
|
+
/** @description The offer the agent approved. When present it is signed into the receipt, and at close the price and the payee are compared against what actually settled. A divergence is RECORDED on the receipt; it does not abort settlement. */
|
|
23645
|
+
SpendQuote: {
|
|
23646
|
+
seller: string;
|
|
23647
|
+
resource: string;
|
|
23648
|
+
price_minor: number;
|
|
23649
|
+
payee: string;
|
|
23650
|
+
session_id?: string;
|
|
23651
|
+
at?: string;
|
|
23652
|
+
};
|
|
21995
23653
|
};
|
|
21996
23654
|
responses: never;
|
|
21997
23655
|
parameters: never;
|