Skip to content

Payment Modifications

You can cancel or refund payments made in the marketplace system. On this page, you will learn about the following operations:

  • PaymentRefund - Partial or full refund operations
  • PaymentCancel - Payment cancellation (same day only)
OperationWhen?Description
CancelSame dayPayment is cancelled on the same day, customer is not charged
RefundNext day and afterThe charged amount is refunded to the customer, takes 2-10 business days

Fully or partially refunds a completed payment.

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
}
]
}
ParameterTypeRequiredDescription
apiKeyStringCalculated API key for cancellation/refund
apiSecretKeyStringSpecial SX value for cancellation operations
mpCodeStringMarketplace code
refCodeStringReference code of the original transaction
trxTypeStringTransaction type: refund
trxDateStringTransaction date (in yyyy-MM-dd format)
totalTrxAmountBigDecimalTotal refund amount
trxCurrencyStringCurrency (TRY, USD, EUR)
ParameterTypeRequiredDescription
sellerExternalIdStringSeller’s external ID
trxAmountBigDecimalAmount to be refunded
refundedCommissionAmountBigDecimalCommission amount to be refunded
withholdingTaxBigDecimalWithholding tax amount to be refunded

Things to consider when refunding discounted transactions:

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

Calculation:

Product Amount: 1000 TL
Seller Discount: 100 TL
Charged Amount (trxAmount - sellerDiscountAmount): 900 TL
totalTrxAmount: 900 TL
{
"totalTrxAmount": 900.00,
"mpDiscountAmount": 100.00,
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"trxAmount": 1000.00,
"sellerDiscountAmount": 0.00
}
]
}

Calculation:

Product Amount: 1000 TL
Marketplace Discount: 100 TL
totalTrxAmount = trxAmount - mpDiscountAmount = 900 TL
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPREF987654",
"trxType": "REFUND",
"trxReferenceCode": "REFUND123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}
// Original payment: 500 TL (3 sellers)
// 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, // Only 1 seller's amount
trxCurrency: 'TRY',
sellerList: [
{
sellerExternalId: 'SELLER_001',
trxAmount: 150.00,
refundedCommissionAmount: 7.50,
withholdingTax: 1.20
}
// Other sellers are not sent
]
});
return refund;
}

Cancels payments made on the same day.

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": []
}
ParameterTypeRequiredDescription
apiKeyStringCalculated API key for cancellation
apiSecretKeyStringSpecial SX value for cancellation operations
mpCodeStringMarketplace code
refCodeStringReference code of the transaction to be cancelled
trxTypeStringTransaction type: cancel
trxDateStringTransaction date (in yyyy-MM-dd format)
totalTrxAmountBigDecimalTotal amount to be cancelled
trxCurrencyStringCurrency
sellerListArraySent as empty array []
{
"data": {
"trxStatus": "APPROVED",
"mpReferenceCode": "MPCANCEL987654",
"trxType": "CANCEL",
"trxReferenceCode": "CANCEL123456"
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}

A special SX value is used for cancellation and refund operations, and the hash calculation is as follows:

const crypto = require('crypto');
function calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey) {
// String concatenation
const hashString = apiSecretKey_iptal + '|' + merchantSecretKey;
// SHA512 hash
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
// Base64 encode
return hash.toString('base64');
}
// Usage
const apiSecretKey_iptal = process.env.API_SECRET_KEY_CANCEL; // Special SX for cancellation
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) {
// Calculate total amount
const totalAmount = sellers.reduce((sum, seller) => {
return sum + (seller.trxAmount - (seller.sellerDiscountAmount || 0));
}, 0);
// Calculate withholding tax
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% withholding tax
}
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];
// If same day, cancel; otherwise refund
if (paymentDay === today) {
return await this.cancelPayment(refCode, totalAmount);
} else {
if (!sellers) {
throw new Error('Seller information required for refund');
}
return await this.refundPayment(refCode, sellers);
}
}
}
// Usage
const manager = new PaymentRefundManager(
process.env.API_SECRET_KEY,
process.env.API_SECRET_KEY_CANCEL,
process.env.MERCHANT_SECRET_KEY,
'MP12345'
);
// Automatic cancel or 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
}
]
);

Scenario 1: Single Product Refund (Multiple Sellers)

Section titled “Scenario 1: Single Product Refund (Multiple Sellers)”
// Original order: 3 sellers, total 500 TL
// Only SELLER_002's product will be refunded
await refundPayment('REF123', [
{
sellerExternalId: 'SELLER_002',
trxAmount: 150.00,
refundedCommissionAmount: 7.50,
withholdingTax: 1.20
}
]);
// SELLER_001 and SELLER_003 were not refunded
// Seller wants to give a discount
// Original: 200 TL, Refund: 50 TL
await refundPayment('REF456', [
{
sellerExternalId: 'SELLER_001',
trxAmount: 50.00, // Only 50 TL refund
refundedCommissionAmount: 2.50,
withholdingTax: 0.40
}
]);
// Product arrived damaged, 30% discount will be given
// Original: 300 TL
await refundPayment('REF789', [
{
sellerExternalId: 'SELLER_001',
trxAmount: 90.00, // 300 * 0.30 = 90 TL refund
refundedCommissionAmount: 4.50,
withholdingTax: 0.72
}
]);

ErrorReasonSolution
ALREADY_REFUNDEDTransaction already refundedCheck refund status
INSUFFICIENT_BALANCEInsufficient balanceSeller account must have sufficient balance
INVALID_DATEInvalid dateCheck date format (yyyy-MM-dd)
TRANSACTION_NOT_FOUNDTransaction not foundCheck refCode
SAME_DAY_USE_CANCELRefund used for same dayUse Cancel
INVALID_HASHHash validation errorCheck cancellation SX value
async function safeRefund(refCode, sellers) {
try {
const result = await refundPayment(refCode, sellers);
if (result.success) {
console.log('Refund successful:', result.data.trxReferenceCode);
return result;
} else {
throw new Error(result.responseMessage);
}
} catch (error) {
console.error('Refund error:', error.message);
// Action based on error type
if (error.message.includes('ALREADY_REFUNDED')) {
console.log('This transaction has already been refunded');
// Update in database
} else if (error.message.includes('INSUFFICIENT_BALANCE')) {
console.log('Insufficient balance, try again later');
// Add to queue
} else {
// General error
console.log('Refund failed, notify support team');
}
throw error;
}
}

async function processRefundWithNotification(refCode, sellers, customerEmail) {
try {
// 1. Process refund
const result = await refundPayment(refCode, sellers);
// 2. Send notification to customer
await sendEmail(customerEmail, {
subject: 'Your Refund Has Been Initiated',
body: `
Hello,
A refund has been initiated for your order number ${refCode}.
Refund Amount: ${result.data.totalAmount} TL
Refund Reference: ${result.data.trxReferenceCode}
The refund amount will be credited to your account within 2-10 business days.
Have a great day.
`
});
// 3. Notify sellers
for (const seller of sellers) {
await notifySeller(seller.sellerExternalId, {
refCode,
amount: seller.trxAmount,
commission: seller.refundedCommissionAmount
});
}
return result;
} catch (error) {
// Inform customer in case of error
await sendEmail(customerEmail, {
subject: 'Refund Process Failed',
body: 'There was a problem with your refund. Please contact customer service.'
});
throw error;
}
}

After learning about cancellation and refund operations:

  1. Masterpass Integration - Alternative payment methods
  2. Reporting - Refund reports and analyses
  3. Payment Operations - Payment processing