Developers
Read the docs first. That's the point of them.
REST, JSON, a bearer token. Server-managed 3-D Secure, so you never touch a CAVV. If anything here needs a phone call to understand, that's our bug — not your misunderstanding.
Two API keys, two surfaces
Pick the one that describes you, not the one that sounds bigger
Merchant
You process payments for your own account.
- Initiate, capture, refund, void and check status
- 3-D Secure verification handled server-side
- No merchant id needed — your key is the account
Partner
You are an ISO with your own gateway, managing linked merchants.
- List linked merchants and read their transactions
- Initiate on their behalf by passing a merchant id
- Capture, refund and void stay merchant-only
Quickstart
Shorter than you expect
One base URL, one header. API keys are provisioned by our team and delivered securely — there is no self-service key generation, and there won't be until we can do it without weakening onboarding.
# Sandbox https://api.sandbox.bergopay.com/
Authenticating requests
Every authenticated endpoint expects a bearer token. That is the whole authentication story.
Authorization: Bearer {YOUR_AUTH_KEY} Content-Type: application/json Accept: application/json
Response envelope
Every response carries the same four keys, whether it succeeded or not. Check success, read code when it is false.
{
"success": true,
"message": "Transaction initiated",
"code": "",
"data": { ... }
}
Check your key
GET /api/v1/key-info REQUIRES AUTHReturns what the key you are holding is allowed to do. A useful first call when something behaves unexpectedly.
3-D Secure
You will not be handling a CAVV today
3DS is server-managed. You never construct or store CAVV, ECI or DS Transaction IDs — you verify, you get an id, you pass the id.
- Step 1 — call the verify endpoint with card details, amount, currency and your return URL
- Step 2 — frictionless returns
status: full_authimmediately; a challenge returns achallenge_url - Step 3 — after a challenge the cardholder returns to your URL with a verification id and status
- Step 4 — initiate the transaction with that id in
card_verification_data
{
"amount": 12.5,
"currency": "EUR",
"card": {
"name": "John Doe",
"number": "4200000000000091",
"exp_month": "12",
"exp_year": "2030",
"cvv": "123"
},
"auth_url": "https://yoursite.com/checkout/3ds-complete"
}
// 200 — frictionless { "success": true, "data": { "id": 166, "status": "full_auth", "auth_type": "frictionless", "version": "2.2.0", "eci": "05" } }
Carry that id into the transaction and the stored authentication data is attached for you.
Merchant endpoints
Five calls cover the whole card lifecycle
Initiate a transaction
POST /api/v1/transactions REQUIRES AUTHsale charges immediately. auth places a hold and needs a capture to settle. Choose deliberately — the difference shows up in your refund and dispute profile months later.
{
"amount": 12.5,
"currency": "EUR",
"transaction_type": "sale",
"card": {
"number": "4111111111111111",
"exp_month": "12",
"exp_year": "2030",
"cvv": "111",
"name": "John Doe"
},
"reference": "order-10001",
"success_url": "https://yoursite.com/checkout/success",
"error_url": "https://yoursite.com/checkout/error",
"customer": {
"merchant_customer_id": "cust-001",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"country_code": "PL",
"ip_address": "198.51.100.5"
},
"card_verification_data": { "id": 43 }
}
Use vault_token instead of a card object to charge a stored instrument. reference is your order ID and comes back on every related record.
// 200 { "success": true, "message": "Transaction initiated", "data": { "id": 2, "amount": 1250, "currency": "EUR", "status": "auth", "transaction_type": "auth", "merchant_trans_id": "ORDER-912346", "acquirer_trans_id": "514009741995", "acquirer_auth_code": "400066" } }
Capture
POST /api/v1/transactions/{id}/capture MERCHANT ONLYApplies only when the transaction type was auth. Send an amount to capture partially.
Refund
POST /api/v1/transactions/{id}/refund MERCHANT ONLY{ "amount": 12.5, "reason": "Customer returned item" }
Void
POST /api/v1/transactions/{id}/void MERCHANT ONLYCancels an auth before it settles. Cheaper and cleaner than refunding afterwards.
Status
GET /api/v1/transactions/{id}/status REQUIRES AUTHStatuses returned by the API include auth, captured, refunded and voided. Partner keys can read status for merchants they are linked to.
Partner endpoints
You already have a gateway. We won't send you a checkout.
Partner keys manage linked merchants. You keep your own checkout, tokenisation and merchant IDs; we sit upstream. One rule worth internalising early: capture, refund and void remain merchant-only, even where a partner key can read status.
List linked merchants
GET /api/v1/merchants PARTNER ONLYGet a single merchant
GET /api/v1/merchants/{merchant_id} PARTNER ONLYMerchant transactions
GET /api/v1/merchants/{merchant_id}/transactions PARTNER ONLYFilter with status, from, to and per_page. Maximum page size is 100.
GET /api/v1/merchants/1/transactions ?status=success &from=2026-01-01 &to=2026-12-31 &per_page=25
Initiating on behalf of a merchant
Partner keys may call the transactions endpoint, but must include a merchant_id for a merchant linked to that partner.
{
"amount": 129.00,
"currency": "EUR",
"transaction_type": "sale",
"merchant_id": 123,
"card": { ... },
"reference": "YOUR-ORDER-4471"
}
Cascading and retry behaviour follows the limits published on the gateway page — never around 3-D Secure, never past scheme retry caps.
Errors
An error should tell you what to do next
Failures use the same envelope, with a machine-readable code and, for validation problems, a per-field errors object.
// 401 { "success": false, "message": "Authentication failed", "code": "ERR_AUTH_FAILED", "data": null }
// 422 { "success": false, "message": "Validation errors", "code": "ERR_VALIDATION_FAILED", "data": null, "errors": { "amount": ["The transaction amount must be a number."] } }
Branch on code, not on message. Messages are written for humans and may be reworded.
Testing
Test cards for every bad day
Use these against the 3DS verify endpoint. Test the unhappy paths — they are the ones that reach your customers.
| Card number | Scheme | Flow | Expected |
|---|---|---|---|
| 4200000000000091 | Visa | Frictionless | SUCCESS |
| 4200000000000109 | Visa | Frictionless | ATTEMPTED |
| 4200000000000042 | Visa | Challenge | CHALLENGE |
| 4012001037461114 | Visa | Error | TECHNICAL ERROR |
| 4012001037141112 | Visa | Error | NOT ENROLLED |
| 4532497088771651 | Visa | Not applicable | NOT PARTICIPATING |
| 5200000000000007 | Mastercard | Frictionless | SUCCESS |
| 5200000000000023 | Mastercard | Frictionless | ATTEMPTED |
| 5200000000000015 | Mastercard | Challenge | CHALLENGE |
| 5434580000000006 | Mastercard | Error | TECHNICAL ERROR |
| 5457350076543210 | Mastercard | Error | NOT ENROLLED |
| 5497260847316287 | Mastercard | Not applicable | NOT PARTICIPATING |
The full set includes further frictionless and challenge variants covering whether method data is returned. Ask and we will send the complete list with your sandbox key.
Get started
Break it in the sandbox first.
Tell us which track you are on and what you are building. You will get sandbox credentials, the full reference, and an engineer who answers rather than a form that acknowledges.