Skip to content
BaxPayDevelopers

Get started

Quickstart

From nothing to a collected payment in about five minutes, entirely in sandbox.

Get a sandbox API key

Create an account in the BaxPay Business dashboard and, on the Developers page, create a bx_test_ key. Copy it now — it is shown once. The key is the mode: everything it touches is sandbox data, and no real money can move.

Create a payment link

One call: an amount and a description. You get back a hosted page URL.

Pay it with a test card

Open the URL and pay with 4242 4242 4242 4242, or watch 4000 0000 0000 0002 get declined.

See the money land

Retrieve the link (now PAID) — or better, receive the payment_link.paid webhook.

Charge €47.30 for a haircut. Three things to notice:

  • Idempotency-Key is required on every call that creates or moves money. Retrying with the same key can never create a second link.
  • businessWide: true takes the payment for the whole business. To book it to one location instead, send that location's storeId. One of the two is required.
  • amount is in euros (47.30), not cents.
curl -X POST https://sandbox-api.baxpay.com/v1/payment-links \
  -H "Authorization: Bearer $BAXPAY_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Haircut — 16 July", "amount": 47.30, "businessWide": true }'

Every response is wrapped: the link itself is in data.

{
  "success": true,
  "data": {
    "id": "1c9f4a2e-…",
    "token": "plk_4f1f0c4c4e1a…",
    "url": "https://pay.baxpay.com/plk_4f1f0c4c4e1a…",
    "description": "Haircut — 16 July",
    "amount": 47.3,
    "feeAmount": 1.47,
    "chargeAmount": 47.3,
    "netAmount": 45.83,
    "currency": "EUR",
    "feePayer": "RECEIVER",
    "status": "OPEN",
    "livemode": false,
    "paidAt": null
  },
  "timestamp": "2026-07-16T14:02:10.000Z",
  "path": "/v1/payment-links"
}

chargeAmount is what the customer pays and netAmount is what you receive after BaxPay's fee (feeAmount). With the default feePayer: "RECEIVER", you absorb the fee.

2 · Pay it

Open data.url in a browser. You'll see the hosted page your customers see: your business name, the description, the amount and a test mode banner. Pay by card with 4242 4242 4242 4242 (any future expiry, any CVC); 4000 0000 0000 0002 is always declined. The page flips to a receipt.

In sandbox you can also pay from a terminal. This is the call the hosted page makes:

curl -X POST https://sandbox-api.baxpay.com/v1/pay/link/plk_4f1f0c4c4e1a…/card \
  -H "Content-Type: application/json" \
  -d '{ "number": "4242 4242 4242 4242", "expMonth": 12, "expYear": 2030, "cvc": "123", "holder": "MARIE DUPONT" }'
{ "success": true, "data": { "status": "PAID", "maskedInstrument": "•••• 4242" } }

3 · Confirm the money landed

If you registered a webhook for payment_link.paid, BaxPay has already pushed this to your endpoint, signed:

{
  "id": "f017738f-…",
  "type": "payment_link.paid",
  "livemode": false,
  "data": {
    "paymentLinkId": "1c9f4a2e-…",
    "description": "Haircut — 16 July",
    "amount": 47.3,
    "currency": "EUR",
    "method": "CARD_NOT_PRESENT",
    "transactionRef": "be294a82-…"
  },
  "createdAt": "2026-07-16T14:03:21.530Z"
}

Or retrieve the link:

curl https://sandbox-api.baxpay.com/v1/payment-links/1c9f4a2e-… \
  -H "Authorization: Bearer $BAXPAY_API_KEY"
{
  "success": true,
  "data": {
    "id": "1c9f4a2e-…",
    "status": "PAID",
    "paidAt": "2026-07-16T14:03:21.512Z",
    "paidMethod": "CARD_NOT_PRESENT",
    "paidTransactionId": "be294a82-…"
  }
}

Polling is fine for a quickstart. In production, subscribe to webhooks instead.

Where to go next