API Reference

Integrate NirbhorPay into your application to accept payments via bKash, Nagad, and Rocket.

Base URL: https://nirbhorpay.devbucket.co|Sandbox keys: up_test_sk_…|Live keys: up_live_sk_…

Sandbox vs Live

Every API key belongs to one of two environments. Use sandbox for development and testing — no real money moves. Switch to live when you are ready to accept real payments.

SandboxLive
Key prefixup_test_sk_…up_live_sk_…
Real moneyNoYes
Gateway callsSimulatedReal (bKash / Nagad / Rocket / UPay)
Checkout UIShows simulate buttonsShows real payment form
Where to createDashboard → API Keys → Sandbox tabDashboard → API Keys → Live tab

Using the sandbox

Create a payment with a sandbox key exactly as you would in production. The checkout page will show Simulate Success and Simulate Failure buttons instead of a real gateway form.

POST /api/businesses/biz_abc/checkout
X-Nirbhorpay-Api-Key: up_test_sk_...   ← sandbox key

{
  "full_name": "Test User",
  "amount": 100,
  "redirect_url": "https://yoursite.com/payment/success"
}

After the customer (or your automated test) clicks Simulate Success, the transaction moves to COMPLETED and NirbhorPay fires your webhook (if configured) with a synthetic transaction_id of the form SANDBOX_<timestamp>.

Sandbox keys are silently rejected on the live gateway endpoints and vice versa. Mixing environments is a common integration mistake — always double-check the key prefix before going live.

Going live checklist

  1. 1Create a live API key from the dashboard (prefix up_live_sk_…)
  2. 2Replace every occurrence of your sandbox key with the live key in your environment variables
  3. 3Update your redirect_url, cancel_url, and webhook_url to production URLs
  4. 4Verify at least one real payment end-to-end before opening to customers

Authentication

All API requests must include your secret key in the following header:

X-Nirbhorpay-Api-Key: up_live_sk_...   # or up_test_sk_... for sandbox
Secret keys are shown only once at creation time. Store them securely — they cannot be retrieved again.

Each key carries explicit permissions. Attempting an action your key is not permitted for returns 403 API_KEY_FORBIDDEN. Exceeded rate limits return 429 RATE_LIMITED.

Integration flow

  1. 1Call POST /checkout → receive payment_url and invoice_id
  2. 2Redirect your customer to payment_url
  3. 3Customer pays on the hosted checkout page
  4. 4NirbhorPay calls your redirect_url and/or webhook_url
  5. 5Call POST /verify server-side to confirm before fulfilling the order

1. Create a payment

POST/api/businesses/{businessId}/checkout

Initialise a new payment session. Returns a hosted checkout URL to redirect your customer to. Requires the payment:create permission.

Request body

FieldTypeRequiredDescription
full_namestringYesCustomer's full name (min 2 chars)
emailstringNoCustomer's email address
amountnumberYesAmount in BDT (must be > 0)
redirect_urlstring (URL)NoWhere to send the customer after payment
cancel_urlstring (URL)NoWhere to send the customer if they cancel
webhook_urlstring (URL)NoPer-payment webhook endpoint
return_type"GET" | "POST"NoHow redirect_url is called. Default: "GET"
metadataobjectNoArbitrary string key/value pairs stored with the transaction

When return_type is "GET", NirbhorPay appends ?invoice_id=<id> to the redirect URL.

Example request

POST /api/businesses/biz_abc/checkout
X-Nirbhorpay-Api-Key: up_live_sk_...  # use up_test_sk_... for sandbox

{
  "full_name": "Rahim Uddin",
  "email": "rahim@example.com",
  "amount": 500,
  "redirect_url": "https://yoursite.com/payment/success",
  "cancel_url": "https://yoursite.com/payment/cancel",
  "webhook_url": "https://yoursite.com/webhooks/payment",
  "metadata": { "order_id": "ORD-9921" }
}

Response 200 OK

{
  "status": true,
  "payment_url": "https://nirbhorpay.devbucket.co/pay/INV-ABC123",
  "invoice_id": "INV-ABC123",
  "webhook_signing_key": "a3f9..." // only present when webhook_url is supplied
}

webhook_signing_key is returned only when you pass a webhook_url. Use it to verify the HMAC-SHA256 signature on incoming inline webhook deliveries (see Webhooks).

Errors

StatuserrorMeaning
400VALIDATION_ERRORMissing or invalid fields
401MISSING_API_KEYNo API key header
401INVALID_API_KEYKey not found or revoked
403API_KEY_FORBIDDENKey lacks payment:create permission
429RATE_LIMITEDToo many requests

2. Verify a payment

POST/api/businesses/{businessId}/payments/verify

Confirm the final status and details of a payment. Always call this server-side before fulfilling an order. Requires the payment:verify permission.

Request body

FieldTypeRequiredDescription
invoice_idstringYesThe invoice_id returned from checkout

Example request

POST /api/businesses/biz_abc/payments/verify
X-Nirbhorpay-Api-Key: up_live_sk_...  # use up_test_sk_... for sandbox

