Create a charge, let the customer pay, verify the webhook. That’s the whole integration.
Each business (“concern”) has an X-Api-Key and X-Api-Secret. Create and view them in the console under Concerns. Send both as headers; keep the secret server-side only.
Amounts are in major units (Taka). return_url is where the customer’s browser comes back; ipn_url is your server-to-server webhook.
curl -X POST https://payments.rythzen.com/api/v1/charge \
-H "X-Api-Key: hostiq_live_xxxxxxxx" \
-H "X-Api-Secret: <your-secret>" \
-H "Content-Type: application/json" \
-d '{
"order_id": "INV-1042",
"amount": 1499.00,
"currency": "BDT",
"customer_name": "Rahim Uddin",
"customer_email": "[email protected]",
"customer_phone": "01712345678",
"product_name": "Shared Hosting - 1yr",
"return_url": "https://my.hostiquro.com/pay/callback",
"ipn_url": "https://api.hostiquro.com/webhooks/rythzenpay",
"metadata": {"invoice_id": 1042},
"pass_fee_to_customer": true
}'Response — redirect the customer to redirect_url:
{
"ok": true,
"ref": "rp_8f3a12c9d7e6b5a4f0",
"redirect_url": "https://pg.eps.com.bd/PG?data=...",
"merchant_txn_id": "1784736012345678",
"amount_base": "1499.00",
"amount_gross": "1537.44",
"fee": "38.44",
"currency": "BDT"
}We send the browser back to your return_url with ?ref=&status=&sig=. The signature is HMAC-SHA256(secret, "ref|status|amount_base"). Always confirm server-side with the status endpoint before fulfilling.
GET https://payments.rythzen.com/api/v1/status/{ref}
-H "X-Api-Key: ..." -H "X-Api-Secret: ..."We POST the final result to your ipn_url with an X-RythzenPay-Signature header and retry until you return a 2xx.
// Verify the signed webhook (Node example)
import crypto from "crypto";
app.post("/webhooks/rythzenpay", (req, res) => {
const p = req.body; // ref, order_id, status, amount_base, ...
const expected = crypto
.createHmac("sha256", RYTHZENPAY_SECRET)
.update(`${p.ref}|${p.status}|${p.amount_base}`)
.digest("hex");
if (expected !== req.get("X-RythzenPay-Signature")) return res.sendStatus(401);
if (p.status === "success") markOrderPaid(p.order_id, p.ref);
res.sendStatus(200); // 2xx = delivered, else we retry
});