Build on a clean, predictable API.
One REST API over acceptance, orchestration and settlement. Idempotent writes, a single status model across every payment method, signed webhooks as the source of truth, and a sandbox for the cases that are hard to produce on purpose.
One API over every capability
Your systems talk to one gateway. Behind it, acceptance, orchestration and settlement are separate concerns with risk controls in line and a ledger underneath, so adding a provider, a method or a market does not change your integration.
- One payment resource for cards, wallets, bank rails and local methods
- Provider differences normalised before they reach your code
- Risk screening and routing applied in line, not bolted on
- A ledger that ties every payment to the settlement that paid it
Three ways to connect
They differ in how much of the checkout you own and how much compliance scope you take on. All three produce the same payment object and the same webhooks.
Hosted payment page
Redirect to a Flowa Pay-hosted checkout. Card data never touches your systems, new methods appear without a release, and the integration is a redirect plus a webhook handler. Smallest compliance scope, fastest to live.
Embedded checkout
Drop-in components keep the customer on your page while the card fields stay in an isolated payment surface. Your design, without the card data entering your application.
Server-to-server
You build the entire interface and submit payment details through the API. Maximum control, and the largest compliance obligation, because card data passes through systems you operate.
Keys, environments and scope
- API keys are server-side only. A key must never reach a browser or a mobile binary.
- Test and live are separate credentials over separate data. A test key cannot touch live objects.
- Keys are scoped to the actions your account is enabled for, and can be rotated without downtime.
- Every request is authenticated and carried over TLS; unauthenticated requests are rejected outright.
API credentials and sandbox access are issued as part of merchant onboarding, once your account is approved. Availability depends on merchant category, jurisdiction, underwriting and the applicable payment or acquiring partner.
Retries that cannot double-charge
- Send an idempotency key on every mutating request, derived from your own order or reference.
- Retrying with the same key returns the original result instead of creating a second payment.
- Reusing a key with a different payload is rejected rather than silently accepted.
- This is what makes a network timeout a safe condition rather than an accounting problem.
One call, any method
Create a payment, then follow the next action the response gives you. The same request shape works whether the customer pays by card, wallet or bank transfer: the method is a parameter, not a different integration.
The API is REST over HTTPS with JSON bodies, so it is callable from any language without a vendor library. Examples illustrate the documented interface; the full reference is issued with your sandbox credentials.
curl https://api.flowapay.co/v1/payments \
-H "Authorization: Bearer $FLOWA_KEY" \
-H "Idempotency-Key: ord_1837" \
-H "Content-Type: application/json" \
-d '{
"amount": "1200.00",
"currency": "EUR",
"method": "card",
"reference": "ord_1837",
"return_url": "https://yourshop.com/return"
}'
# 201 Created
{
"id": "pay_8f2c41",
"status": "requires_action",
"next_action": { "type": "redirect", "url": "https://..." },
"amount": "1200.00",
"currency": "EUR"
}One status model, every method
A bank redirect, a wallet confirmation and a card authorization are very different events. They produce the same states, so your state machine does not branch per provider.
Core endpoints
Which endpoints and methods are enabled depends on the capabilities approved for your account during onboarding.
The authoritative channel
A browser redirect can be interrupted, a tab closed, a mobile connection dropped. No integration should treat the customer's return as confirmation. Webhooks are delivered server to server and are the result of record.
- Verify the signature. Every payload is signed with your endpoint secret. Reject anything that does not verify.
- Be idempotent. Delivery is at least once. Each event carries a stable id, so de-duplicate on it.
- Acknowledge fast. Return 2xx immediately and do your own work asynchronously; slow handlers trigger retries.
- Expect retries. Failed deliveries are retried with backoff until acknowledged.
Failures you can branch on
Every error returns a stable machine-readable code, a human-readable message and whether retrying could help. You should never have to parse prose to decide what to do.
Sandbox
A separate environment with its own credentials and its own data, built for the cases that are hard to produce deliberately in production: a specific decline reason, an authentication challenge, an asynchronous method that completes minutes later, a webhook retry after a failed delivery. Build against those before go-live rather than meeting them in production.
Deterministic outcomes
Trigger approval, each decline reason, and authentication challenge or frictionless paths on demand.
Asynchronous flows
Exercise redirect-based and delayed-confirmation methods, including the pending state your UI must handle.
Webhook delivery
Test signature verification, duplicate delivery and retry behaviour against your real endpoint.
Operating the integration
Versioning
Breaking changes ship under a new version. Existing versions keep working, and changes are announced before they take effect.
Rate limits
Limits are applied per account. A limited request returns 429 with a Retry-After header, so back-off is deterministic rather than guesswork.
Observability
Every payment records the route taken, the decision returned and the rule that selected it, which is what makes a production incident diagnosable.
Reconciliation
Pull settlements and their statement lines through the API so your ledger matches ours without manual export.
Security
Server-side credentials, signed webhooks, request validation and tokenization keep card data out of your systems on hosted and embedded integrations.
Support
Integration questions go to a named contact during onboarding, with solution engineering for enterprise rollouts.
Developer FAQ
Credentials, including sandbox access, are issued as part of merchant onboarding once the account is approved. They are not self-service, because the methods and capabilities enabled on an account depend on underwriting.
The API is REST over HTTPS with JSON, so it is usable from any language with an HTTP client. We do not claim a published SDK for a language unless it is actually available to you; ask your contact what is current for your stack.
Retry it with the same idempotency key. You receive the original result rather than creating a second payment. This is the single most important habit in a payment integration.
Yes. Delivery is at least once, and retries happen until you acknowledge. Handlers must be idempotent and de-duplicate on the event id.
No. Use it for the customer's experience only. The webhook is the authoritative result, and a payment is complete when the webhook says so.
Branch on the normalised reason code rather than the provider's raw message. Hard declines should not be retried; soft declines are retried on a reason-specific schedule by the platform.
Yes. Breaking changes ship under a new version and existing versions remain supported, with notice before any change takes effect.
Go deeper
Start building
Talk to us about your stack and the methods you need, and we will scope the integration with you.