退款一笔卡片收款
curl --request POST \
--url https://api.qbank.cl/platform/v1/payins/{payinID}/refunds \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": "150.00",
"kind": "refund",
"reason": "customer request",
"idempotency_key": "refund-order-8842"
}
'import requests
url = "https://api.qbank.cl/platform/v1/payins/{payinID}/refunds"
payload = {
"amount": "150.00",
"kind": "refund",
"reason": "customer request",
"idempotency_key": "refund-order-8842"
}
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({
amount: '150.00',
kind: 'refund',
reason: 'customer request',
idempotency_key: 'refund-order-8842'
})
};
fetch('https://api.qbank.cl/platform/v1/payins/{payinID}/refunds', 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/payins/{payinID}/refunds",
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([
'amount' => '150.00',
'kind' => 'refund',
'reason' => 'customer request',
'idempotency_key' => 'refund-order-8842'
]),
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/payins/{payinID}/refunds"
payload := strings.NewReader("{\n \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\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/payins/{payinID}/refunds")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/payins/{payinID}/refunds")
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 \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\n}"
response = http.request(request)
puts response.read_body{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "completed",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reason": "customer request",
"idempotency_hit": true,
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:03Z"
}{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "completed",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reason": "customer request",
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:03Z"
}{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "pending",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reconciliation_required": true,
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:00Z"
}{
"error": "idempotency_key_required",
"message": "idempotency_key is required"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "the account balance is not enough to fund this refund; top up and retry with the same idempotency_key"
}{
"error": "forbidden",
"message": "credentials required"
}{
"error": "not_found",
"message": "resource not found"
}{
"error": "idempotency_conflict",
"message": "another refund with this key is in flight"
}{
"error": "refund_exceeds_payin",
"message": "the requested amount exceeds what is left to refund on this payin"
}退款一笔卡片收款
将资金退还给持卡人,并冲销你余额中的入账。仅支持状态为 credited 的卡片收款 (其他通道返回 refund_not_supported)—— 且仅当其余额实际可用时:结算仍待处理的 已确认收款(settlement_pending: true,余额在 settle_at 到账)将以 422 settlement_pending 被拒。按毛额扣款:原收款的手续费与汇率点差 不可退还。idempotency_key 为必填;重放会返回同一笔退款并带 idempotency_hit, 绝不会向处理方发送第二次退款。调用方为会话时需要 OTP(API key 豁免)。
POST
/
v1
/
payins
/
{payinID}
/
refunds
退款一笔卡片收款
curl --request POST \
--url https://api.qbank.cl/platform/v1/payins/{payinID}/refunds \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": "150.00",
"kind": "refund",
"reason": "customer request",
"idempotency_key": "refund-order-8842"
}
'import requests
url = "https://api.qbank.cl/platform/v1/payins/{payinID}/refunds"
payload = {
"amount": "150.00",
"kind": "refund",
"reason": "customer request",
"idempotency_key": "refund-order-8842"
}
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({
amount: '150.00',
kind: 'refund',
reason: 'customer request',
idempotency_key: 'refund-order-8842'
})
};
fetch('https://api.qbank.cl/platform/v1/payins/{payinID}/refunds', 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/payins/{payinID}/refunds",
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([
'amount' => '150.00',
'kind' => 'refund',
'reason' => 'customer request',
'idempotency_key' => 'refund-order-8842'
]),
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/payins/{payinID}/refunds"
payload := strings.NewReader("{\n \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\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/payins/{payinID}/refunds")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/payins/{payinID}/refunds")
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 \"amount\": \"150.00\",\n \"kind\": \"refund\",\n \"reason\": \"customer request\",\n \"idempotency_key\": \"refund-order-8842\"\n}"
response = http.request(request)
puts response.read_body{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "completed",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reason": "customer request",
"idempotency_hit": true,
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:03Z"
}{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "completed",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reason": "customer request",
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:03Z"
}{
"refund_id": "6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c",
"payin_id": "d0135ed5-8e9c-4f8b-a522-8ec100470426",
"account_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"kind": "refund",
"status": "pending",
"currency": "USD",
"local_amount": "150.00",
"usdt_debited": "150.000000",
"requested_by": "account",
"idempotency_key": "refund-order-8842",
"reconciliation_required": true,
"receipt_url": "https://api.qbank.cl/platform/v1/payin-refunds/6f1a2b3c-4d5e-4f6a-8b9c-0d1e2f3a4b5c/receipt",
"created_at": "2026-07-25T13:10:00Z",
"updated_at": "2026-07-25T13:10:00Z"
}{
"error": "idempotency_key_required",
"message": "idempotency_key is required"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "the account balance is not enough to fund this refund; top up and retry with the same idempotency_key"
}{
"error": "forbidden",
"message": "credentials required"
}{
"error": "not_found",
"message": "resource not found"
}{
"error": "idempotency_conflict",
"message": "another refund with this key is in flight"
}{
"error": "refund_exceeds_payin",
"message": "the requested amount exceeds what is left to refund on this payin"
}授权
会话 JWT(来自注册/登录)或 API key(pk_...)。
也接受 X-API-Key: <token> 作为替代请求头。
请求头
一次性 OTP 令牌(见 OTP 指南)。仅适用于会话调用方。
路径参数
请求体
application/json
响应
相同幂等键的重放 —— 返回同一笔退款,并带 idempotency_hit。
chargeback 由发卡机构强制发起 —— 会自动记账,并可能使余额变为负数。
可用选项:
refund, void, chargeback 可用选项:
pending, completed, failed 原始收款的货币。
从 USDT 余额中扣除的金额。原收款的手续费与汇率点差不予退还。
可用选项:
account, admin, issuer 当 status 为 failed 时出现 —— 扣款已全额冲回。
退款处于 pending 期间出现 —— 结果由对账流程解决,绝不会重新下发。
出现在 payin_refunded webhook 中 —— 该笔变动后的 USDT 余额(拒付时可能为负)。
最后修改于 2026年8月22日
⌘I