Manage the order lifecycle in B2C Commerce including order creation, status transitions, failure handling, and checkout completion. Use this skill whenever the user needs to create an order from a basket, transition order status, handle failed or cancelled orders, implement payment authorization in checkout, or understand async order processing — even if they just say "my order is stuck" or "finish the checkout flow".
Manage the order lifecycle in B2C Commerce including order creation, status transitions, failure handling, and checkout completion. Use this skill whenever the user needs to create an order from a basket, transition order status, handle failed or cancelled orders, implement payment authorization in checkout, or understand async order processing — even if they just say "my order is stuck" or "finish the checkout flow".
B2C Ordering
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)
varOrderMgr = require('dw/order/OrderMgr');
varTransaction = require('dw/system/Transaction');
varStatus = require('dw/system/Status');
functioncreateOrder(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 paymentvar 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 statusTransaction.wrap(function() {
order.setConfirmationStatus(order.CONFIRMATION_STATUS_CONFIRMED);
});
return { error: false, order: order };
}
Async Flow (SCAPI Pattern)
Critical — transaction context depends on where this code runs. The Transaction.wrap() calls below are correct when you drive placement from a controller, job step, or custom endpoint (code that runs outside a platform transaction). But the headless SCAPI Shopper Orders API creates the order in CREATED status and hands it to the dw.ocapi.shop.order.afterPOST hook, which already runs inside a platform transaction. If you call OrderMgr.placeOrder() / OrderMgr.failOrder() from afterPOST, call them directly with NO Transaction.wrap — a nested transaction rolls back your change and surfaces an opaque HTTP 400: An error occurred in ExtensionPoint dw.ocapi.shop.order.afterPOST. See the canonical afterPOST example in b2c-hooks.
For SCAPI/headless, create the order before payment authorization:
varOrderMgr = require('dw/order/OrderMgr');
varTransaction = require('dw/system/Transaction');
// Step 1: Create order (before payment)functioncreateOrderAsync(basket, orderNo) {
var order;
Transaction.wrap(function() {
// Create with specific order number (for idempotency)
order = OrderMgr.createOrder(basket, orderNo);
});
return order;
}
// Step 2: After payment success, place the orderfunctionplaceOrderAfterPayment(order) {
Transaction.wrap(function() {
OrderMgr.placeOrder(order);
order.setConfirmationStatus(order.CONFIRMATION_STATUS_CONFIRMED);
order.setExportStatus(order.EXPORT_STATUS_READY);
});
}
// Step 2 (alt): Payment failed, fail the orderfunctionfailOrderAfterPayment(order) {
Transaction.wrap(function() {
OrderMgr.failOrder(order, false); // Don't reopen basket
});
}
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
varOrderMgr = require('dw/order/OrderMgr');
var order = OrderMgr.getOrder('00001234');
if (order) {
var status = order.status.value;
var total = order.totalGrossPrice;
}
Search Orders
varOrderMgr = require('dw/order/OrderMgr');
// Search by customer emailvar 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
varOrderMgr = require('dw/order/OrderMgr');
varCalendar = require('dw/util/Calendar');
var startDate = newCalendar();
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
varOrderMgr = require('dw/order/OrderMgr');
varTransaction = require('dw/system/Transaction');
varOrder = require('dw/order/Order');
functioncancelOrder(orderNo) {
var order = OrderMgr.getOrder(orderNo);
if (!order) {
return { error: true, message: 'Order not found' };
}
// Can only cancel NEW or OPEN ordersif (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 };
}
Failed orders cannot be reopened. Instead, use failOrder(order, true) to reopen the basket:
varOrderMgr = require('dw/order/OrderMgr');
varTransaction = require('dw/system/Transaction');
// When payment fails, fail the order and reopen basketfunctionhandlePaymentFailure(order) {
Transaction.wrap(function() {
// reopenBasket=true allows customer to retry checkoutOrderMgr.failOrder(order, true);
});
// Basket is now available again for the customerreturn { error: true, message: 'Payment failed. Please try again.' };
}
SCAPI: Fail with Reopen (B2C 24.3+)
For SCAPI integrations, use the failed_with_reopen status to fail an order while reopening the basket: