Payment Operations
Payment Operations Overview #
With the marketplace payment system, you can accept card payments from end users and distribute these payments to sellers and the marketplace according to their commissions.
On this page you will learn about the following operations:
- Creating payments (3D and non-3D)
- Querying payment status
- Fetching stored card list
- Fetching installment information
- Updating commission
Withholding Tax Use Reminder #
Withholding Tax Obligation
Applying 1% withholding tax is mandatory in marketplace transactions. You must calculate the withholding tax amount over the net sales amount excluding VAT and taxes, and report it in the
Calculation:
Applying 1% withholding tax is mandatory in marketplace transactions. You must calculate the withholding tax amount over the net sales amount excluding VAT and taxes, and report it in the
withholdingTax field.Calculation:
Product Price: 100 TL Excluding VAT: 80 TL Withholding Tax: 80 TL × 0.01 = 0.8 TL
1. CreatePayment #
Initiates a new payment transaction. Used for both 3D Secure and non-3D transactions.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/createPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/createRequest Parameters #
{
"apiKey": "calculated_api_key",
"apiSecretKey": "sx_value",
"bankCard": {
"cardHolder": "AHMET YILMAZ",
"cardNumber": "4546711234567894",
"cvv": "123",
"expiryMonth": "12",
"expiryYear": "2026",
"isThreeD": true,
"registerCard": false
},
"installment": 2,
"isFetchInstallments": false,
"encodedValue": null,
"trxCurrency": "TRY",
"trxAmount": 150.00,
"trxCode": "ORDER_12345",
"trxType": "SALES",
"callbackUrl": "https://yoursite.com/payment-callback",
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"commissionRate": null,
"commissionAmount": null,
"mpCost": null,
"trxAmount": 100.00,
"withholdingTax": 0.80,
"sellerDiscountAmount": 0.00
},
{
"sellerExternalId": "SELLER_002",
"trxAmount": 50.00,
"withholdingTax": 0.40,
"sellerDiscountAmount": 0.00
}
],
"shippingCost": 0.00,
"otherAmount": 0.00,
"mpDiscountAmount": 0.00,
"totalDiscountAmount": 0.00,
"marketplaceCode": "MP12345",
"customerCardInfo": {
"mpCustomerKey": "12345678901",
"cardAlias": null,
"cardTranId": null,
"cardToken": null
}
}Parameter Details #
Basic Parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
| apiKey | String | ✅ | Key generated with hash calculation |
| apiSecretKey | String | ✅ | SX value |
| trxCurrency | String | ✅ | Currency code (TRY, USD, EUR) |
| trxAmount | BigDecimal | ✅ | Total transaction amount |
| trxCode | String | ✅ | Transaction tracking code (your own reference) |
| trxType | String | ✅ | Transaction type: SALES |
| callbackUrl | String | ✅ | URL where 3D result will be posted |
| marketplaceCode | String | ✅ | Marketplace code |
Card Information (bankCard) #
| Parameter | Type | Required | Description |
|---|---|---|---|
| cardHolder | String | ✅* | Name on card (Optional for stored card) |
| cardNumber | String | ✅* | Card number (Optional for stored card) |
| cvv | String | ✅* | CVV code (Optional for stored card) |
| expiryMonth | String | ✅* | Expiry month (Optional for stored card) |
| expiryYear | String | ✅* | Expiry year (Optional for stored card) |
| isThreeD | Boolean | ✅ | Use 3D Secure? |
| registerCard | Boolean | ✅ | Store card? (Only for 3D transactions) |
Installment Information #
| Parameter | Type | Required | Description |
|---|---|---|---|
| installment | Integer | ✅ | Number of installments (1 = single payment) |
| isFetchInstallments | Boolean | ✅ | Fetch installment info from Paynkolay? |
| encodedValue | String | ❌ | Encoded value from FetchPaymentInstallments |
Seller List (sellerList) #
| Parameter | Type | Required | Description |
|---|---|---|---|
| sellerExternalId | String | ✅ | Seller's external ID |
| trxAmount | BigDecimal | ✅ | Transaction amount for seller |
| commissionRate | BigDecimal | ❌ | Custom commission rate (outside profile) |
| commissionAmount | BigDecimal | ❌ | Calculated commission amount |
| mpCost | BigDecimal | ❌ | Transaction fee |
| withholdingTax | BigDecimal | ❌ | Withholding tax amount |
| sellerDiscountAmount | BigDecimal | ❌ | Seller discount amount |
Commission Rules
commissionRateandcommissionAmountcannot be sent at the same time- If custom commission will not be applied, send both as null
- If you only send
commissionRate, amount is automatically calculated - If you only send
commissionAmount, rate is not calculated
Discounts and Fees #
| Parameter | Type | Required | Description |
|---|---|---|---|
| shippingCost | BigDecimal | ❌ | Shipping fee |
| otherAmount | BigDecimal | ❌ | Other fees |
| mpDiscountAmount | BigDecimal | ❌ | Marketplace discount amount |
| totalDiscountAmount | BigDecimal | ❌ | Total discount amount |
Customer Card Information (customerCardInfo) #
| Parameter | Type | Required | Description |
|---|---|---|---|
| mpCustomerKey | String | ✅* | Customer identifier (ID/Mobile/Passport) - Required for card storage |
| cardAlias | String | ❌ | Card alias (for storage) |
| cardTranId | String | ❌ | Stored card ID (for payment with stored card) |
| cardToken | String | ❌ | Stored card token (for payment with stored card) |
Response #
Successful Response #
{
"data": {
"refCode": "REF123456789",
"trxCode": "ORDER_12345",
"form": "PGh0bWw+...3D HTML Form Base64..."
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Response Parameters #
| Parameter | Type | Description |
|---|---|---|
| refCode | String | Paynkolay reference code |
| trxCode | String | Your transaction code |
| form | String | Base64 encoded HTML form (filled in 3D transactions) |
3D Secure Transaction Flow #
sequenceDiagram
participant Client as Müşteri Tarayıcı
participant Your as Sizin Sunucu
participant PNK as Paynkolay
participant Bank as Banka 3D
Client->>Your: Ödeme Formu Gönder
Your->>PNK: CreatePayment (isThreeD=true)
PNK->>Your: form (Base64 HTML)
Your->>Your: Base64 Decode
Your->>Client: HTML Form Render
Client->>Bank: 3D Doğrulama
Bank->>Client: SMS/OTP
Client->>Bank: Kod Gir
Bank->>Your: callbackUrl'e POST
Your->>Your: Hash Doğrula
Your->>Client: Sonuç Sayfası3D Form Processing #
// Yanıttaki form'u decode et
const response = await createPayment(paymentData);
if (response.success && response.data.form) {
// Base64 decode
const htmlForm = Buffer.from(response.data.form, 'base64').toString('utf-8');
// HTML'i müşteriye göster
res.send(htmlForm);
}Callback Handling #
When the 3D transaction is completed, the following data will be POSTed to your callbackUrl:
app.post('/payment-callback', (req, res) => {
const {
trxCode,
trxAmount,
authAmount,
commissionRate,
authCode,
bankMessage,
installment,
responseMessage,
referenceCode,
currencyCode,
hash,
responseCode,
commissionAmount,
timestamp,
issuerBankCode,
installmentFeeRate,
installmentFeeAmount,
cardType,
paymentSystem
} = req.body;
// Hash doğrula
// verifyCallbackHash fonksiyonu detayları için: Hash Hesaplama sayfası
if (!verifyCallbackHash(req.body, apiSecretKey)) {
return res.status(400).send('Invalid hash');
}
// Başarılı ödeme
if (responseCode === '00' || responseCode === '0000') {
// Siparişi onayla
updateOrderStatus(trxCode, 'PAID');
} else {
// Hata durumu
updateOrderStatus(trxCode, 'FAILED');
}
res.status(200).send('OK');
});2. GetPaymentStatus #
Queries the status of a payment transaction.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/statusPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/statusRequest #
{
"refCode": "REF123456789",
"trxCode": "ORDER_12345"
}It is sufficient to send at least one of `refCode` or `trxCode`.
Response #
{
"data": [
{
"trxStatus": "SUCCESS",
"trxCode": "ORDER_12345",
"refCode": "REF123456789",
"trxType": "SALES",
"trxAmount": 150.00,
"trxCurrency": "TRY"
}
],
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Status Codes #
| Code | Description |
|---|---|
| SUCCESS | Successful transaction |
| PENDING | Transaction in progress |
| FAILED | Failed transaction |
| CANCELLED | Cancelled |
| REFUNDED | Refunded |
3. GetStoredCardList #
Lists stored cards belonging to a customer.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/storedCardListPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/storedCardListRequest #
{
"mpCode": "MP12345",
"apiSecretKey": "sx_value",
"mpCustomerKey": "12345678901",
"apiKey": "calculated_api_key"
}Response #
{
"data": {
"cardTotalCount": 2,
"storedCardList": [
{
"cardToken": "token_abc123",
"cardTranId": "tran_xyz789",
"cardMaskedPan": "454671******7894",
"cardIssuer": "Akbank",
"cardType": "Credit",
"cardBrand": "VISA",
"cardAlias": "İş Kartım"
},
{
"cardToken": "token_def456",
"cardTranId": "tran_uvw321",
"cardMaskedPan": "540061******1234",
"cardIssuer": "İş Bankası",
"cardType": "Debit",
"cardBrand": "MASTERCARD",
"cardAlias": "Kişisel Kart"
}
]
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Payment with Stored Card #
// Önce saklı kartları çek
const cards = await getStoredCardList({
mpCode: 'MP12345',
apiSecretKey: 'sx',
mpCustomerKey: '12345678901',
apiKey: calculateApiKey()
});
// Kullanıcıya kartları göster, seçim yaptır
const selectedCard = cards.data.storedCardList[0];
// Saklı kart ile ödeme
await createPayment({
// ... diğer parametreler
bankCard: {
isThreeD: true,
registerCard: false
// Kart bilgileri GÖNDERİLMEZ
},
customerCardInfo: {
mpCustomerKey: '12345678901',
cardTranId: selectedCard.cardTranId, // VEYA
cardToken: selectedCard.cardToken
}
});4. FetchPaymentInstallments #
Fetches installment options from Paynkolay.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/fetchInstallmentsPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/fetchInstallmentsRequest #
{
"mpCode": "MP12345",
"apiSecretKey": "sx_value",
"cardNumber": "45467112",
"amount": 1000.00,
"isCardValid": false
}| Parameter | Type | Required | Description |
|---|---|---|---|
| mpCode | String | ✅ | Marketplace code |
| apiSecretKey | String | ✅ | SX value |
| cardNumber | String | ✅ | First 6-8 digits of card number or full number |
| amount | BigDecimal | ✅ | Transaction amount |
| isCardValid | Boolean | ❌ | If true, card validity is checked |
Response #
{
"data": {
"cardScope": "WORLD",
"paymentInstallments": [
{
"installment": 1,
"installmentAmount": 1000.00,
"cardTrxType": "CREDIT",
"bankCode": "0046",
"commissionAmount": 0.00,
"commissionRate": 0.00,
"trxAmount": 1000.00,
"currencyCode": "TRY",
"currencyNumber": "949",
"program": "WORLD",
"cardBankNo": "0046",
"plusInstallment": 0,
"encodedValue": "encoded_value_1"
},
{
"installment": 2,
"installmentAmount": 510.00,
"cardTrxType": "CREDIT",
"bankCode": "0046",
"commissionAmount": 20.00,
"commissionRate": 2.00,
"trxAmount": 1020.00,
"currencyCode": "TRY",
"currencyNumber": "949",
"program": "WORLD",
"cardBankNo": "0046",
"plusInstallment": 0,
"encodedValue": "encoded_value_2"
}
]
},
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Installment Selection and Payment #
// 1. Taksit seçeneklerini çek
const installments = await fetchPaymentInstallments({
mpCode: 'MP12345',
apiSecretKey: 'sx',
cardNumber: cardNumber.substring(0, 8),
amount: 1000.00
});
// 2. Kullanıcıya taksit seçeneklerini göster
installments.data.paymentInstallments.forEach(inst => {
console.log(`${inst.installment} Taksit: ${inst.installmentAmount} TL`);
});
// 3. Kullanıcı seçim yaptı (örn: 2 taksit)
const selectedInstallment = installments.data.paymentInstallments[1];
// 4. Ödemeyi oluştur
await createPayment({
// ... diğer parametreler
installment: selectedInstallment.installment,
isFetchInstallments: true,
encodedValue: selectedInstallment.encodedValue
});5. UpdatePaymentCommission #
Updates the commission information of a payment transaction. Can only be used within the transaction day.
Endpoint #
TEST:
POST https://apitest.paynkolay.com.tr/marketplace/v1/payment/updateCommissionPROD:
POST https://api.paynkolay.com.tr/marketplace/v1/payment/updateCommissionRequest #
{
"mpCode": "MP12345",
"refCode": "REF123456789",
"trxCode": "ORDER_12345",
"sellerList": [
{
"sellerExternalId": "SELLER_001",
"commissionAmount": 5.00,
"trxAmount": 100.00,
"withholdingTax": 0.80,
"sellerDiscountAmount": 0.00
}
]
}Important
- This service can only be used on the same day as the payment transaction
- Does not work the next day
- Don't forget to update withholding tax information as well
Response #
{
"data": [
{
"mpCode": "MP12345",
"refCode": "REF123456789",
"trxCode": "ORDER_12345",
"trxCurrency": "TRY",
"trxAmount": 100.00,
"trxStatus": "SUCCESS",
"sellerTransactionList": [
{
"sellerName": "Ahmet Yılmaz",
"trxAmount": 100.00,
"trxCurrency": "TRY",
"trxStatus": "SUCCESS",
"pfCommissionRate": 2.50,
"pfCommissionAmount": 2.50,
"mpCommissionRate": 5.00,
"mpCommissionAmount": 5.00,
"mpCost": 0.50,
"trxType": "SALES",
"withholdingTax": 0.80
}
]
}
],
"success": true,
"responseCode": "200",
"responseMessage": "SUCCESS"
}Complete Payment Flow Example #
class MarketplacePayment {
async processPayment(orderData) {
try {
// 1. Taksit seçeneklerini çek
const installments = await this.fetchInstallments(
orderData.cardNumber,
orderData.amount
);
// 2. Stopaj hesapla
const sellers = orderData.items.map(item => ({
sellerExternalId: item.sellerId,
trxAmount: item.price,
withholdingTax: this.calculateWithholdingTax(item.priceWithoutVAT),
sellerDiscountAmount: item.sellerDiscount || 0
}));
// 3. ApiKey hesapla
const apiKey = this.calculateApiKey(
orderData.orderId,
orderData.amount,
'TRY',
'SALES'
);
// 4. Ödeme oluştur
const payment = await this.createPayment({
apiKey,
apiSecretKey: this.apiSecretKey,
bankCard: {
cardHolder: orderData.cardHolder,
cardNumber: orderData.cardNumber,
cvv: orderData.cvv,
expiryMonth: orderData.expiryMonth,
expiryYear: orderData.expiryYear,
isThreeD: true,
registerCard: orderData.saveCard
},
installment: orderData.selectedInstallment,
trxAmount: orderData.amount,
trxCode: orderData.orderId,
trxType: 'SALES',
trxCurrency: 'TRY',
callbackUrl: 'https://yoursite.com/payment-callback',
sellerList: sellers,
marketplaceCode: this.mpCode,
customerCardInfo: {
mpCustomerKey: orderData.customerId
}
});
// 5. 3D form'u göster
if (payment.data.form) {
const htmlForm = Buffer.from(
payment.data.form,
'base64'
).toString('utf-8');
return { type: '3D_FORM', html: htmlForm };
}
return { type: 'SUCCESS', data: payment.data };
} catch (error) {
console.error('Payment error:', error);
throw error;
}
}
calculateWithholdingTax(amountWithoutVAT) {
return amountWithoutVAT * 0.01; // %1 stopaj
}
}Next Steps #
After learning about payment operations:
- 1. Payment Modifications - Cancel and refund operations
- 2. Masterpass Integration - Alternative payment methods
- 3. Reporting - Transaction reports