API

The glue service exposes three groups of endpoints. All requests other than the public checkout API require a Logto-issued JWT in Authorization: Bearer ….

Base URL: https://api.<your-domain> (Caddy routes it to the glue container on :4000).

Public (no auth)

| № | Method | Path | Purpose | |---|---|---|---| | 1 | GET | /api/products | list active products | | 2 | GET | /api/products/:id | product detail | | 3 | POST | /api/checkout/initiate | create order, returns checkout URL | | 4 | GET | /api/orders/:id | poll order status | | 5 | GET | /api/customer/entitlements | what the current Logto user owns |

Merchant (admin role required)

| № | Method | Path | Purpose | |---|---|---|---| | 1 | POST | /api/merchant/products | create product | | 2 | PATCH | /api/merchant/products/:id | update product | | 3 | DELETE | /api/merchant/products/:id | soft-delete product | | 4 | GET | /api/merchant/orders | list orders | | 5 | GET | /api/merchant/orders/:id | order detail | | 6 | POST | /api/merchant/orders/:id/refund | mark refunded (manual) | | 7 | GET | /api/merchant/customers | list customers | | 8 | GET | /api/merchant/analytics | totals (sales, orders) | | 9 | GET/POST | /api/merchant/wallets | configure xPub per chain |

Outgoing webhooks (merchant subscribes)

Events posted to merchant-configured URLs:

| № | Event | Triggered when | |---|---|---| | 1 | order.created | invoice initiated | | 2 | order.paid | Bitcart/Solana confirms payment | | 3 | order.expired | invoice TTL elapsed | | 4 | entitlement.applied | handler succeeded | | 5 | entitlement.failed | handler exhausted retries | | 6 | customer.created | new Logto user via checkout |

Each request is signed with HMAC-SHA256 of the body under GLUE_OUTBOUND_WEBHOOK_SECRET in the X-OpenBitum-Signature header. Verify before trusting.

Example: create an invoice

curl -X POST https://api.example.com/api/checkout/initiate \
  -H 'Content-Type: application/json' \
  -d '{"productId":"prd_01H9...", "email":"buyer@example.com"}'

Response:

{
  "orderId": "ord_01H9...",
  "checkoutUrl": "https://example.com/checkout/ord_01H9..."
}

Poll GET /api/orders/:id every 2 s on the checkout page until status === "paid".

SDK

@openbitum/sdk (npm) provides a typed client for the public + merchant endpoints. The package is wired into the monorepo at packages/sdk — installable separately once published. Coming after MVP launch: per-language clients (Python, Go).