OI Payments Docs

Introduction

A centralized payment service — hosted checkout, invoicing, refunds, a double-entry ledger, and signed webhooks — that any internal application can integrate against.

OI Payments is a shared payment service. Instead of every application re-implementing gateway integration, reconciliation, and refund handling, an app integrates once against this API and gets:

  • Hosted checkout through the SSLCOMMERZ gateway — you never touch card data.
  • Invoicing with line items, branded PDFs, payable links, and installments.
  • Refunds (full or partial) with an optional approval workflow.
  • Signed webhooks so your app reacts to payment, refund, and invoice events.
  • A double-entry ledger and settlement reconciliation behind the scenes.
  • An admin dashboard with role-based access for operators.

How integration works

sequenceDiagram
    participant App as Your app
    participant API as OI Payments API
    participant GW as SSLCOMMERZ
    participant Cust as Customer

    App->>API: POST /payments (X-Api-Key + X-Api-Secret)
    API-->>App: PaymentDto { reference, checkoutUrl }
    App->>Cust: redirect to checkoutUrl
    Cust->>GW: completes payment
    GW->>API: server-to-server callback (IPN)
    API-->>App: webhook payment.succeeded (signed)
    App->>API: GET /payments/{id} (confirm)

Your app authenticates with an API key + secret, creates a payment, and redirects the customer to the returned checkoutUrl. The gateway calls back to the service; the service confirms the payment, posts to the ledger, and delivers a signed webhook to your app. Money never moves optimistically — your app reacts to the confirmed state, not the redirect.

Three things to know first

Money is integer minor units

Every amount is an integer count of the currency's smallest unit (paisa for BDT) — 10000 means 100.00 BDT. Never use floating point for money.

Test and live are fully isolated

Every record carries a mode of TEST or LIVE, derived from the credential that authenticated the request — never from the request body. A test key can never touch live data.

Every response uses one envelope

Success or failure, every endpoint returns the same { data, meta, pagination } shape with a stable, machine-readable errorCode. See Responses & errors.

Where to go next

On this page