The OrderMgr API provides order creation, status management, and querying. Understanding the order lifecycle is essential for checkout implementation and order processing.
Order Lifecycle
Orders progress through these statuses:
Basket → CREATED → NEW → (COMPLETED or CANCELLED or FAILED)
| Status | Description | Can Transition To |
|---|---|---|
CREATED |
Order created, not yet placed | NEW, FAILED |
NEW |
Order placed, awaiting fulfillment | OPEN, COMPLETED, CANCELLED, FAILED |
OPEN |
Order in processing | COMPLETED, CANCELLED |
COMPLETED |
Order fulfilled | - |
CANCELLED |
Order cancelled | NEW (via undoCancel) |
FAILED |
Order failed (payment, validation) | - (cannot be reopened) |
Important: Once an order reaches FAILED status, it cannot be reopened or cancelled. Use failOrder(order, true) to reopen the basket for retry instead.
Creating Orders
Standard Flow (Synchronous)
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
var Status = require('dw/system/Status');
function createOrder(basket) {
var order;
Transaction.wrap(function() {
// Create order from basket (status: CREATED)
order = OrderMgr.createOrder(basket);
});
if (!order) {
return { error: true, message: 'Order creation failed' };
}
// Authorize payment
var paymentResult = authorizePayment(order);
if (!paymentResult.success) {
Transaction.wrap(function() {
OrderMgr.failOrder(order, true); // Reopen basket
});
return { error: true, message: 'Payment failed' };
}
// Place the order (status: CREATED → NEW)
var placeResult;
Transaction.wrap(function() {
placeResult = OrderMgr.placeOrder(order);
});
if (placeResult.error) {
return { error: true, message: 'Order placement failed' };
}
// Set confirmation status
Transaction.wrap(function() {
order.setConfirmationStatus(order.CONFIRMATION_STATUS_CONFIRMED);
});
return { error: false, order: order };
}
SCAPI Flow: Create, Authorize Through Order PI, Then Place
Lead with the Shopper Orders state machine instead of manually placing from order.afterPOST:
POST /checkout/shopper-orders/v1/organizations/{orgId}/orders
-> commits order in CREATED
PATCH /checkout/shopper-orders/v1/organizations/{orgId}/orders/{orderNo}/payment-instruments/{piId}
-> invokes dw.order.payment.authorizeCreditCard or dw.order.payment.authorize
-> passes successfullyAuthorized to order.payment_instrument.afterPATCH
-> default afterPATCH places when authorized coverage reaches the order total
NEW -> success
CREATED -> not fully placed; authorize remaining PIs, fail safely, or reconcile
Return undefined from a successful custom order-PI afterPATCH implementation so the platform's
default coverage-based placement behavior runs. A non-null Status ends execution and suppresses
that implementation.
On a deterministic payment failure, use the Shopper Orders fail action with reopenBasket=true.
On an indeterminate gateway result, retain the CREATED order for reconciliation rather than
risking a duplicate authorization.
Use dw.ocapi.shop.order.afterPOST as the alternative when checkout deliberately needs a single
server-side phase that creates, authorizes, and performs the Commerce-side place-or-fail transition,
or when the processor cannot participate in order-PI authorization. That hook runs inside order
creation's transaction: do not add a nested Transaction.wrap, and understand that Status.ERROR
rolls back the Commerce order but not an external gateway side effect. See
b2c-hooks.
OrderMgr API Reference
Order Creation
| Method | Description |
|---|---|
createOrder(basket) |
Create order with auto-generated number |
createOrder(basket, orderNo) |
Create order with specific number |
createOrderNo() |
Generate next order number |
createOrderSequenceNo() |
Get next sequence number (for custom formatting) |
Order Status
| Method | Description |
|---|---|
placeOrder(order) |
Place order (CREATED → NEW) |
failOrder(order, reopenBasket) |
Fail order (set to FAILED status) |
cancelOrder(order) |
Cancel order (set to CANCELLED status) |
undoCancelOrder(order) |
Revert cancelled order to NEW |
Note: There is no undoFailOrder() method. Failed orders cannot be reopened. Use failOrder(order, true) to reopen the basket for retry.
Order Queries
| Method | Description |
|---|---|
getOrder(orderNo) |
Get order by number |
searchOrder(query, ...args) |
Search for single order |
searchOrders(query, sortString, ...args) |
Search for multiple orders |
queryOrder(query, ...args) |
Query single order |
queryOrders(query, sortString, ...args) |
Query multiple orders |
Querying Orders
Get Order by Number
var OrderMgr = require('dw/order/OrderMgr');
var order = OrderMgr.getOrder('00001234');
if (order) {
var status = order.status.value;
var total = order.totalGrossPrice;
}
Search Orders
var OrderMgr = require('dw/order/OrderMgr');
// Search by customer email
var orders = OrderMgr.searchOrders(
'customerEmail = {0} AND status != {1}',
'creationDate desc',
'customer@example.com',
dw.order.Order.ORDER_STATUS_FAILED
);
while (orders.hasNext()) {
var order = orders.next();
// Process order
}
orders.close();
Query by Date Range
var OrderMgr = require('dw/order/OrderMgr');
var Calendar = require('dw/util/Calendar');
var startDate = new Calendar();
startDate.add(Calendar.DAY_OF_YEAR, -7);
var orders = OrderMgr.searchOrders(
'creationDate >= {0} AND status = {1}',
'creationDate desc',
startDate.time,
dw.order.Order.ORDER_STATUS_NEW
);
while (orders.hasNext()) {
var order = orders.next();
// Process order
}
orders.close();
Order Status Management
Cancel Order
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
var Order = require('dw/order/Order');
function cancelOrder(orderNo) {
var order = OrderMgr.getOrder(orderNo);
if (!order) {
return { error: true, message: 'Order not found' };
}
// Can only cancel NEW or OPEN orders
if (order.status.value !== Order.ORDER_STATUS_NEW &&
order.status.value !== Order.ORDER_STATUS_OPEN) {
return { error: true, message: 'Order cannot be cancelled' };
}
Transaction.wrap(function() {
OrderMgr.cancelOrder(order);
});
return { error: false };
}
Fail Order
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
function failOrder(order, reopenBasket) {
// reopenBasket: true = customer can retry checkout
// false = basket is lost
Transaction.wrap(function() {
OrderMgr.failOrder(order, reopenBasket);
});
}
Handling Failed Orders
Failed orders cannot be reopened. Instead, use failOrder(order, true) to reopen the basket:
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
// When payment fails, fail the order and reopen basket
function handlePaymentFailure(order) {
Transaction.wrap(function() {
// reopenBasket=true allows customer to retry checkout
OrderMgr.failOrder(order, true);
});
// Basket is now available again for the customer
return { error: true, message: 'Payment failed. Please try again.' };
}
SCAPI: Fail Order and Reopen Basket
For SCAPI integrations, use the Shopper Orders fail action after a deterministic payment failure:
POST /checkout/shopper-orders/v1/organizations/{orgId}/orders/{orderNo}/actions/fail?siteId={siteId}&reopenBasket=true
Authorization: Bearer {token}
Content-Type: application/json
{
"reasonCode": "payment_auth_failure"
}
The current payment-oriented reason codes are payment_auth_failure, payment_confirm_failure, and
payment_capture_failure. The endpoint returns 409 when the order is no longer in a state that can
be failed. Confirm the current Shopper Orders schema before generating version-specific code.
Undo Cancelled Order
Cancelled orders can be reopened using undoCancelOrder():
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
var Order = require('dw/order/Order');
function reopenCancelledOrder(orderNo) {
var order = OrderMgr.getOrder(orderNo);
if (order.status.value !== Order.ORDER_STATUS_CANCELLED) {
return { error: true, message: 'Order is not cancelled' };
}
Transaction.wrap(function() {
// Revert to NEW status
OrderMgr.undoCancelOrder(order);
});
return { error: false, order: order };
}
Order Properties
| Property | Description |
|---|---|
orderNo |
Order number |
status |
Current order status |
confirmationStatus |
Confirmation status |
exportStatus |
Export status for OMS |
paymentStatus |
Payment status |
shippingStatus |
Shipping status |
customerEmail |
Customer email |
customerName |
Customer name |
totalGrossPrice |
Order total (with tax) |
totalNetPrice |
Order total (without tax) |
totalTax |
Total tax amount |
creationDate |
Order creation date |
productLineItems |
Line items in order |
shipments |
Order shipments |
paymentInstruments |
Payment instruments |
Custom Order Numbers
Use the dw.order.createOrderNo hook for custom order number generation:
// hooks.json
{
"hooks": [
{
"name": "dw.order.createOrderNo",
"script": "./hooks/orderNo.js"
}
]
}
// hooks/orderNo.js
var OrderMgr = require('dw/order/OrderMgr');
var Site = require('dw/system/Site');
exports.createOrderNo = function() {
var seqNo = OrderMgr.createOrderSequenceNo();
var prefix = Site.current.ID.toUpperCase();
var year = new Date().getFullYear();
return prefix + '-' + year + '-' + seqNo;
};
Best Practices
Do
- Wrap Script API order mutations in a transaction only when the caller does not already provide one
- Check order status before transitions
- Close order iterators when done
- Use
failOrder(order, true)to let customers retry - Implement idempotent order creation (use specific order numbers)
- Set appropriate export/confirmation status
Don't
- Place orders before successful payment authorization
- Cancel orders without refund processing
- Leave orders in CREATED status indefinitely
- Forget to handle concurrent order modifications
- Skip status validation before transitions
Error Handling
| Scenario | Solution |
|---|---|
| Basket is empty | Validate basket before createOrder() |
| Invalid basket | Check for missing shipping/billing addresses |
| Payment failed | Use failOrder(order, true) to reopen basket |
| Order number exists | Use auto-generated numbers or validate uniqueness |
| Status transition invalid | Check current status before calling status methods |
Related Skills
- b2c-hooks - Order hooks (calculate, payment, createOrderNo)