Xatern OneAPI v1

Orders

An order has two tracks. status is its progress. payment_status is its money.

The order object

Money is a number. Times are ISO 8601 in UTC. balance is total minus paid. Staff names, internal notes and file paths are never shown.

JSON
{
  "number": "NT-482913",
  "status": "awaiting_payment",
  "payment_status": "unpaid",
  "payment_method": "bank",
  "placed_at": "2026-11-02T08:15:00Z",
  "updated_at": "2026-11-02T08:15:00Z",
  "currency": "PHP",
  "total": 1020,
  "due_today": 1020,
  "paid": 0,
  "balance": 1020,
  "freight": 120,
  "sale_saving": 0,
  "promo_code": null,
  "promo_saving": 0,
  "contact": { "name": "Maria Santos", "phone": "+639171234567", "email": "maria@example.test", "social": null },
  "delivery": { "method": "jnt", "region": "NCR", "city": "Quezon City", "street": "12 Sample St", "landmark": "Blue gate", "courier": null, "tracking_number": null },
  "lines": [
    { "product_id": "SKU-ROSE-50", "name": "Rose Mist 50 ml", "qty": 2, "unit_price": 450, "line_total": 900, "preorder": false }
  ],
  "payments": []
}
FieldMeaning
numberThe order number, for example NT-482913. Show it to the shopper.
statusProgress. See the list below.
payment_statusMoney. See the list below.
payment_methodOne of the shop payment method keys, for example bank.
total, due_today, paid, balanceAmounts. A layaway or pre-order can have due_today lower than total.
freight, sale_saving, promo_code, promo_savingDelivery fee and savings.
contactname, phone, email, social.
deliverymethod (pickup or a courier), address parts, courier and tracking_number once shipped.
linesproduct_id, name, qty, unit_price, line_total, preorder.
paymentsEach payment: kind, method, amount, reference, status, reason, created_at.

Statuses

statusMeaning
awaiting_paymentPlaced. Waiting for the shopper to pay.
proof_receivedA payment screenshot is waiting for the shop to check.
confirmedAccepted. Cash orders start here.
downpayment_confirmedA pre-order downpayment was confirmed. Waiting for stock.
balance_dueStock arrived. The shopper pays the rest.
preparingThe shop is packing the order.
ready_for_pickupReady for the shopper to collect.
shippedWith the courier. delivery.courier and delivery.tracking_number are set.
completedDone.
cancelledCancelled. Stock is put back.

Payment statuses

payment_statusMeaning
unpaidNo money yet.
checkingA screenshot is being checked.
part_paidSome money in, a balance is left.
paidPaid in full.
refund_dueA cancelled order held money. A refund is owed.
refundedThe refund was recorded.

Ignore any value you do not know. More can be added later.

Cash orders (cash on delivery, cash at the shop) arrive as confirmed with payment_status unpaid. Do not ask the shopper for a screenshot. Tell them they pay on delivery or at pickup.

Place an order

  1. Read the catalog with GET /catalog. Price the order from it.
  2. Send the order with POST /orders. Save the number and token from the reply.
  3. Upload a proof if the payment method is a transfer.
  4. Show the order to the shopper with GET /orders/{number}?token=.

Your site prices the order. Xatern One refuses one that does not add up.

FieldWhat to send
idempotency_keyA UUID you make once per checkout. Sending it again returns the first order.
payment_methodOne of the shop payment method keys.
contact{name, phone, email, social}. Phone can be local (09171234567) or international (+639171234567). Email and social may be null.
delivery{method, region, city, street, landmark}. For pickup, {"method":"pickup"} is enough.
lines1 to 100 lines of {product_id, name, qty, unit_price, line_total, preorder}. line_total is unit_price times qty. Each line must be a visible size at the current price.
total, due_today, balanceNumbers with at most 2 decimals. balance is total minus due_today.
freight, promo_code, promo_saving, sale_savingOptional. total is the sum of line_total, minus promo_saving, plus freight.
JavaScript
const res = await fetch("https://api.xatern.com/v1/orders", {
  method: "POST",
  headers: {
    Authorization: "Bearer xpk_live_YOUR_PUBLISHABLE_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify(order)
});
const data = await res.json();
if (!data.ok) throw new Error(data.error);
const { number, token } = data.order;

The request body can be up to 64 KB. Send it as JSON with Content-Type: application/json.

Upload a payment proof

For a transfer such as GCash or a bank transfer, the shopper sends a screenshot. Send it as multipart form data to POST /orders/{number}/payment-proof with token, reference and file. The file is a JPG, PNG, WebP or HEIC image up to 8 MB. Shrinking it to about 200 KB first makes uploads faster.

JavaScript
const form = new FormData();
form.append("token", token);
form.append("reference", "GC123456789");
form.append("file", fileInput.files[0]);
const res = await fetch("https://api.xatern.com/v1/orders/" + number + "/payment-proof", {
  method: "POST",
  headers: { Authorization: "Bearer xpk_live_YOUR_PUBLISHABLE_KEY" },
  body: form
});
const data = await res.json();
if (!data.ok) throw new Error(data.error);

The order moves to proof_received and waits for the shop. Only one payment is checked at a time. If the shop says the payment did not match, the shopper can send a new screenshot the same way.

Xatern One API v1. Example data on these pages is made up.