Возвраты
Возврат отправляет деньги обратно на банковский счёт плательщика из доступного баланса проекта. Возвращайте любую часть оплаченного платежа — сразу или в несколько приёмов.
#!/usr/bin/env bash# Refund a succeeded payment to the payer's bank account.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
payment_id=$(mka_required PAYMENT_ID)body=$(cat <<JSON{ "amount": "${AMOUNT:-1000.00}", "currency": "LKR", "reason": "requested_by_customer", "recipient": { "bank_name": "Bank of Ceylon", "account_holder": "N. Fernando", "account_number": "0087654321" }}JSON)mka_request POST "/v1/payments/$payment_id/refunds" "$body" "$(mka_new_key)"// Refund a succeeded payment to the payer's bank account.import { newKey, print, request, required } from "../signed-request.mjs";
const paymentId = required("PAYMENT_ID");const answer = await request("POST", `/v1/payments/${paymentId}/refunds`, { body: { amount: process.env.AMOUNT ?? "1000.00", currency: "LKR", reason: "requested_by_customer", recipient: { bank_name: "Bank of Ceylon", account_holder: "N. Fernando", account_number: "0087654321", }, }, idempotencyKey: newKey(),});print(answer);<?php// Refund a succeeded payment to the payer's bank account.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
$paymentId = mka_required('PAYMENT_ID');mka_show(mka_request( 'POST', "/v1/payments/{$paymentId}/refunds", [ 'amount' => getenv('AMOUNT') ?: '1000.00', 'currency' => 'LKR', 'reason' => 'requested_by_customer', 'recipient' => [ 'bank_name' => 'Bank of Ceylon', 'account_holder' => 'N. Fernando', 'account_number' => '0087654321', ], ], mka_new_key(),));"""Refund a succeeded payment to the payer's bank account."""import os
from signed_request import new_key, request, required, show
payment_id = required("PAYMENT_ID")show(request( "POST", f"/v1/payments/{payment_id}/refunds", body={ "amount": os.environ.get("AMOUNT", "1000.00"), "currency": "LKR", "reason": "requested_by_customer", "recipient": { "bank_name": "Bank of Ceylon", "account_holder": "N. Fernando", "account_number": "0087654321", }, }, idempotency_key=new_key(),))//go:build ignore
// Refund a succeeded payment to the payer's bank account.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { paymentID := signedrequest.Required("PAYMENT_ID") signedrequest.Show(signedrequest.Request("POST", "/v1/payments/"+paymentID+"/refunds", map[string]any{ "amount": signedrequest.Env("AMOUNT", "1000.00"), "currency": "LKR", "reason": "requested_by_customer", "recipient": map[string]any{ "bank_name": "Bank of Ceylon", "account_holder": "N. Fernando", "account_number": "0087654321", }, }, signedrequest.NewKey()))}amount— не больше, чем получил платёж, за вычетом уже возвращённого и того, что в пути. Больше —422 refund_exceeds_payment. Ваша комиссия за платёж не возвращается.recipient— банковский счёт плательщика:bank_name,account_holderиaccount_number(от 6 до 20 цифр; пробелы и дефисы отбрасываются). Счёт хранится зашифрованным и читается в маскированном виде:Bank of Ceylon ••••4321.reason—requested_by_customer,duplicateилиfraudulent.
Сумма сразу блокируется на доступном балансе; если она больше, чем у вас есть, — это
422 insufficient_available_balance, и ничего не блокируется. Вернуть можно только платёж в статусе
succeeded: для любого другого — 409 payment_not_refundable.
Статусы
Заголовок раздела «Статусы»| Статус | Значение |
|---|---|
requested |
Сумма заблокирована на вашем балансе; возврат ждёт, пока его отправит агент. |
processing |
Агент отправляет возврат. |
succeeded |
Плательщик получил деньги. Финальный. |
failed |
За сутки возврат никто не взял (not_taken) или платформа его отклонила (refused). Блокировка снимается. Финальный. |
Быстро отправленный возврат может перейти из requested сразу в succeeded; не ждите processing.
Вебхуки и порядок событий
Заголовок раздела «Вебхуки и порядок событий»Каждое изменение — событие refund.status_changed с refund_id и refund_version. События одного
возврата могут прийти не по порядку: храните наибольший refund_version, который вы видели для каждого
возврата, и игнорируйте меньший. Если сомневаетесь, прочитайте возвраты платежа:
#!/usr/bin/env bash# A payment's refunds, oldest first.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
payment_id=$(mka_required PAYMENT_ID)mka_request GET "/v1/payments/$payment_id/refunds"// A payment's refunds, oldest first.import { print, request, required } from "../signed-request.mjs";
const paymentId = required("PAYMENT_ID");const answer = await request("GET", `/v1/payments/${paymentId}/refunds`);print(answer);<?php// A payment's refunds, oldest first.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
$paymentId = mka_required('PAYMENT_ID');mka_show(mka_request('GET', "/v1/payments/{$paymentId}/refunds"));"""A payment's refunds, oldest first."""from signed_request import request, required, show
payment_id = required("PAYMENT_ID")show(request("GET", f"/v1/payments/{payment_id}/refunds"))//go:build ignore
// A payment's refunds, oldest first.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { paymentID := signedrequest.Required("PAYMENT_ID") signedrequest.Show(signedrequest.Request("GET", "/v1/payments/"+paymentID+"/refunds", nil, ""))}Тот же Idempotency-Key с тем же телом возвращает возврат, созданный первым, с 201.