curl --request POST \
--url https://api.qbank.cl/platform/v1/payouts/qr/confirm \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider_reference": "QR-REF-889923",
"amount": "700.00",
"currency": "BOB",
"description": "QR lunch payment",
"idempotency_key": "qr-2026-07-07-a"
}
'import requests
url = "https://api.qbank.cl/platform/v1/payouts/qr/confirm"
payload = {
"provider_reference": "QR-REF-889923",
"amount": "700.00",
"currency": "BOB",
"description": "QR lunch payment",
"idempotency_key": "qr-2026-07-07-a"
}
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({
provider_reference: 'QR-REF-889923',
amount: '700.00',
currency: 'BOB',
description: 'QR lunch payment',
idempotency_key: 'qr-2026-07-07-a'
})
};
fetch('https://api.qbank.cl/platform/v1/payouts/qr/confirm', 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.qbank.cl/platform/v1/payouts/qr/confirm",
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([
'provider_reference' => 'QR-REF-889923',
'amount' => '700.00',
'currency' => 'BOB',
'description' => 'QR lunch payment',
'idempotency_key' => 'qr-2026-07-07-a'
]),
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.qbank.cl/platform/v1/payouts/qr/confirm"
payload := strings.NewReader("{\n \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\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.qbank.cl/platform/v1/payouts/qr/confirm")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/payouts/qr/confirm")
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 \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\n}"
response = http.request(request)
puts response.read_body{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "completed",
"status_code": "",
"status_message": "",
"bank_reference": "00761123456",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z",
"idempotency_hit": true
}{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "completed",
"status_code": "",
"status_message": "",
"bank_reference": "00761123456",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z"
}{
"error": "invalid_request",
"message": "provider_reference (from the scan) is required"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "account balance is not enough for this operation"
}{
"error": "account_blocked",
"message": "account is not active"
}{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "failed",
"status_code": "core_rejected",
"status_message": "QR already paid",
"bank_reference": "",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z"
}Confirm a QR payout (Bolivia, Brazil)
Step 2 of the QR payout (Bolivia and Brazil/PIX), charged exactly like a regular payout: the local amount converts at your account’s rate and usdt_amount + fixed fee is debited. The result is synchronous — the response carries the final state (completed, or failed with an automatic refund). Requires an idempotency key like every money-moving operation. In Bolivia the scanned reference is single-use (one QR = one payment); in Brazil a static PIX QR is reusable by design — pay it again with a different key, and a failed attempt never burns the QR. amount is always required; in Brazil, if the PIX QR carries a fixed amount it must match exactly — a mismatch answers 422 with the payout in status: failed and the refund already applied (open-amount QRs pay whatever you send).
curl --request POST \
--url https://api.qbank.cl/platform/v1/payouts/qr/confirm \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider_reference": "QR-REF-889923",
"amount": "700.00",
"currency": "BOB",
"description": "QR lunch payment",
"idempotency_key": "qr-2026-07-07-a"
}
'import requests
url = "https://api.qbank.cl/platform/v1/payouts/qr/confirm"
payload = {
"provider_reference": "QR-REF-889923",
"amount": "700.00",
"currency": "BOB",
"description": "QR lunch payment",
"idempotency_key": "qr-2026-07-07-a"
}
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({
provider_reference: 'QR-REF-889923',
amount: '700.00',
currency: 'BOB',
description: 'QR lunch payment',
idempotency_key: 'qr-2026-07-07-a'
})
};
fetch('https://api.qbank.cl/platform/v1/payouts/qr/confirm', 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.qbank.cl/platform/v1/payouts/qr/confirm",
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([
'provider_reference' => 'QR-REF-889923',
'amount' => '700.00',
'currency' => 'BOB',
'description' => 'QR lunch payment',
'idempotency_key' => 'qr-2026-07-07-a'
]),
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.qbank.cl/platform/v1/payouts/qr/confirm"
payload := strings.NewReader("{\n \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\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.qbank.cl/platform/v1/payouts/qr/confirm")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/payouts/qr/confirm")
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 \"provider_reference\": \"QR-REF-889923\",\n \"amount\": \"700.00\",\n \"currency\": \"BOB\",\n \"description\": \"QR lunch payment\",\n \"idempotency_key\": \"qr-2026-07-07-a\"\n}"
response = http.request(request)
puts response.read_body{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "completed",
"status_code": "",
"status_message": "",
"bank_reference": "00761123456",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z",
"idempotency_hit": true
}{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "completed",
"status_code": "",
"status_message": "",
"bank_reference": "00761123456",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z"
}{
"error": "invalid_request",
"message": "provider_reference (from the scan) is required"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "account balance is not enough for this operation"
}{
"error": "account_blocked",
"message": "account is not active"
}{
"payout_id": "8e2a1b0c-9d8e-7f60-5a4b-3c2d1e0f9a8b",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"idempotency_key": "qr-2026-07-07-a",
"country": "BO",
"currency": "BOB",
"method": "qr",
"local_amount": "700.00",
"fx_rate": "6.91",
"usdt_amount": "101.302460",
"fee": "0.300000",
"total_debit": "101.602460",
"settlement_asset": "USDT",
"settlement_amount": "101.602460",
"settlement_rate": "1",
"beneficiary": {
"qr_reference": "QR-REF-889923"
},
"description": "QR lunch payment",
"status": "failed",
"status_code": "core_rejected",
"status_message": "QR already paid",
"bank_reference": "",
"created_at": "2026-07-07T12:00:00Z",
"updated_at": "2026-07-07T12:00:01Z"
}Authorizations
Session JWT (from register/login) or API key (pk_...).
X-API-Key: <token> is accepted as an alternative header.
Headers
Alternative to the idempotency_key body field.
Body
From the scan step.
Local amount as a positive decimal string.
BO, BR BOB, USD, BRL Virtual balance to debit for this operation. Accepted values are USDT, USDC, BTC, GOLD, SILVER, PLATINUM, BOB, MXN and ARS. Fiat execution currently returns 503 pricing_unavailable. Omit to use your account's default settlement asset.
USD, USDT, USDC, BTC, GOLD, SILVER, PLATINUM, BOB, MXN, ARS Response
Idempotency replay of an existing QR payout.
Your account's rate at execution time (local units per 1 USDT).
Execution rate provenance. lot, blend or spot; omitted for historical rows without attribution.
lot, blend, spot Virtual balance the operation was actually debited from.
USD, USDT, USDC, BTC, GOLD, SILVER, PLATINUM Exact amount debited from the settlement asset's balance (in that asset's units). Equals total_debit when the asset is USDT. If the payout fails this exact amount is refunded — never re-quoted.
Effective USD price per unit of the settlement asset used to convert the USDT total ("1" for USDT/USDC).
pending with compliance_pending: true means technical beneficiary screening is queued before any debit or core dispatch. After screening passes, pending can use compliance_dispatch_pending, compliance_dispatching or core_unreachable while the debit remains held.
pending, processing, completed, failed Normalized state detail. compliance_pending is pre-debit; compliance_dispatch_pending, compliance_dispatching and core_unreachable are durable post-screening transition codes.
False before a pending technical-screening payout is debited. True after screening passes and the debit/hold exists, including pending dispatch transitions.
True when screening or a hard compliance gate ended the payout before any debit. It is distinct from a failed payout whose debit was later refunded.
True only while technical screening is queued before any debit or core dispatch; false after the screening process result is accepted.
Bank/rail transaction reference (e.g. the bank's transfer id, which the beneficiary can use to cross-check the payment with their bank). On US ACH/wire/SWIFT it is the CBF reference returned immediately at create; on other corridors it stays empty until the rail reports it.
UETR/SWIFT gpi tracking identifier reported by the bank after execution; empty until available.
Domestic wire/ACH tracking identifier reported by the bank after execution; empty until available.
Present (true) when the response is an idempotent replay.
Present only when a receipt exists, normally after debit and a final-state transition. Omitted while the payout is pending technical screening before debit.