PayWay
Login
Charges

Charges

Create a hosted checkout session and track its outcome. All charge calls authenticate with a pk_… API key from your backend.

POST/v1/chargesAPI key (Bearer pk_…)

Create charge

Create a hosted checkout session and get a checkout_url to redirect the customer to.

Call this from your server only — never expose the API key in a browser bundle. The routing engine picks an enabled credential slot by your preferredGateway / credentialId and priority, then returns the slot that actually produced the checkout URL.

Headers

HeaderValueRequiredNotes
Content-Typeapplication/jsonyes
Idempotency-Key<uuid>noRecommended for client retries. Server-side Idempotency-Key dedupe is not enforced yet.

Request body

FieldTypeRequiredNotes
amountdecimalyesMust be > 0. BDT.
currencyenum (BDT)yesBDT only for go-live.
orderIdstringyesYour order reference. Unique per tenant recommended.
successUrlstringyesAbsolute HTTPS URL for approved payments.
failUrlstringyesAbsolute HTTPS URL for failed payments.
cancelUrlstringnoDefaults to failUrl when omitted.
preferredGatewayenum (auto | bkash | sslcommerz)noDefault auto.
credentialIdnumbernoPin to one slot; overrides preferredGateway filter.
allowFailoverbooleannoDefault true. With credentialId + false, no cross-slot retry.

Request examples

curl -X POST "https://api.payway.sianik.com/v1/charges" \
  -H "Authorization: Bearer pk_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: <uuid>" \
  -d '{
  "amount": 500,
  "currency": "BDT",
  "orderId": "ORD-1001",
  "successUrl": "https://shop.com/ok",
  "failUrl": "https://shop.com/fail",
  "cancelUrl": "https://shop.com/cancel",
  "preferredGateway": "auto",
  "allowFailover": true
}'

Responses

201Session created

Redirect the customer's browser to checkoutUrl.

{
  "sessionId": "chs_8f2a1c9d3b4e5f60",
  "checkoutUrl": "https://sandbox.sslcommerz.com/gwprocess/v4/gw.php?Q=pay&SESSIONKEY=…",
  "status": "pending",
  "gateway": "sslcommerz",
  "credentialId": 11,
  "credentialLabel": "Main Store",
  "orderId": "ORD-1001",
  "amount": 500,
  "currency": "BDT"
}
400Validation errorVALIDATION_ERROR
{
  "code": "VALIDATION_ERROR",
  "message": "orderId, successUrl, failUrl required."
}
401Bad / missing API keyUNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "Invalid API key."
}
402Wallet depletedWALLET_DEPLETED
{
  "code": "WALLET_DEPLETED",
  "message": "SaaS fee credit is empty (operator-seeded; no self-serve top-up)."
}
403Tenant inactiveTENANT_INACTIVE
{
  "code": "TENANT_INACTIVE",
  "message": "Tenant inactive."
}
409No routeNO_ROUTE
{
  "code": "NO_ROUTE",
  "message": "No enabled credential slots match this request."
}
502Gateway unavailableGATEWAY_UNAVAILABLE
{
  "code": "GATEWAY_UNAVAILABLE",
  "message": "All gateway slots failed."
}
  • PayWay never requires or stores customer email/phone/name.
  • Fees are deducted once per (tenant, gatewayTransactionId) after a verified success.

Try it

POSThttps://api.payway.sianik.com/v1/charges
GET/v1/charges/{sessionId}API key (Bearer pk_…)

Get charge status

Poll the status of a charge session by its public session id.

Path parameters

FieldTypeRequiredNotes
sessionIdstringyesThe chs_… id returned by create charge.

Request examples

curl -X GET "https://api.payway.sianik.com/v1/charges/chs_8f2a1c9d3b4e5f60" \
  -H "Authorization: Bearer pk_live_xxx"

Responses

200Session found

This endpoint returns snake_case fields.

{
  "session_id": "chs_8f2a1c9d3b4e5f60",
  "status": "success",
  "gateway": "bkash",
  "credential_id": 21,
  "credential_label": "Brand X",
  "order_id": "ORD-1001",
  "amount": 500,
  "gateway_transaction_id": "TR0011abc"
}
404Not foundNOT_FOUND
{
  "code": "NOT_FOUND",
  "message": "Session not found."
}
  • Statuses: pending | success | failed | cancelled. expired is reserved and not assigned.

Try it

GEThttps://api.payway.sianik.com/v1/charges/{sessionId}

Routing & failover

The routing engine builds a queue of enabled credential slots, then tries them in order:

  1. If credentialId is set → that slot first (plus sibling slots by priority when allowFailover is true).
  2. Else if preferredGateway is bkash / sslcommerz → only enabled slots of that type, ordered by priority.
  3. Else auto → all enabled bKash + SSLCommerz slots, ordered by priority (lower first).
  4. Failover only triggers on timeout, network error, or HTTP 5xx from the gateway.
  5. The response reports gateway, credentialId, and credentialLabel of the slot that actually produced the checkout URL.
Pin a single slot. Send { "credentialId": 11, "allowFailover": false } to force one slot with no cross-slot retry.
Idempotency. Send an Idempotency-Key header on create for your own safe retries. Server-side dedupe of that header is not enforced yet — fees still deduct once per (tenant, gatewayTransactionId) after success.