Hosted Checkout#
Create a checkout session from your server and send the shopper to a payment page hosted by AuxCORE — full page, or embedded in an iframe on your site. Card data never reaches your servers. The WooCommerce plugin is built on this flow.
How it works#
- Your server creates a session with
POST /api/v1/public/checkout-sessionand your secret key. The response holds aredirectUrland aniframeUrl. - The shopper pays on the hosted page — send them to
redirectUrl, or loadiframeUrlin an iframe. - AuxCORE returns the shopper to your
returnUrl,declineUrlorcancelUrl— or to its own outcome page if you gave none, or they are not on your registered store URL. - Your server fulfils the order from the webhook, not from the return redirect:
transaction.approvedcarries yourorderId.session.cancelledandsession.expiredtell you the shopper did not pay.
The session lasts 10 minutes by default. After that the shopper cannot pay on it; create a new one.
Create a checkout session#
Send your secret key in x-api-key; the merchant comes from the key (ERP keys also send X-Merchant-ID).
curl -X POST https://uat.auxcore.net/api/v1/public/checkout-session \
-H "x-api-key: YOUR_SECRET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 49.90,
"orderId": "ORD-1042",
"description": "Order #1042",
"customerEmail": "jane@example.com",
"customerName": "Jane Doe",
"billingAddress": {
"line1": "123 Main St",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"country": "US"
},
"returnUrl": "https://shop.example.com/orders/1042/thanks",
"declineUrl": "https://shop.example.com/orders/1042/payment-failed",
"cancelUrl": "https://shop.example.com/cart"
}'Request fields#
| Field | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | Amount to charge; must be greater than 0 |
currency |
string | No | Default USD |
orderId |
string | No | Your order reference. Copied onto the transaction and into its webhooks; defaults to wc-<sessionId> |
description |
string | No | Order description |
customerEmail, customerName, billingPhone |
string | No | Prefill the payer's details |
billingAddress, shippingAddress |
object | No | line1, line2, city, state, postalCode, country (default US), email, phone, firstName, lastName, company |
lineItems |
array | No | Itemisation stored with the session: { "name", "quantity", "unitPrice", "total" }. The charge comes from amount |
returnUrl |
string | No | Where to send the shopper after an approval (alias successUrl) |
declineUrl |
string | No | Where to send the shopper after a decline (alias failureUrl) |
cancelUrl |
string | No | Where to send the shopper who cancels |
reference, invoiceNumber, notes |
string | No | Your own references, stored with the session |
ttlSeconds |
integer | No | Session lifetime, from 60 up to the platform maximum (600 by default) |
paymentPurpose |
string | No | Route the charge to the merchant's gateway reserved for this purpose (e.g. donation): 1–30 characters of a-z, 0-9, -, _ |
metadata |
object | No | Free-form data echoed back in the response. Older plugins send the fields above inside metadata; they are read from there when missing at the top level |
webhookUrl and webhookSecret are rejected (400 UNSUPPORTED_FIELD): webhooks are registered once per merchant with POST /register-webhook, not per session.
Response#
201 Created
{
"success": true,
"status": "success",
"data": {
"sessionId": "cs_4f1d0c6b2a9e8d7c6b5a4f3e2d1c0b9a",
"refNo": "AUX-20261008-9f3a1c2e",
"iframeUrl": "https://uat.auxcore.net/iframe?cs=cs_4f1d0c6b2a9e8d7c6b5a4f3e2d1c0b9a",
"redirectUrl": "https://uat.auxcore.net/vt?cs=cs_4f1d0c6b2a9e8d7c6b5a4f3e2d1c0b9a",
"expiresAt": "2026-10-08T09:24:00.000Z",
"metadata": null,
"merchantLogo": null,
"merchantName": "Acme Coffee",
"redirectUrls": {
"success": "https://shop.example.com/orders/1042/thanks",
"decline": "https://shop.example.com/orders/1042/payment-failed",
"cancel": "https://shop.example.com/cart"
}
}
}- Use
redirectUrlfor a full-page checkout andiframeUrlto embed it. Use the URLs exactly as returned; their host depends on the environment. redirectUrlsshows which of your redirect URLs will actually be used.nullmeans that URL was dropped — see Redirects and embedding.
Errors#
| Status | error.code |
Cause |
|---|---|---|
400 |
VALIDATION_ERROR |
amount missing or not positive, or paymentPurpose malformed |
400 |
UNSUPPORTED_FIELD |
webhookUrl or webhookSecret sent |
403 |
FORBIDDEN |
A merchantId (body, X-Merchant-ID or metadata) that the key does not belong to |
422 |
PAYMENT_PURPOSE_NOT_CONFIGURED |
No active card gateway serves that paymentPurpose |
429 |
— | Rate limit: session creation and the shopper-side session calls share 30 requests per 15 minutes per IP (Rate Limits) |
Redirects and embedding#
Both depend on the merchant's registered store URL — the store origin saved with the merchant's WooCommerce settings in the dashboard (Merchant setup).
- Redirects:
returnUrl,declineUrlandcancelUrlare honoured only on that origin. Any other URL is dropped (it shows asnullinredirectUrls) and the shopper lands on AuxCORE's outcome page instead. - Embedding: the page may be framed by that origin and by the Allowed origins of the API key that created the session. Anywhere else the browser refuses the iframe — use
redirectUrlinstead.
Without a registered store URL, sessions still work as full-page checkouts; only merchant redirects and iframe embedding are unavailable.
Confirm the payment#
Never treat the return redirect as proof of payment — a shopper can open a return URL directly. Confirm on your server:
- Webhooks (recommended). Subscribe to the default events with
POST /register-webhook. Matchdata.orderIdontransaction.approved,transaction.declinedandtransaction.in_review(hold the order until it is approved).session.cancelledandsession.expiredcarry thesessionIdandorderIdof a session that was not paid. - Lookup (fallback). If no webhook arrives within a few seconds, look the payment up with
GET /api/v1/public/transaction-list?orderId=…(Transactions).