Developer resources

Documentation

Your guide to the merchant workspace, payment providers, and API integration.

Browse documentation

Part 1

Merchant Manual

A tour of every feature in the platform — what real-world problem it solves for your business, and exactly how to use it.

Platform overview

The problem it solves

Payment infrastructure is fragmented — cards, bank rails and crypto each live in a different portal, each with their own KYC, onboarding and reconciliation headache.

How it works

PayOrchestrate gives you one account that unifies two providers: Swipe (cards, SEPA, SWIFT, ACH, card-linked payouts) and B2BinPay (crypto deposits). You configure them once, and every payment link, embed frame, transaction and payout flows through the same dashboard.

Each merchant account has: a Swipe customer + primary wallet, an optional B2BinPay wallet, an embed key for your website, and a full audit trail of transactions.

Getting paid — prerequisites

The problem it solves

You need a legally compliant route to receive customer money. Different rails (card vs. SEPA vs. crypto) have different compliance and onboarding requirements.

How it works

Enable at least one provider before you can accept a single payment. Swipe covers fiat (card/bank); B2BinPay covers crypto. You can enable both.

  • Swipe — Click Enable in the Swipe router. Complete KYC to unlock bank rails (SEPA/SWIFT/ACH). Card rails work immediately after enable.
  • B2BinPay — Create a wallet in B2BinPay Back Office, copy the Wallet ID into our Source Configuration, click Save.

Swipe — cards, bank rails & payouts

The problem it solves

Accepting card payments or bank transfers normally means a merchant account, a gateway, a processor, compliance onboarding and weeks of back-and-forth.

How it works

Swipe abstracts all of that behind a single wallet. You enable it in one click, pass KYC once, and you get card pay-ins, virtual IBANs for SEPA/SWIFT/ACH, and outbound payouts from the same balance.

1. Enable Swipe. Swipe sidebar → Credentials → Enable Swipe. We create a customer + wallet; you’ll see the IDs once provisioned.

2. Pass KYC. Business Identity → Start KYC. Required for bank rails; cards work pre-KYC.

3. Create a pay-in. Simulation Center → Pay-in Execution. Enter amount/currency, choose Card, Quote, Execute — you get a hosted checkout URL to send the customer.

4. Provision a virtual bank account. Virtual Route → pick type (SEPA Node, SWIFT, ACH), country, currency → Provision Route. You get an IBAN/account number.

5. Send a payout. Global Payout Settle → destination + amount → Quote → Settle.

B2BinPay — crypto deposits

The problem it solves

Accepting crypto means managing wallets, monitoring chains for confirmations, converting to fiat, and reconciling to customer orders.

How it works

We connect to your B2BinPay wallet and generate deposit links on demand. Customers pay to a hosted page; B2BinPay credits your wallet; we surface the status back to you via webhook.

1. Link wallet. B2BinPay sidebar → Source Configuration → paste Wallet ID from B2BinPay Back Office → Save. Green dot + “Wallet Linked” confirms it.

2. Create deposit link. Deposit Execution → Create Deposit Link. We return the hosted payment URL. Copy the link or use Copy embed iframe to drop it straight on your site.

Payment Router

The problem it solves

Different orders need different rails — a small card payment vs. a €50k SEPA vs. a crypto deposit. Juggling three UIs is slow and error-prone.

How it works

The Router is a single switchboard: pick the provider, fill in the order details, generate a link or execute a payout. It wraps both Swipe and B2BinPay so operational workflows stay in one place.

Use Router → Simulation Center to test pay-ins and payouts without writing code.

Transactions & reconciliation

The problem it solves

Finance teams waste hours stitching provider CSVs to internal orders. Disputes and refunds are especially painful without a single source of truth.

How it works

Every pay-in, payout, deposit and settlement across Swipe and B2BinPay is stored against your account. The Transactions view is your canonical ledger — filterable by status, rail, provider, date.

Open it from Router → Transactions.

Profile & credentials

The problem it solves

Credentials sprawl (API keys, wallet IDs, 2FA seeds) is the #1 source of breached merchant accounts. Most platforms leave you to manage this on your own.

How it works

Profile centralises your identity, 2FA status, publishable key, Swipe customer/wallet IDs, embed key and credential vaults. Secrets are masked by default; 2FA via Google Authenticator is required on every sign-in.

Your publishable key (safe to use on your site) and embed key (scopes the iframe to your account) live here. Service-role keys never appear client-side.

Part 2

API Integration Manual

Connect your website or application to PayOrchestrate. Today the primary integration surface is the embed checkout iframe, backed by server-to-server webhooks for status events.

