Payment Gateway API
Accept credit/debit cards (Visa, Mastercard, Maestro), Apple Pay, Google Pay, and SEPA bank transfers on any website. No merchant onboarding required. No API keys. Instant payouts in USDC (Polygon) to your own wallet.
Integration Flow
1 server-side API call + 1 client-side redirect + callback webhook. Optionally, a currency conversion call before the redirect.
Create Wallet (server-side API call)
Generate a temporary encrypted wallet address by passing your USDC wallet + a callback URL. You receive an encrypted address_in and an ipn_token for tracking. Store the ipn_token in your database.
Redirect Customer (client-side redirect)
Redirect the customer's browser to the checkout URL with the encrypted wallet, amount, currency, and provider. The customer completes payment via the provider's hosted checkout.
Receive & Verify Callback (webhook)
After payment, a GET callback hits your URL with transaction data. Always verify via the Payment Status endpoint before marking the order as paid. USDC arrives instantly in your wallet.
Base URL
/control/* — server-side HTTP GET requests. No authentication or API keys required./process-payment.php — browser redirect, not a server-to-server API call. Redirect the user's browser via HTTP 302 or window.location.
URL Encoding Rules
Incorrect URL encoding is the most common integration error. Follow these rules precisely.
encodeURIComponent or urlencode to any value — the library does it for you. This eliminates double-encoding bugs entirely.
Option B: Manual Encoding (only if not using URLSearchParams)
If you build URL strings manually, apply encodeURIComponent() exactly once to each dynamic value:
| Parameter | Encoding Rule |
|---|---|
| callback | Apply encodeURIComponent() once to the full callback URL (including query params). |
| address_in | May contain /, =, +. Apply encodeURIComponent() once. |
Apply encodeURIComponent() once — @ becomes %40. |
JavaScript — Recommended (URLSearchParams)
PHP Example
Amount & Precision
To avoid floating-point rounding issues, follow these rules when handling amounts.
| Field | What it represents | When to use |
|---|---|---|
| value_coin | USDC amount received by the order's temporary wallet from the payment provider. | Use for payment verification — compare against your expected order amount. |
| value_forwarded_coin | Total USDC forwarded from the order wallet to the merchant (after network fees). | Use for accounting — this is what actually arrives in your wallet. |
When verifying payments, allow a small tolerance (e.g. ±0.02 USDC) to account for minor FX rounding by providers.
GET Create Wallet
Generate a temporary encrypted wallet address for an order. Each request generates a new temporary wallet + ipn_token. Your integration must track existing sessions to avoid creating duplicates for the same order. All received USDC is instantly forwarded to your merchant wallet.
ipn_token in responses, which must remain secret.
Request Parameters
| Parameter | Description |
|---|---|
| addressrequired | Your USDC (Polygon) wallet address to receive instant payouts. |
| callbackrequired | Your callback URL (must be HTTPS). Include your order identifier as a query parameter (e.g. ?orderId=123) — it will be preserved in the callback. If using URLSearchParams / http_build_query, pass directly. If building URLs manually, URL-encode once. |
Example Request
Response
| Field | Description |
|---|---|
| address_in | Encrypted wallet address. Pass as the address param to Process Payment. If using URLSearchParams / http_build_query, pass directly — do not manually encode. If building URLs manually, apply encodeURIComponent() once. |
| polygon_address_in | Unencrypted Polygon wallet address assigned to this order (for reference/on-chain tracking). |
| callback_url | The decoded callback URL you provided. |
| ipn_token | Secret token for verifying payment status. Store server-side in your database only — never expose in frontend code, client-side URLs, or logs. |
ipn_token, even for the same callback URL. To avoid orphaned wallets on retries, always check your database for an existing session before calling this endpoint. See Idempotency.
REDIRECT Process Payment
Redirect the customer's browser to the payment page. This is not a server-side API call — send the customer here via HTTP redirect or window.location.
Request Parameters
| Parameter | Description |
|---|---|
| addressrequired | The address_in from Create Wallet. If using URLSearchParams / http_build_query, pass directly (no manual encoding). If building URLs manually, apply encodeURIComponent() once. |
| amountrequired | Payment amount as a string (e.g. 103.78). Do not use floating-point math. |
| providerrequired | Payment provider identifier. See providers list (e.g. moonpay, stripe, transak). |
| currencyrequired | Fiat currency code (e.g. USD, EUR). Some providers support USD only — use the Convert endpoint first. |
| emailoptional | Customer email. If using URLSearchParams / http_build_query, pass directly. If building URLs manually, encode once. Pre-fills the provider's checkout form. |
Example
GET Convert to USD
Some providers (Stripe, Wert, Transfi, Ramp Network) support USD only. Use this endpoint to convert other currencies before calling Process Payment.
Request Parameters
| Parameter | Description |
|---|---|
| fromrequired | Source currency code (e.g. EUR, SEK, GBP, CHF). |
| valuerequired | Amount to convert (e.g. 1258.31). |
Example
GET Callback Event
When a customer completes payment, a GET request is sent to your callback URL with all your original query parameters plus the following transaction data.
address_in values
The address in the checkout URL is the encrypted address_in from Create Wallet. The address_in in the callback query string is the unencrypted Polygon wallet and equals polygon_address_in from Create Wallet.
Callback Parameters
| Parameter | Description |
|---|---|
| value_coin | USDC amount paid by the provider to the order wallet. |
| coin | Payout coin type, usually polygon_usdc or polygon_usdt. |
| txid_in | Polygon TXID — payment from provider to the order's temporary wallet. |
| txid_out | Polygon TXID — instant payout from temporary wallet to your merchant wallet. |
| address_in | Unencrypted Polygon wallet for this order. Must match polygon_address_in from Create Wallet. |
| value_forwarded_coin | Total USDC forwarded to the merchant wallet (after network fees). |
value_coin, txid_out, or any callback query parameters for settlement. Treat the callback only as a trigger. Always verify via the Callback Verification flow before marking an order as paid.
GET Check Payment Status
Verify whether a payment has been completed. Use the ipn_token stored during Create Wallet.
Request Parameters
| Parameter | Description |
|---|---|
| ipn_tokenrequired | The ipn_token from the Create Wallet response. |
Response
| Field | Description |
|---|---|
| status | paid or unpaid |
| value_coin | USDC amount sent by the provider to the order wallet. |
| txid_out | Blockchain TXID of the payout to your merchant wallet. |
| coin | Payout coin type (e.g. polygon_usdc). |
pending longer than 10 minutes. For client-facing status, use the Polling endpoint pattern.
Callback Verification
Callbacks arrive as unsigned GET requests. Anyone who knows your callback URL could send a fake request. Always verify before marking an order as paid.
Required Verification Flow
Receive Callback
Extract the order ID from your callback's query parameters (e.g. orderId). Look up the stored ipn_token for that order in your database.
Verify via Payment Status
Call GET /control/payment-status.php?ipn_token={stored_token} and confirm status=paid.
Validate Amount & TXID
Compare the returned value_coin against your expected order amount (with ±0.02 tolerance). Optionally verify txid_out matches.
Idempotency Check
Before marking paid, check that this txid_out hasn't already been processed (prevents replay attacks). Only then update your order status.
200 OK within 5 seconds — even if the orderId is missing, the session is unknown, or verification fails. Return 200 first, then process asynchronously (e.g. enqueue a background job or cron task). For most integrations, inline verification completes well within 5 seconds — but for high volume, a queue is recommended. A slow or non-200 response causes retries and duplicate processing.
Callback Behavior
Understanding callback delivery behavior is critical for building a reliable integration.
Delivery Rules
| Behavior | Detail |
|---|---|
| Method | GET request to your callback URL with transaction data as query parameters. |
| Expected response | Return HTTP 200 as quickly as possible. Response body is ignored. Do not return redirects (3xx). |
| Retries | If your server returns a non-200 status or times out, the callback may be retried. Assume at-least-once delivery — your handler must be idempotent. |
| Timeout | Your callback handler should respond within 5 seconds. If you need heavy processing (DB writes, email sending), return 200 first and process asynchronously. |
| Ordering | Callbacks are not guaranteed to arrive in order. Always check current payment status rather than assuming sequence. |
| Duplicates | You may receive the same callback multiple times. If the order is already paid, return 200 without re-processing. |
payment-status for orders stuck in pending longer than 10 minutes.
Idempotency
The API does not enforce idempotency — your integration must handle it on both Create Wallet and Callback.
Create Wallet
Each call generates a new wallet, even with identical parameters. If a network timeout triggers a retry, you'll end up with two wallets for one order. Always check your database first:
Callback Handler
Protect against double-processing with an atomic conditional update and a unique txid_out constraint:
Payment Status Matrix
The upstream API returns paid or unpaid. Map these to richer internal states for better operational handling.
| Internal Status | Upstream | Condition | Action |
|---|---|---|---|
| pending | unpaid |
Order created, awaiting payment | Show "waiting" UI. Poll at intervals. |
| paid | paid |
value_coin within ±0.02 of expected |
Mark order complete. Deliver goods/service. |
| paid_review | paid |
value_coin deviates >0.02 from expected |
Payment received but amount mismatch. Flag for manual review. |
| expired | unpaid |
Order older than timeout (e.g. 30 min) | Show "session expired". Offer retry. |
| failed | — | Upstream API error during verification | Log error. Retry verification via background job. |
unpaid and flag for manual review. Do not auto-reject or auto-approve.
Error Handling
The API may return errors in the following format.
Error Response Format
Common HTTP Status Codes
| Code | Meaning | What to do |
|---|---|---|
| 200 | Success | Parse response JSON normally. |
| 400 | Bad Request | Check your parameters — likely a missing or malformed value (bad encoding, invalid wallet address). |
| 422 | Unprocessable | Parameters are syntactically valid but semantically wrong (e.g. unsupported currency for provider). |
| 429 | Rate Limited | Too many requests. Wait 30–60 seconds before retrying. Implement exponential backoff. |
| 500 | Server Error | Transient failure. Retry with exponential backoff (max 3 retries). |
"status": "success" in the JSON response body, even on HTTP 200. Some errors may return 200 with an error message in the body.
Quickstart: Next.js (App Router)
A production-ready integration pattern using Next.js with proper callback verification, idempotency, and error handling.
1. Create Payment Session
2. Callback Handler (with Verification)
Polling & Confirmation UX
After redirecting the customer to checkout, show a "Waiting for confirmation" page that polls your backend. The callback updates your DB; the polling endpoint reads from it.
Polling Endpoint
Client-side Adaptive Polling
Edge Cases
| Scenario | Handling |
|---|---|
| User closes tab before confirmation | Callback still arrives → order marked paid in DB. Send confirmation email as fallback. |
| Callback arrives late (1–3 min) | Polling catches it via throttled upstream checks (lastVerifiedAt logic). |
| Callback never arrives | Background cron job checks pending orders older than 10 min. |
| Multiple browser tabs polling | lastVerifiedAt throttle prevents upstream API abuse (max 1 check per 15s per order). |
Payment Providers
Use the provider parameter in Process Payment. Each provider has different minimum order amounts, supported currencies, and fee structures. Fees are generally lower for larger transaction amounts.
| Provider ID | Currencies | Customer KYC | Notes |
|---|---|---|---|
| moonpay | USD, EUR, GBP + 30 more | Required (most amounts) | Wide global coverage. Popular default choice. |
| stripe | USD only | Minimal | Use Convert for EUR/GBP. Familiar checkout UX. |
| transak | USD, EUR, GBP + 50 more | Above small amounts | Best international currency coverage. |
| wert | USD only | Minimal (small amounts) | Fast customer onboarding. Use Convert for other currencies. |
| rampnetwork | USD only | Required | Use Convert endpoint. Strong EU regulatory compliance. |
| guardarian | USD, EUR + others | Above limits | Competitive fees. |
| mercuryo | USD, EUR, GBP + others | Required | Competitive fees on larger amounts. |
| banxa | USD, EUR, AUD + others | Required | Strong in APAC region. |
| transfi | USD only | Required | Use Convert endpoint for other currencies. |
| utorg | USD, EUR + others | Above limits | Multi-currency support. |
| revolut | USD, EUR, GBP + 30 more | Revolut account | Recommended for UK — bypasses 24h FCA cooling-off. Instant settlement. |
Fee Handling
Understanding the fee structure helps you price correctly and set expectations with customers.
Fee Breakdown
| Fee | Paid by | Amount | Details |
|---|---|---|---|
| Provider fee | Customer (at checkout) | 3–7% | Charged by MoonPay, Transak, etc. Shown transparently during their checkout. Lower for larger amounts. |
| Gateway fee | Deducted from payout | <1% | Syncom Europe infrastructure fee. Reflected in the difference between value_coin and value_forwarded_coin. |
| Network fee | Deducted from payout | ~$0.01 | Polygon USDC transfer fee. Negligible. |
How Fees Work in Practice
Provider fees are always added on top of your order amount at the provider's checkout. The customer sees a transparent breakdown:
Provider fees are typically charged to the customer at the provider's checkout page. The merchant specifies the order amount, and the provider adds their fee on top. The final received amount may differ slightly due to FX rounding — always use value_forwarded_coin from the callback for accounting, not the original order amount.
Custom Checkout Domain
By default, your customers see checkout.syncom-europe.com during payment. If you want your own branded checkout domain (e.g. checkout.yourcompany.com), follow this guide.
How It Works
You create a Cloudflare Worker on your own domain that proxies requests to pay.syncom-europe.com and checkout.syncom-europe.com. Your customers see your domain throughout the entire payment flow, while all processing (including affiliate commission) stays intact.
Add your domain to Cloudflare
Create a free Cloudflare account and add your domain. Change your nameservers to the ones provided by Cloudflare.
Create DNS records
Add proxied (orange cloud) A records for your subdomains. The IP can be anything (e.g. 8.8.8.8) — it will be overridden by the Worker route.
Create a Cloudflare Worker
Go to Workers & Pages → Create → Worker. Paste the worker code below and deploy.
Add routes
In the Worker settings, add routes for both subdomains with a wildcard: pay.yourcompany.com/* and checkout.yourcompany.com/*
Worker Code
Replace pay.yourcompany.com and checkout.yourcompany.com with your actual subdomains:
DNS Records Example
| Type | Name | Content | Proxy |
|---|---|---|---|
| A | pay | 8.8.8.8 | Proxied (orange cloud) |
| A | checkout | 8.8.8.8 | Proxied (orange cloud) |
After Setup
Once deployed, use your custom domains in all API calls and redirects:
Access-Control-Allow-Origin dynamically from the request origin. If you need to send credentials (cookies/auth headers) from the browser, set an explicit origin (not *) and add Access-Control-Allow-Credentials: true.
Integration Checklist
Verify these items before going live.
| # | Item | Why |
|---|---|---|
| 1 | ipn_token stored server-side only |
It's a secret — never expose in frontend, URLs, or logs. |
| 2 | Callback returns 200 within 5 seconds |
Non-200 or slow responses trigger retries and duplicate processing. |
| 3 | Always verify via Payment Status endpoint | Callback query params can be spoofed — never trust for settlement. |
| 4 | txid_out stored with UNIQUE constraint |
Prevents replay attacks and double-crediting. |
| 5 | Polling endpoint reads from DB, not upstream | Avoids rate limiting and reduces upstream API load. |
| 6 | Background job for stuck pending orders (>10 min) |
Catches cases where callback never arrives. |
Requirements
For the Merchant
A USDC wallet on the Polygon network. Use any self-custodial wallet — Trust Wallet (SWIFT option), MetaMask, Coinbase Wallet, or similar.
For the Customer
A 3D Secure enabled card (Verified by Visa / Mastercard SecureCode). First-time customers may need to complete identity verification (KYC) with the payment provider — typically under 2 minutes.
Technical Requirements
Callback endpoints must use HTTPS. The callback handler must respond within a reasonable timeout. Store ipn_token values in your database for payment verification.
Rate Limits & Fair Use
There are no hard rate limits, but we expect reasonable use. Do not poll the Payment Status endpoint more than once per 15 seconds per order. Excessive automated requests may be throttled without notice.
Support
For integration questions and technical support, contact support@syncom-europe.com.
Changelog
| Version | Date | Changes |
|---|---|---|
| v1.1 | 2025-02-13 | Added: Callback Behavior (retry/timeout rules), Idempotency guidance, Payment Status Matrix, Polling & Confirmation UX, Fee Handling section, Custom Checkout Domain guide, enhanced Provider table with KYC info. Fixed: URL encoding section (URLSearchParams recommended), Process Payment classified as browser redirect, currency parameter HTML encoding. |
| v1.0 | 2025-02-13 | Initial release — Create Wallet, Process Payment, Convert to USD, Callback Event, Payment Status. |