Draft order with custom line items (overridden originalUnitPrice) — how to deduct inventory on payment?

Hi all,

We’re building a B2B/wholesale flow that creates Shopify draft orders via the GraphQL Admin API (draftOrderCreate, version 2025-07).

The constraint: the wholesale customer should see only their final wholesale price on the draft order’s invoice — no retail price crossed out, no “discount −$X” line.

What we ended up doing (the only approach we found): every line item is a custom line — no variantId, just title + originalUnitPrice + customAttributes carrying the variant link:

mutation OrderProcessingDraftOrderCreate($input: DraftOrderInput!) {
  draftOrderCreate(input: $input) {
    draftOrder { id invoiceUrl }
    userErrors { field message }
  }
}
{
  "input": {
    "lineItems": [
      {
        "title": "Wholesale Product · Black / Large",
        "quantity": 2,
        "originalUnitPrice": "20.00",
        "taxable": true,
        "requiresShipping": true,
        "sku": "SKU123",
        "customAttributes": [
          { "key": "_variant_id",  "value": "12345" },
          { "key": "_variant_gid", "value": "gid://shopify/ProductVariant/12345" },
          { "key": "_product_gid", "value": "gid://shopify/Product/678" },
          { "key": "_sku",         "value": "SKU123" }
        ]
      }
    ],
    "acceptAutomaticDiscounts": false,
    "purchasingEntity": { "customerId": "gid://shopify/Customer/9999" }
  }
}

This works perfectly for the invoice UX — the customer sees Wholesale Product · Black / Large — $20 × 2 = $40, full stop. No retail price comparison.

The problem: when the customer pays the invoice URL and the draft order converts to a real order, inventory is not deducted. The variant’s available count stays the same. We understand why — the line has no variantId, so Shopify has nothing to debit. reserveInventoryUntil also doesn’t apply for the same reason (no inventory binding).

What we’ve tried / ruled out:

  • Switching to variant-backed line items + appliedDiscount — works for inventory, but renders a “−$X” discount line on the invoice, which leaks the retail price to wholesale customers. We don’t want that.
  • appliedDiscount.description: "Wholesale price" — softens the language, but the original price + discount split still shows.
  • Cart Transform — can split/merge/update existing lines but can’t add new ones, so doesn’t help here.
  • Searching the schema for an originalUnitPriceOverride-style field on variant-backed lines — couldn’t find one in 2025-07.

Specific questions:

  1. Is there any current Admin API mechanism that lets us provide a variantId AND a custom originalUnitPrice on the same draft-order line, so Shopify keeps the inventory binding? (i.e., variant-backed line, but with the price overridden — like a “negotiated price” without rendering the discount line.)
  2. If not, is the recommended pattern to subscribe to ORDERS_CREATE (or ORDERS_PAID), read a custom attribute back to the variant, and call inventoryAdjustQuantities to manually debit stock? Are there any pitfalls with this approach (e.g., race conditions with overselling, multi-location handling, refund/cancel restock parity)?
  3. Is anyone aware of a planned API change that would allow per-line price override on variant-backed draft order lines without surfacing a discount line on the invoice? Is this on the roadmap?
  4. For shops with tracked: true inventory items, what’s the right name/reason combo on inventoryAdjustQuantities for “this is a sale debit, not an admin correction” — i.e., the same semantics Shopify itself uses internally when an order pays? We’ve been considering name: "available", reason: "correction" but worried that pollutes inventory history.

Happy to share more of our setup if it helps.

Thanks!

Hey @Shrutika_Lokhande! You’re right that fully custom draft order lines are not tied to a variant, so Shopify does not have variant inventory to debit. For this use case on 2025-07, you should be able to keep the variant binding and override the draft order line price with the priceOverride field on DraftOrderLineItemInput.

Use variantId, quantity, and priceOverride together. That avoids modeling the item as a custom line with originalUnitPrice or exposing the price change as a line discount with appliedDiscount.

mutation draftOrderCreate($input: DraftOrderInput!) {
  draftOrderCreate(input: $input) {
    draftOrder {
      id
      invoiceUrl
    }
    userErrors {
      field
      message
    }
  }
}

