Getting started

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.

bash
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.

bash
curl https://sandbox.key2pays.com/api/v1/ping -H "Authorization: Bearer $K2P"
json
{
  "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.

bash
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.

bash
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.

bash
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 3000https://abc-123.ngrok-free.app). Then register the URL:

bash
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

bash
# 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/v1https://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-Simulate header — 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).
Done. From here: Payment lifecycle for the full state machine, Sandbox-Simulate for CI patterns, delivery log to debug missing events.