API Docs

Getting Started

Two calls: start Light KYC with the buyer’s identity, then create a payment and redirect to hosted checkout. Phone, address and birthdate belong on KYC start only.

API Access

Create a sandbox key (sdk_…) in the merchant portal after registration. Live keys (pk_…) activate after KYB approval.

Base URL
https://stixpay.com

Send X-API-Key on every request. Environment comes from the key prefix — do not send a sandbox body flag.

KeyUse
sdk_…Test — KYC auto-approved, Test Gateway only
pk_…Live — production KYC + providers
secret_…Webhook signing only (not an API key)

Try it in the API Console. Full schema: openapi.yaml.

How a payment works

  1. 1
    POST /api/kyc/start — create the customer and start Light KYC (auto-approved with sdk_…).
  2. 2
    POST /api/payment/create — same customer_email + payment fields. Receive redirect_url.
  3. 3
    Redirect the buyer to redirect_url (hosted checkout).
  4. 4
    Listen for payment.succeeded / payment.failed, or poll GET /api/payment/{payment_id}/status.
KYC start Create payment Hosted checkout Webhook / poll

KYC is per customer (shared across merchants) and must be approved on the same key plane (sandbox vs live). Without Light KYC approved, create payment returns HTTP 422 kyc_required. Sandbox KYC does not affect the live profile.

1 — Start KYC

POST /api/kyc/start Auth

Creates the StixPay customer if needed and starts Light KYC. Send all identity fields here.

Body

FieldDescription
customer_emailBuyer email
customer_first_nameFirst name
customer_lastnameLast name
customer_phoneE.164, e.g. +33611223344
birthdateYYYY-MM-DD
customer_addressStreet address
postal_codePostal / ZIP
cityCity
countryISO alpha-2, e.g. FR, US. USA is normalized to US.
customer_stateUS state — required when country is US (or USA). 2-letter code, e.g. CA, NY. Aliases: state, state_of_residence.
levellight

Request

POST /api/kyc/start
Content-Type: application/json
X-API-Key: sdk_your_test_key

{
  "customer_email": "[email protected]",
  "customer_first_name": "Jane",
  "customer_lastname": "Doe",
  "customer_phone": "+33611223344",
  "birthdate": "1990-01-15",
  "customer_address": "1 rue de Rivoli",
  "postal_code": "75001",
  "city": "Paris",
  "country": "FR",
  "level": "light"
}

Response (sandbox)

HTTP 200
{
  "success": true,
  "already_approved": true,
  "customer_user_id": 1842,
  "customer_created": true,
  "kyc_state": "verified_light",
  "set_password_url": "https://stixpay.com/customer/set_password.php?token=…",
  "environment": "test"
}

For US buyers, include a state code (customer_state, state, or state_of_residence) — e.g. "country": "US", "customer_state": "CA".

New customers get a set-password link by email; hosted checkout can also finish password setup.

Poll KYC: GET /api/kyc/[email protected]

2 — Create payment

POST /api/payment/create Auth

Same API key plane as KYC start. Returns payment_id + redirect_url. Do not send phone, address, postal code, city or birthdate.

Body

FieldDescription
amountAmount > 0
currencye.g. EUR
payment_methodOptional. How the buyer pays on hosted checkout (card, Apple Pay, bank transfer, …). Alias: checkout_payment_method. Default: credit_card. See values below. Do not send with product_id (NFT).
merchant_order_idUnique per merchant
customer_emailSame email as KYC start
store_nameStore label
success_urlAbsolute URL
failure_urlAbsolute URL
provider_codeOptional. Lock the on-ramp rail (wert, banxa_api, banxa_hosted, transak_api, …).

payment_method — what it does

It tells StixPay which checkout rail to open for the buyer (card form, Apple Pay, SEPA, PayPal, …). It is independent of KYC. Availability still depends on the on-ramp provider, the buyer’s country/currency, and methods enabled for your merchant.

ValueMeaning
credit_cardDebit / credit card (default)
apple_payApple Pay
google_payGoogle Pay
open_bankingSEPA / open banking transfer
paypalPayPal
idealiDEAL (NL)
sofortSofort
klarna_paynowKlarna Pay Now
gbp_bank_transferGBP bank transfer
ach_bank_transferACH bank transfer (US)
payid_bank_transferPayID bank transfer (AU)
npp_bank_transferNPP bank transfer (AU)
interacInterac (CA)
pixPix (BR)
speiSPEI (MX)
khipuKhipu
zar_bank_transferZAR bank transfer (ZA)
psePSE (CO)
vietqrVietQR / QR wallet

Common aliases are accepted (e.g. cardcredit_card, sepaopen_banking). If omitted or empty, StixPay uses credit_card.

Request

POST /api/payment/create
Content-Type: application/json
X-API-Key: sdk_your_test_key

{
  "amount": 19.99,
  "currency": "EUR",
  "payment_method": "credit_card",
  "merchant_order_id": "ORDER_123",
  "customer_email": "[email protected]",
  "store_name": "Example Store",
  "success_url": "https://shop.example/success",
  "failure_url": "https://shop.example/failed"
}

Response

HTTP 200
{
  "success": true,
  "payment_id": "9021",
  "merchant_order_id": "ORDER_123",
  "redirect_url": "https://stixpay.com/customer/checkout.php?token=…",
  "expires_at": "2026-09-01 10:00:00"
}

Redirect the buyer to redirect_url.

If KYC is missing

HTTP 422
{
  "success": false,
  "error": "kyc_required",
  "message": "Customer Light KYC is not approved for the test (sandbox) environment…"
}

Payment status

  • pending — created; buyer has not finished checkout
  • pending_topup — on hosted checkout / paying
  • succeeded — paid (payment.succeeded)
  • failed — not paid (payment.failed)
  • expired — not completed in time

Lookups (GET)

All require X-API-Key except health.

GET /api/kyc/status Auth

Opaque KYC state for a customer you started. Query: customer_email (or customer_user_id).

GET /api/kyc/[email protected]
X-API-Key: sdk_your_test_key
GET /api/payment/{payment_id} Auth

Full payment object for a payment_id returned by create payment.

GET /api/payment/{payment_id}/status Auth

Lightweight status for polling after redirect.

GET /api/transactions Auth

Paginated list. Query: page, per_page, status, q (search order id / email / payment id).

GET /api/balance Auth

Merchant balance breakdown (available / hold / reserve, EUR).

GET /api/quote Auth

Indicative FX quote. Query: amount, currency (required).

GET /api/quote?amount=19.99&currency=EUR
X-API-Key: sdk_your_test_key
GET /api/rates Auth

Reference FX rate table.

GET /api/health

Public platform status (no API key).

Webhooks

Register your URL in Merchant → Webhooks and select the events to receive. Verify X-Webhook-Signature (HMAC-SHA256 of the raw body with your secret_…). Respond with HTTP 200.

Envelope: { id, type, created, data }.

Payments & KYC

EventWhen
customer.kyc.updatedCustomer Light KYC state changed
payment.succeededPayment completed
payment.failedPayment failed
payment_intent.canceledPayment cancelled before completion
refund.completedRefund completed

Payouts

EventWhen
payout.completedMerchant payout to your bank / crypto wallet completed
payout.failedMerchant payout failed
transaction_payout_successOn-ramp settlement / USDC payout for a paid transaction succeeded

Test delivery: POST /api/webhook/test or “Send test” in the portal.