Skip to content

Orders

View as Markdown

Your users place orders in Beauty Router’s interface, or on your own New order page through the API. One checkout creates one order for each brand or distributor in the cart.

After an order is created, Beauty Router charges the card at once. If the charge succeeds, the order is placed, and the brand or distributor starts preparing it. If it fails, the order is payment_failed. Beauty Router then tracks the delivery.

A prequalified company’s order is pending_verification, with no charge. When verification passes, the charge runs, and the order becomes placed or payment_failed.

You learn about orders in two ways:

  • In the page. The library calls onOrderCreated with the orders from the checkout. See Embedded marketplace. POST /v1/orders/batch returns the orders it created.
  • On your server. Beauty Router sends an order.created webhook for each new order, and order.updated when the status, tracking, delivery address, or other order details change. See Webhooks.

To show orders in your salon app without building a screen, use the embedded interface: showOrders(element) shows all the company’s orders, showOrder(element, orderId) shows one order, and showOrderTracking(element, orderId) shows its tracking page.

GET /v1/orders returns the orders of the logged-in user’s company, newest first, with paging. Each item has the same fields as one order.

Terminal window
curl "https://api.beautyrouter.com/v1/orders?limit=100" \
-H "Authorization: Bearer $USER_TOKEN"

The list includes drafts. status is an optional filter that returns only the orders with that status, such as status=draft.

GET /v1/orders/{orderId} returns one order, which can be a draft. The order must belong to the company of the logged-in user. Otherwise the request fails with not_found.

Terminal window
curl https://api.beautyrouter.com/v1/orders/order-8Jd3kFs6Gh \
-H "Authorization: Bearer $USER_TOKEN"
{
"id": "order-8Jd3kFs6Gh",
"number": "4821-7730",
"companyId": "loc-7Hk2pQx9Lm",
"userId": "user-3Vb8nWq1Rt",
"status": "in_transit",
"supplier": {
"id": "sup-1Ry6tUi3Op",
"name": "Amberlin"
},
"lines": [
{
"productId": "prod-4Fz9QbX2kL",
"name": "Amberlin Bond Repair Shampoo 33.8 fl oz",
"quantity": 6,
"unitPrice": 24.50,
"discount": 0.00,
"total": 147.00
},
{
"productId": "prod-6Gh2jKl8Zx",
"name": "Amberlin Bond Repair Conditioner 33.8 fl oz",
"quantity": 4,
"unitPrice": 26.50,
"discount": 0.00,
"total": 106.00
}
],
"productsTotal": 253.00,
"discount": 0.00,
"shipping": 0.00,
"salesTax": 22.01,
"total": 275.01,
"currency": "usd",
"deliveryAddress": {
"line1": "1450 Larimer St",
"line2": "Suite 200",
"city": "Denver",
"state": "CO",
"postalCode": "80202",
"country": "US",
"phone": "+13035550142"
},
"trackingNumbers": [
{
"number": "1Z999AA10123456784",
"url": "https://www.ups.com/track?tracknum=1Z999AA10123456784",
"carrier": "UPS"
}
],
"createdAt": "2026-10-26T15:42:10Z",
"updatedAt": "2026-10-28T19:03:55Z",
"deliveredAt": null
}

Amounts are decimal numbers in dollars. See Money.

Field Description
id The order ID, such as order-8Jd3kFs6Gh.
number The order number people see, such as 4821-7730.
companyId The company the order belongs to, such as loc-7Hk2pQx9Lm.
userId The user who placed the order, such as user-3Vb8nWq1Rt.
status The order status. See Statuses.
cancelReason Why the order was canceled. Only on canceled orders.
supplier The brand or distributor that fulfills the order: id and name.
lines The products in the order. See the line fields below.
productsTotal The total of the lines.
discount The discount on the order.
shipping The shipping charge, or null on a draft with no address.
salesTax The sales tax, or null on a draft with no address.
total The amount the salon pays, or null on a draft with no address.
currency Always "usd".
deliveryAddress Where the order is delivered, in the same format as the company’s delivery address. null on a draft with no address.
trackingNumbers The shipments of the order: number, url, and carrier.
createdAt When the order was placed.
updatedAt When the order last changed.
deliveredAt When the order was delivered, or null.
Line field Description
productId The Beauty Router product ID.
name The product name.
quantity How many units the salon ordered.
unitPrice The wholesale price of one unit, before the discount.
discount The discount on the whole line.
total The line total.

A salon can pay a shipping charge: a flat amount or a carrier quote, free above the supplier’s threshold. Shipping is locked when the order is created. Until the order is placed, other amounts can still change, so keep the order up to date from order.updated.

