İçeriğe geç

Ödeme Değişiklikleri

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)
İşlemNe Zaman?Açıklama
CancelAynı günÖdeme işlemi aynı gün içinde iptal edilir, müşteriden para çekilmez
RefundErtesi gün ve sonrasıÇekilen para müşteriye iade edilir, 2-10 iş günü sürer

Gerçekleşmiş bir ödemeyi tamamen veya kısmen iade eder.

TEST:

POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/refund

PROD:

POST https://api.paynkolay.com.tr/marketplace/v1/payment/refund
{
"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
}
]
}
ParametreTipZorunluAçıklama
apiKeyStringİptal/iade için hesaplanmış API anahtarı
apiSecretKeyStringİptal işlemleri için özel SX değeri
mpCodeStringPazaryeri kodu
refCodeStringOrijinal işlemin referans kodu
trxTypeStringİşlem tipi: refund
trxDateStringİşlem tarihi (yyyy-MM-dd formatında)
totalTrxAmountBigDecimalToplam iade tutarı
trxCurrencyStringPara birimi (TRY, USD, EUR)
ParametreTipZorunluAçıklama
sellerExternalIdStringSatıcının external ID’si
trxAmountBigDecimalİade edilecek tutar
refundedCommissionAmountBigDecimalİade edilecek komisyon tutarı
withholdingTaxBigDecimalİade edilecek stopaj tutarı

İndirim uygulanan işlemlerde iade yaparken dikkat edilmesi gerekenler:

{
"totalTrxAmount": 900.00,
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 1000.00,
"sellerDiscountAmount": 100.00,
"withholdingTax": 7.20
}
]
}

Hesaplama:

Ürün Tutarı: 1000 TL
Satıcı İndirimi: 100 TL
Çekilen Tutar (trxAmount - sellerDiscountAmount): 900 TL
totalTrxAmount: 900 TL
{
"totalTrxAmount": 900.00,
"mpDiscountAmount": 100.00,
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 1000.00,
"sellerDiscountAmount": 0.00
}
]
}

Hesaplama:

Ürün Tutarı: 1000 TL
Pazaryeri İndirimi: 100 TL
totalTrxAmount = trxAmount - mpDiscountAmount = 900 TL
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPREF987654",
"trxType": "REFUND",
"trxReferenceCode": "REFUND123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}
// Orijinal ödeme: 500 TL (3 satıcı)
// Sadece 1 satıcıya iade yapılacak
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ı
trxCurrency: 'TRY',
sellerList: [
{
sellerExternalId: 'SELLER_001',
trxAmount: 150.00,
refundedCommissionAmount: 7.50,
withholdingTax: 1.20
}
// Diğer satıcılar gönderilmez
]
});
return refund;
}

Aynı gün içinde gerçekleşen ödemeleri iptal eder.

TEST:

POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/cancel

PROD:

POST https://api.paynkolay.com.tr/marketplace/v1/payment/cancel
{
"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": []
}
ParametreTipZorunluAçıklama
apiKeyStringİptal için hesaplanmış API anahtarı
apiSecretKeyStringİptal işlemleri için özel SX değeri
mpCodeStringPazaryeri kodu
refCodeStringİptal edilecek işlemin referans kodu
trxTypeStringİşlem tipi: cancel
trxDateStringİşlem tarihi (yyyy-MM-dd formatında)
totalTrxAmountBigDecimalİptal edilecek toplam tutar
trxCurrencyStringPara birimi
sellerListArrayBoş array gönderilir []
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPCANCEL987654",
"trxType": "CANCEL",
"trxReferenceCode": "CANCEL123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}

İ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) {
// String birleştirme
const hashString = apiSecretKey_iptal + '|' + merchantSecretKey;
// 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);

class PaymentRefundManager {
constructor(apiSecretKey, apiSecretKey_cancel, merchantSecretKey, mpCode) {
this.apiSecretKey = apiSecretKey;
this.apiSecretKey_cancel = apiSecretKey_cancel;
this.merchantSecretKey = merchantSecretKey;
this.mpCode = mpCode;
}
calculateRefundApiKey() {
const hashString = this.apiSecretKey_cancel + '|' + this.merchantSecretKey;
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 apiKey = this.calculateRefundApiKey();
const response = await axios.post(
'https://apitest.paynkolay.com.tr/marketplace/v1/payment/refund',
{
apiKey,
apiSecretKey: this.apiSecretKey_cancel,
mpCode: this.mpCode,
refCode,
trxType: 'refund',
trxDate: new Date().toISOString().split('T')[0],
totalTrxAmount: totalAmount,
trxCurrency: 'TRY',
sellerList: sellersWithTax
}
);
return response.data;
}
calculateWithholdingTax(amountWithoutVAT) {
return amountWithoutVAT * 0.01; // %1 stopaj
}
async cancelPayment(refCode, totalAmount) {
const apiKey = this.calculateRefundApiKey();
const response = await axios.post(
'https://apitest.paynkolay.com.tr/marketplace/v1/payment/cancel',
{
apiKey,
apiSecretKey: this.apiSecretKey_cancel,
mpCode: this.mpCode,
refCode,
trxType: 'cancel',
trxDate: new Date().toISOString().split('T')[0],
totalTrxAmount: totalAmount,
trxCurrency: 'TRY',
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
}
]
);

Senaryo 1: Tek Ürün İadesi (Çok Satıcılı)

Section titled “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 edilmedi
// 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
}
]);
// Ü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
}
]);

İptal/İade Başarısız Olabilir Çünkü:

Section titled “İptal/İade Başarısız Olabilir Çünkü:”
HataSebepÇözüm
ALREADY_REFUNDEDİşlem zaten iade edilmişİade durumunu kontrol edin
INSUFFICIENT_BALANCEYetersiz bakiyeSatıcı hesabında yeterli bakiye olmalı
INVALID_DATEGeçersiz tarihTarih formatını kontrol edin (yyyy-MM-dd)
TRANSACTION_NOT_FOUNDİşlem bulunamadırefCode’u kontrol edin
SAME_DAY_USE_CANCELAynı gün için refund kullanılmışCancel kullanın
INVALID_HASHHash doğrulama hatasıİptal SX değerini kontrol edin
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;
}
}

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;
}
}

İ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