API playground

Every request on this page is a real HTTPS call from your browser to the live sandbox at api.finscale.dev. Pick a scenario, send it, and read the same responses your integration will see — no signup, no server, no money moved.

Guided tour

The core loop of a payments integration in four requests. Run them in order — each button fills the console, sends the request, and jumps to the response.

01 Create a payment

POST /v1/payments — a card payment for 4900 minor units (€49.00). It authorizes and captures in one call.

02 Observe failover

Same request with the magic amount 4999: the first provider times out and Finscale retries the next. Read provider_attempts.

03 Retrieve it

GET /v1/payments/{id} — fetches the payment from step 02 by id, straight from your request history.

04 Refund it

POST /v1/refunds against the same payment — it works whichever provider processed the original.

Your sandbox key

Test keys are auto-provisioned for the playground: the sandbox accepts any sk_test_ key and moves no money.

sk_test_pg_…

This key was generated in your browser and lives only in this browser's storage. Rotating replaces it — the sandbox treats every sk_test_ key identically, so nothing breaks. Real key management is covered in Authentication.

Scenario presets

Each preset fills the console — edit anything before sending. The write scenarios use exact payload shapes from the API reference; the special behaviors are driven by magic amounts.

ScenarioWhat to look forDocs
status: succeeded, amount_captured: 4900, and an approved risk decision. Payment lifecycle
Amount 4999: two entries in provider_attempts — a timeout, then an approval on the next provider. Smart routing
Amount 4002: status: failed with failure_code: card_declined — a final decline, never retried. Errors
Amount 4991: held in processing with risk.decision: "review" and a score in the review band. Risk engine
Amount 4992: failed with failure_code: payment_blocked — no provider is ever attempted. Risk engine
status: requires_action — the customer approves the collect request in their UPI app. Real-time payments
requires_action with next_action.type: "redirect" — send the customer to their bank, then back to return_url. Bank redirects
requires_action: the customer receives a reference to pay in cash at a store. Vouchers
capture_method: "manual" authorizes to requires_capture; the second button sends POST /capture. Add an amount for a partial capture — it keeps the authorization open. Authorization flows
Uses the newest pay_ id from your history. The refund returns status: succeeded. Refunds
GET by id — the same object shape the create call returned. Payment lifecycle
The cursor-paginated list envelope: object: "list", data, has_more. Pagination
Your opaque provider set — prov_… ids with methods, regions, and auth_rate_7d. Provider health
available vs pending funds, per currency, in minor units. Balance
KYB starts at kyb_status: "kyb_pending" — capabilities pending, mid: null until the merchant is active. Merchant API
dp_ objects with reason, stage, status, and the evidence_due_by deadline. Disputes

Console

Sent on writes only. A fresh key is stamped after every send — reuse one deliberately and the sandbox replays the same object id. See Idempotency.

Response

Ready
Response
// Send a request — the response appears here.

Request history

Your last 20 requests, stored only in this browser. Click one to restore both the request and its response. The refund, retrieve, and capture presets read the newest pay_ id from here — if you haven't created a payment yet, they fall back to the demo payment pay_8Q2mX4nT1cVb.

    How this works

    There is no application server behind this page — your browser calls https://api.finscale.dev directly. The domain fronts a CloudFront distribution, and a Lambda@Edge function answers every /v1/* request at the edge: a stateless, deterministic mock of the documented API. Any sk_test_ key authenticates, live keys are rejected, and no money exists anywhere in the loop. The sandbox allows cross-origin requests from any page, which is what lets the console call it without a proxy.

    Deterministic means reproducible. The same request always produces the same shape, and creates are idempotent — the same Idempotency-Key always maps to the same object id, which is why the console stamps every write with a fresh key. Special test behaviors hang off magic amounts:

    AmountTest-mode behavior
    4999 First provider times out; automatic failover approves on the next. Both attempts appear in provider_attempts.
    4991 Risk review: held in processing with risk.decision: "review".
    4992 Risk blocked: failed with failure_code: payment_blocked; no provider attempted.
    4002 Final decline: failed with failure_code: card_declined. Never retried on another provider.

    The full test matrix — test cards, simulated redirect flows, webhook testing — is on Testing. Field-by-field schemas for everything you can send from here are in the API reference.