Full API Checkout
You collect everything, including the card, and create the order through the API. The customer never leaves your surface. Chaiz still quotes the plans, processes the payment, and issues the contract.
This is the most work and the most control.
Card data passes through your systems on this path, which puts you in PCI DSS scope. That is a compliance obligation, not a technical detail. If you are not already handling card data under an existing PCI program, use Search and Hand Off instead: the customer pays on a Chaiz page, you never see a card number, and the search call is identical.
The flow
Step 1: search
Identical to Search and Hand Off. Keep the
searchResultPlanId of whichever plan the customer picks. Ignore the handoff URLs; you are not using
them on this path.
A searchResultPlanId is valid for 30 days. Beyond that, ordering it fails and you need a fresh
search.
Step 2: create the order
curl -X POST https://chaiz-api-uat.azurewebsites.net/api/v2/Partners/Order/CreateWithUserDetails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"searchResultPlanIds": [12345],
"selectedAddonIds": [11, 43],
"payment": {
"accountNumber": "4111111111111111",
"creditCardExpirationDateString": "12/2028",
"cvc": "123",
"methodType": 1,
"paymentOption": 0
},
"userDetails": {
"externalId": "your-customer-reference",
"firstName": "Jane",
"lastName": "Roe",
"email": "customer@example.com",
"address": "1871 Park Avenue",
"addressApartment": "5",
"city": "New York",
"state": "NY",
"zip": "10018",
"phoneNumber": "9162255645"
},
"device": "Desktop"
}'
You do not resend the vehicle or the mileage. Both are read from the search that produced the
searchResultPlanId.
Payment
| Field | Notes |
|---|---|
accountNumber |
Card number, 13 to 16 digits. In UAT use 4111111111111111. |
creditCardExpirationDateString |
MM/YYYY. Note the four-digit year. |
cvc |
3 to 5 digits. |
methodType |
1 Visa, 2 Mastercard, 3 American Express, 4 Discover, 5 ACH savings, 6 ACH checking. |
paymentOption |
0 monthly installments, 2 pay in full. Required. |
paymentOption is an enum whose member names do not read the way you would expect: 0 is monthly
installments and 2 is pay in full. Use the numbers above. Which options are available at all depends
on your account and on the plan's duration, so a value your account does not allow will be rejected.
Customer details
Required: firstName, lastName, email, address, city, state, zip.
Validation is stricter than you may expect, and these are the usual causes of a rejected order:
statemust be the two-letter code that actually matches thezip. A mismatch is rejected.firstNameandlastName: 2 to 32 characters, letters plus dot, space, dash, apostrophe. No digits.address: 5 to 60 characters and must include a street name.addressApartment: 4 characters maximum.city: 3 to 32 characters.phoneNumber: optional but recommended, 10 digits, US format.
Set isBillingAddressDifferent: true and populate the billing* fields when billing differs from the
customer's address. Send externalId to carry your own customer or transaction reference through to
the order and the webhook.
Validate this client-side before submitting. A customer who has already entered a card should not be the one to discover that their apartment number is too long.
Step 3: read the response, carefully
A 201 body is an array of wrappers, one per plan you ordered. Each wrapper's response is a
single order ID string:
[
{ "response": "8f14e45f-ceea-467a-9c2b-1ffb3b1c4d2e", "errorResponse": null }
]
Order two plans and you get two entries. Do not expect one object with an array of IDs inside it.
A 200 on this endpoint is a failure, not a success. Validation problems, declined payments,
expired plans, and fraud checks all return 200 with a populated errors array. Branch on the status
code being 201, or on errors being empty. Do not treat any 2xx as a completed sale, or you will
report sales that never happened.
| Status | Meaning |
|---|---|
201 |
Order created. Each array entry's response is an order ID. |
200 |
Not created. Also an array; read errorResponse.errors on the entries for the reason: declined card, expired plan, failed validation, or a fraud check. |
401 |
Missing or invalid Bearer token. |
Common reasons: payment declined (CreditCardError, 3000), invalid card number, expired plan or a
state mismatch between the customer and the plan (StateMismatchPlanNotAvailable, 1009). See
Errors.
Payment is authorized before the contract is created and captured after. If anything fails in between, the authorization is voided automatically, so a failed order does not leave a charge on the customer's card. You do not need to reverse anything yourself.
Step 4: receive the order webhook
On order creation we POST to the webhook URL configured on your account:
{
"externalId": "your-customer-reference",
"success": true,
"orderId": "8f14e45f-ceea-467a-9c2b-1ffb3b1c4d2e"
}
Failures carry success: false and an errorMessage.
Webhooks are configured by Chaiz, not through the API. There is no subscription endpoint. Send your callback URL to dev-support@chaiz.com during onboarding.
Webhook delivery is best-effort and deliberately cannot fail an order. If your endpoint is down, the
order still completes and the notification is lost. Treat the 201 response as your source of truth
and the webhook as a convenience, and persist the orderId from the 201 yourself.
Checking an order later
curl "https://chaiz-api-uat.azurewebsites.net/api/v2/Partners/Order/Status?orderId=8f14e45f-ceea-467a-9c2b-1ffb3b1c4d2e" \
-H "Authorization: Bearer YOUR_API_KEY"
Returns true when the order is active, and false with a 410 when it was never created, was
cancelled, or is inactive. It is a liveness check and nothing more: no plan, price, or customer detail
comes back. You need to have kept the orderId yourself.
Going live
- Validate customer details in your own form before submitting. Most rejections are avoidable.
- Branch on
201, never on2xx. This is the single most common integration bug on this endpoint. - Persist the
orderIdfrom the201response rather than relying on the webhook. - Confirm your PCI posture covers this flow before handling a live card.
- Give dev-support@chaiz.com your webhook URL and confirm you receive a test delivery in UAT.
- Test a decline as well as an approval, and confirm your UI does the right thing on a
200. - Swap to
https://api.chaiz.comwith your production key.
Next steps
- Plan Search Reference for filters and vehicle identification.
- Errors & Rate Limits for the error envelope and validation codes.
- Search and Hand Off if the PCI obligation changes your mind. The search half of your work carries over unchanged.