Developer Portal

API documentation, integration guides, and webhook reference for building on the payment platform.

Quick Start

Integrate your CMS, website, or application with the checkout and licensing API in three steps:

1
Create an API Key
Go to your store settings and generate a Store API Key for server-to-server authentication.
2
Create a Checkout Session
POST to the session endpoint with your cart items. You'll get back a signed checkout URL.
3
Redirect the Customer
Send your customer to the checkout URL. After payment, they're redirected back to your success URL.

Minimal Example (cURL)

curl -X POST https://pay.example.com/api/v1/stores/my-store/checkout/session/ \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"cart": {"WIN-11-PRO": 1}, "currency": "GBP"}'

Authentication

All authenticated API endpoints require a Store API Key passed in the Authorization header.

Authorization: Bearer <your_store_api_key>

API Key Types

TypePrefixUse
Store API Key sk_... Server-to-server: checkout sessions, licensing fulfillment
Public endpoints None Geo subdivisions, tax rates (no key required)

Managing Keys

API keys are managed per-store in the Partner Portal under Stores → [Store] → API Keys. Keys are shown once on creation; store them securely. You can revoke a key at any time.

Security Best Practices

  • Never expose API keys in client-side code or public repositories
  • Use environment variables to store keys in your application
  • Rotate keys regularly and revoke unused keys
  • Use HTTPS for all API requests

API Reference

POST /api/v1/stores/<store_slug>/checkout/session/

Creates a signed checkout session and returns a URL to redirect customers to. This is the primary integration method for CMS and e-commerce platforms.

Request Headers

Authorization: Bearer <your_store_api_key>
Content-Type: application/json

Request Body

{
  "cart": {
    "PRODUCT-SKU-1": 1,
    "PRODUCT-SKU-2": 2
  },
  "currency": "GBP",
  "locale": "en",
  "metadata": {
    "external_reference": "your-order-123",
    "return_url_success": "https://your-site.com/success",
    "return_url_cancel": "https://your-site.com/cancel"
  }
}

Response (201 Created)

{
  "token": "abc123...",
  "checkout_url": "https://pay.example.com/s/your-store/cart/?token=abc123...",
  "expires_at": "2026-03-02T12:00:00Z"
}

cURL

curl -X POST \
  https://pay.example.com/api/v1/stores/my-store/checkout/session/ \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"cart": {"WIN-11-PRO": 1}, "currency": "GBP"}'

Python

import requests

resp = requests.post(
    "https://pay.example.com/api/v1/stores/my-store/checkout/session/",
    headers={"Authorization": "Bearer sk_live_..."},
    json={
        "cart": {"WIN-11-PRO": 1},
        "currency": "GBP",
    },
)
data = resp.json()
checkout_url = data["checkout_url"]
POST /api/v1/stores/<store_slug>/licensing/fulfill/

For licensing-only stores where payment is handled externally. Submit an external payment reference to allocate license keys.

Request Body

{
  "customer_email": "[email protected]",
  "items": [
    {"sku": "PRODUCT-SKU", "quantity": 1}
  ],
  "external_reference": "your-payment-id",
  "currency": "GBP",
  "total_minor": 2999
}

Response (201 Created)

{
  "order_id": "ORD-ABC123",
  "status": "fulfilled",
  "items": [
    {
      "sku": "PRODUCT-SKU",
      "license_keys": ["XXXXX-XXXXX-XXXXX-XXXXX"]
    }
  ]
}
GET /api/v1/geo/subdivisions/?country=<ISO2>

Returns state/province/region subdivisions for a given country code. Useful for building address dropdowns.

Response Example (?country=US)

{
  "country": "US",
  "subdivisions": [
    {"code": "AL", "name": "Alabama"},
    {"code": "AK", "name": "Alaska"},
    ...
  ]
}
GET /api/v1/tax/rates/?country=<ISO2>

Returns applicable tax rates for a given country. Useful for pre-checkout price display.

