Payment Flows
Moyasar supports two payment flows:
1. Purchase (default)
Authorizes and captures in one step. The card is charged immediately and the payment status is paid.
2. Authorization
Only places a hold on the card without capturing the funds. You then decide whether to capture (charge) or void (release) the held amount.
Authorization
To authorize a payment without charging, set manual to true in the source when creating the payment.
Endpoint: POST /v1/payments
Authentication: Publishable key
- JSON
- cURL
{
"amount": 5000,
"currency": "SAR",
"description": "Order #1234",
"callback_url": "https://example.com/callback",
"source": {
"type": "creditcard",
"name": "John Doe",
"number": "4111111111111111",
"month": "01",
"year": "2027",
"cvc": "123",
"manual": true
}
}
curl -X POST https://api.moyasar.com/v1/payments \
-u pk_test_YOUR_PUBLISHABLE_KEY: \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "SAR",
"description": "Order #1234",
"callback_url": "https://example.com/callback",
"source": {
"type": "creditcard",
"name": "John Doe",
"number": "4111111111111111",
"month": "01",
"year": "2027",
"cvc": "123",
"manual": true
}
}'
The response will have "status": "authorized" instead of "paid".
Authorized payments must be captured within 14 days on the Mada scheme. Other card schemes (Visa, Mastercard, etc.) may allow longer capture windows. If you do not capture or void in time, the hold will eventually expire and the funds will be released back to the cardholder.
Capture
Captures an authorized payment, charging the cardholder.
Endpoint: POST /v1/payments/{id}/capture
Authentication: Secret key
Full Capture
curl -X POST https://api.moyasar.com/v1/payments/{payment_id}/capture \
-u sk_test_YOUR_SECRET_KEY:
No request body is needed. The full authorized amount is captured.
Partial Capture
To capture less than the authorized amount, pass the amount parameter (in the smallest currency unit).
- JSON
- cURL
{
"amount": 3000
}
curl -X POST https://api.moyasar.com/v1/payments/{payment_id}/capture \
-u sk_test_YOUR_SECRET_KEY: \
-H "Content-Type: application/json" \
-d '{ "amount": 3000 }'
- Capture amount cannot exceed the authorized amount.
- The payment status changes to
captured.
Void
Releases the hold on an authorized payment, or reverses a paid/captured payment.
Endpoint: POST /v1/payments/{id}/void
Authentication: Secret key
curl -X POST https://api.moyasar.com/v1/payments/{payment_id}/void \
-u sk_test_YOUR_SECRET_KEY:
No request body is needed. The payment status changes to voided.
- Authorized payments — can be voided within 14 days on the Mada scheme. Other card schemes may allow a longer window. If not voided in time, the issuer will automatically release the held funds back to the cardholder.
- Paid/captured payments — can only be voided within approximately 2 hours of the original transaction. After that, use a refund instead.
Prefer void over refund when possible. Voids release the hold instantly and avoid processing fees.
Refund
Returns funds to the cardholder for a charged payment.
Endpoint: POST /v1/payments/{id}/refund
Authentication: Secret key
Full Refund
curl -X POST https://api.moyasar.com/v1/payments/{payment_id}/refund \
-u sk_test_YOUR_SECRET_KEY:
No request body is needed. The full charged amount is refunded.
Partial Refund
To refund less than the charged amount, pass the amount parameter (in the smallest currency unit).
- JSON
- cURL
{
"amount": 2000
}
curl -X POST https://api.moyasar.com/v1/payments/{payment_id}/refund \
-u sk_test_YOUR_SECRET_KEY: \
-H "Content-Type: application/json" \
-d '{ "amount": 2000 }'
- Refund amount cannot exceed the charged amount.
- For
paidpayments, the maximum refundable amount is the fullamount. - For
capturedpayments, the maximum refundable amount is thecapturedamount. - The payment status changes to
refunded. - For live accounts using aggregation, your account balance must be sufficient to cover the refund.
Handling Failures
Capture Failure
- Check the payment status via
GET /v1/payments/{id}. - If still
authorized, retry the capture once. - If it fails again, ask the cardholder to use a different card and create a new payment.
Void Failure
- Check the payment status via
GET /v1/payments/{id}. - If still voidable, retry the void once.
- If it fails again:
- Authorized payments: No action needed. The hold will expire on its own and the funds will return to the cardholder.
- Paid/captured payments: Issue a refund instead.
Refund Failure
- Check the payment status via
GET /v1/payments/{id}. - If still
paidorcaptured, retry the refund once. - If it fails again, contact Moyasar support with the payment ID.
Quick Reference
| Operation | Endpoint | Auth | Allowed From Status |
|---|---|---|---|
| Authorize | POST /v1/payments with manual: true | Publishable key | — |
| Capture | POST /v1/payments/{id}/capture | Secret key | authorized |
| Void | POST /v1/payments/{id}/void | Secret key | authorized, paid, captured |
| Refund | POST /v1/payments/{id}/refund | Secret key | paid, captured |