Order Creation Failed
order_creation_failed400
We couldn't create a payment order with the processor. No charge was attempted.
What this means
Before a checkout flow opens, we ask the processor (Dodo) to create an order — this is the upstream object that ties together the plan, the amount, and the customer record. The processor rejected or failed to create the order. The user never reached the payment screen, so no charge was attempted and no subscription state was modified.
When you'll see this
- The processor's API rate-limited our request burst (we batch checkout requests during launch traffic spikes).
- A required field in the order payload was missing or malformed (rare — would indicate a server-side regression on our side).
- The plan ID being purchased isn't recognized by the processor (configuration drift between Asterwise plan IDs and Dodo product IDs).
- The processor's order creation endpoint returned a transient 5xx.
Learn more about how this works
The checkout flow has three stages: order creation, payment, and verification. This error is stage 1 — the order doesn't exist yet, so there's nothing to clean up. Retrying is safe and usually works the second time, because the most common cause is a transient processor issue.
The most common gotcha: if this error persists across multiple retries spaced minutes apart, it's not transient. Either our config has drifted (a new plan we forgot to register with the processor) or the processor is having a real outage. Check status.asterwise.com to disambiguate.
Example response
{
"success": false,
"error": "order_creation_failed",
"message": "Failed to create payment order. Please try again.",
"details": [],
"retry_after": null,
"doc_url": "https://docs.asterwise.com/reference/errors/order_creation_failed",
"request_id": "req_01HXYZABCDEFGH",
"timestamp": "2026-05-25T12:34:56Z"
}
- Wait 30 seconds and retry the "Subscribe" button in asterwise.com/dashboard.
- If it fails again, refresh the dashboard page completely (clear any cached state) and try once more.
- If three attempts fail, email [email protected] with the
request_idfrom any of the failed attempts — that's enough for us to investigate.
Retriable on transient causes; surface clearly on persistent ones.
Python:
Production handler
- Python
- TypeScript
import httpx
import time
def create_order(plan_id, base_url, headers):
for attempt in range(3):
response = httpx.post(
f"{base_url}/v1/billing/order",
headers=headers,
json={"plan_id": plan_id},
timeout=15,
)
if response.status_code == 400:
body = response.json()
if body.get("error") == "order_creation_failed":
if attempt < 2:
time.sleep(5 * (attempt + 1))
continue
raise RuntimeError(
f"Order creation failed after 3 attempts. "
f"request_id={body.get('request_id')}"
)
response.raise_for_status()
return response.json()
async function createOrder(planId: string, baseUrl: string, headers: HeadersInit) {
for (let attempt = 0; attempt < 3; attempt++) {
const response = await fetch(`${baseUrl}/v1/billing/order`, {
method: "POST",
headers,
body: JSON.stringify({ plan_id: planId }),
});
if (response.status === 400) {
const body = await response.clone().json();
if (body.error === "order_creation_failed") {
if (attempt < 2) {
await new Promise((r) => setTimeout(r, 5_000 * (attempt + 1)));
continue;
}
throw new Error(
`Order creation failed after 3 attempts. ` +
`request_id=${body.request_id}`,
);
}
}
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
}
Avoid this error by
- Always start checkout from the official Asterwise dashboard UI. Custom checkout pages multiply the failure surface for limited benefit.
- Don't pre-create orders speculatively (e.g. on page load) — create them only when the user clicks "Subscribe". Speculative orders waste processor quota and amplify this error.
- Monitor
order_creation_failedrate in your own logs. A baseline of zero is healthy; sustained non-zero rates point to config drift or processor degradation.