Getting started
First steps with the Fynex Payments API — get your token from the dashboard, verify it, take a first test payment with either integration style, and prepare for production.
This guide takes you from zero to your first successful test payment on the Fynex sandbox. It is the broad "first steps" tour: get a token, verify it, choose an integration style, use sandbox cards, confirm the outcome, and learn the conventions you'll rely on everywhere else.
Note
Examples use this environment's API,
https://api.fynex.ai. Whether a payment is a test or real is decided by your account, not the host: a Demo account never moves real money. See Going live when you are ready for real payments.
- API base URL:
https://api.fynex.ai/payments-api/v1 - Full API reference: this site
- Dashboard:
https://dashboard.fynex.ai
1. Get your API token
Every request is authenticated with a seller bearer token, which you obtain yourself from the dashboard:
- Log in to
https://dashboard.fynex.aiwith your username and password. - Select your seller account.
- Open the Integration page.
- Click the reveal (eye) icon to show the token, then Copy.
The token is an opaque string with no prefix — it is exactly the value you
pass as Authorization: Bearer <token>. Treat it like a password.
Caution
The Regenerate button on the Integration page issues a new token and immediately invalidates the old one — there is no overlap window. Only use it when you intend to rotate. For first-time setup, just reveal and copy.
Store the token and base URL in your environment:
export FYNEX_API="https://api.fynex.ai/payments-api/v1"
export FYNEX_TOKEN="<the token you copied>"
See Authentication for token storage, rotation, and error details.
2. Verify the token works
The quickest "is my token alive?" check returns the payment methods enabled on your account:
curl -sS "$FYNEX_API/payment-methods" \
-H "Authorization: Bearer $FYNEX_TOKEN"
200 OKwith a JSON body → your token works and your account is active.401 Unauthorized→ the token is missing, malformed, or invalid.403 seller account is not active→ the token is valid and recognised, but the account isn't active. New demo accounts are activated automatically, so you normally won't see this in the sandbox; if you do, contact Fynex with your seller account ID. (Going live for real-money payments requires KYB + a Fynex-assigned live terminal.)
3. Take your first test payment
There are two integration styles. Start with hosted checkout — it's the fastest and keeps your servers out of PCI scope.
Option A — Hosted checkout (recommended first)
Fynex hosts the card form; you create a session and redirect the customer to it.
curl -sS -X POST "$FYNEX_API/checkout" \
-H "Authorization: Bearer $FYNEX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"externalOrderRef": "ORDER-DEMO-1",
"amount": 19.99,
"currencyCode": "GBP",
"countryCode": "GB",
"autoSettlement": true,
"returnUrls": {
"success": "https://example.com/success",
"failure": "https://example.com/failure"
}
}'
A 201 Created response returns a checkoutUrl:
{
"sessionId": "6f9b84e1-3b83-4fb9-9f42-a8ac27d11d6b",
"checkoutUrl": "https://pay.fynex.ai/checkout/6f9b84e1-...",
"expiresAt": "2026-04-29T11:30:00Z"
}
Open checkoutUrl in a browser and pay with a sandbox card (see step 4). The page redirects to your returnUrls.success or returnUrls.failure when done. For the full field-by-field hosted-checkout walkthrough, see the Quickstart.
Option B — Server-to-server
Submit card details directly to the API. Use this when you collect card data yourself.
curl -sS -X POST "$FYNEX_API/initialize-payment" \
-H "Authorization: Bearer $FYNEX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"externalOrderRef": "TEST-HAPPY-1",
"amount": 19.99,
"paymentType": "card",
"paymentMethod": "card",
"currencyCode": "GBP",
"countryCode": "GB",
"autoSettlement": true,
"skip3DS": true,
"cardData": {
"cardNumber": "4111111111111111",
"expMonth": 12,
"expYear": 2028,
"holderName": "Test User",
"cvv": "123"
},
"returnLinks": [
{ "rel": "default", "href": "https://example.com/return", "method": "GET" }
]
}'
With "skip3DS": true the response has requiresAction: false and the payment proceeds straight through. To test the 3DS flow, omit skip3DS (or set it false) — the response then returns requiresAction: true and an actionUrl; redirect the customer there, let them complete the challenge, then call POST /finalize-payment with the same paymentId. See Server-to-server for the full lifecycle.
4. Sandbox test cards
Test cards work on a Demo account. What decides it is the account's operational mode, never the host — a Demo account is a sandbox account on any Fynex host. For a guaranteed success on either option above, use:
| Card number | Notes |
|---|---|
4000 0000 0000 2701 |
Visa — authenticates frictionlessly, reaches lifecycleStatus captured |
For all of them:
- Expiry month: any future month (e.g.
12) - Expiry year: any future year — 4-digit (
2028) recommended - CVV: any 3 digits (e.g.
123) - Cardholder name: Latin letters (
A-Z), spaces, apostrophes, dots, or hyphens only
Note
On Option B (server-to-server) with
skip3DS: true, 3DS never runs and any well-formed card number reaches the same generic success/decline path. On Option A (hosted checkout) and on Option B withskip3DSomitted orfalse, 3DS always runs and the card's PAN decides the outcome — see Test cards & sandbox for the full decline and 3DS-challenge card set.
You can use any well-formed billing data (e.g. test@example.com, Test User, +44 7700 900000) — the sandbox doesn't validate it against real services, and no emails are sent. See Test cards for the full reference.
5. Check the result
You have two ways to confirm a payment's outcome:
- Poll the payment status (same token):
curl -sS "$FYNEX_API/payments/TEST-HAPPY-1" \
-H "Authorization: Bearer $FYNEX_TOKEN"
The response includes lifecycleStatus (e.g. captured, failed, cancelled — see Payment Lifecycle) along with status, amount, currencyCode, countryCode, paymentType, paymentMethod, externalOrderRef, the failureCode / failureDescription / failureStage if the payment failed, and the createdAt / updatedAt / failedAt timestamps.
- Webhooks — Fynex sends a
PaymentCompletedwebhook to the URL(s) configured on your account. Your endpoint must return HTTP200; any other status is retried (up to 3 times) and then marked failed.
Note
Distinguish
cancelled(customer abandoned the form) fromfailed(hard decline) — show a neutral "payment not completed" message forcancelled, not an error.
See Polling & SSE for the full verification pattern.
Conventions to know
Idempotency-Keyheader is mandatory on the payment operations — checkout, initialize-payment, finalize-payment, capture, refund and refund cancellation. Use a fresh UUID per logical request; retrying with the same key safely returns the existing operation instead of creating a duplicate. Payouts takeidempotencyKeyin the body. Creating a payee, a payee setup, a payout method, a webhook or a split rule accepts the header optionally; wallet routes do not read it.returnLinksvsreturnUrls: server-to-server usesreturnLinks(an array; each item hasrel∈default | on_completed | on_failed | on_cancelled, anhref, andmethod: "GET"). Hosted checkout usesreturnUrlsat session creation.countryCodeis required on bothinitialize-paymentandcheckout; if your account/terminal is pinned to a country, it must match it.- Amounts are in major units (e.g.
19.99= £19.99).
Common next steps
- Captures & refunds — manual capture (
autoSettlement: false) and refunding captured payments. - Server-to-server — the full direct-integration and 3DS redirect lifecycle.
- Polling & SSE — verify payment status without webhooks.
Connect an AI agent (MCP)
An MCP endpoint for AI agents is in preview and not yet available on production.
Going to production
When you're ready, use your Live account's token — get it from the production dashboard's (https://dashboard.fynex.ai) Integration page, the same way as staging. Tokens are per-environment and independent.
Never send test card numbers on a Live account. Note the wording: sandbox versus real card networks is a property of your account's operational mode, not of the host you call — Demo accounts exist on both environments, and test cards are correct on any of them. Confirm operationalMode with GET /account before sending a test PAN; see Test cards & sandbox.
Need help?
Reach out to your Fynex contact with your externalOrderRef and the approximate time of the request, and we can trace it end to end.