Home  /  Developers

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.

REST + JSON Bearer authentication Server-managed 3DS Sandbox with test cards

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
Merchant endpoints

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
Partner endpoints

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 AUTH

Returns 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_auth immediately; a challenge returns a challenge_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
POST /api/v1/3ds/verify REQUIRES AUTH
{
  "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 AUTH

sale 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 ONLY

Applies 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 ONLY

Cancels an auth before it settles. Cheaper and cleaner than refunding afterwards.

Status

GET /api/v1/transactions/{id}/status REQUIRES AUTH

Statuses 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 ONLY

Get a single merchant

GET /api/v1/merchants/{merchant_id} PARTNER ONLY

Merchant transactions

GET /api/v1/merchants/{merchant_id}/transactions PARTNER ONLY

Filter 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 numberSchemeFlowExpected
4200000000000091VisaFrictionlessSUCCESS
4200000000000109VisaFrictionlessATTEMPTED
4200000000000042VisaChallengeCHALLENGE
4012001037461114VisaErrorTECHNICAL ERROR
4012001037141112VisaErrorNOT ENROLLED
4532497088771651VisaNot applicableNOT PARTICIPATING
5200000000000007MastercardFrictionlessSUCCESS
5200000000000023MastercardFrictionlessATTEMPTED
5200000000000015MastercardChallengeCHALLENGE
5434580000000006MastercardErrorTECHNICAL ERROR
5457350076543210MastercardErrorNOT ENROLLED
5497260847316287MastercardNot applicableNOT 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.

Keys are issued by us, not generated by you. Sandbox credentials are delivered securely once onboarding starts, so you can build while the paperwork runs in parallel. Production credentials follow a completed onboarding review.

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.