Kuveyt Türk
Kuveyt Türk Sanal POS (KT Pay Gate) integration reference.
Uses Kuveyt Türk's KT Pay Gate JSON API. Every request carries a hashData
signature: base64(HMAC-SHA512(fields + hashPassword, hashPassword)), where
hashPassword is base64(SHA1(password)).
The 3D Secure → Provision → refund flow has not been verified end to end yet: the public test merchant in Kuveyt Türk's document rejects payments. The request signatures are verified against the KT Pay Gate test environment. Test with a small amount before going live.
Configuration
import { betterPayment, kuveytturk } from 'better-payment';
const payment = betterPayment({
providers: {
kuveytturk: kuveytturk({
merchantId: process.env.KUVEYTTURK_MERCHANT_ID!,
customerId: process.env.KUVEYTTURK_CUSTOMER_ID!,
username: process.env.KUVEYTTURK_USERNAME!,
password: process.env.KUVEYTTURK_PASSWORD!,
// paymentType?: number (default 1; required by the API)
// baseUrl: defaults from mode (boatest.kuveytturk.com.tr / sanalpos.kuveytturk.com.tr)
}),
},
});merchantId and customerId come with your Sanal POS approval. username and
password belong to a user with the API role, created in the Kuveyt Türk
corporate panel (Yönetim → Kullanıcı İşlemleri).
paymentId is your order id: the conversationId you pass, or a generated id.
3D Secure
KT Pay Gate processes 3D Secure payments only; createPayment() throws NOT_SUPPORTED.
const init = await payment.kuveytturk.initThreeDSPayment({
...paymentRequest,
conversationId: 'ORDER123',
callbackUrl: 'https://yoursite.com/api/pay/kuveytturk/payment/complete-3ds',
// failUrl?: string (defaults to callbackUrl)
});
// init.threeDSHtmlContent is the bank's card verification pageThe request needs buyer.ip, buyer.email and a Turkish buyer.gsmNumber.
Callback URLs cannot contain &. Currencies: TRY, USD and EUR; installments: 1 to 12.
After card verification, Kuveyt Türk POSTs the result to callbackUrl:
const result = await payment.kuveytturk.completeThreeDSPayment(callbackBody);The callback is not signed, so it is never trusted on its own:
- a callback without
Success=Truefails; one withoutMD,OrderIdandMerchantOrderIdis rejected asINVALID_HASH; - the order is looked up at the bank, and the bank's
OrderIdmust match the callback, otherwise it is rejected asINVALID_HASH; - the card is charged with
Provision, using the amount recorded at the bank.
The payment is success only when Provision succeeds. paymentId and conversationId are set only once the order is confirmed at the bank, so a failure never carries an order id taken from the callback.
Refund, Cancel & Status
await payment.kuveytturk.cancel({ paymentId: 'ORDER123', ip: '1.2.3.4' }); // Cancel
await payment.kuveytturk.refund({ paymentId: 'ORDER123', price: '50.00', currency: 'TRY', ip: '1.2.3.4' }); // Drawback / PartialDrawback
const status = await payment.kuveytturk.getPayment('ORDER123'); // GetTransactions
// status: 'success', 'cancelled' (fully cancelled or refunded), 'failure'cancel() voids a payment on the same day, before end of day. After end of day,
use refund(): the full amount sends Drawback, a lower amount PartialDrawback.
BIN and installment queries are not supported for Kuveyt Türk: binCheck() and installmentInfo() throw NOT_SUPPORTED. Send installment in the payment request and compute paidPrice from your contracted rates.