{
  "input": {
    "acceptAutomaticDiscounts": false,
    "lineItems": [
      {
        "variantId": "gid://shopify/ProductVariant/12345",
        "quantity": 2,
        "priceOverride": {
          "amount": "20.00",
          "currencyCode": "USD"
        }
      }
    ],
    "purchasingEntity": {
      "customerId": "gid://shopify/Customer/9999"
    }
  }
}

priceOverride is a MoneyInput and should be set in presentment currency. The docs note that originalUnitPriceWithCurrency is for custom line items and is ignored when variantId is provided, and originalUnitPrice is deprecated.

One caveat is bundles. Price overrides cannot be applied to bundle components, and Shopify removes the override if the line becomes part of a bundle.

I would avoid the ORDERS_CREATE or ORDERS_PAID plus inventoryAdjustQuantities workaround unless you intentionally keep fully custom lines. That path means your app owns location selection, idempotency, oversell handling, and refund or cancellation restock parity. Keeping the line variant-backed with priceOverride is the cleaner route.

@Donal-Shopify This falls apart if the Draft order is sold in Shopify POS though, the priceOverride is not respected and reverts back to catalog pricing. (priceOverride removed from POS).

Is this behavior you know of or can comment on? Major issue I’m hitting right now as Admin and Draft Orders respect price overrides and line item locking, but it’s all out the Window when selling at POS.

Seems a over complicated cart transform function may be one way around with by checking custom line item attributes but that would be insecure and we are not on Shopify plus.

Hi @Wesley_Darnell, I took a look into this for you internally - priceOverride on a draft order and “price override” in POS are two different mechanisms that happen to share a name.

The priceOverride field on DraftOrderLineItemInput is a replacement unit price, used in place of the variant’s catalog price in the draft order. It works when the draft order is completed through the Admin or sent as an invoice. POS can load draft orders onto the cart, but the documentation doesn’t say whether priceOverride is preserved when that happens.

POS handles price changes through the custom discount mechanism. Staff can apply a custom line-item discount and use the “Price after discount” field to set the final price. The regular retail value still displays under it. You can reach the same amount this way, and because the line stays variant-bound, inventory still debits. The trade-off is the presentation you were trying to avoid. It shows as a discount rather than as the clean wholesale price, and there’s no supported way to get a clean unit price at POS at this time. I’ve logged this as feedback for the team to consider.

On Cart Transform, you’re right that this isn’t an option on your plan. Line update operations are limited to development stores and Shopify Plus.

Which POS flow are you using, and when you say “priceOverride removed from POS,” do you mean the draft order field not carrying over, or POS’s own staff price override being unavailable?

@Donal-Shopify Thanks for taking the time to investigate, very appreciated.
In 2023 it appears a previously existing “Price Override” feature of the POS software was removed.
I was not around for this time, but I assume this matched the draft order price override and it’s behavior. Maybe it didn’t, if so disregard on the “Removed” comment.
[Image and community posts at the end of my post]

The behavior I’m trying to describe may simply be a bug, if the draft order price is already supposed to be respected.

This feature (Price Override) works PERFECT in Shopify Admin on existing draft orders where you can set the ‘priceOverride’ (By API or in UI) which seems to trigger the UI of “product price locked”.
Issue is in POS when you load a draft order to the cart, it shows the true draft order Price Override price for a split second then resets to the main product price.
We just wish behavior from Admin to POS was uniform and don’t understand why the two systems would ever behave differently or not respect such attributes like Price Override that are completely valid in Shopify Admin draft orders.

I am more so speaking to the draft order attributes/pricing/price override not carrying over to the POS cart line items essentially (or at least sticking, as it kind of appears correctly priced but then resets to catalog).
As that would satisfy our use case where we do have the draft order made and exactly as intended in Shopify Admin–just needing to sell it as is on POS.
Though frankly a POS staff price override being unavailable is certainly another issue that does affect us. Lots of community posts regarding the lack of staff override available.

We are really working against the POS as only being able to discount a product in POS does not satisfy situations like “Service” products where they are sometimes priced higher than the base product. We are hacking around this currently by duplicating products as custom line items in our draft orders just so POS functions as expected keeping the expected price – but this wasn’t/isn’t needed in Shopify Admin, only the POS. We hope to revert to keeping the true product items in the cart if this “bug” (as il call it) is fixed.

I’d be happy even if there was a POS setting to never reset a draft order price to current catalog if locked/price overridden, or if the default behavior was this as then it would match Shopify Admin.