Get started

Quickstart

Go from API key to a confirmed payment with a webhook receipt, in under five minutes.

What you need

  1. A merchant account in the Xpend Console (sandbox is fine).
  2. A server you control to receive webhooks.
  3. cURL, Node, or Python.

1. Create an API credential

In the merchant console, open Developers → API credentials and create a key. The plaintext secret is shown once.

export XPEND_SECRET_KEY="key_id.plaintext_secret"
export XPEND_BASE="https://bapi.justxpend.ai"

2. Verify the credential

curl $XPEND_BASE/v1/merchant/principal \
  -H "Authorization: Bearer $XPEND_SECRET_KEY"

Response

{
  "merchant_id": "mch_01HXY...",
  "environment": "sandbox",
  "actor_type": "api_credential",
  "actor_id": "cred_01HXY...",
  "scopes": ["payment_intents:create", "payment_intents:read", "webhooks:manage"]
}

3. Create a payment intent

curl $XPEND_BASE/v1/payment-intents \
  -H "Authorization: Bearer $XPEND_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_8421" \
  -d '{
    "amount": "150.00",
    "chain": "ethereum",
    "token": "USDC",
    "metadata": {
      "order_id": "order_8421"
    }
  }'

Response

{
  "payment_intent_id": "pi_01HXYZ8K3P...",
  "chain": "ethereum",
  "token": "USDC",
  "deposit_address": "0x1234abcd5678ef901234abcd5678ef901234abcd",
  "status": "PENDING",
  "deposit_status": "none",
  "expires_at": "2026-03-19T16:25:00Z",
  "created_at": "2026-03-19T16:20:00.000Z",
  "metadata": {
    "order_id": "order_8421"
  },
  "checkout_url": "https://pay.justxpend.ai/c?token=xY9k2mN_pQr4sT5uV6wX7yZ8aB0cD1eF2gH3iJ4kL5m"
}

4. Register a webhook endpoint

curl $XPEND_BASE/v1/webhooks/endpoints \
  -H "Authorization: Bearer $XPEND_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/xpend",
    "event_types": ["payment_intent.completed", "payout.completed"]
  }'

Save the signing secret

The response includes signing_secret exactly once.

5. Pay & receive the webhook

In sandbox, open checkout_url when present, or display the returned deposit_address. After confirmation your endpoint receives:

{
  "id": "evt_01HXYZA4...",
  "type": "payment_intent.completed",
  "api_version": "2026-04-01",
  "created_at": "2026-03-19T16:32:11Z",
  "merchant_id": "merchant_xyz",
  "environment": "test",
  "data": {
    "payment_intent": {
      "payment_intent_id": "pi_01HXYZ8K3P...",
      "metadata": {
        "order_id": "order_8421"
      },
      "settled_amount": "150000000",
      "currency": "USDC",
      "chain": "ethereum",
      "credited_at": "2026-03-19T16:32:11.000Z",
      "fees": null
    }
  }
}

That's it

You have an end-to-end loop. Next: harden signature verification and idempotent handling.