Skip to content
v0.12.0See what's new

One API forTurkish payments.

Better Payment gives iyzico, PayTR, Sipay, Parampos and seven banks one type-safe interface, with signature-verified callbacks and a secure-by-default HTTP handler.

$npm install better-payment

iyzicogateway

3D Secure · Non-3D · Refund · Cancel · BIN · Installments

request…

One API for

  • +2 more
providers, one interface
11
runtime dependencies
0
open source license
MIT
runs anywhere JS runs
Node + Edge

Every gateway has a
completely different API.

Different request shapes, signatures, error formats and callback rules. Better Payment implements each one against the provider's specification and gives you one set of types to work with.

11 banks and payment institutions, one API

Pick one to compare its API

iyzico

Payment gateway

IYZWSv2-signed JSON API with non-3D and 3D Secure payments, a hosted checkout form, pay with IBAN (PWI), subscriptions, and BIN and installment queries.

Capabilities

  • Non-3D & 3D Secure
  • Hosted checkout form
  • Pay with IBAN (PWI)
  • Subscriptions
  • BIN & installment queries
  • Refund, cancel, status
Without · iyzico APIWith Better Payment
// JSON body + IYZWSv2 signature on every request
const rnd = Date.now() + "123456789";
const uri = "/payment/iyzipos/checkoutform/initialize/auth/ecom";
const signature = createHmac("sha256", secretKey)
  .update(rnd + uri + JSON.stringify(body))
  .digest("hex");
const auth = btoa(
  `apiKey:${apiKey}&randomKey:${rnd}&signature:${signature}`,
);

const res = await fetch(baseUrl + uri, {
  method: "POST",
  headers: {
    Authorization: "IYZWSv2 " + auth,
    "x-iyzi-rnd": rnd,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
});
// Map iyzico's status and error codes yourself
// Hosted checkout form
const result = await payment.iyzico.initCheckoutForm({
  price: "100.00",
  paidPrice: "100.00",
  currency: "TRY",
  basketId: "B1",
  callbackUrl: "https://yoursite.com/checkout/callback",
  buyer: { ... },
  basketItems: [ ... ],
});

// Render result.checkoutFormContent on your page
result.status; // "success" | "failure" | "pending"

Everything you need,
nothing you don't.

Unified API surface

createPayment, initThreeDSPayment, refund, cancel and getPayment take the same request types on every provider and return the same result shape.

Learn more

Zero dependencies

No runtime dependencies, ESM and CJS builds, and a browser-safe client. Runs on Node.js, Vercel Edge, Cloudflare Workers, Deno and Bun.

Learn more

Verified callbacks

3D Secure callbacks and PayTR notifications are checked against your own credentials, in constant time, before anything counts as paid.

Learn more

Secure-by-default handler

The HTTP handler exposes only callbacks and card queries by default. Refunds, cancels and lookups require an authorize hook.

Learn more

No double charges

A timeout returns pending with NETWORK_ERROR instead of guessing. Payment, refund and cancel requests are never retried automatically.

Learn more

Bank virtual POS,
same interface.

Talk to a bank's virtual POS directly, without a payment institution in between, using the same request and result types.

AkbankLive

Sanal POS · direct integration

Akbank's Sanal POS JSON API with HMAC-SHA512 signed requests, signature-verified 3D Secure (3D_PAY) callbacks, refunds, voids and order status queries.

View Akbank docs
  • HMAC-SHA512Signed requests & callbacks
  • 2D & 3D SecureBoth flows supported
  • Verified Callbacks3D results checked with your key
  • Direct APINo third-party middleware

On the roadmap

Scroll to explore what's next

  1. Bank virtual POS

  2. Live
  3. Live
  4. Live
  5. Live
  6. Live
  7. Live
  8. Live
  9. Live
  10. Live
  11. Live
  12. Live
  13. Live
  14. Live
  15. Live
  16. Payment institutions

  17. Live
  18. Live
  19. Planned · #40
  20. Planned · #40
  21. Planned · #40

Want to contribute?
Let's build the next part together.

A new provider, a clearer guide, a test that catches a bug. Every contribution makes Better Payment better for everyone.

Up and running
in minutes.

Install the package, configure one provider and take your first 3D Secure payment. No adapters, no glue code.

View full documentation
  1. 01

    Install the package

    terminal
    $ npm install better-payment
  2. 02

    Configure your providers

    lib/payment.ts
    import { betterPayment, iyzico } from "better-payment";
    
    export const payment = betterPayment({
      mode: "sandbox", // test URLs and provider test modes
      providers: {
        iyzico: iyzico({
          apiKey: process.env.IYZICO_API_KEY!,
          secretKey: process.env.IYZICO_SECRET_KEY!,
        }),
      },
    });
  3. 03

    Start a 3D Secure payment

    app/checkout.ts
    import { payment } from "@/lib/payment";
    
    const result = await payment.iyzico.initThreeDSPayment({
      price: "100.00",
      paidPrice: "100.00",
      currency: "TRY",
      basketId: "B1",
      callbackUrl: "https://yoursite.com/api/pay/iyzico/payment/complete-3ds",
      paymentCard: { ... },
      buyer: { ... },
      shippingAddress: { ... },
      billingAddress: { ... },
      basketItems: [ ... ],
    });
    
    // Render result.threeDSHtmlContent. The bank posts back to callbackUrl,
    // where the handler verifies the result before you mark the order paid.

Stop rewriting
payment logic.

One package for iyzico, PayTR, Sipay, Parampos and seven banks, with full TypeScript support. Upgrading from 3.x? Read the upgrade guide.

$npm install better-payment