Quickstart (15-min walkthrough)
From zero to a verified sandbox transaction with webhook delivery in 15 minutes. Eight concrete steps.
Concrete walkthrough — 8 commands, ~15 minutes, end with a verified webhook delivery on your local machine. Every command below works copy-pasted against https://sandbox.key2pays.com/api/v1 with a test secret key.
1. Get sandbox keys
Log into the merchant portal at merchant.key2pays.com → Shops & API keys. You'll see one pair of test keys per shop: pk_test_… (publishable, safe for client) and sk_test_… (secret, server-only). Copy the secret — that's all you need for backend integration.
export K2P=sk_test_…
2. Ping the API
Confirms your key works, shows which environment you're hitting, returns the merchant name resolved from the credential. Idempotent and free.
curl https://sandbox.key2pays.com/api/v1/ping -H "Authorization: Bearer $K2P"
{
"ok": true,
"environment": "sandbox",
"keyKind": "secret",
"keyId": "sk_test_…7u10",
"apiVersion": "2026-05-01",
"merchant": { "id": "MCH-ON-009", "name": "Golden Dragon" }
}3. Identify the merchant + see capabilities
Returns the merchant's tier, trustScore, enabled methods, and what features are unlocked.
curl https://sandbox.key2pays.com/api/v1/me -H "Authorization: Bearer $K2P"
4. List the methods available for this shop
One row per retailer / bank / native rail. Each one has a 4-digit paymentMethodId — store it, pass it back on POST /payments.
curl "https://sandbox.key2pays.com/api/v1/payment-methods?country=MX" -H "Authorization: Bearer $K2P"
You'll get ~24 entries for MX. Note one — e.g. { "paymentMethodId": "1008", "name": "SPEI" }.
5. Create your first payment
With Sandbox-Simulate: paid the tx auto-completes in 5 seconds and a payment.completed webhook fires — perfect for testing your handler without manual UI clicks.
curl https://sandbox.key2pays.com/api/v1/payments \
-H "Authorization: Bearer $K2P" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Sandbox-Simulate: paid" \
-d '{
"amount": 50,
"paymentMethodId": "1008",
"country": "MEX",
"userEmail": "test@test.com",
"merchantOrderId": "ORD-001"
}'6. Receive the webhook on your local machine
Expose your localhost with ngrok or cloudflared first (e.g. ngrok http 3000 → https://abc-123.ngrok-free.app). Then register the URL:
curl https://sandbox.key2pays.com/api/v1/webhooks \
-H "Authorization: Bearer $K2P" \
-H "Content-Type: application/json" \
-d '{
"url": "https://abc-123.ngrok-free.app/webhooks/key2pay",
"events": ["payment.completed", "payment.failed", "payment.refunded"]
}'
# Response includes `secret` ONCE — save it now:
# { "id": "wh_...", "url": "...", "secret": "whsec_...", … }Re-run step 5. Within ~5 seconds your endpoint receives a POST with payment.completed. Verify the X-Key2Pay-Signature header using HMAC-SHA256 with your secret — see Webhooks & signing for the verification snippet.
7. Refund
# TXN-... is the transactionId from step 5
curl https://sandbox.key2pays.com/api/v1/payments/TXN-…/refund \
-H "Authorization: Bearer $K2P" \
-H "Content-Type: application/json" \
-d '{ "amount": 25, "reason": "requested_by_customer" }'
# Response (camelCase + ISO 8601, amount in local-currency major units):
# { "refundId": "CLM-...", "transactionId": "TXN-...", "amount": 25, "amountUsd": 1.45, "currency": "MXN", "status": "pending", "createdAt": "..." }Your webhook handler also receives payment.refunded.
8. Go to production
- Get production keys from the dashboard (
sk_live_…). - Swap base URL
https://sandbox.key2pays.com/api/v1→https://api.key2pays.com/api/v1. - Replace the sandbox webhook subscription with a production URL (the secret is per-subscription, so generate a fresh one).
- Drop the
Sandbox-Simulateheader — production ignores it but emits a log warning if it's present. - Enable IP allowlist for your secret key (Account settings) once your backend has stable egress IPs.
- Rotate the secret on a schedule via POST /webhooks/{id}/rotate-secret (24h grace window).