Finalize an existing v2 draft transfer
Finalizes a transfer created by `POST /v2/transfers/create`. The client may send the full `CreatePaymentRequestV2` again, or omit the body and let the server reuse the finalize-shaped payload stored on the draft. V2 request metadata uses `metadata`, not legacy `meta`. Cross-currency transfers require a locked top-level `quote_id` from `POST /v2/transfers/quotes`. Repeated and concurrent calls are deduplicated by the draft `transfer_id`: the finalized transfer uses a server-derived `draft-finalize:` idempotency key, while the draft superseded link is updated under a row lock and preserved on retries.
/v2/transfers/{transfer_id}/finalizeAuthorization
BearerAuth JWT authentication token
In: header
Path Parameters
Transfer UUID
transfer_id path parameter
Header Parameters
Language preference for the response
Optional idempotency key for finalize retries; when a body is present it must match body idempotency_key. This key governs the draft lookup only. The resulting finalized transfer is deduplicated by a server-derived key bound to the draft transfer_id, so repeated finalize calls on the same draft return the same finalized transfer regardless of the client key sent.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Canonical v2 finalize/draft payment body. Same as v1 CreatePaymentRequest, but client metadata is sent as metadata instead of legacy meta.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v2/transfers/string/finalize" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e", "channel": "string", "amount": { "amount_minor": "string", "currency": "string" }, "source": { "counterparty_id": "fd38dae9-b300-4017-a630-101c4279eafd", "cp_account_id": "eb064395-4075-439f-a7b1-d660c0883425" }, "destination": { "counterparty_id": "fd38dae9-b300-4017-a630-101c4279eafd", "cp_account_id": "eb064395-4075-439f-a7b1-d660c0883425" }, "fee_bearer": "DEBT" }'{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"transfer_id": "d4a2d8dd-7def-4545-a062-761683b9aa05",
"status": "draft",
"active": true,
"product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
"product_code": "string",
"customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
"source": {
"counterparty_id": "fd38dae9-b300-4017-a630-101c4279eafd",
"cp_account_id": "eb064395-4075-439f-a7b1-d660c0883425"
},
"destination": {
"counterparty_id": "fd38dae9-b300-4017-a630-101c4279eafd",
"cp_account_id": "eb064395-4075-439f-a7b1-d660c0883425"
},
"channel": "string",
"fee_bearer": "DEBT",
"quote_id": "3c071a1d-db86-46a7-9dc8-72ba3fbca992",
"reference": "string",
"amount": {
"amount": "string",
"currency": "string",
"precision": 0
},
"fee_amount": {
"amount": "string",
"currency": "string",
"precision": 0
},
"amount_net": {
"amount": "string",
"currency": "string",
"precision": 0
},
"recipient_amount": {
"amount": "string",
"currency": "string",
"precision": 0
},
"metadata": {},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}{
"status": 0,
"message": "string"
}Creates a transfer in `draft` status from the modern v2 finalize payload. The request body is the same `CreatePaymentRequestV2` used by `POST /v2/transfers/finalize` and uses `metadata` for client metadata. The server validates sender, recipient, amount currency, pre-flight rules, and quote prerequisites, then stores the finalize-shaped payload on the draft so `POST /v2/transfers/{transfer_id}/finalize` can reuse it.
Canonical modern finalize endpoint. Creates a transfer after pre-flight discovery and returns `TransferPaymentResponse`. Request body is `CreatePaymentRequestV2`: same selector/amount semantics as v1 finalize, but client metadata is sent as `metadata` (not `meta`). The server maps to the same product matrix filter, resolves `source` to the real debit `source_account_id = accounts.accounts.id`, normalizes `destination` to exact universal `destination_account_id = counterparties.cp_accounts.id`, runs `ValidatePreFlightRequest`, then `PreFlightForFinalize`; on deny returns 422. Cross-currency requires a locked top-level `quote_id` from `POST /v2/transfers/quotes`.