PayWay
Login
Track B · hosted API

Unified charge API

Optional cloud path: one HTTP contract across many SSLCommerz / bKash credential slots. Default product is library-first — start at /docs/library (simulator + guides). Customer funds settle at merchant gateway accounts either way.

Looking for Track A? Merchant-hosted SDK docs, config, and interactive simulation live under Library-first · Guide · Simulate.

Getting started

  1. Sign in to the portal (demo@payway.local / ChangeMe123! in dev) to get a JWT.
  2. Add at least one credential slot (SSLCommerz or bKash).
  3. Mint an API key and store it in your backend secrets.
  4. Follow the implementation guide (Web Forms Path A/B, then redirect + confirm status).
  5. Or call POST /v1/charges directly and redirect to checkoutUrl.
  6. Receive the result via webhooks and/or poll GET /v1/charges/{id}.
Base URL. Local dev runs at http://localhost:5080. Every path below is prefixed with /v1. The interactive “Try it” panels call whatever base URL you set.
Field casing. The API uses camelCase JSON (orderId, successUrl,preferredGateway). Send API keys only from your backend — never ship them in a browser bundle.

SDKs & plugins

Prefer a thin client over raw HTTP when you can:

StackPackageInstall
.NET (Web Forms → 8)Sianik.PayWayNuGet — TFMs net462+ through net8 (samples for net45/net35)
Node / TypeScript@sianik/paywaynpm install @sianik/payway (Node 14+)
PHPsianik/paywaycomposer require sianik/payway (PHP 7.4+)
WooCommercePayWay for WooCommerceInstall zip from GitHub Releases (payway-woocommerce-x.y.z.zip)

All clients need baseUrl + apiKey. SSLCommerz / bKash credentials stay in the PayWay portal. Step-by-step (Web Forms first): Implementation guide.

Authentication

Two token types, both sent as Authorization: Bearer <token>:

TokenUsed forHow to get it
pk_… API key/v1/charges (server-to-server)Portal → Create API key (shown once)
Portal JWT/v1/portal/* managementPOST /v1/portal/auth/login (7-day expiry)
POST/v1/portal/auth/loginPublic

Portal login

Exchange tenant owner email + password for a 7-day portal JWT.

Use the returned access_token as a Bearer token for every /v1/portal/* management call. The dev seed tenant is demo@payway.local / ChangeMe123!.

Headers

HeaderValueRequiredNotes
Content-Typeapplication/jsonyes

Request body

FieldTypeRequiredNotes
emailstringyesTenant owner email.
passwordstringyesPlain password; verified with BCrypt server-side.

Request examples

curl -X POST "https://api.payway.sianik.com/v1/portal/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "demo@payway.local",
  "password": "ChangeMe123!"
}'

Responses

200Authenticated
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
  "tenant_id": 1,
  "name": "Demo Tenant"
}
401Invalid credentialsUNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "Invalid credentials."
}

Try it

POSThttps://api.payway.sianik.com/v1/portal/auth/login

Error model

Errors return the matching HTTP status with a JSON body { "code": "…", "message": "…" }. Decrypted gateway secrets are never returned.

HTTPcodeWhen
400VALIDATION_ERRORBad payload (amount ≤ 0, missing orderId/successUrl/failUrl, currency ≠ BDT).
401UNAUTHORIZEDMissing or invalid API key / credentials.
402WALLET_DEPLETEDFree tier exhausted and SaaS fee credit is 0 (operator-seeded; no self-serve top-up).
403TENANT_INACTIVETenant account disabled.
404NOT_FOUNDSession / resource not found.
409NO_ROUTENo enabled credential slots match the request.
502GATEWAY_UNAVAILABLEEvery candidate slot failed with an infra error.