Clear docs
Examples for every request and reply, in Arabic and English.
Create payments from your system, send the customer to the payment page, and get notified when they pay. Or install a ready plugin with no coding.
// Create an invoice, then send the customer to pay$res = payunit('POST', '/v1/invoices', ['amount' => '120.00','currency' => 'USD','external_ref' => 'order-1024',]);header('Location: ' . $res['checkout_url']);
201 Created · 184 ms
{ "id": "inv_8Kq2", "status": "pending",
"checkout_url": "https://test.payunit.co/pay/inv_8Kq2" }
Webhooks
POST invoice.paid 200
Payunit-Signature: v1=9f2c…
POST payment.refunded 200
From your business dashboard, with a test key.
One request gives you the payment page link.
Your system knows at once that the customer paid.
Examples for every request and reply, in Arabic and English.
Turn it on and PayUnit shows as a payment method in your store.
For hosting companies: customers pay WHMCS invoices through PayUnit.
Ready code that saves you time.
The key is shown once, and you can cancel it any time.
Refund all or part of a payment with one request.
Real requests to the PayUnit API. Change the key and amount and try them.
Send the amount and your order number, and get the payment page link for your customer.
curl -X POST https://test.payunit.co/api/v1/invoices \
-H "Authorization: Bearer pay_live_3f9a….SECRET" \
-H "Content-Type: application/json" \
-d '{
"amount": "120.00",
"currency": "USD",
"external_ref": "order-1024",
"success_url": "https://shop.example/thanks"
}'
{
"id": "inv_8Kq2Xz4LmT7pRw1c",
"status": "pending",
"amount": "120.00",
"checkout_url": "https://test.payunit.co/pay/inv_8Kq2…"
}
See whether the invoice is paid and how much you got after fees.
curl https://test.payunit.co/api/v1/invoices/inv_8Kq2Xz4LmT7pRw1c \
-H "Authorization: Bearer pay_live_3f9a….SECRET"
{
"status": "paid",
"amount": "120.00",
"fee": "1.50",
"net": "118.50",
"paid_at": "2026-09-30T10:24:11Z"
}
Refund all or part of a payment. The idempotency key stops a double refund.
curl -X POST https://test.payunit.co/api/v1/payments/48213095517260/refunds \
-H "Authorization: Bearer pay_live_3f9a….SECRET" \
-H "Idempotency-Key: refund-1024-1" \
-d '{ "amount": "40.00", "reason": "Returned item" }'
{
"status": "completed",
"amount": "40.00"
}
With a pay_test_ key every request works the same on fully separate test data. Pay or fail a test invoice and receive signed events just like live ones, without moving any money.
# Test key: same address, same requests, no money moves
curl -X POST https://test.payunit.co/api/v1/invoices/inv_test_8Kq2Xz4LmT7p/simulate \
-H "Authorization: Bearer pay_test_7c1d….SECRET" \
-d '{ "result": "paid" }'
{
"id": "inv_test_8Kq2Xz4LmT7p",
"status": "paid",
"environment": "test"
}
Make sure the notice is from PayUnit before you update the order in your system.
// Verify the signature before trusting the event
$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_PAYUNIT_TIMESTAMP'];
$signature = $_SERVER['HTTP_PAYUNIT_SIGNATURE'];
$expected = 'v1=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(400); exit;
}
$event = json_decode($body, true); // $event['event'] === 'invoice.paid'
The full documentation and your keys are inside your business account.
Any language that sends HTTPS and JSON; a PHP library is ready.
Yes, with test keys that move no real money.
Each notice is signed with your own secret; check it before updating the order.
No. Upload the plugin and enter your key.
Open a business account in a minute. No opening fee and no monthly subscription.