Bu sayfada
Oluştur
Ödenmiş veya fazla ödenmiş bir faturayı tam tutarda ya da fazla ödeme farkı kadar ilk onaylanan gönderici adresine iade edin.
API anahtarı: Payment
Son onaylanan yatırma işleminden itibaren 14 gün içinde paid veya paid_over durumundaki bir fatura için zincir üstü iade oluşturur. Hem hedef adres hem de iade tutarı sunucu tarafından otomatik hesaplanır: fonlar ilk onaylanan fatura yatırmasının gönderici adresine (first_sender) döner ve üye işyeri bakiyesinden amount + fee düşülür.
İstek gövdesi
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
invoice_id |
string | Evet | Anahtarın kapsamındaki bir projeye ait önekli fatura kimliği (inv_...) |
mode |
string | Evet | "full" (kalan iade edilebilir fatura bakiyesini döndürür) veya "overpayment" (yalnızca talep edilen fatura tutarını aşan fazlalığı döndürür) |
external_order_id |
string | Evet | Üye işyeri ve ortam başına benzersiz idempotency referansınız (en fazla 200 karakter) |
Örnek istek
{
"invoice_id": "inv_7K2M9P4Q8R1X5Z3A0bC2dE",
"mode": "full",
"external_order_id": "refund-1042-full"
}
Kod örnekleri
Her sekme bir Payment anahtarı (pk_) ile resmi SDK kullanır. İmzalama, serileştirme, güvenli yeniden denemeler ve tipli hatalar SDK tarafından yönetilir.
API_KEY_ID="pk_live_xxxxxxxxxxxx"
API_SECRET="sk_live_xxxxxxxxxxxx"
BODY='{"invoice_id":"inv_7K2M9P4Q8R1X5Z3A0bC2dE","mode":"full","external_order_id":"refund-1042-full"}'
TS=$(date +%s)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | sed 's/^.* //')
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" POST /v1/refunds '' "$BODY_HASH" \
| openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)
curl -sS https://api.paymos.io/v1/refunds \
-H "Authorization: HMAC-SHA256 $API_KEY_ID:$SIGNATURE" \
-H "X-Request-Timestamp: $TS" \
-H "Content-Type: application/json" \
-d "$BODY"
import { Paymos, externalOrderId } from '@paymos/sdk';
const paymos = new Paymos({
apiKey: process.env.PAYMOS_API_KEY,
apiSecret: process.env.PAYMOS_API_SECRET,
});
const refund = await paymos.refunds.create({
invoiceId: 'inv_7K2M9P4Q8R1X5Z3A0bC2dE',
mode: 'full',
externalOrderId: externalOrderId('refund'),
});
console.log(refund.withdrawalId, refund.status);
import os
from paymos import Paymos
paymos = Paymos(
api_key=os.environ["PAYMOS_API_KEY"],
api_secret=os.environ["PAYMOS_API_SECRET"],
)
refund = paymos.refunds.create(
invoice_id="inv_7K2M9P4Q8R1X5Z3A0bC2dE",
mode="full",
external_order_id="refund-1042-full",
)
print(refund["withdrawal_id"], refund["status"])
<?php
use Paymos\Client;
use Paymos\ClientConfig;
use Paymos\IdempotencyKey;
$paymos = new Client(new ClientConfig(
getenv('PAYMOS_API_KEY'),
getenv('PAYMOS_API_SECRET')
));
$refund = $paymos->refunds()->create(array(
'invoice_id' => 'inv_7K2M9P4Q8R1X5Z3A0bC2dE',
'mode' => 'full',
'external_order_id' => IdempotencyKey::externalOrderId('refund'),
));
echo $refund['withdrawal_id'] . ' ' . $refund['status'];
package main
import (
"context"
"fmt"
"os"
paymos "github.com/Paymos-labs/go-sdk/v2"
)
func main() {
client, err := paymos.NewClient(os.Getenv("PAYMOS_API_KEY"), os.Getenv("PAYMOS_API_SECRET"))
if err != nil {
panic(err)
}
refund, err := client.Refunds.Create(context.Background(), paymos.CreateRefundParams{
InvoiceID: "inv_7K2M9P4Q8R1X5Z3A0bC2dE",
Mode: paymos.RefundModeFull,
ExternalOrderID: "refund-1042-full",
})
if err != nil {
panic(err)
}
fmt.Println(refund.WithdrawalID, refund.Status)
}
using Paymos;
using var paymos = new PaymosClient(
Environment.GetEnvironmentVariable("PAYMOS_API_KEY")!,
Environment.GetEnvironmentVariable("PAYMOS_API_SECRET")!);
var refund = await paymos.Refunds.CreateAsync(new CreateRefundRequest(
InvoiceId: "inv_7K2M9P4Q8R1X5Z3A0bC2dE",
Mode: RefundMode.Full,
ExternalOrderId: "refund-1042-full"));
Console.WriteLine($"{refund.WithdrawalId} {refund.Status}");
import io.paymos.CreateRefundRequest;
import io.paymos.PaymosClient;
import io.paymos.Refund;
import io.paymos.RefundMode;
PaymosClient paymos = new PaymosClient(
System.getenv("PAYMOS_API_KEY"),
System.getenv("PAYMOS_API_SECRET"));
Refund refund = paymos.refunds.create(new CreateRefundRequest(
"inv_7K2M9P4Q8R1X5Z3A0bC2dE",
RefundMode.FULL,
"refund-1042-full"));
System.out.println(refund.withdrawalId() + " " + refund.status());
require 'paymos'
paymos = Paymos::Client.new(
api_key: ENV.fetch('PAYMOS_API_KEY'),
api_secret: ENV.fetch('PAYMOS_API_SECRET')
)
refund = paymos.refunds.create(
invoice_id: 'inv_7K2M9P4Q8R1X5Z3A0bC2dE',
mode: 'full',
external_order_id: 'refund-1042-full'
)
puts "#{refund.withdrawal_id} #{refund.status}"
use paymos::{CreateRefundRequest, PaymosClient, RefundMode};
let paymos = PaymosClient::new(
std::env::var("PAYMOS_API_KEY")?,
std::env::var("PAYMOS_API_SECRET")?,
)?;
let refund = paymos
.refunds()
.create(&CreateRefundRequest {
invoice_id: "inv_7K2M9P4Q8R1X5Z3A0bC2dE".to_owned(),
mode: RefundMode::Full,
external_order_id: "refund-1042-full".to_owned(),
})
.await?;
println!("{} {}", refund.withdrawal_id, refund.status);
Yanıt (201 Created / idempotent eşleşmede 200)
{
"withdrawal_id": "wdr_6Qm2fK8xR4vN7cT1bY9dL5",
"invoice_id": "inv_7K2M9P4Q8R1X5Z3A0bC2dE",
"mode": "full",
"external_order_id": "refund-1042-full",
"status": "created",
"is_final": false,
"is_test": false,
"amount": "100.00",
"fee": "1.00",
"currency": "USDT",
"network": "TRC20",
"destination_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"first_sender": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"created_at": 1767225600,
"type": "refund",
"project_id": "prj_3F9xL2mN8pQ4rT6vW1yZ5b"
}
Yanıt alanları
| Alan | Tür | Açıklama |
|---|---|---|
withdrawal_id |
string | Bu iadeyi temsil eden önekli çekim kimliği (wdr_...) |
invoice_id |
string | İade edilen önekli fatura kimliği (inv_...) |
mode |
string | İade modu: "full" veya "overpayment" |
external_order_id |
string | Oluşturma isteğinden geri döndürülen idempotency referansınız |
status |
string | Güncel durum (created, signed, pending_review, cancelling, completed, failed veya cancelled) |
is_final |
boolean | İade uç bir duruma (completed, failed, cancelled) ulaştığında true |
is_test |
boolean | Sandbox iadeleri için true |
amount |
string | Ödeyiciye geri gönderilen tam token tutarı |
fee |
string? | amount tutarına ek olarak üye işyeri bakiyesinden düşülen sabit ağ çıkış ücreti. Sıfır olduğunda yer almaz |
currency |
string | Kripto varlık sembolü (faturanın ödeme para birimiyle aynıdır) |
network |
string | Blockchain ağ kodu (faturanın ödeme ağıyla aynıdır) |
destination_address |
string | Çıkış hedef adresi (her zaman first_sender ile aynıdır) |
first_sender |
string | Faturadaki ilk onaylanan yatırmanın kanonik gönderici adresi |
tx_hash |
string? | status değeri completed olduğunda zincir üstü işlem karması |
explorer_url |
string? | status değeri completed olduğunda tx_hash için blok gezgini bağlantısı |
created_at |
integer | Saniye cinsinden Unix zaman damgası |
completed_at |
integer? | İadenin tamamlandığı saniye cinsinden Unix zaman damgası |
failed_at |
integer? | İadenin başarısız olduğu saniye cinsinden Unix zaman damgası |
cancelled_at |
integer? | İadenin iptal edildiği saniye cinsinden Unix zaman damgası |
type |
string | Her zaman "refund" |
project_id |
string | Faturanın sahibi olan önekli proje kimliği (prj_...) |
İdempotency
Her iade denemesi için deterministik bir external_order_id gönderin. POST /v1/refunds çağrısını aynı (invoice_id, mode, external_order_id) ile yeniden denemek, ikinci bir çıkış oluşturmak yerine mevcut iadeyi 200 OK ile döndürür. Aynı external_order_id değerini farklı bir invoice_id veya mode ile kullanmak 409 idempotency_conflict ile reddedilir.
Bir fatura için aynı anda yalnızca bir aktif iade işlemde olabilir. Önce "overpayment" iadesi başlatabilir, bu işlem completed durumuna ulaştıktan sonra kalan anapara için "full" iadesi oluşturabilirsiniz.
Hatalar
| Kod | HTTP | Ne zaman |
|---|---|---|
payment_key_required |
403 | İstek bir Payment (pk_) anahtarı yerine Payout (rk_) anahtarıyla imzalandı |
refunds_not_enabled |
503 | Fatura iadeleri bu ortamda etkin değil |
invoice_not_found |
404 | invoice_id mevcut değil veya API anahtarının proje kapsamı dışında |
refund_not_eligible |
409 | Fatura paid veya paid_over durumunda değil ya da yatırmaları iadeye uygun değil |
refund_no_overpayment |
409 | mode değeri "overpayment" ancak faturada iade edilebilir fazla ödeme bakiyesi yok |
refund_sender_unknown |
409 | İlk onaylanan yatırmanın gönderici adresi mevcut değil |
refund_window_expired |
409 | Faturanın son onaylanan yatırmasından bu yana 14 günden fazla süre geçti |
refund_network_unsupported |
409 | Faturanın ödeme ağında çıkış işlemleri desteklenmiyor |
refund_in_flight |
409 | Bu fatura için başka bir iade hâlâ uç olmayan bir durumda devam ediyor |
invoice_already_refunded |
409 | Fatura zaten tamamen iade edildi |
refund_source_inconsistent |
409 | Fatura yatırma veya iade geçmişi tutarlılık doğrulamasını geçemedi |
insufficient_balance |
409 | Üye işyeri bakiyesi amount + fee tutarını karşılamaya yetmiyor |
Tam katalog için bkz. Hata Kodları.