Products · Checkout
Hosted Checkout
A redirect-based branded payment page MerasPay hosts. PCI scope is ours; the customer sees your brand. Zero front-end integration needed.
SAQ-Acs_
How it works
- 1
Create a Checkout Session
Your server callsPOST /v1/checkout/sessionswithline_items, asuccess_url, and acancel_url. The response contains a short-livedurloncheckout.merashub.com. - 2
Redirect the customer
Send the customer tosession.url— a unique page atcheckout.merashub.com/cs_.... You can do this with a standard HTTP redirect, a button, or a meta-refresh. - 3
Customer selects rail and pays
MerasPay presents the available payment methods (Waafi, D-Money, card, and any others you have enabled). The customer picks their preferred rail and completes the payment entirely on the hosted page. - 4
MerasPay redirects back
On success, the customer is redirected tosuccess_url?session_id={CHECKOUT_SESSION_ID}. On cancel or session expiry, they are sent tocancel_url. - 5
Confirm status server-side
Your server callsGET /v1/checkout/sessions/{id}using thesession_idquery parameter to verifystatus === "complete"before fulfilling the order. - 6
Webhook also fires
checkout.session.completedis delivered to your registered webhook endpoint with the full session object. Use this as a durable, server-side fulfillment trigger.
Endpoints
POST
/v1/checkout/sessionsCreate a new Checkout Session.
GET
/v1/checkout/sessions/{id}Retrieve a session and confirm its status.
POST
/v1/checkout/sessions/{id}/expireImmediately expire an open session.
Create parameters
| Name | Type | Description |
|---|---|---|
line_itemsrequired | array | Array of { name, amount_minor, currency, quantity }. All items must share the same currency. At least one item is required. |
success_urlrequired | url | URL the customer is redirected to after payment. MerasPay appends ?session_id={CHECKOUT_SESSION_ID}. |
cancel_urlrequired | url | URL the customer is sent to if they click "Go back" or the session expires. |
customer_id | cus_ | Attach the session to an existing Customer for saved payment methods. |
payment_method_types | array | Restrict available rails. Defaults to all rails enabled for your merchant account. Example: ["waafi", "dmoney", "card"]. |
expires_after_seconds | integer | Session lifetime in seconds. Maximum 86400 (24 h). Defaults to 1800. |
metadata | map | Free-form string-string map. Returned on the session object and in webhooks. |
Example
POST /v1/checkout/sessionsbash
curl -X POST https://api.merashub.com/v1/checkout/sessions \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"line_items": [
{
"name": "Premium subscription",
"amount_minor": 5000,
"currency": "DJF",
"quantity": 1
}
],
"success_url": "https://yourapp.com/checkout/success",
"cancel_url": "https://yourapp.com/checkout/cancel",
"expires_after_seconds": 1800
}'201 Createdjson
{
"id": "cs_01J3NP7XRQGB4TM5FW9E2VK8LH",
"status": "open",
"url": "https://checkout.merashub.com/cs_01J3NP7XRQGB4TM5FW9E2VK8LH",
"amount_total": 5000,
"currency": "DJF",
"expires_at": "2026-05-25T09:30:00Z",
"line_items": [
{
"name": "Premium subscription",
"amount_minor": 5000,
"currency": "DJF",
"quantity": 1
}
],
"metadata": {},
"created_at": "2026-05-25T09:00:00Z"
}Webhook event
When a session transitions to complete, MerasPay delivers a checkout.session.completed event to your webhook endpoint.
checkout.session.completedjson
{
"id": "evt_01J3NP9ABCDE4TM5FW9E2VK8LH",
"type": "checkout.session.completed",
"created_at": "2026-05-25T09:04:12Z",
"data": {
"object": {
"id": "cs_01J3NP7XRQGB4TM5FW9E2VK8LH",
"status": "complete",
"payment_intent": "pi_01J3NP8XYZQ4TM5FW9E2VK8LH",
"amount_total": 5000,
"currency": "DJF",
"customer_id": null,
"metadata": {}
}
}
}ℹ
Branding and customisation
Checkout inherits your trade name, logo (from merchant.merashub.com/settings/branding), and the primary colour you set. Full white-label — custom domain and no MerasPay attribution — is available on the Enterprise plan.
⚠
Always verify server-side
Check the session status server-side after the redirect — don't fulfil on the URL redirect alone. A customer can manipulate the
session_id query string. Use GET /v1/checkout/sessions/{id} or the checkout.session.completed webhook to confirm status === "complete".