{ "invoice_id": "INV-ABC123" }

Response 200 OK

{
  "status": true,
  "full_name": "Rahim Uddin",
  "email": "rahim@example.com",
  "amount": "500.00",
  "fee": "5.00",
  "charged_amount": "505.00",
  "invoice_id": "INV-ABC123",
  "payment_method": "BKASH",
  "sender_number": "01712345678",
  "transaction_id": "TXN8273618",
  "state": "COMPLETED"
}
FieldDescription
statustrue if payment completed, false otherwise
amountOriginal amount in BDT
feeGateway fee deducted
charged_amountTotal charged to sender (amount + fee)
payment_methodGateway used: BKASH, NAGAD, ROCKET, or UPAY
sender_numberMobile number the payment was sent from
transaction_idGateway's own transaction reference
statePENDING | COMPLETED | FAILED | CANCELLED

Errors

StatuserrorMeaning
400VALIDATION_ERRORMissing invoice_id
401MISSING_API_KEYNo API key header
401INVALID_API_KEYKey not found or revoked
403API_KEY_FORBIDDENKey lacks payment:verify permission
404NOT_FOUNDNo transaction found for this invoice ID
429RATE_LIMITEDToo many requests

3. Refund a payment

POST/api/businesses/{businessId}/payments/{id}/refund

Refund a completed payment. The transaction status transitions to REFUNDED and a payment.refunded webhook event fires. Requires the payment:refund permission.

The id path parameter is the transaction id returned from the payments list or verify endpoints. Only COMPLETED payments can be refunded.

Example request

POST /api/businesses/biz_abc/payments/clx.../refund
X-Nirbhorpay-Api-Key: up_live_sk_...

Response 200 OK

Returns the full serialized transaction with status: "REFUNDED".

Errors

StatuserrorMeaning
400ONLY_COMPLETED_CAN_REFUNDPayment is not in COMPLETED state
401MISSING_API_KEYNo API key header
401INVALID_API_KEYKey not found or revoked
403API_KEY_FORBIDDENKey lacks payment:refund permission
404TRANSACTION_NOT_FOUNDNo transaction found for this id
429RATE_LIMITEDToo many requests

Payment status lifecycle

PENDINGCOMPLETED/CANCELLED/FAILED/REFUNDED

Payments expire if not completed within 15 minutes. An expired payment stays PENDING but cannot be completed — treat it as failed if expiresAt has passed.

Webhooks

Register webhook endpoints from your dashboard. NirbhorPay sends a POST request to your URL when a payment event fires. Failed deliveries are retried up to 5 times with exponential back-off starting at 1 minute.

Events

EventTriggered when
payment.completedPayment confirmed successfully
payment.failedPayment attempt failed
payment.cancelledPayment was cancelled
payment.refundedPayment was refunded

Payload

{
  "event": "payment.completed",
  "transaction": {
    "id": "clx...",
    "invoice_id": "INV-ABC123",
    "amount": "500.00",
    "status": "COMPLETED",
    "customer_name": "Rahim Uddin",
    "customer_email": "rahim@example.com",
    "sender_number": "01712345678",
    "gateway": "BKASH",
    "transaction_id": "TXN8273618",
    "created_at": "2026-04-10T10:00:00.000Z",
    "updated_at": "2026-04-10T10:02:34.000Z"
  }
}

Verifying the signature

Every webhook request includes two headers:

HeaderValue
X-Nirbhorpay-SignatureHMAC-SHA256 of the raw request body, signed with your webhook secret
X-Nirbhorpay-EventThe event name, e.g. payment.completed
// Node.js example
import { createHmac } from "crypto"

function isValidWebhook(rawBody, signature, secret) {
  const expected = createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex")
  return expected === signature
}

// In your route handler:
const sig = req.headers["x-nirbhorpay-signature"]
if (!isValidWebhook(req.rawBody, sig, process.env.WEBHOOK_SECRET)) {
  return res.status(401).send("Invalid signature")
}
// safe to process
Always verify the signature before trusting the payload.

Gateway fees

GatewayDefault fee rate
bKash1.0%
Nagad1.0%
Rocket1.5%
UPayconfigured per account

Fee rates are configurable per gateway account in your dashboard. The defaults above apply unless overridden. Fees are reflected in fee and charged_amount on the verify response.

API key permissions

PermissionWhat it allows
payment:createCreate new payment sessions
payment:verifyVerify payment status
payment:listList transactions
payment:refundIssue refunds
link:createCreate payment links
webhook:manageManage webhook endpoints

Error format

All errors follow this shape:

{
  "status": false,
  "error": "ERROR_CODE",
  "message": "Human-readable description (where provided)"
}

Validation errors include a per-field issues array:

{
  "status": false,
  "error": "VALIDATION_ERROR",
  "issues": [
    { "path": ["amount"], "message": "Amount must be greater than 0" }
  ]
}
NirbhorPay API Reference
← Back to home