better-payment

Quick Start

Make your first payment in under 5 minutes.

1. Initialize BetterPayment

import { BetterPayment, ProviderType } from 'better-payment';

const payment = new BetterPayment({
  mode: 'sandbox', // sandbox URLs and provider test modes; default is 'production'
  defaultProvider: ProviderType.IYZICO,
  providers: {
    iyzico: {
      enabled: true,
      config: {
        apiKey: process.env.IYZICO_API_KEY!,
        secretKey: process.env.IYZICO_SECRET_KEY!,
      },
    },
  },
});

2. Build a Payment Request

Build the request on the server from your own order data. Never take amounts from the browser.

import { Currency, BasketItemType } from 'better-payment';

const request = {
  price: '100.00',
  paidPrice: '100.00',
  currency: Currency.TRY,
  installment: 1,
  basketId: 'B67832',
  conversationId: 'ORDER123', // your order id (letters and digits only for PayTR)
  paymentCard: {
    cardHolderName: 'John Doe',
    cardNumber: '5528790000000008',
    expireMonth: '12',
    expireYear: '2030',
    cvc: '123',
  },
  buyer: {
    id: 'BY789',
    name: 'John',
    surname: 'Doe',
    gsmNumber: '+905350000000',
    email: 'johndoe@example.com',
    identityNumber: '74300864791',
    registrationAddress: 'Nidakule Göztepe, Merdivenköy Mah.',
    city: 'Istanbul',
    country: 'Turkey',
    ip: '85.34.78.112',
  },
  shippingAddress: {
    contactName: 'Jane Doe',
    city: 'Istanbul',
    country: 'Turkey',
    address: 'Nidakule Göztepe, Merdivenköy Mah.',
  },
  billingAddress: {
    contactName: 'Jane Doe',
    city: 'Istanbul',
    country: 'Turkey',
    address: 'Nidakule Göztepe, Merdivenköy Mah.',
  },
  basketItems: [
    {
      id: 'BI101',
      name: 'Binocular',
      category1: 'Collectibles',
      itemType: BasketItemType.PHYSICAL,
      price: '100.00',
    },
  ],
};

3. Start 3D Secure

const init = await payment.initThreeDSPayment({
  ...request,
  callbackUrl: 'https://yoursite.com/api/pay/iyzico/payment/complete-3ds',
});

if (init.status === 'pending') {
  // Render init.threeDSHtmlContent in the browser
  // (or redirect to init.redirectUrl when the provider returns one)
}

4. Complete 3D Secure

The bank POSTs the result to callbackUrl. Pass that POST body as it is:

const result = await payment.completeThreeDSPayment(callbackBody);

if (result.status === 'success') {
  // mark the order as paid
}

The library checks the callback with your credentials and, when the provider requires it, finalizes the payment. A forged or failed callback always returns failure. The HTTP handler does this for you.

5. Handle results

statusmeaning
successConfirmed by the provider
failureRejected; see errorCode / errorMessage
pendingWaiting for the customer, or the outcome is unknown (errorCode: 'NETWORK_ERROR')
cancelledVoided or fully refunded (status queries)

On NETWORK_ERROR the payment may still have gone through. Check it with getPayment(paymentId) before trying again. Payment, refund and cancel requests are never retried automatically.

Using Multiple Providers

const payment = new BetterPayment({
  defaultProvider: ProviderType.IYZICO,
  providers: {
    iyzico: { enabled: true, config: { /* ... */ } },
    paytr: { enabled: true, config: { /* ... */ } },
  },
});

await payment.createPayment(request);                 // default provider
await payment.paytr.initThreeDSPayment(paytrRequest); // specific provider
await payment.use(ProviderType.PAYTR).getPayment('ORDER123');

On this page