Status Meaning
draft The order is saved for later. It holds no stock, and the supplier does not see it. See Drafts.
pending_verification The company is prequalified, and the order waits until its verification ends. There is no charge yet.
payment_failed The card charge failed, or a payment is waiting for 3-D Secure. Beauty Router tries once more after 24 hours when the failure can be retried. If that fails too, or the failure cannot be retried, it cancels the order at 24 hours.
placed The card was charged, and the brand or distributor starts preparing the order right after.
ready_to_ship The order is ready to ship.
in_transit The order shipped. trackingNumbers has the shipments.
delivered The order was delivered.
delivery_failed The delivery failed.
canceled The order was canceled. cancelReason says why.

Only a placed order takes stock from the supplier. A draft, a pending_verification order, and a payment_failed order hold none, so stock can run out before they are placed.

Reason Meaning
salon The salon canceled the order.
supplier The brand or distributor canceled the order.
payment The card charge failed, or the payment was disputed or refunded.
verification The company did not pass verification.

You can change an order through the API, or let the salon do it in showOrder(element, orderId).

Action Endpoint Order statuses
Cancel the order POST /v1/orders/{orderId}/cancel pending_verification, placed, payment_failed
Change the delivery address PUT /v1/orders/{orderId}/delivery-address draft, pending_verification
Delete a draft DELETE /v1/orders/{orderId} draft

An order with another status fails with order_action_not_allowed. A user logged in with canOrder: false gets user_cannot_order. Each call returns the order, and your server also receives an order.updated webhook. A draft sends no webhook. Deleting a draft returns 204 with no body.

These have no API, so use showOrder:

  • Choose another payment card: draft, pending_verification, and payment_failed.
  • Pay again: payment_failed, when a retry is allowed.
Terminal window
curl -X POST https://api.beautyrouter.com/v1/orders/order-8Jd3kFs6Gh/cancel \
-H "Authorization: Bearer $USER_TOKEN"

The order gets the status canceled with the cancelReason salon. The rest depends on the status:

Status What happens
pending_verification The order closes. There is no charge to refund, and no brand or distributor is involved.
placed Beauty Router refunds the full amount, and tells the brand or distributor.
payment_failed There is no charge to refund.

The brand may have started shipping a placed order. When its system refuses the cancel, the request fails with 409 supplier_refused_cancel, and the order stays placed.

Send the full address, with the same fields as the company’s delivery address. phone is optional here. Without it, the order uses the company’s phone. This changes the order only. The company’s default address stays as it is.

Terminal window
curl -X PUT https://api.beautyrouter.com/v1/orders/order-8Jd3kFs6Gh/delivery-address \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"line1": "2210 Pearl St",
"city": "Boulder",
"state": "CO",
"postalCode": "80302",
"country": "US",
"phone": "+13035550187"
}'

A placed order cannot change its address, because the brand or distributor starts preparing it right away. The request fails with order_action_not_allowed.

The address must pass these checks:

Check Otherwise
A carrier can deliver to it. validation_failed
The company has a license in that state. address_state_without_license
Every hazardous product in the order can go there. hazmat_destination
The brand or distributor ships there. ship_to_restricted

Beauty Router recalculates the sales tax, so total can change. A pending_verification order keeps its shipping. A draft’s shipping is worked out when it is placed.

Terminal window
curl -X DELETE https://api.beautyrouter.com/v1/orders/order-2Xc9vBn4Mq \
-H "Authorization: Bearer $USER_TOKEN"

The response is 204 with no body. A later request for that ID fails with not_found.

showOrderTracking(element, orderId) shows the tracking page of one order, with a tab for each package. Until the order ships, it says that tracking is not available yet.

To build your own tracking screen, use trackingNumbers on the order. Each item has the number, the url of the carrier’s tracking page, and the carrier. The url and the carrier are left out when Beauty Router does not have them.

The salon can rate an order once it is delivered. showOrderRating(element, orderId) shows the rating form, and showOrder(element, orderId) offers it too. To report a problem with a delivery_failed or canceled order, the salon uses showOrder. The Rate your order email opens your orderUrl page.

Beauty Router charges the card, so the card statement shows BEAUTYRTR, an asterisk, and a short form of your app’s name, such as BEAUTYRTR* ROSELANE. The whole line has at most 22 characters, which leaves 11 for your app’s name.

You set the short form in the salon app admin area. It has at most 11 characters, with Latin letters, digits, and spaces, and at least one letter.

When you save your app’s name and leave the short form empty, the admin area fills it in: the name’s Latin letters, digits, and spaces, cut to 11 characters. You can change it, and a later name change leaves it alone. If the name has no Latin letter, the field stays empty, and statements show BEAUTYRTR alone.

Beauty Router emails your users when an order is placed, shipped, delivered, or canceled, in your app’s name. See Emails.