A merchant-friendly payment flow modelled on the Noghte gateway: create a transaction, redirect your payer, then confirm the result server-to-server. Collect from your own site or app and have the net (amount minus the gateway fee) credited to your office wallet in USD.
api_key (starts with gw_) goes in the request body, never in browser code. Create one in the console under Wallet → Merchant gateway API (shown once). A test key collects in sandbox; a live key collects for real.
The flow
- Your server calls
POST /api/gateway/tokenand gets atrans_idandpayment_url. - Redirect the payer's browser (a normal GET) to
payment_url. - The payer pays by card (Flitt, with 3-D Secure) or crypto/USDT (KemApp).
- The payer's browser is sent back to your
callback_uriwith the result in the query string. - Your server calls
POST /api/gateway/verifywith the sametrans_idand the amount you stored. Treat the order as paid only when the response iscode: 0.
callback_uri come from the payer's browser and can be forged. Always confirm with /api/gateway/verify on your server.
Create a transaction
curl https://api.hermeseus.com/api/gateway/token \
-H "Content-Type: application/json" \
-d '{
"api_key": "gw_xxxxxxxx...",
"order_id": "ORDER-1001",
"amount": 1000,
"currency": "USD",
"callback_uri": "https://yourshop.example/payment/callback",
"forced_gateway": null,
"customer_email": "buyer@example.com",
"customer_phone": "+15551234567",
"payer_name": "Jane Doe",
"payer_desc": "Invoice #2043",
"custom_json_fields": "{\"cart_id\":77}",
"auto_verify": "no"
}'| Field | Req | Description |
|---|---|---|
api_key | yes | Your gateway key (gw_…). In the body, server-side only. |
order_id | yes | Your order id. 1–100 chars, A–Z a–z 0–9 _ - . : /. Not checked for uniqueness — send a unique value per attempt. Echoed back on return and in verify. |
amount | yes | Amount to collect, in currency (> 0). |
callback_uri | yes | http/https return URL. May already have a query string; our params are appended with &. |
currency | no | 3–4 letter code (default USD). Converted to the gateway's charge currency; credited to your wallet in USD. |
forced_gateway | no | flitt or kemapp to skip the picker. |
customer_email, customer_phone, payer_name, payer_desc | no | Stored; shown to the payer / in the console where relevant. |
custom_json_fields | no | A JSON string (max 5000 chars). Returned in verify as custom (an object). Sending an object instead of a string is rejected with -38. |
auto_verify | no | yes/no. We always finalize automatically from the gateway's signed callback, so verify just reports the stored result either way. |
Response 201
{
"code": -1,
"trans_id": "9f1c0b64-5b2e-4a1e-9b1a-2c3d4e5f6a7b",
"amount": 1000,
"currency": "USD",
"payment_url": "https://payment.skygate.travel/gateway/payment/9f1c0b64-5b2e-4a1e-9b1a-2c3d4e5f6a7b"
}code: -1 here means “created” (success) — this value is used only in token. Store trans_id and the amount next to your order, then redirect the payer to payment_url.
Payer return to callback_uri
After the payer returns from the gateway, we send their browser (GET) back to your callback_uri:
https://yourshop.example/payment/callback?np_status=OK&status=credited&code=0&trans_id=9f1c0b64-…&order_id=ORDER-1001&amount=1000¤cy=USD&ref_number=flt_abc123
| Param | Value |
|---|---|
np_status | OK paid · Failed declined/expired · Pending (you returned before the server callback settled — just verify) |
code | 0 paid · -2 failed · -4 expired/canceled · -3 still pending |
status, trans_id, order_id | The transaction status, our id, and your order id |
amount, currency, ref_number | Sent only on success (ref_number = the gateway's payment id) |
Verify (confirm the payment)
curl https://api.hermeseus.com/api/gateway/verify \
-H "Content-Type: application/json" \
-d '{
"api_key": "gw_xxxxxxxx...",
"trans_id": "9f1c0b64-5b2e-4a1e-9b1a-2c3d4e5f6a7b",
"amount": 1000
}'| Field | Req | Description |
|---|---|---|
api_key | yes | The same key the transaction was created with. |
trans_id | yes | The transaction id from token. |
amount | yes | Must equal the transaction amount (use the value you stored, not the one from the browser). Mismatch → -34. |
currency | no | Unit of amount and the reply (default: the transaction's currency). |
Response 200 (paid)
{
"code": 0,
"amount": 1000,
"currency": "USD",
"order_id": "ORDER-1001",
"gateway": "flitt",
"credited_usd": 960.00,
"fee_percent": 4,
"ref_id": "flt_abc123",
"customer_phone": "+15551234567",
"custom": { "cart_id": 77 },
"three_ds_verified": true,
"created_at": "2026-01-01T12:00:00+00:00"
}Only code: 0 means paid. credited_usd is the net added to your wallet (amount × (1 − fee%)). It is idempotent: calling verify again returns the same result.
Response codes
| code | Meaning | HTTP |
|---|---|---|
0 | Paid (verify) | 200 |
-1 | Created (token only) | 201 |
-2 | Failed / declined | 400 |
-3 | Awaiting the gateway result | 400 |
-4 | Expired / canceled | 400 |
-5 | Payer hasn't started the gateway yet | 400 |
-34 | Amount doesn't match the transaction | 400 |
-37 | Transaction not found (for this key) | 404 |
-38 | Validation error | 422 |
-39 | Invalid / revoked API key | 401 |
-43 | Rate limited (120/min) | 429 |
-45 | No gateway available in this mode | 503 |
-46 | Invalid transaction state | 400 |
Fees
The platform fee is set per gateway and applied when the payment is credited: credited = amount × (1 − fee%). Current live fees:
| Gateway | Fee | Status |
|---|---|---|
flitt — Flitt (card · 3-D Secure) | 0% | Not configured |
kemapp — KemApp (crypto · USDT) | 0% | Not configured |
failed. Crypto (KemApp) has no 3DS step. Crediting is driven only by the gateway's signed server callback plus a server-to-server re-check — never by the payer's browser.