Testing SADAD Bill
Use a test key (sk_test_...). In test mode the bill is issued by a sandbox provider — a real-looking sadad_number with no bank behind it.
Issue a test bill
Endpoint: POST /v1/payments
Authentication: Secret key
- JSON body
- cURL
POST /v1/payments
{
"amount": 15000,
"currency": "SAR",
"description": "Test SADAD bill",
"source": { "type": "sadadbill" }
}
POST /v1/payments
curl https://api.moyasar.com/v1/payments \
-u sk_test_YOUR_SECRET_KEY: \
-d "amount=15000" \
-d "currency=SAR" \
-d "description=Test SADAD bill" \
-d "source[type]=sadadbill"
Returns initiated with a fake sadad_number:
{
"id": "e21048bc-378e-47f8-860f-129cfde465a0",
"status": "initiated",
"source": {
"type": "sadadbill",
"provider_name": "sandbox-اختبار",
"biller_code": "001",
"sadad_number": "472858584297",
"gateway_id": "moyasar_sb_aQHM2nEqvGKHQyBns4We8",
"expired_at": "2026-08-17",
"message": null
}
}
About 5 minutes later the sandbox settles the bill by webhook, just like production.
Drive the outcome
Every sandbox bill is paid after ~5 minutes — except one magic amount that expires:
| Amount | Outcome | Webhook |
|---|---|---|
SAR 500.00 (50000) | expired | payment_expired |
| any other amount | paid | payment_paid |
Use both to test your payment_paid and payment_expired handlers.
What to verify
- You display
source.sadad_numberandsource.expired_at. - Your
payment_paidhandler fulfils the order and is idempotent (webhooks can repeat). - Your
payment_expiredhandler treats the order as unpaid.
Going live
Contact Moyasar support to enable SADAD Bill on your live account, then switch to your live key (sk_live_...).