Skip to main content
ShadhinPay Docs

Payments

Create a payment, redirect the customer to checkout, track its status, and list payments.

A payment represents one attempt to collect money from a customer. You create it, send the customer to the hosted checkout, and ShadhinPay tells you the outcome via status and webhooks.

The flow at a glance

Create the payment (POST /payments) and get a paymentUrl.
Redirect the customer to paymentUrl to pay with bKash or Nagad.
The customer is returned to your callbackUrl, and you receive a payment.completed webhook.
Confirm by reading the payment status, then fulfil the order.

Create a payment

POST /api/v1/payments

Requires the auth headers and an X-Idempotency-Key.

Request body

FieldTypeRequiredNotes
amountstringyesDecimal string, "10""200000" BDT
currencystringyes"BDT"
merchantTxnIdstringyesYour order reference; unique per business
callbackUrlstringyesWhere the customer returns after paying (HTTPS in live)
preferredVendorstringnoBKASH or NAGAD — skips the picker
customerPhonestringnoHelps pre-fill checkout
customerEmailstringno
descriptionstringnoShown on checkout
valueAvalueDstringnoYour own metadata, echoed back on reads/webhooks
expiresInMinutesintegernoCheckout window; default 15
isSandboxbooleannoOnly valid with a test key

Example

curl -X POST https://api.shadhinpay.pay/api/v1/payments \
  -H "Client-Id: HM_4f8c2b1a" \
  -H "Business-Id: HB_71c4a09e" \
  -H "X-Api-Key: sk_live_aB3kC9...9xQ2" \
  -H "X-Idempotency-Key: order-7831-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "1500.50",
    "currency": "BDT",
    "merchantTxnId": "order-7831",
    "callbackUrl": "https://shop.example.com/checkout/return",
    "preferredVendor": "BKASH",
    "customerPhone": "8801712345678",
    "description": "Order #7831",
    "valueA": "campaign=summer",
    "expiresInMinutes": 15
  }'

Response — 201 Created

{
  "status": "success",
  "message": "Payment initiated successfully",
  "data": {
    "paymentId": "PAY_20260517_K8X3M2",
    "merchantTxnId": "order-7831",
    "amount": "1500.50",
    "currency": "BDT",
    "status": "PENDING",
    "vendor": "BKASH",
    "paymentUrl": "https://com.shadhinpay.pay/pay/PAY_20260517_K8X3M2",
    "description": "Order #7831",
    "refundTotal": "0.00",
    "initiatedAt": "2026-05-17T10:00:00Z",
    "completedAt": null,
    "expiresAt": "2026-05-17T10:15:00Z",
    "valueA": "campaign=summer"
  }
}

Your next step: redirect the customer's browser to paymentUrl. That hosted page either jumps straight to the chosen provider (if you set preferredVendor) or shows a picker. After paying, the customer is sent back to your callbackUrl.

Don't fulfil on the redirect alone

The return to your callbackUrl is a UX signal, not proof of payment. Always confirm the outcome from the webhook or by reading the payment status before releasing goods.

Payment statuses

StatusMeaning
PENDINGCreated; waiting for the customer to approve at the provider
COMPLETEDPaid successfully
FAILEDThe provider rejected the payment
CANCELLEDThe customer cancelled
EXPIREDThe checkout window passed without payment
REFUNDEDFully refunded (partial refunds keep status COMPLETED)

You may also briefly see INITIATED — an internal pre-PENDING state — in reads immediately after creation.

Get a payment

GET /api/v1/payments/{paymentId}

Returns the full payment object, including current status and refundTotal. Use this to confirm an outcome or reconcile against your records.

curl https://api.shadhinpay.pay/api/v1/payments/PAY_20260517_K8X3M2 \
  -H "Client-Id: HM_4f8c2b1a" \
  -H "Business-Id: HB_71c4a09e" \
  -H "X-Api-Key: sk_live_aB3kC9...9xQ2"

List payments

GET /api/v1/payments

Supports pagination plus filters:

Query paramNotes
statusFilter by payment status
vendorBKASH or NAGAD
from / toISO-8601 date-time range
amountMin / amountMaxNumeric bounds
merchantTxnIdFind by your order reference
page / sizePage index (from 0) and page size (max 100)

The list response may include a summary block with successCount, failedCount, and totalAmount for the filtered set.

Next steps

  • Webhooks — get notified the moment a payment settles
  • Refunds
  • Testing — drive each outcome in the sandbox

On this page