Integration overview

  1. Merchant enables Swipe and/or links B2BinPay — account is provisioned.
  2. Merchant copies their embed key from Profile or from the provider page in the Router.
  3. Merchant drops an iframe into their checkout page, passing amount + currency.
  4. Customer pays in the frame; funds land in the merchant’s Swipe wallet or B2BinPay wallet.
  5. Our server fires a webhook to the merchant’s configured callback URL with the final status.

Your embed key

The embed key identifies which merchant account a payment belongs to. Find it in:

  • Profile → System Integration → Embed Key
  • Router → Swipe → Credentials
  • Router → B2BinPay → Embed checkout iframe

Treat the embed key like a public key — safe to put in HTML, but it scopes all payments to your account. Rotate it only if you suspect abuse.

Embed checkout URL

https://payorchestrate.com/embed/checkout?key=YOUR_EMBED_KEY&amount=99.50&currency=EUR

Load this URL inside an iframe on your site. We resolve the merchant from key, create a fresh payment for amount + currency, and render the provider’s checkout inside the frame.

Drop-in iframe

<iframe
  src="https://payorchestrate.com/embed/checkout?key=YOUR_EMBED_KEY&amount=99.50&currency=EUR"
  title="Pay"
  width="100%"
  height="500"
  style="border:0; max-width: 480px;"
></iframe>

The frame is self-contained — it handles card entry, 3-D Secure, wallet selection and crypto QR codes depending on the provider and rail.

URL parameters

ParamRequiredDescription
keyYesYour merchant embed key.
amountYes*Decimal amount (e.g. 99.50). Not required if link is used.
currencyYes*ISO 4217 code (EUR, USD, GBP) or crypto ticker for B2BinPay flows.
providerNoswipe (default) or b2binpay.
linkNoURL-encoded existing hosted payment link. When set, we render that link instead of creating a new payment.
referenceNoYour internal order ID. Echoed back on the webhook.

Webhooks & callbacks

When a payment’s status changes (authorised, captured, failed, refunded, deposit confirmed), we POST a JSON payload to your callback URL. Status events originate from the provider and are relayed through our servers at:

POST https://payorchestrate.com/api/webhooks/swipelux
POST https://payorchestrate.com/api/webhooks/b2binpay

Representative payload:

{
  "event": "payment.succeeded",
  "provider": "swipe",
  "merchant_account_id": "acc_...",
  "payment_id": "pay_...",
  "reference": "ORDER-12345",
  "amount": "99.50",
  "currency": "EUR",
  "status": "succeeded",
  "created_at": "2026-04-15T10:22:31Z"
}

Your endpoint must respond with HTTP 2xx within 10 seconds. Non-2xx responses are retried with exponential backoff for up to 24 hours. Always verify the signature header (X-PayOrchestrate-Signature) before trusting the payload.

Your outbound webhooks

In addition to PSP callbacks hitting our platform, you can register your own HTTPS endpoint to receive normalized payment events for your merchant account. Configure this under Integrations → Webhooks.

  • Events fire when payments are created via the REST API, when PSP status webhooks update the ledger, and when you refund.
  • Each delivery is signed with HMAC-SHA256 (X-Webhook-Signature).
  • Choose event patterns such as payment.* or payment.completed.
{
  "id": "evt_abc123",
  "type": "payment.completed",
  "created_at": "2026-06-01T12:00:00.000Z",
  "livemode": true,
  "data": {
    "transaction": {
      "id": "uuid",
      "reference": "ORDER-12345",
      "provider": "cyberpay",
      "status": "completed",
      "amount": 100,
      "currency": "USD"
    }
  }
}

Testing & go-live

  • Use Simulation Center in the Router to generate test pay-ins/payouts end-to-end without real funds.
  • Load your embed URL in a local HTML file and confirm the frame renders and posts back to your webhook.
  • Before going live: verify 2FA is enabled on your profile, KYC is approved for bank rails, and your production webhook endpoint responds 2xx to a simulated event.

Part 3

REST API (v1)

A server-to-server JSON API for creating checkout sessions programmatically. Ideal when you need to generate a redirect URL from your backend before sending the customer to a hosted payment page.

Overview & authentication

