Integrate Paynet checkout in 15 minutes
A developer walkthrough: take your test API key, start a payment, redirect to checkout, and verify the webhook, with test cards so nothing touches real money.
This guide takes you from zero to a working payment in about fifteen minutes. You will create a payment, send the shopper to checkout, and confirm the result from a webhook, all in test mode, so no real money moves.
1. Get a test API key
Every Paynet account starts with a test API key named Default. You find it under API keys in your dashboard, or you can create another one there. Test keys start with sk_test_, and every payment made with one is a sandbox payment: no bank is contacted, nothing is billed, and you do not need a verified domain yet.
2. Create a payment
Send a single request with the amount in Armenian dram, your order id, and where to return the shopper:
curl https://paynet.am/api/v1/payments \
-H "X-Paynet-Key: sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "AMD",
"order_id": "ORD-1001",
"return_url": "https://shop.am/return",
"callback_url": "https://shop.am/webhooks/paynet"
}'
processor is optional. Leave it out and the shopper picks a payment method on the hosted checkout. The response includes a checkout_url. Redirect the shopper there.
3. Use the test cards
On the sandbox checkout the card number decides the outcome:
4111 1111 1111 1111- approved4000 0000 0000 0002- declined4000 0000 0000 0069- insufficient funds4000 0000 0000 0119- processor timeout
Expiry, CVV and cardholder name are not checked, so enter anything.
4. Verify the webhook
When the payment reaches a final status, Paynet POSTs a signed payload to your callback_url. Paynet sends two events:
transaction.status.updated- the payment reached a final status:completed,failedorexpired.payment.refunded- a refund went through. The body then also carries arefundobject.
A completed sandbox payment looks like this (shortened):
{
"delivery_id": "...",
"event": "transaction.status.updated",
"livemode": false,
"timestamp": "2026-06-02T09:00:00+04:00",
"transaction": { "uuid": "...", "order_id": "ORD-1001", "status": "completed", "amount": 5000, "currency": "AMD" }
}
Match on the event name and the transaction.status field, not on a single event per outcome. Verify the X-Paynet-Signature header first: it is the hex HMAC-SHA256 of the raw request body, computed with the webhook secret of the website the payment is booked on (Websites, the webhook button, Reveal secret). For a test payment while you have no verified website of your own, that is your Paynet hosted page, m plus your account number .pay.paynet.am. That signature check is the one step you should never skip. Then dedupe on delivery_id and read the payment back with GET /api/v1/orders/{order_id}/payment before you mark the order paid.
5. Go live
Live payments need a few things in place: a verified domain for your return_url and callback_url, a verified business, and a real provider (ARCA, Idram or Telcell) connected and turned on for that domain. Then swap your test key for a live key (sk_live_). The same code path you just tested handles production, no rewrite required.