Webhooks

Configure a webhook URL in your store settings to receive real-time order status notifications. Events are sent as POST requests with an HMAC signature for verification.

Available Events

EventDescription
order.createdNew order created (payment initiated)
order.fulfilledPayment completed and keys allocated
order.refundedOrder was refunded
order.disputedChargeback/dispute opened

Webhook Payload

{
  "event": "order.fulfilled",
  "order_id": "ORD-ABC123",
  "external_reference": "your-ref-123",
  "status": "fulfilled",
  "total_minor": 2999,
  "currency": "GBP",
  "customer_email": "[email protected]"
}

Signature Verification (Python)

import hmac, hashlib

# Header: X-AnonymousPay-Signature: sha256=<hex_digest>

expected = hmac.new(
    webhook_secret.encode(),
    request.body,
    hashlib.sha256
).hexdigest()
assert hmac.compare_digest(expected, signature)

Setup

  1. Go to Partner Portal → Store Settings → Payments & Commerce
  2. Enter your webhook URL (must be HTTPS in production)
  3. Set a webhook secret for signature verification
  4. Your server should respond with HTTP 200 within 10 seconds

Stripe Webhooks (Self-hosted / LAN)

If your instance is on a private network, use the Stripe CLI to forward events:

stripe listen --forward-to http://<your-host>:8000/stripe/webhook/ \
  --events payment_intent.succeeded,charge.dispute.created,\
    charge.dispute.updated,charge.dispute.closed,\
    charge.dispute.funds_withdrawn,charge.dispute.funds_reinstated,\
    charge.refunded

Integration Guides

WordPress / WooCommerce

Use the checkout session API to create a "Buy Now" button on your WordPress site.

// functions.php
add_action('wp_ajax_create_checkout', function() {
    $response = wp_remote_post(
        'https://pay.example.com/api/v1/stores/my-store/checkout/session/',
        [
            'headers' => [
                'Authorization' => 'Bearer ' . EPAY_API_KEY,
                'Content-Type' => 'application/json',
            ],
            'body' => json_encode([
                'cart' => ['SKU-001' => 1],
                'currency' => 'GBP',
            ]),
        ]
    );
    wp_send_json(json_decode(wp_remote_retrieve_body($response)));
});
Custom CMS / SPA

Server-side: create a checkout session via API. Client-side: redirect to the returned URL.

// Node.js / Express
app.post('/buy', async (req, res) => {
  const resp = await fetch(
    `${EPAY_URL}/api/v1/stores/${STORE}/checkout/session/`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        cart: req.body.cart,
        currency: 'GBP',
      }),
    }
  );
  const { checkout_url } = await resp.json();
  res.redirect(checkout_url);
});
Direct Links (No API)

For simple integrations, use direct add-to-cart links with no server-side code required:

<!-- Single product -->
<a href="/s/my-store/cart/?add=SKU-001¤cy=GBP">
  Buy Now
</a>

<!-- Multiple products -->
<a href="/s/my-store/cart/?items=SKU1:1,SKU2:2¤cy=GBP">
  Buy Bundle
</a>
Marketplace Embed

List your products on the shared marketplace at /market/. Manage listings from the Marketplace tab in your partner portal. Customers browse, add to cart, and checkout — attribution is automatic.

Rate Limits

EndpointAuthRate Limit
Checkout Session Bearer sk_... 100 req/min per key
Licensing Fulfill Bearer sk_... 100 req/min per key
Geo Subdivisions None 300 req/min per IP
Tax Rates None 300 req/min per IP

All API responses include X-RateLimit-Remaining and X-RateLimit-Reset headers. If you hit the limit, the API returns HTTP 429 with a Retry-After header.

Error Responses

CodeMeaning
400Bad request (invalid JSON, missing fields)
401Unauthorized (missing or invalid API key)
404Store or product not found
429Rate limit exceeded
500Internal server error