Ödeme Değişiklikleri
Ödeme Değişiklikleri Genel Bakış #
Pazaryeri sisteminde gerçekleşen ödemeleri iptal edebilir veya iade yapabilirsiniz. Bu sayfada aşağıdaki işlemleri öğreneceksiniz:
- PaymentRefund - Kısmi veya tam iade işlemleri
- PaymentCancel - Ödeme iptali (aynı gün içinde)
İptal vs İade #
| İşlem | Ne Zaman? | Açıklama |
|---|---|---|
| Cancel | Aynı gün | Ödeme işlemi aynı gün içinde iptal edilir, müşteriden para çekilmez |
| Refund | Ertesi gün ve sonrası | Çekilen para müşteriye iade edilir, 2-10 iş günü sürer |
Aynı gün içinde iptal için PaymentCancel, ertesi günler için PaymentRefund kullanın.
1. PaymentRefund #
Gerçekleşmiş bir ödemeyi tamamen veya kısmen iade eder.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/refundPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/refundİstek Parametreleri #
{
"apiKey": "calculated_api_key_for_refund",
"apiSecretKey": "sx_iptal_value",
"mpCode": "MP12345",
"refCode": "REF123456789",
"trxType": "refund",
"trxDate": "2025-01-20",
"totalTrxAmount": 150.00,
"trxCurrency": "TRY",
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 100.00,
"refundedCommissionAmount": 5.00,
"withholdingTax": 0.80
},
{
"sellerExternalId": "SELLER_002",
"trxAmount": 50.00,
"refundedCommissionAmount": 2.50,
"withholdingTax": 0.40
}
]
}Parametre Detayları #
| Parametre | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| apiKey | String | ✅ | İptal/iade için hesaplanmış API anahtarı |
| apiSecretKey | String | ✅ | İptal işlemleri için özel SX değeri |
| mpCode | String | ✅ | Pazaryeri kodu |
| refCode | String | ✅ | Orijinal işlemin referans kodu |
| trxType | String | ✅ | İşlem tipi: refund |
| trxDate | String | ✅ | İşlem tarihi (yyyy-MM-dd formatında) |
| totalTrxAmount | BigDecimal | ✅ | Toplam iade tutarı |
| trxCurrency | String | ✅ | Para birimi (TRY, USD, EUR) |
Satıcı Listesi (sellerList) #
| Parametre | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| sellerExternalId | String | ✅ | Satıcının external ID'si |
| trxAmount | BigDecimal | ✅ | İade edilecek tutar |
| refundedCommissionAmount | BigDecimal | ❌ | İade edilecek komisyon tutarı |
| withholdingTax | BigDecimal | ❌ | İade edilecek stopaj tutarı |
İade Tutarı: 100 TL
KDV Hariç: 80 TL
İade Stopajı: 80 TL × 0.01 = 0.8 TL
d-flex align-items-start mb-4" role="alert">
warning
İndirim Parametreleri ile İade #
İndirim uygulanan işlemlerde iade yaparken dikkat edilmesi gerekenler:
Satıcı İndirimi Olan İade #
{
"totalTrxAmount": 900.00,
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 1000.00,
"sellerDiscountAmount": 100.00,
"withholdingTax": 7.20
}
]
}Ürün Tutarı: 1000 TL
Satıcı İndirimi: 100 TL
Çekilen Tutar (trxAmount - sellerDiscountAmount): 900 TL
totalTrxAmount: 900 TLPazaryeri İndirimi Olan İade #
{
"totalTrxAmount": 900.00,
"mpDiscountAmount": 100.00,
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 1000.00,
"sellerDiscountAmount": 0.00
}
]
}Ürün Tutarı: 1000 TL
Pazaryeri İndirimi: 100 TL
totalTrxAmount = trxAmount - mpDiscountAmount = 900 TLYanıt #
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPREF987654",
"trxType": "REFUND",
"trxReferenceCode": "REFUND123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Kısmi İade Örneği #
// Orijinal ödeme: 500 TL (3 satıcı)
// Sadece 1 satıcıya iade yapılacak / Only 1 seller will be refunded
async function partialRefund() {
const refund = await paymentRefund({
apiKey: calculateRefundApiKey(),
apiSecretKey: process.env.API_SECRET_KEY_CANCEL,
mpCode: 'MP12345',
refCode: 'REF_ORIGINAL',
trxType: 'refund',
trxDate: '2025-01-20',
totalTrxAmount: 150.00, // Sadece 1 satıcının tutarı / Only 1 seller's amount
trxCurrency: 'TRY',
sellerList: [
{
sellerExternalId: 'SELLER_001',
trxAmount: 150.00,
refundedCommissionAmount: 7.50,
withholdingTax: 1.20
}
// Diğer satıcılar gönderilmez / Other sellers are not sent
]
});
return refund;
}2. PaymentCancel #
Aynı gün içinde gerçekleşen ödemeleri iptal eder.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/cancelPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/cancelİstek Parametreleri #
{
"apiKey": "calculated_api_key_for_cancel",
"apiSecretKey": "sx_iptal_value",
"mpCode": "MP12345",
"refCode": "REF123456789",
"trxType": "cancel",
"trxDate": "2025-01-20",
"totalTrxAmount": 150.00,
"trxCurrency": "TRY",
"sellerList": []
}| Parametre | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| apiKey | String | ✅ | İptal için hesaplanmış API anahtarı |
| apiSecretKey | String | ✅ | İptal işlemleri için özel SX değeri |
| mpCode | String | ✅ | Pazaryeri kodu |
| refCode | String | ✅ | İptal edilecek işlemin referans kodu |
| trxType | String | ✅ | İşlem tipi: cancel |
| trxDate | String | ✅ | İşlem tarihi (yyyy-MM-dd formatında) |
| totalTrxAmount | BigDecimal | ✅ | İptal edilecek toplam tutar |
| trxCurrency | String | ✅ | Para birimi |
| sellerList | Array | ✅ | Boş array gönderilir [] |
warning
Yanıt #
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPCANCEL987654",
"trxType": "CANCEL",
"trxReferenceCode": "CANCEL123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}İptal/İade Hash Hesaplama #
İptal ve iade işlemleri için özel bir SX değeri kullanılır ve hash hesaplaması aşağıdaki gibidir:
const crypto = require('crypto');
function calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey, trxType, trxDate, amount, trxCurrency, referenceCode) {
// String birleştirme
const hashString = apiSecretKey_iptal + '|' + merchantSecretKey + '|' + trxType + '|' + trxDate + '|' + amount + '|' + trxCurrency + '|' + referenceCode;
// SHA512 hash
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
// Base64 encode
return hash.toString('base64');
}
// Kullanım
const apiSecretKey_iptal = process.env.API_SECRET_KEY_CANCEL; // İptal için özel SX
const merchantSecretKey = process.env.MERCHANT_SECRET_KEY;
const apiKey = calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey, 'refund', '2025-01-20', 100.00, 'TRY', 'REF123');İptal/İade işlemleri için kullanılan
apiSecretKey değeri, ödeme işlemlerinden farklıdır. Bu değer size iptal sx olarak ayrıca verilecektir.Tam İade Örneği #
class PaymentRefundManager {
constructor(apiSecretKey, apiSecretKey_cancel, merchantSecretKey, mpCode) {
this.apiSecretKey = apiSecretKey;
this.apiSecretKey_cancel = apiSecretKey_cancel;
this.merchantSecretKey = merchantSecretKey;
this.mpCode = mpCode;
}
calculateRefundApiKey(trxType, trxDate, amount, trxCurrency, referenceCode) {
const hashString = this.apiSecretKey_cancel + '|' + this.merchantSecretKey + '|' + trxType + '|' + trxDate + '|' + amount + '|' + trxCurrency + '|' + referenceCode;
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
return hash.toString('base64');
}
async refundPayment(refCode, sellers) {
// Toplam tutarı hesapla
const totalAmount = sellers.reduce((sum, seller) => {
return sum + (seller.trxAmount - (seller.sellerDiscountAmount || 0));
}, 0);
// Stopaj hesapla
const sellersWithTax = sellers.map(seller => ({
...seller,
withholdingTax: this.calculateWithholdingTax(
seller.trxAmountWithoutVAT || seller.trxAmount * 0.8
)
}));
const trxType = 'refund';
const trxDate = new Date().toISOString().split('T')[0];
const trxCurrency = 'TRY';
const apiKey = this.calculateRefundApiKey(trxType, trxDate, totalAmount, trxCurrency, refCode);
const response = await axios.post(
'https://apitest.paynkolay.com.tr/marketplace/v1/payment/refund',
{
apiKey,
apiSecretKey: this.apiSecretKey_cancel,
mpCode: this.mpCode,
refCode,
trxType,
trxDate,
totalTrxAmount: totalAmount,
trxCurrency,
sellerList: sellersWithTax
}
);
return response.data;
}
calculateWithholdingTax(amountWithoutVAT) {
return amountWithoutVAT * 0.01; // %1 stopaj
}
async cancelPayment(refCode, totalAmount) {
const trxType = 'cancel';
const trxDate = new Date().toISOString().split('T')[0];
const trxCurrency = 'TRY';
const apiKey = this.calculateRefundApiKey(trxType, trxDate, totalAmount, trxCurrency, refCode);
const response = await axios.post(
'https://apitest.paynkolay.com.tr/marketplace/v1/payment/cancel',
{
apiKey,
apiSecretKey: this.apiSecretKey_cancel,
mpCode: this.mpCode,
refCode,
trxType,
trxDate,
totalTrxAmount: totalAmount,
trxCurrency,
sellerList: []
}
);
return response.data;
}
async cancelOrRefund(refCode, paymentDate, totalAmount, sellers = null) {
const today = new Date().toISOString().split('T')[0];
const paymentDay = new Date(paymentDate).toISOString().split('T')[0];
// Aynı gün ise cancel, değilse refund
if (paymentDay === today) {
return await this.cancelPayment(refCode, totalAmount);
} else {
if (!sellers) {
throw new Error('Refund için satıcı bilgileri gerekli');
}
return await this.refundPayment(refCode, sellers);
}
}
}
// Kullanım
const manager = new PaymentRefundManager(
process.env.API_SECRET_KEY,
process.env.API_SECRET_KEY_CANCEL,
process.env.MERCHANT_SECRET_KEY,
'MP12345'
);
// Otomatik cancel veya refund
const result = await manager.cancelOrRefund(
'REF123456789',
'2025-01-20',
150.00,
[
{
sellerExternalId: 'SELLER_001',
trxAmount: 100.00,
refundedCommissionAmount: 5.00
},
{
sellerExternalId: 'SELLER_002',
trxAmount: 50.00,
refundedCommissionAmount: 2.50
}
]
);Kısmi İade Senaryoları #
Senaryo 1: Tek Ürün İadesi (Çok Satıcılı) #
// Orijinal sipariş: 3 satıcı, toplam 500 TL
// Sadece SELLER_002'nin ürünü iade edilecek
await refundPayment('REF123', [
{
sellerExternalId: 'SELLER_002',
trxAmount: 150.00,
refundedCommissionAmount: 7.50,
withholdingTax: 1.20
}
]);
// SELLER_001 ve SELLER_003 iade edilmediSenaryo 2: Kısmi Tutar İadesi #
// Satıcı indirim yapmak istiyor
// Orijinal: 200 TL, İade: 50 TL
await refundPayment('REF456', [
{
sellerExternalId: 'SELLER_001',
trxAmount: 50.00, // Sadece 50 TL iade
refundedCommissionAmount: 2.50,
withholdingTax: 0.40
}
]);Senaryo 3: Hasarlı Ürün İndirimi #
// Ürün hasarlı geldi, %30 indirim yapılacak
// Orijinal: 300 TL
await refundPayment('REF789', [
{
sellerExternalId: 'SELLER_001',
trxAmount: 90.00, // 300 * 0.30 = 90 TL iade
refundedCommissionAmount: 4.50,
withholdingTax: 0.72
}
]);Hata Durumları #
İptal/İade Başarısız Olabilir Çünkü: #
| Hata | Sebep | Çözüm |
|---|---|---|
| ALREADY_REFUNDED | İşlem zaten iade edilmiş | İade durumunu kontrol edin |
| INSUFFICIENT_BALANCE | Yetersiz bakiye | Satıcı hesabında yeterli bakiye olmalı |
| INVALID_DATE | Geçersiz tarih | Tarih formatını kontrol edin (yyyy-MM-dd) |
| TRANSACTION_NOT_FOUND | İşlem bulunamadı | refCode'u kontrol edin |
| SAME_DAY_USE_CANCEL | Aynı gün için refund kullanılmış | Cancel kullanın |
| INVALID_HASH | Hash doğrulama hatası | İptal SX değerini kontrol edin |
Hata Yönetimi Örneği #
async function safeRefund(refCode, sellers) {
try {
const result = await refundPayment(refCode, sellers);
if (result.success) {
console.log('İade başarılı:', result.data.trxReferenceCode);
return result;
} else {
throw new Error(result.responseMessage);
}
} catch (error) {
console.error('İade hatası:', error.message);
// Hata tipine göre işlem
if (error.message.includes('ALREADY_REFUNDED')) {
console.log('Bu işlem zaten iade edilmiş');
// Veritabanında güncelle
} else if (error.message.includes('INSUFFICIENT_BALANCE')) {
console.log('Yetersiz bakiye, sonra tekrar dene');
// Kuyruğa ekle
} else {
// Genel hata
console.log('İade başarısız, destek ekibine bildir');
}
throw error;
}
}İptal/İade Bildirimi #
async function processRefundWithNotification(refCode, sellers, customerEmail) {
try {
// 1. İade işlemini gerçekleştir
const result = await refundPayment(refCode, sellers);
// 2. Müşteriye bildirim gönder
await sendEmail(customerEmail, {
subject: 'İade İşleminiz Başlatıldı',
body: `
Merhaba,
${refCode} numaralı siparişiniz için iade işlemi başlatılmıştır.
İade Tutarı: ${result.data.totalAmount} TL
İade Referans: ${result.data.trxReferenceCode}
İade tutarı 2-10 iş günü içinde hesabınıza geçecektir.
İyi günler dileriz.
`
});
// 3. Satıcılara bildir
for (const seller of sellers) {
await notifySeller(seller.sellerExternalId, {
refCode,
amount: seller.trxAmount,
commission: seller.refundedCommissionAmount
});
}
return result;
} catch (error) {
// Hata durumunda da müşteriyi bilgilendir
await sendEmail(customerEmail, {
subject: 'İade İşlemi Başarısız',
body: 'İade işleminizde bir sorun oluştu. Lütfen müşteri hizmetleriyle iletişime geçin.'
});
throw error;
}
}Sonraki Adımlar #
İptal ve iade işlemlerini öğrendikten sonra:
- 1. Masterpass Entegrasyonu - Alternatif ödeme yöntemleri
- 2. Raporlama - İade raporları ve analizler
- 3. Ödeme İşlemleri - Ödeme alma