All /api/v1/* endpoints are authenticated with a secret API key passed as a Bearer token. Keys are scoped to your merchant account and can be created and revoked from Integrations → API Keys.

Key security rules

  • Keys start with sk_live_
  • Shown once at creation — copy immediately
  • Never expose in client-side code or public repos
  • Revoke instantly from the dashboard if compromised

Base URL

https://payorchestrate.com/api/v1

Auth header

Authorization: Bearer sk_live_<your-key>

Discovery — GET /api/v1

curl https://payorchestrate.com/api/v1

Returns the full endpoint catalog, auth rules, and supported providers. No API key required.

MethodPathPurpose
GET/api/v1Discovery (no auth)
POST/api/v1/checkoutCreate pay-in session (cyberpay)
GET/api/v1/transactionsList payments
GET/api/v1/transactions/{id}Get status (+ optional refresh)
POST/api/v1/refundsRefund a pay-in
POST/api/v1/payoutsCreate or execute payout

GET /api/v1 — API discovery

Call this endpoint during integration to discover available routes programmatically. The response includes authentication instructions and the same endpoint list documented here.

curl https://payorchestrate.com/api/v1

POST /api/v1/checkout

Creates a hosted checkout session for the specified provider and returns a checkout_url to redirect your customer to.

Method

POST

Content-Type

application/json

Auth

Bearer sk_live_…
POST https://payorchestrate.com/api/v1/checkout
Authorization: Bearer sk_live_YOUR_KEY
Content-Type: application/json

{
  "provider": "cyberpay",
  "amount": 100.00,
  "currency": "USD",
  "country": "US",
  "redirect_url": "https://yoursite.com/thank-you",
  "reference": "ORDER-12345",
  "customer": {
    "email": "user@example.com",
    "phone": "+1234567890",
    "first_name": "John",
    "last_name": "Doe"
  }
}

Request body reference

FieldTypeRequiredDescription
providerstringYesPayment provider. Currently: cyberpay
amountnumberYesPositive decimal (e.g. 100.00)
currencystringYesISO 4217 code — USD, EUR, GBP, etc.
countrystringNoISO 3166-1 alpha-2 (e.g. US). Defaults to currency’s home country.
redirect_urlstringNoWhere to send the customer after payment. Defaults to your platform home page.
referencestringNoYour internal order ID. Echoed back on webhooks. Auto-generated if omitted.
customer object
customer.emailstringYesCustomer email address.
customer.phonestringYesCustomer phone in E.164 format (e.g. +12125551234).
customer.first_namestringNoDefaults to "Customer".
customer.last_namestringNoDefaults to "User".

GET /api/v1/transactions

List ledger rows for your merchant account. Results are ordered newest first. Use filters to reconcile by status, provider, or your merchant reference.

GET https://payorchestrate.com/api/v1/transactions?limit=50&status=pending&provider=cyberpay
Authorization: Bearer sk_live_YOUR_KEY
Query paramDescription
limit1–100, default 50
statuspending, completed, failed, refunded, etc.
providercyberpay, payagency, swipe, b2binpay
directionpayin, payout, adjustment
referenceMatch external_id or internal UUID
created_afterISO 8601 lower bound
created_beforeISO 8601 upper bound
include=rawInclude PSP raw_response on each row
{
  "ok": true,
  "count": 2,
  "transactions": [
    {
      "id": "uuid",
      "reference": "ORDER-12345",
      "provider": "cyberpay",
      "direction": "payin",
      "status": "completed",
      "amount": 100,
      "currency": "USD",
      "checkout_url": "https://cashier.cyberpay.link/...",
      "created_at": "2026-06-01T12:00:00.000Z"
    }
  ]
}

GET /api/v1/transactions/{id}

Fetch a single transaction by internal id (UUID) or your merchant reference (stored as external_id).

GET https://payorchestrate.com/api/v1/transactions/ORDER-12345?refresh=true
Authorization: Bearer sk_live_YOUR_KEY
  • refresh=true — polls Cyberpay or PayAgency for the latest status and updates your ledger.
  • include=raw — includes the PSP raw payload on the transaction object.
{
  "ok": true,
  "refreshed": true,
  "provider_status": "COMPLETED",
  "transaction": {
    "id": "uuid",
    "reference": "ORDER-12345",
    "status": "completed",
    "provider": "cyberpay"
  }
}

POST /api/v1/refunds

Refund a completed pay-in. The original transaction must belong to your account and match the provider. Refunds cannot be undone.

POST https://payorchestrate.com/api/v1/refunds
Authorization: Bearer sk_live_YOUR_KEY
Content-Type: application/json

{
  "provider": "cyberpay",
  "reference": "ORDER-12345",
  "reason": "Customer requested refund"
}

Supported providers: cyberpay (uses merchant reference), payagency (uses PSP transaction id when available).

POST /api/v1/payouts

Initiate a payout. Behaviour depends on the provider:

  • Cyberpay — returns a hosted payout_url (cashier) for the beneficiary to complete.
  • PayAgency — direct card payout; requires payout_details (wallet_id, card_number, expiry).
  • Swipe — two-step: first call creates a quote_id; second call passes quote_id to execute.
// Cyberpay hosted payout
POST https://payorchestrate.com/api/v1/payouts
{
  "provider": "cyberpay",
  "amount": 50,
  "currency": "USD",
  "country": "US",
  "customer": { "email": "payee@example.com", "phone": "+12125551234" }
}

// Swipe — step 1: create quote
{ "provider": "swipe", "amount": 50, "currency": "USD",
  "destination_id": "swipe-beneficiary-id",
  "customer": { "email": "payee@example.com", "phone": "+12125551234" } }

// Swipe — step 2: execute
{ "provider": "swipe", "quote_id": "quote_abc123",
  "customer": { "email": "payee@example.com", "phone": "+12125551234" } }

Response & errors

200 — Success

{
  "ok": true,
  "checkout_url": "https://cashier.cyberpay.link/session/...",
  "reference": "ORDER-12345",
  "provider": "cyberpay",
  "amount": 100,
  "currency": "USD"
}

Redirect your customer to checkout_url. The session is typically valid for 15–30 minutes depending on the provider.

Error shape

{
  "ok": false,
  "error": "Human-readable message",
  "code": "ERROR_CODE"
}
HTTPcodeMeaning
401UNAUTHORIZEDMissing or invalid API key.
400BAD_REQUESTRequest body is not valid JSON.
400VALIDATIONA required field is missing or invalid.
403PSP_UNAVAILABLEYour account is not entitled to this provider.
404NOT_FOUNDTransaction or quote not found.
502PSP_ERRORThe provider rejected the request. See error for details.
503PSP_UNAVAILABLEProvider is disabled platform-wide.
500INTERNALUnexpected server error.

Outbound webhooks (to your server)

The REST API and PSP flows automatically trigger outbound webhooks when you configure a URL in Integrations → Webhooks. You do not call a separate API to enable this — save your endpoint once and events flow when the ledger changes.

Verify signatures on every request. Header format: X-Webhook-Signature: t=1690000000,v1=<hmac_hex> where v1 = HMAC-SHA256(secret, "{timestamp}.{body}").

Use Send test event in the dashboard to validate your handler before going live.

Inbound PSP webhooks & reconciliation

Pay-ins and payouts created via the API use the same webhook endpoints as the dashboard and embed flows. Configure your PSP dashboard to send notifications to:

  • https://payorchestrate.com/api/webhooks/cyberpay
  • https://payorchestrate.com/api/webhooks/payagency
  • https://payorchestrate.com/api/webhooks/swipelux
  • https://payorchestrate.com/api/webhooks/b2binpay

Use GET /api/v1/transactions/{reference}?refresh=true when you need an on-demand status poll before the webhook arrives. Your reference from checkout is stored as external_id and echoed in webhook payloads where the PSP supports it.

Code examples

cURL

curl -X POST https://payorchestrate.com/api/v1/checkout \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d ‘{
    "provider": "cyberpay",
    "amount": 100.00,
    "currency": "USD",
    "country": "US",
    "redirect_url": "https://yoursite.com/thank-you",
    "reference": "ORDER-12345",
    "customer": {
      "email": "user@example.com",
      "phone": "+12125551234",
      "first_name": "Jane",
      "last_name": "Smith"
    }
  }’

JavaScript (fetch)

const res = await fetch("https://payorchestrate.com/api/v1/checkout", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    provider: "cyberpay",
    amount: 100.00,
    currency: "USD",
    country: "US",
    redirect_url: "https://yoursite.com/thank-you",
    reference: "ORDER-12345",
    customer: {
      email: "user@example.com",
      phone: "+12125551234",
      first_name: "Jane",
      last_name: "Smith",
    },
  }),
});

const { ok, checkout_url, error } = await res.json();
if (!ok) throw new Error(error);

// Redirect the customer
window.location.href = checkout_url;

Python (requests)

import requests

response = requests.post(
    "https://payorchestrate.com/api/v1/checkout",
    headers={
        "Authorization": "Bearer sk_live_YOUR_KEY",
        "Content-Type": "application/json",
    },
    json={
        "provider": "cyberpay",
        "amount": 100.00,
        "currency": "USD",
        "country": "US",
        "redirect_url": "https://yoursite.com/thank-you",
        "reference": "ORDER-12345",
        "customer": {
            "email": "user@example.com",
            "phone": "+12125551234",
            "first_name": "Jane",
            "last_name": "Smith",
        },
    },
)

data = response.json()
if not data["ok"]:
    raise Exception(data["error"])

checkout_url = data["checkout_url"]
# Redirect the customer to checkout_url

Need something that isn’t covered?

Open a support ticket from the Router, or reach out to your account manager. We publish this manual alongside the product — if a feature changes, the docs do too.