Saltar al contenido principal

Order Cart Validation

Overview

Order Cart Validation (OCV) lets DoorDash validate a customer's cart against your system in real time, during checkout, before the order is submitted. It gives your system a chance to confirm the merchant can fulfill the order — and to tell the customer what to fix if the merchant cannot — while they are still in the cart and able to act.

OCV can catch problems that would otherwise become a cancellation after the order is placed, including:

  • Out-of-stock or unavailable (86'd) items
  • Price or subtotal discrepancies between DoorDash and your system
  • Invalid modifiers or incomplete required selections
  • Store closed, offline, or at capacity

If validation succeeds, the customer can place the order and DoorDash will transmit it to your system.

If validation fails, DoorDash blocks submission and displays a message on the checkout screen based on the validation failure reason you return.

The Problem OCV Solves

Today, a customer builds a cart, reaches checkout, places the order — and then the order is rejected at POS injection. Often that cancellation is preventable: an out-of-stock item, a missing required modifier, a store that just went offline. The result is an order cancellation, lost sales, and a poor experience for both the customer and the merchant.

OCV prevents these avoidable cancellations by validating the cart before submission. Why this matters:

  • Fewer cancellations. Invalid orders are caught before they are placed, reducing POS-driven cancellations.
  • Improved checkout experience. Customers receive real-time feedback on problematic carts and can resolve issues before placing the order, improving order conversion.

Real-world example

A case study conducted with a top DoorDash integration partner who implemented Order Cart Validation resulted in:

  • 62.9% relative reduction in POS-driven cancellations.
  • 11.5% relative reduction in orders with defects (orders that had a customer-visible issue like a cancellation, missing or incorrect items, lateness, or a customer complaint).
  • 47% of carts that failed validation were eventually converted due to customer corrections.

How It Works

OCV is triggered when a customer proceeds from cart to checkout. The high-level flow:

  1. The customer builds a cart on the store page and taps Continue to move toward checkout.
  2. DoorDash invokes OCV by calling the validation endpoint with the full cart payload.
  3. The customer proceeds to the checkout page while validation processes in the background.
  4. When the customer taps Place Order:
    1. If validation succeeds, the order is submitted.
    2. If validation fails, the error is surfaced on the checkout page and submission is blocked.
  5. Depending on how actionable the error is, the customer either fixes the cart (and is re-validated) or is unable to proceed.

The difference is clearest side by side — the same checkout flow without OCV (the order is only rejected after the customer places it) and with OCV (the problem is caught in the cart, so the customer can fix it and still check out):

Without OCV

Without OCV: the customer completes checkout and the order is cancelled after submission

With OCV

With OCV: the cart is validated at checkout, so the customer can resolve the issue before placing the order

What to Know

  • The full cart is sent. Each validation request contains the complete cart (see the request payload below). cart_id is the session identifier for the validation.
  • Editing the cart triggers re-validation. If the customer changes the cart contents, OCV runs again when they next attempt checkout.
  • Order submission is unchanged. OCV is a separate pre-check; the existing order submission payload and flow are not modified.

Technical Requirements

How you implement OCV depends on where your integration sits relative to the merchant's point of sale (POS).

Direct POS integrations

If you are the POS (or integrate directly with it), you validate the cart against the POS itself — the source of truth for item availability, pricing, store hours, and capacity — and return the result.

Middleware / aggregator (MWP) integrations

If you are a middleware platform (MWP) sitting between DoorDash and one or more downstream POS systems, validation can happen at two layers:

  • Middleware layer (Required) — your own view of menu pricing, item availability, capacity throttling, and store status.
  • Downstream POS layer (Recommended) — validate against the downstream POS, the true source of truth.

Why downstream validation matters: the middleware's state is only as fresh as its last sync with the POS. In our analysis of item-availability cancellations, the large majority occurred at stores where the middleware layer had no recent availability update from the POS before the order — meaning a middleware-only check would have validated against stale data and let the order through. Validating at the POS layer closes this gap and materially reduces post-checkout cancellations.

Validation Scope

Once OCV is implemented, 100% of integrated orders must be validated through OCV. The specific validation checks vary by integration type, but the requirement to validate every order does not. Complete the applicable requirements below during cart validation.

For Direct POS integrations

Validation / behaviorCertification requirementWhen to implement
Item availability validationRequiredAlways
Store availability validationRequiredAlways
Include the affected item ID in merchant_supplied_id or item nameRequiredFor item-related failures, such as out-of-stock items or invalid modifiers
Price discrepancy validation and modifier gap validationRecommendedWhen order submission would reject the order for those reasons

For Middleware / aggregator integrations

Validation / behaviorCertification requirementWhen to implement
Item availability validation against the middleware menuRequiredAlways
Include the affected item ID in merchant_supplied_id or item nameRequiredFor item-related failures, such as out-of-stock items or invalid modifiers
Item availability validation against the downstream POSRecommendedWhen the downstream POS menu is the source of truth
Store availability validation against the downstream POSRecommendedWhen the downstream POS would reject orders due to store-availability gaps
Price discrepancy validation and modifier gap validationRecommendedWhen the downstream POS would reject the order for those reasons

Endpoint Requirements

Partners must expose the following endpoint:

POST /orderCartValidation

Request Schema

Trigger: Fired automatically by DoorDash when the customer moves to the checkout page.

Headers: Standard signed headers as configured in your developer webhook subscription.

URL Parameters: None (cart_id and all cart data are passed in the request body payload).

Example Request

POST /orderCartValidation

{
"cart_id": "string", // Unique ID for this cart-validation session
"store": {
"merchant_supplied_id": "string", // Location ID
"provider_type": "string"
},
"fulfillment": {
"type": "dx_delivery", // dx_delivery | pickup | mx_fleet_delivery
"asap": true, // true = ASAP, false = scheduled
"requested_time": "2025-12-05T18:30:00Z"
},
"subtotal": 0.00, // Pre-tax cart subtotal
"tax": 0.00, // Tax applied to the cart
"categories": [
{
"name": "string",
"merchant_supplied_id": "string",
"items": [
{
"name": "string",
"merchant_supplied_id": "string",
"price": 0.00,
"quantity": 0,
"extras": [ /* modifier groups -> options, supports nesting */ ],
"special_instructions": "string",
"line_item_id": "string" // Correlates this line to validation errors
}
]
}
],
"experience": "DOORDASH" // Ordering channel
}

Response Schema

You must return one of the following:

Success Response

{
"valid": true, // Cart validation successful
"cart_id": "string", // Returned ID matching the request
"expires_at": "2025-11-05T16:00:00Z", // Time until validation expires
"earliest_pickup_time": "2025-11-05T16:15:00Z" // Earliest available pickup time slot
}

Failure Response

{
"valid": false, // Cart validation failed
"cart_id": "string",
"expires_at": "2025-11-05T16:00:00Z",
"errors": [ // List of issue(s) found during validation
{
"code": "ITEM_OUT_OF_STOCK", // Error from list of standardized error codes
"merchant_supplied_id": "line_01", // Item ID
"message": "Cheeseburger is out of special item hours" // Message for further internal detail
}
]
}

Response Rules

  • The cart_id must match the request.
  • Use structured error codes (see below).
  • Errors must be item-level when applicable.
  • Do not return generic errors when a specific error applies.
  • Only populate errors when valid is false. Do not send errors alongside valid: true — downstream logic can key off error presence and treat the order as failed even though it was marked valid. Use valid: true with an empty errors array for non-blocking conditions.

Error Codes

Partners must return one of the following standardized error codes. DoorDash maps each code to the customer-facing string shown at checkout.

Error CodeDescriptionCustomer-facing string
INVALID_ORDERCart structure is invalid or incomplete.There's an issue with your {item}. Please update or remove it and try again.
ITEM_OUT_OF_STOCKItem is unavailable (86'd) at the restaurant.This {item} is currently unavailable. Please remove or update this item and try again.
STORE_HOURS_ISSUEOrder placed outside of configured POS store hours.We're having issues accepting orders at this time. Please try again later.
INTERNAL_ERRORUnexpected system failure.We ran into an unexpected issue. You can try again.
OTHERUnclassified error.We're having issues accepting orders at this time. Please try again later.
CONNECTIVITY_ISSUENetwork/POS transmission issue.We were unable to reach the store. Please try again.
TIME_OUTValidation timed out.We were unable to reach the store. Please try again.
STORE_CLOSEDThe store is closed or not accepting orders.This store is currently closed. You can try again later or select a different store.
STORE_CLOSED_EARLYRestaurant closed or not accepting orders.This store is currently closed. You can try again later or select a different store.
POS_OFFLINEThe restaurant cannot be reached due to the POS being offline or otherwise unavailable.This store is currently unavailable. You can try again later or select a different store.
CAPACITY_THROTTLINGKitchen capacity limit reached.The store is busier than usual and is unable to take orders at this time. You can try again in a few minutes.
STALE_PICKUP_TIMEThe selected time is no longer valid.Your selected pickup/delivery time is no longer available. You can choose a new time and try again.
ORDER_ONLINE_DISABLEDThe store has online ordering disabled.This restaurant is not accepting online orders at this time.
INVALID_ADDRESSAddress is invalid.This address is invalid. Please update your delivery address.
STORE_RENOVATIONThe store is unavailable due to renovation.This restaurant temporarily paused online orders. You can try again later or select a different store.
STORE_TEMP_CLOSEDThe store is temporarily closed.This restaurant temporarily paused online orders. You can try again later or select a different store.
WEATHER_ISSUESOrders paused due to external conditions.Orders are currently paused due to local conditions. You can try again later or select a different store.
NO_SLOTS_AVAILABLEThere are no open fulfillment time slots at this location.Your order cannot be completed today. Please schedule your order for a future date to proceed.
REQUESTED_SLOT_UNAVAILABLEThe wanted fulfillment time is unavailable at this location.The store is busy and your order will arrive later than originally estimated.
PROMO_CONFIG_ISSUEThe POS rejected the promotion ID on the order payload.The promotion on this order is not valid at this time. Please try again without or with a different promotion.

Field details

Top-Level Fields

FieldDescription
cart_id (Required)Unique identifier for tracking this cart validation session.
store.merchant_supplied_id (Required)Your internal store/location identifier.
store.provider_typePOS integration type being used.
fulfillment (Required)Fulfillment method. Enum: dx_delivery, pickup, mx_fleet_delivery.
asap (Required)Boolean. true for ASAP orders; false for scheduled orders.
requested_timeTimestamp of requested fulfillment time.
subtotalPre-tax cart subtotal (decimal).
taxTax amount applied to the cart (decimal).
categories (Required)Structured array of menu categories containing ordered items.
experienceOrdering channel. Value: DOORDASH.

categories[] — Category Object

FieldDescription
nameCategory display name (e.g., "Burgers", "Sides").
merchant_supplied_idYour internal identifier for this menu category.
items (Required)Array of item objects ordered within this category.

categories[].items[] — Item Object

FieldDescription
nameDisplay name of the menu item.
merchant_supplied_id (Required)Your internal POS identifier for this item.
priceUnit price of the item (decimal).
quantity (Required)Quantity of this item requested by the customer.
extrasArray of modifier/add-on group objects.
special_instructionsOptional free-text notes from the customer for this item.
line_item_id (Required)Unique identifier for this line item, used to correlate validation errors back to the item.

items[].extras[] — Modifier Group Object

FieldDescription
nameDisplay name of the modifier group.
merchant_supplied_idYour internal identifier for this modifier group.
optionsArray of the modifier options selected by the customer.

extras[].options[] — Modifier Option Object

FieldDescription
nameDisplay name of the modifier option.
merchant_supplied_idYour internal identifier for this modifier option.
pricePrice adjustment for this modifier option (decimal).
quantityQuantity of this modifier option selected.
extrasSupports further nesting for complex modifiers.
line_option_idUnique identifier for this specific modifier option selection.

Field Summary — Response

Your endpoint must return one of the following response structures. All responses must include cart_id matching the request.

Success Response Fields

FieldDescription
valid (Required)Boolean. Must be true to indicate the cart passed validation.
cart_id (Required)Must match the cart_id from the request exactly.
expires_at (Required)Timestamp indicating when this validation result expires.
earliest_pickup_timeEarliest available pickup time slot.

Failure Response Fields

FieldDescription
valid (Required)Boolean. Must be false to indicate validation failed.
cart_id (Required)Must match the cart_id from the request exactly.
expires_at (Required)Timestamp indicating when this validation result expires.
errors (Required)Array of error objects detailing all issues found. See error object fields below.

errors[] — Error Object Fields

FieldDescription
code (Required)Standardized error code string. Must be one of the defined error codes (see Error Codes section). This is used to determine the customer-facing error message.
merchant_supplied_id (Required)The ID of the specific item or entity associated with this error. This is used to map the problematic item in the customer-facing error response.
message (Optional)An optional message for further internal detail on the error.

Latency & Timeout Behavior

  • If the partner does not return an OCV response by the time the customer attempts to place an order, validation will be bypassed and the order will be submitted. This is considered an OCV timeout.
  • Excessive OCV timeouts may result in OCV being disabled for affected stores.

Stale Cart Revalidation

DoorDash will automatically re-run OCV for a cart that sits idle on checkout for an extended period, in order to catch store/menu data drift before the order is submitted.

  • Behavior: if a cart remains idle for more than 5 minutes, DoorDash re-validates using the same cart_id, up to a maximum of 3 re-validation attempts per cart session.
  • As such, ensure that rate limits for the OCV endpoint can support multiple API calls for the same cart.

Testing & Certification

Before production launch:

  1. Implement the required cart-validation capabilities outlined in the Technical Requirements section.
  2. Configure and test your integration in the sandbox environment.
  3. Validate required scenarios and confirm that your integration returns the appropriate responses.
  4. Share test results with your DoorDash Technical Account Manager.
  5. Once all requirements are met, coordinate with your Technical Account Manager to complete certification and plan launch.

Contact your DoorDash Technical Account Manager to begin certification.

FAQ

Q: What happens if my endpoint doesn't respond in time?

A: If no response is received before the customer places the order, validation is bypassed and the order is submitted as-is. Repeated timeouts may result in OCV being disabled for the affected stores.

Q: Do I need to return every applicable error, or just one?

A: Return all applicable errors as a list. Don't return a generic error when a specific one applies, and errors should be item-level whenever possible.

Q: How do I begin certification?

A: Contact your Technical Account Manager to begin the certification process.

Q: If a cart is valid but I want to flag a non-blocking issue (e.g., a tax mismatch), should I still populate errors?

A: No, only populate errors when valid is false. Sending errors alongside valid: true is risky: DoorDash's downstream logic can key off error presence and treat the order as failed even though it was marked valid. Use valid: true with an empty errors array for non-blocking conditions.

Q: Can the same cart_id be validated multiple times (e.g., customer edits cart)?

A: If the customer edits the contents of the cart, that will not change the cart_id (unless they remove all items and start again, or create a cart for another store). So yes, the same cart_id can be sent in multiple validations. DoorDash's subsequent OCV call would reference the same cart_id and would reflect the entire updated cart.