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"
}Confirmar un payout por QR (Bolivia, Brasil)
Paso 2 del payout por QR (Bolivia y Brasil/PIX), cobrado exactamente igual que un payout normal: el monto local se convierte a la tasa de tu cuenta y se debita usdt_amount + comisión fija. El resultado es síncrono — la respuesta trae el estado final (completed, o failed con reembolso automático). Requiere una llave de idempotencia como toda operación que mueve dinero. En Bolivia la referencia escaneada es de un solo uso (un QR = un pago); en Brasil un QR PIX estático es reutilizable por diseño — págalo de nuevo con una llave distinta, y un intento fallido jamás inutiliza el QR. amount es siempre obligatorio; en Brasil, si el QR PIX trae monto fijo debe coincidir exacto — un mismatch responde 422 con el payout en status: failed y el reembolso ya aplicado (los QR de monto abierto pagan lo que envíes).
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"
}Autorizaciones
JWT de sesión (de register/login) o llave de API (pk_...).
X-API-Key: <token> se acepta como header alternativo.
Encabezados
Alternativa al campo idempotency_key del body.
Cuerpo
Del paso de escaneo.
Monto local como string decimal positivo.
BO, BR BOB, USD, BRL Saldo virtual a debitar para esta operación. Omítelo para usar el asset de settlement predeterminado de tu cuenta.
USD, USDT, USDC, BTC, GOLD, SILVER, PLATINUM, BOB, MXN, ARS Respuesta
Respuesta idempotente de un payout por QR existente.
La tasa de tu cuenta al momento de la ejecución (unidades locales por 1 USDT).
Origen de la tasa ejecutada. lot, blend o spot; se omite en filas históricas sin atribución.
lot, blend, spot Saldo virtual desde el que realmente se debitó la operación.
USD, USDT, USDC, BTC, GOLD, SILVER, PLATINUM Monto exacto debitado del saldo del asset de settlement (en unidades de ese asset). Es igual a total_debit cuando el asset es USDT. Si el payout falla se reembolsa este monto exacto — nunca se re-cotiza.
Precio USD efectivo por unidad del asset de settlement usado para convertir el total en USDT ("1" para USDT/USDC).
pending con compliance_pending: true significa que el screening técnico del beneficiario espera antes de cualquier débito o despacho al core. Después del screening, pending también puede usar compliance_dispatch_pending, compliance_dispatching o core_unreachable mientras el débito permanece retenido.
pending, processing, completed, failed Detalle del estado normalizado. compliance_pending es pre-débito; compliance_dispatch_pending, compliance_dispatching y core_unreachable son códigos durables de transición después del screening.
Falso antes de debitar un payout pendiente de screening. Verdadero después de que el screening pasa y existe el débito/hold, incluso durante las transiciones de despacho.
True cuando el screening o un control duro terminó el payout antes de cualquier débito. Es distinto de un payout fallido cuyo débito se reembolsó después.
Verdadero solo mientras el screening técnico espera antes de cualquier débito o despacho al core; pasa a falso cuando se acepta el resultado process.
Referencia de la transaccion en el banco/rail (ej. el id de transferencia del banco, con el que el beneficiario cruza el pago con su banco). En US ACH/wire/SWIFT es la referencia CBF que vuelve al crear; en el resto de corredores queda vacia hasta que el rail la reporta.
Identificador UETR/SWIFT gpi reportado por el banco después de la ejecución; vacío hasta estar disponible.
Identificador doméstico wire/ACH reportado por el banco después de la ejecución; vacío hasta estar disponible.
Presente (true) cuando la respuesta es una repetición idempotente.
Presente solo cuando existe un comprobante, normalmente después del débito y del estado final. Se omite mientras el payout espera screening técnico antes del débito.