API and webhooks
An API that brings money in and can never send it out.
JSON over HTTPS, one payable object, signed webhooks and a test mode. A person approves every movement of funds.

The pictures on this page show the built product with a test business and simulated payments.
The API in one page
Create a session, redirect, wait for the webhook.
Your server makes one call to api.orrerie.com and sends the payer to the checkout it returns. Fulfil the order on the order.paid event or by reading the order, never on the payer's browser coming back.
- One payable object, the order: sessions, links, invoices, till sales and subscription periods each make one.
- Idempotency keys on every call that creates something, so a retry never creates it twice.
curl https://api.orrerie.com/v1/checkout_sessions \
-H "Authorization: Bearer $ORRERIE_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-attempt-1" \
-d '{
"amount": "21.99",
"currency": "USD",
"description": "Order #1042",
"reference": "1042",
"customer_email": "jane@example.com",
"success_url": "https://acme.example/thanks?session={CHECKOUT_SESSION_ID}",
"cancel_url": "https://acme.example/cart"
}'
# Then send the payer's browser to the "url" in the answer:
# HTTP/1.1 303 See Other
# Location: https://pay.orrerie.com/c/cs_z7ek5wj68fyz80j7bz1eq4e0order.paidJavaScript// after verifyOrrerieSignature(...) returned true
switch (event.type) {
case 'order.paid': // sent once; status is "paid" or "overpaid"
await markPaid(event.data.object.reference, event.data.object.id);
break;
case 'order.underpaid':
await flagShort(event.data.object.reference, event.data.object.amount_due);
break;
case 'order.unpaid': // a payment was undone by the chain
await holdFulfilment(event.data.object.reference);
break;
default:
break; // ignore types you do not use
}Webhooks
Signed messages to your own server.
Each webhook is an HTTPS POST signed with HMAC-SHA-256 under a secret only you and Orrerie hold. The dashboard lists every attempt with the body sent and the answer received, and any attempt can be sent again.
- An endpoint that keeps failing is marked Failing.
- After 7 days of failures it is paused.
How an order becomes Paid, step by stepWebhooks, in the docs

Events
Every event, and where it went.
Each event is kept with each delivery of it, so you can see what your server was told and when.
- Live secret keys: 2 before the business check, 20 after.
- Webhook endpoints: 1, then 10. Requests: 60 a minute, then 600.

Money out
A key can ask. Only a person can approve.
A requested payout waits for an Owner or Finance member to approve it in the dashboard with a passkey. An API key unlocks no wallet key.
- A key can request a refund, a payout, a withdrawal or a conversion.
- Only a person approves it, with a passkey, on a Review that Orrerie rebuilds from its own facts.
- Nothing a key does can make a new address usable sooner.

| The API can | The API cannot |
|---|---|
| Read wallets, addresses, balances and the ledger. | Create or change a wallet, a key or a threshold. |
| Create orders, sessions, links, invoices and subscriptions. | Change where your takings land. |
| Request a refund, a payout, a withdrawal or a conversion. | Approve, sign or send any of them. |
| Propose a saved address. | Make a saved address active, or shorten its 24-hour wait. |
Test mode
Simulated payments, real states.
Test keys and test mode use simulated payments; there are no test-network wallets.
- A test checkout offers buttons to pay in full, underpay, overpay, pay late, let the order expire or fail the routing.
- Each drives the same states and webhooks as a real payment.
- A test checkout says plainly that no real payment is possible there.
- Test secret keys start with sk_test_ and reach test data only.

Create a test key.
Try the API with simulated payments before any real money moves.