Start
Test mode
Test mode is the same API with simulated payments. The key decides the mode. No real money moves, and no payer is ever shown an address.
Live mode and test mode, side by side
| Live mode | Test mode | |
|---|---|---|
| Keys | sk_live_, pk_live_ | sk_test_, pk_test_ |
| Objects | livemode: true | livemode: false, same id prefixes |
| Money | Real, on the eleven networks | None. Payments are simulated. |
| Wallets | The merchant's eleven wallets | The same eleven are listed with livemode: false and address: null; balances are simulated and start at zero, growing as simulated payments settle |
| Addresses shown to a payer | Real deposit addresses | None, ever. payment_ is null and test_simulation_url is set |
| Hosted checkout | The real page | The same page with a fixed banner "Test mode: no real payment is possible here." and, where the address and QR code would be, a "Test payment" panel with the buttons Pay in full, Underpay by 10%, Overpay by 10%, Pay late, Let it expire and Fail routing |
| Approvals | Passkey in the dashboard | Nothing to sign: the dashboard shows "Approve (test)", or call the helper POST / |
| Emails | Sent only to your business's own members. Orrerie emails no customer in this release. | Sent only to the merchant's own members, with "[TEST]" in the subject. A test-mode email never goes to a customer's address |
| Webhooks | Endpoints added in the signed-in dashboard; a live key cannot add one | Endpoints created with a test key; signed the same way; 3 delivery attempts instead of 12 |
| Tier limits | Enforced | Not enforced, except the rate limit and the counts of keys and endpoints |
| Data life | Kept | Deleted 90 days after creation; "Delete all test data" in the dashboard clears it at once |
Test mode never shows an address
In test mode payment_instruction.address is null and test_simulation_url is set. There are no test-network wallets, so nobody can send real coins to an address that is only being watched on a test network.
What a test key cannot change
The account is one in both modes. A test key reads the merchant (with livemode: false), but the public profile (support email, logo, accent colour) is what live payers see, so only a live key or the dashboard changes it. A test key's PATCH /v1/merchant answers livemode_mismatch with reason live_profile and changes nothing.
What simulation covers
An exact payment, an underpayment, an overpayment, a late payment, a provider refund, a reverted payment and an unmatched payment, on any rail and asset. Each walks the real states and sends the real events with livemode: false. Subscriptions have a clock helper; refunds, payouts and conversions have an advance helper that can also end them failed or unknown.
curl
curl https://api.orrerie.com/v1/test/orders/ord_0zymngngvf12b8b2cra7tb8e/simulate_payment \
-H "Authorization: Bearer $ORRERIE_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"scenario": "exact",
"asset": "ethereum:usdc"
}'JavaScript
const response = await fetch("https://api.orrerie.com/v1/test/orders/ord_0zymngngvf12b8b2cra7tb8e/simulate_payment", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ORRERIE_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"scenario": "exact",
"asset": "ethereum:usdc"
}),
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result);Python
import os
import requests
response = requests.post(
"https://api.orrerie.com/v1/test/orders/ord_0zymngngvf12b8b2cra7tb8e/simulate_payment",
headers={"Authorization": f"Bearer {os.environ['ORRERIE_SECRET_KEY']}"},
json={
"scenario": "exact",
"asset": "ethereum:usdc",
},
timeout=30,
)
result = response.json()
if not response.ok:
raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result)PHP
<?php
$request = curl_init('https://api.orrerie.com/v1/test/orders/ord_0zymngngvf12b8b2cra7tb8e/simulate_payment');
curl_setopt_array($request, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('ORRERIE_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'scenario' => 'exact',
'asset' => 'ethereum:usdc',
]),
]);
$body = curl_exec($request);
if ($body === false) {
throw new RuntimeException(curl_error($request));
}
$result = json_decode($body, true);
if (curl_getinfo($request, CURLINFO_HTTP_CODE) >= 400) {
throw new RuntimeException($result['error']['code'] . ': ' . $result['error']['message']);
}
print_r($result);The helper endpoints
These endpoints exist only for sk_test_ keys. With a live key they answer 403 with test_helper_in_live_mode.
- POSTSimulate a payment/v1/test/orders/{id}/simulate_payment
- POSTApprove or advance a test refund, payout or conversion/v1/test/money_out/{id}/advance
- POSTAdvance a test subscription's clock/v1/test/subscriptions/{id}/advance
- POSTSkip a test saved address's approval and wait/v1/test/saved_addresses/{id}/activate
Going live
Going live is changing the key. Objects do not move between modes: products, prices, links and webhook endpoints are created again with the live key.
Limits until your business is verified
Until your business is verified it is on the Unverified tier, with these limits:
- Each of your first three paid orders can be up to US$250, and any later order up to US$1,000.
- Paid orders and unmatched payments you keep may total US$5,000 in any 30 days and US$20,000 in all. Once that total is reached, new orders are refused until you verify the business in the dashboard.
- At most 50 unpaid orders can be open at once.
- Payouts to others are limited to US$1,000 in any 24 hours; withdrawals to your own saved addresses have no tier limit.
A Verified business can take orders of up to US$50,000, and US$250,000 in any 30 days with no total limit, and pay out up to US$100,000 in 24 hours. Over a limit the API answers 403 with tier_order_limit, tier_volume_limit, tier_open_orders_limit or payout_daily_limit_reached (see the limit errors). Test mode does not enforce these limits, so plan for them before your first real sale.