curl --request POST \
--url https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"wallet_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 100.5,
"payment_type": "send",
"idempotency_key": "pay_req_20260604_abc123",
"product_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"user_id": "b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4",
"currency": "USD",
"metadata": {
"order_id": "ORD-12345"
},
"payment_category": 1,
"from_hold": false,
"payee_destination_id": "c8d9e0f1-a2b3-4567-89ab-cdef01234567",
"payee_payment_method_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"payment_method_id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123"
}
'import requests
url = "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank"
payload = {
"wallet_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 100.5,
"payment_type": "send",
"idempotency_key": "pay_req_20260604_abc123",
"product_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"user_id": "b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4",
"currency": "USD",
"metadata": { "order_id": "ORD-12345" },
"payment_category": 1,
"from_hold": False,
"payee_destination_id": "c8d9e0f1-a2b3-4567-89ab-cdef01234567",
"payee_payment_method_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"payment_method_id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
wallet_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
amount: 100.5,
payment_type: 'send',
idempotency_key: 'pay_req_20260604_abc123',
product_id: 'd4e5f6a7-b8c9-0123-4567-890abcdef012',
user_id: 'b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4',
currency: 'USD',
metadata: {order_id: 'ORD-12345'},
payment_category: 1,
from_hold: false,
payee_destination_id: 'c8d9e0f1-a2b3-4567-89ab-cdef01234567',
payee_payment_method_id: 'f6a7b8c9-d0e1-2345-6789-0abcdef01234',
payment_method_id: 'e5f6a7b8-c9d0-1234-5678-90abcdef0123'
})
};
fetch('https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'wallet_id' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'amount' => 100.5,
'payment_type' => 'send',
'idempotency_key' => 'pay_req_20260604_abc123',
'product_id' => 'd4e5f6a7-b8c9-0123-4567-890abcdef012',
'user_id' => 'b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4',
'currency' => 'USD',
'metadata' => [
'order_id' => 'ORD-12345'
],
'payment_category' => 1,
'from_hold' => false,
'payee_destination_id' => 'c8d9e0f1-a2b3-4567-89ab-cdef01234567',
'payee_payment_method_id' => 'f6a7b8c9-d0e1-2345-6789-0abcdef01234',
'payment_method_id' => 'e5f6a7b8-c9d0-1234-5678-90abcdef0123'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank"
payload := strings.NewReader("{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}"
response = http.request(request)
puts response.read_body{
"status_code": 123,
"data": "<unknown>",
"query_generated_time": 123
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"status_code": 429,
"data": {
"detail": "You just made a payment. Please wait before making another.",
"code": "payment_cooldown",
"error_code": 1000
},
"query_generated_time": 1750000000000
}Wallet to Bank (Payout)
Pay out from a wallet to a bank account (ACH push or digital-check
auto-deposit). A payout payment. The required payment_type selects
the flow:
payment_type=send— pay another party. Identify the destination withpayee_destination_id(recommended) or the legacypayee_payment_method_id.payment_type=transfer— withdraw to the user’s own bank. Identify it withpayment_method_id(the user’s linked bank, the same one they fund from); a Plaid-linked bank is connected to the payout provider on demand if it is not already. A virtual bank account cannot be the target of a payout — its balance can only fund the owner’s wallet (see Bank → Wallet).
Either way, funds move available → escrow on submit and settle via
webhook, and the payout is SUA-gated.
curl --request POST \
--url https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"wallet_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 100.5,
"payment_type": "send",
"idempotency_key": "pay_req_20260604_abc123",
"product_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"user_id": "b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4",
"currency": "USD",
"metadata": {
"order_id": "ORD-12345"
},
"payment_category": 1,
"from_hold": false,
"payee_destination_id": "c8d9e0f1-a2b3-4567-89ab-cdef01234567",
"payee_payment_method_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"payment_method_id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123"
}
'import requests
url = "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank"
payload = {
"wallet_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 100.5,
"payment_type": "send",
"idempotency_key": "pay_req_20260604_abc123",
"product_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"user_id": "b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4",
"currency": "USD",
"metadata": { "order_id": "ORD-12345" },
"payment_category": 1,
"from_hold": False,
"payee_destination_id": "c8d9e0f1-a2b3-4567-89ab-cdef01234567",
"payee_payment_method_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"payment_method_id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
wallet_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
amount: 100.5,
payment_type: 'send',
idempotency_key: 'pay_req_20260604_abc123',
product_id: 'd4e5f6a7-b8c9-0123-4567-890abcdef012',
user_id: 'b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4',
currency: 'USD',
metadata: {order_id: 'ORD-12345'},
payment_category: 1,
from_hold: false,
payee_destination_id: 'c8d9e0f1-a2b3-4567-89ab-cdef01234567',
payee_payment_method_id: 'f6a7b8c9-d0e1-2345-6789-0abcdef01234',
payment_method_id: 'e5f6a7b8-c9d0-1234-5678-90abcdef0123'
})
};
fetch('https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'wallet_id' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'amount' => 100.5,
'payment_type' => 'send',
'idempotency_key' => 'pay_req_20260604_abc123',
'product_id' => 'd4e5f6a7-b8c9-0123-4567-890abcdef012',
'user_id' => 'b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4',
'currency' => 'USD',
'metadata' => [
'order_id' => 'ORD-12345'
],
'payment_category' => 1,
'from_hold' => false,
'payee_destination_id' => 'c8d9e0f1-a2b3-4567-89ab-cdef01234567',
'payee_payment_method_id' => 'f6a7b8c9-d0e1-2345-6789-0abcdef01234',
'payment_method_id' => 'e5f6a7b8-c9d0-1234-5678-90abcdef0123'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank"
payload := strings.NewReader("{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.finogates.com/v1/platform/payments/wallet-to-bank")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"wallet_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"amount\": 100.5,\n \"payment_type\": \"send\",\n \"idempotency_key\": \"pay_req_20260604_abc123\",\n \"product_id\": \"d4e5f6a7-b8c9-0123-4567-890abcdef012\",\n \"user_id\": \"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4\",\n \"currency\": \"USD\",\n \"metadata\": {\n \"order_id\": \"ORD-12345\"\n },\n \"payment_category\": 1,\n \"from_hold\": false,\n \"payee_destination_id\": \"c8d9e0f1-a2b3-4567-89ab-cdef01234567\",\n \"payee_payment_method_id\": \"f6a7b8c9-d0e1-2345-6789-0abcdef01234\",\n \"payment_method_id\": \"e5f6a7b8-c9d0-1234-5678-90abcdef0123\"\n}"
response = http.request(request)
puts response.read_body{
"status_code": 123,
"data": "<unknown>",
"query_generated_time": 123
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"status_code": 429,
"data": {
"detail": "You just made a payment. Please wait before making another.",
"code": "payment_cooldown",
"error_code": 1000
},
"query_generated_time": 1750000000000
}Authorizations
The access token received from the authorization server in the OAuth 2.0 flow.
Body
Pay out from a wallet to a bank account (intent_type=payout).
The required payment_type selects the flow and drives validation:
send— pay another party. Providepayee_destination_id(recommended) or the legacypayee_payment_method_id; do NOT sendpayment_method_id.transfer— withdraw to the user's OWN bank. Providepayment_method_id(the user's linked bank, the same one they fund from); do NOT send a payee. A Plaid-linked bank is connected to the payout provider on demand if it is not already.
Either way the payout is SUA-gated, moves available → escrow on submit,
and settles via webhook.
Source wallet UUID — the tenant's master wallet or one of the user's wallets. Server validates tenant ownership and currency and resolves the owner from it.
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Amount in major currency units (e.g. dollars).
100.5
Required. send pays a payee (use payee_destination_id); transfer withdraws to the user's own bank (use payment_method_id).
send, transfer "send"
Unique key to ensure idempotent payment creation.
1 - 120"pay_req_20260604_abc123"
UUID of the payout product (rail + provider route).
"d4e5f6a7-b8c9-0123-4567-890abcdef012"
Optional safety cross-check — when sent, must match the owner of wallet_id.
"b3a9b622-cc63-4d3c-aad6-2d8e29e6f9d4"
ISO 4217 currency code.
3"USD"
Arbitrary key-value metadata to attach to the payment.
{ "order_id": "ORD-12345" }
Optional. The payment category code to tag this payment with, recording what the payment was for. Omit it and the payment is created exactly as before, untagged. If you do send one it must be a code your platform can currently use, otherwise the request is rejected and no money moves. Fetch the codes from GET /v1/platform/catalog/payment-categories. Codes are issued separately in test and live, so read the list in each mode — the same number does not mean the same category across them.
x > 01
Draw this payout from the wallet's frozen (held) funds instead of its available balance. The held balance must cover the amount plus any payer-borne fee, or the request is rejected with insufficient_held_funds. Omit for a normal payout from available balance.
false
send only. UUID of the payee's destination (recommended) — the canonical field for ACH-push and digital-check auto-deposit. Either this or payee_payment_method_id is required when payment_type=send.
"c8d9e0f1-a2b3-4567-89ab-cdef01234567"
Deprecated legacy payee target (send only) — use payee_destination_id instead.
"f6a7b8c9-d0e1-2345-6789-0abcdef01234"
transfer only. UUID of the user's OWN linked bank account to withdraw to. Must belong to the wallet owner and be active. A Plaid-linked bank is connected to the payout provider on demand if it is not already.
"e5f6a7b8-c9d0-1234-5678-90abcdef0123"
Response
Successful Response
Standard response wrapper for single-object responses and errors.
Generic over the payload type. A route that declares
CommonResponse[SomeModel] gets the real data schema rendered in
OpenAPI/Swagger; a bare CommonResponse leaves data untyped.

