You are viewing the beta docs.Go to the stable docs
Better Payment

Akbank

Akbank Sanal POS (JSON API) integration reference.

You are viewing the beta docs

Install the beta with npm install better-payment@beta. Go to the stable docs

Uses Akbank's Sanal POS JSON API. Every request carries an auth-hash header (base64(HMAC-SHA512(body, secretKey))).

Configuration

import { betterPayment, akbank } from 'better-payment';

const payment = betterPayment({
  providers: {
    akbank: akbank({
      merchantSafeId: process.env.AKBANK_MERCHANT_SAFE_ID!,
      terminalSafeId: process.env.AKBANK_TERMINAL_SAFE_ID!,
      secretKey: process.env.AKBANK_SECRET_KEY!,
      // subMerchantId?: string
      // testMode: defaults to mode === 'sandbox' (test 3D gateway)
      // baseUrl: defaults from mode (apipre.akbank.com / api.akbank.com)
    }),
  },
});

paymentId is your order id: the conversationId you pass, or a generated id.

Direct Payment (non-3D)

const result = await payment.akbank.createPayment({ ...paymentRequest, conversationId: 'ORDER123' });
// txnCode 1000; success when responseCode is VPS-0000

3D Secure (3D_PAY)

const init = await payment.akbank.initThreeDSPayment({
  ...paymentRequest,
  conversationId: 'ORDER123',
  callbackUrl: 'https://yoursite.com/api/pay/akbank/payment/complete-3ds',
});
// init.threeDSHtmlContent auto-submits a signed form to the Akbank securepay gateway

Akbank authenticates the card, charges it, and POSTs the signed result to callbackUrl:

const result = await payment.akbank.completeThreeDSPayment(callbackBody);

The result is trusted only if:

  • the HMAC hash over the fields in hashParams is valid, and covers responseCode, orderId, merchantSafeId and terminalSafeId;
  • the terminal ids match your configuration;
  • an order history query (txnCode 1010) for the orderId agrees with the callback. The signed values are joined without a separator, so the signature alone does not pin the order id; a callback that does not match Akbank's record is rejected as INVALID_HASH.

It is success only when responseCode is VPS-0000 and Akbank reports an approved payment for the order. A missing result code is never treated as success. If the query gets no response, the result is pending with NETWORK_ERROR; check it later with getPayment().

Refund, Cancel & Status

await payment.akbank.refund({ paymentId: 'ORDER123', price: '50.00', currency: 'TRY', ip: '1.2.3.4' }); // 1002
await payment.akbank.cancel({ paymentId: 'ORDER123', ip: '1.2.3.4' });                               // 1003
const status = await payment.akbank.getPayment('ORDER123');                                          // 1010
// status: 'success' (N), 'cancelled' (V/R), 'failure'

BIN and installment queries are not supported for Akbank: its Sanal POS API has no installment-rate query. binCheck() and installmentInfo() throw NOT_SUPPORTED. Installment plans come from your Akbank agreement: send installment in the payment request and compute paidPrice from your contracted rates.

On this page