Developer Docs
Onboard a new product to accept payments in under 30 minutes: register, sign your request, call the Charge API, receive the webhook.
Quickstart (< 30 min)
1. Register your product
Create a product in the PaySwitch dashboard. You receive a product_id, api_key, and webhook_secret. Also register a callback URL (must be HTTPS).
2. Sign your request
Every API call is HMAC-signed (see the Signature guide below). Send the `X-Product-Id`, `X-Timestamp`, and `X-Signature` headers.
3. Create a charge
Call `POST /v1/charges` with an `Idempotency-Key` header. The response carries a `checkout_url` / VA / token from the routed provider.
4. Receive the webhook
PaySwitch sends one uniform signed webhook to your callback URL for each status change. Verify `X-PaySwitch-Signature` with the same recipe, then reply `200` quickly.
Signature guide
Every request is signed so it cannot be replayed. Build the signing string:
```
<X-Timestamp>.<METHOD>.<path>.<rawBody>
```
then `X-Signature = hex( HMAC-SHA256(webhook_secret, signing string) )`. The server rejects a wrong signature (`401`) or one outside the time-skew window. `METHOD` upper-case; `path` without query; `rawBody` the exact bytes sent.
Signing example
X-Product-Id: prod_demo
X-Timestamp: 1700000000
Signing string: 1700000000.POST./v1/charges.{"amount":10000,"currency":"IDR"}
X-Signature: a2953244d422279bbb4eed79f2db72b1232d5ebf3c812f55e9656e056e3a32caimport { createHmac } from 'node:crypto';
const ts = String(Math.floor(Date.now() / 1000));
const signingString = `${ts}.${'POST'}.${'/v1/charges'}.${body}`;
const sig = createHmac('sha256', webhookSecret).update(signingString).digest('hex');
// headers: X-Product-Id, X-Timestamp: ts, X-Signature: sigSandbox (test mode)
Use your test credentials to hit the sandbox at `https://sandbox.api.payswitch.efolusi.com`. Test-mode transactions are isolated from live data and move no real funds. Headers and the signature recipe are identical to production. Full reference in the OpenAPI spec: [/openapi.json](/openapi.json).