Better Payment

iyzico

iyzico integration reference — payments, 3D Secure, checkout form, PWI, subscriptions.

iyzico uses a JSON REST API. Every request is signed with IYZWSv2 (HMAC-SHA256).

Configuration

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

const payment = betterPayment({
  providers: {
    iyzico: iyzico({
      apiKey: process.env.IYZICO_API_KEY!,
      secretKey: process.env.IYZICO_SECRET_KEY!,
      // baseUrl: defaults from mode (sandbox-api.iyzipay.com / api.iyzipay.com)
      locale: 'tr', // optional
    }),
  },
});

The basket item prices must add up exactly to price. Use buildBasket() to spread discounts and shipping over the items to the kuruş.

Direct Payment (non-3D)

const result = await payment.iyzico.createPayment(paymentRequest);
// result.paymentId — iyzico paymentId

3D Secure

const init = await payment.iyzico.initThreeDSPayment({
  ...paymentRequest,
  callbackUrl: 'https://yoursite.com/api/pay/iyzico/payment/complete-3ds',
});
// Render init.threeDSHtmlContent (already base64-decoded)

iyzico POSTs status, paymentId, conversationData, conversationId and mdStatus to callbackUrl. Pass that body as it is:

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

The payment is authorized only when the callback has status=success and mdStatus=1. Any other callback returns failure without calling iyzico.

Checkout Form

iyzico's hosted payment form. Card data never reaches your servers.

const form = await payment.iyzico.initCheckoutForm({
  price: '100.00',
  paidPrice: '100.00',
  currency: 'TRY',
  basketId: 'B1',
  callbackUrl: 'https://yoursite.com/checkout/callback',
  enabledInstallments: [1, 2, 3, 6, 9],
  buyer, shippingAddress, billingAddress, basketItems,
});
// form.checkoutFormContent or form.paymentPageUrl, and form.token

const result = await payment.iyzico.retrieveCheckoutForm(token, conversationId);

result.status shows the payment's outcome. The API call can succeed while the payment itself fails (paymentStatus: 'FAILURE'); in that case status is failure. While 3DS is still in progress, status is pending.

PWI (Korumalı Havale/EFT)

const init = await payment.iyzico.initPWIPayment({ /* same shape as the checkout form */ });
const result = await payment.iyzico.retrievePWIPayment(init.token!);
// result.status: 'pending' (paymentStatus WAITING), 'success' (SUCCESS) or 'failure'
// result.iban, result.bankName while waiting

Installments & BIN

const info = await payment.iyzico.installmentInfo({ binNumber: '552879', price: '100.00' });
// info.installmentDetails[].installmentPrices[]

const bin = await payment.iyzico.binCheck('552879');
// bin.cardType, bin.cardAssociation, bin.cardFamily, bin.bankName

Refund, Cancel & Status

// refund an amount of the payment
await payment.iyzico.refund({ paymentId: 'payment-id', price: '50.00', currency: 'TRY', ip: '1.2.3.4' });
// or refund one basket item by its paymentTransactionId (from itemTransactions)
await payment.iyzico.refund({
  paymentId: 'payment-id',
  paymentTransactionId: 'payment-transaction-id',
  price: '50.00',
  currency: 'TRY',
  ip: '1.2.3.4',
});

await payment.iyzico.cancel({ paymentId: 'payment-id', ip: '1.2.3.4' });

const status = await payment.iyzico.getPayment('payment-id');

Subscriptions (v2 API)

await payment.iyzico.createSubscriptionProduct({ name: 'Pro', description: '...' });
await payment.iyzico.createPricingPlan({
  productReferenceCode, name: 'Monthly', price: '99.90',
  paymentInterval: PaymentInterval.MONTHLY, paymentIntervalCount: 1,
});

await payment.iyzico.initializeSubscription({ pricingPlanReferenceCode, subscriptionInitialStatus: SubscriptionStatus.ACTIVE, customer, paymentCard });
await payment.iyzico.retrieveSubscription({ subscriptionReferenceCode }); // GET
await payment.iyzico.upgradeSubscription({ subscriptionReferenceCode, newPricingPlanReferenceCode });
await payment.iyzico.updateSubscriptionCard({ subscriptionReferenceCode, callbackUrl });
await payment.iyzico.cancelSubscription({ subscriptionReferenceCode });

Subscription responses keep iyzico's structure (data, systemTime). Their status is mapped to success / failure, and the full response is in rawResponse.

On this page