BigCommerce field notes
Fix BigCommerce orders, payments, inventory, and webhooks with a script
A working library of the problems that hit real BigCommerce stores, across orders and payments, webhooks, inventory and catalog, customers, fulfillment, promotions, and reporting, and how to detect or repair each one with a small Python or Node.js script on the BigCommerce API. Every guide has a diagram of the problem, a diagram of the fix, full code in both languages, tests, and links to the source reports.
Orders and payments
8 guidesOrders stuck on Awaiting Payment after capture
The gateway took the money but the order sits on Awaiting Payment. Move the paid ones to Awaiting Fulfillment.
ReconcilerPaid order stuck on Incomplete
A completed payment left the order on Incomplete so it never reaches fulfillment. Find and finish them.
ReconcilerManual Verification Required never cleared
Orders flagged for manual verification sit forever. Surface the ones a human has approved.
ReconcilerDeclined order still holds stock
A declined order kept its stock reserved. Release the stock so real buyers can order.
RepairDuplicate orders from a double submit
A double click made two identical orders. Detect the duplicates and cancel the extra.
RepairTransactions total does not match the order
Captures minus refunds no longer equal the order total. Flag the orders that do not tie out.
ReconcilerGateway refund not reflected on the order
A refund in the gateway never updated the order. Record it back so the status is right.
ReconcilerDisputed order not flagged
A chargeback pulled funds but the order shows nothing. Put the dispute state on the order.
RepairWebhooks
10 guidesWebhook deactivated after failures
BigCommerce disabled your webhook after repeated failures. Detect the gap and recreate it.
ReconcilerDuplicate webhook deliveries run twice
The same event arrives more than once and doubles your work. Dedupe on the delivery id.
ReconcilerMissed webhooks with no backfill
Your app was down past the retry window. Poll updated orders and apply what you missed.
ReconcilerWebhook payload not verified
The webhook body was trusted without verification. Check the signature before acting.
DiagnosticWebhook domain blocklisted after low delivery success ratio
Endpoint success rate under 90 percent over 2 minutes gets the domain blocklisted. Script detects delivery gaps and alerts.
soonWebhook fires duplicate events within the same second
Same order status change delivers multiple near identical payloads. Script dedupes by resource id, status, and timestamp window.
soonWebhook keeps firing after its owning app or token is removed
Deleting the API account or uninstalling the app does not stop its hooks. Script lists hooks and deletes orphans explicitly.
soonUninstall webhook registration silently rejected
Registering the store or app uninstall scope gets refused with a 400, so the app never learns of removal. Script verifies registration and alerts on gaps.
soonOrder webhooks stop firing entirely with no surfaced error
All customer or order events silently stop delivering for a store. Script compares recent order timestamps against received webhook logs to detect the gap.
soonStatus webhook payload carries only an id, hiding dropped updates
store/order/statusUpdated omits the new status, so a failed follow up GET silently loses the change. Script cross checks recent order status against last known state.
soonInventory and catalog
8 guidesNegative inventory from overselling
Selling past zero pushed stock negative. Reset the oversold variants back to zero.
RepairAvailable drifts from real on-hand
The store count no longer matches the shelf. True it up from a counted source.
ReconcilerVariant inventory not tracked
Tracking was off so a variant never runs out. Detect them and turn tracking on.
RepairOut of stock but still purchasable
Out of stock products can still be bought. Fix the availability so they stop selling.
DiagnosticProducts stranded with no category
Products with no category hide from browsing. Assign a fallback category.
ReconcilerDuplicate or missing SKUs
SKUs are duplicated or blank across products. Report the conflicts to fix by hand.
DiagnosticBroken product images
Product images point to missing files. Detect the broken ones and clear them.
DiagnosticPrice list not applied to a group
A customer group is missing its price list prices. Detect and reassign.
ReconcilerCustomers
9 guidesDuplicate customers for one email
The same shopper has several customer records. Merge them so history stays together.
ReconcilerGuest orders not linked to accounts
Guest orders never linked to the customer account. Link them by email.
RepairCustomer group mis-assigned
Customers landed in the wrong group so pricing is wrong. Reassign from the rule.
ReconcilerCustomers filter by id is rejected as unsupported
Filtering the v2 customers list by id via query param throws a field not supported error. Script falls back to fetching the direct resource path to reconcile lookups.
soonCustomer password update intermittently returns random 400 errors
Password change calls fail nondeterministically even when the request is valid. Script verifies success via date_modified or a login test rather than trusting the response code.
soonCreate customer for an existing email errors without returning the existing id
The already exists response omits the matching customer_id, forcing a second lookup. Script catches the error and resolves the id via an email filter query.
soonCustomer address create no-ops on an exact duplicate with a 200 response
Posting an address identical to an existing one returns success but omits the address from the response body. Script GETs addresses afterward to confirm the real state.
soonNo API endpoint to merge two customer records
There is no native merge operation, so duplicate profiles leave fragmented order and address history. Script reassigns orders to one customer_id and consolidates addresses manually.
soonCustomer group change does not immediately refresh cached pricing
Customers moved between groups keep seeing the old group's prices until a manual re-sync. Script re-fetches the customer after group changes and validates pricing matches the new group.
soonFulfillment and shipping
3 guidesShipment tracking never added
A shipped order has no tracking number. Flag the ones that shipped without it.
DiagnosticOrders stuck Awaiting Shipment past SLA
A paid order sat unshipped past your promise. Tag the overdue ones for review.
DiagnosticPartial shipment total mismatch
A partial shipment left the quantities wrong. Reconcile shipped versus ordered.
ReconcilerPromotions and coupons
2 guidesTax, currency, and reporting
3 guidesOrder tax off by a cent
Tax differs between the storefront and the API. Find the orders that disagree.
ReconcilerPresentment vs settlement currency
The buyer paid one currency and you settled another. Make the exchange explicit.
ReconcilerTest orders counted in sales reports
Test orders slipped into real reports. Flag and separate them from live sales.
DiagnosticMigration and housekeeping
3 guidesStale product modifiers after import
An import left broken product modifiers. Detect the ones that no longer apply.
DiagnosticAbandoned cart records pile up
Old abandoned carts clutter the store. Report the stale ones for cleanup.
ReconcilerBackfill order metadata for matching
Old orders lack the external id needed to reconcile. Backfill it safely.
RepairOrders
12 guidesOrder update call recalculates and overwrites a coupon adjusted total
PUTing unrelated order fields triggers a total recalculation that erases coupon discounts. Script diffs stored versus current totals to catch corruption.
soonOrder shipments response drops the items array
Client libraries parse out the items field present in the raw v2 shipment response, under reporting shipped lines. Script reconciles against raw JSON.
soonWriting order status text instead of status_id fails or no-ops
PUT requests with a status string instead of the integer status_id error or silently do nothing. Script always resolves and writes status_id.
soonOrder shipping address update does not recompute tax or shipping cost
Changing an order's shipping address leaves stale total_tax and shipping_cost fields. Script detects address changes and recomputes totals via quote endpoints.
soonOrder total wrong when only one of price_ex_tax or price_inc_tax is set
Partial tax field overrides on order creation leave totals inconsistent. Script validates both fields are set together and diffs totals against line sums.
soonOrder missing shipping address when no line item is flagged physical
Orders with only non-physical products get no shipping_addresses record even when one is expected. Script flags orders where a physical flag or address is inconsistent.
soon422 fulfillment address incomplete despite address looking complete
POST to orders or consignments rejects with 422 due to a missing required subfield not obvious from the payload. Script validates required address keys before posting and logs the failing field.
soonOrder count endpoint disagrees with actual paginated order list
The dedicated order count endpoint returns a total that does not match the number of orders retrievable by paging. Script paginates fully and diffs against the count endpoint.
soonOrder-level refund does not recalculate total_tax
Applying a refund at the order level leaves total_tax inconsistent with the refunded amount. Script recomputes expected tax and reconciles against the stored record.
soonManual status change to Refunded does not move any money
Setting status_id to Refunded via API or admin creates no refund transaction. Script reconciles order status against the transactions endpoint to catch orders marked refunded with no matching transaction.
soonStatus change skips side effect actions like capture or void
Writing status_id directly bypasses the admin Action menu logic, so expected payment actions never fire. Script flags orders whose status implies a payment action that never appears in transactions.
soonRefunded line items are not returned to inventory automatically
API refunds never adjust stock levels for the refunded quantity. Script diffs refunded line quantities against inventory_level and issues compensating adjustments.
soonPayments / Refunds
2 guidesRefund rejected on orders paid with split payment methods
Refund calls error with an invalid split payment message on multi tender orders. Script fetches transactions first and splits the refund per payment method.
soonConcurrent refund requests on one order corrupt payment status
Overlapping refund POSTs for the same order produce inconsistent payment_status. Script serializes refunds per order with a queue or lock.
soonCatalog / Products
8 guidesSKUs endpoint truncates at 50 records without paginating
The product SKUs call returns only the first 50 by default with no pagination applied automatically. Script pages with limit and page and compares counts to detect truncation.
soonBrand update immediately before product create returns empty reply
Back to back brand update and product create calls intermittently fail with an empty server response. Script retries with backoff and verifies the product actually exists afterward.
soonCategory image_file field rejected as invalid on update
PUT to a category with image_file throws a 400 even though it is a documented field. Script detects categories with stale or missing images that silently fail bulk sync.
soonVariant price override stops following base product price changes
Once a variant has an explicit price, later edits to the base product price are silently ignored for that variant. Script finds variants with a set price diverging from the current product default.
soonDuplicating a product creates variants with colliding SKUs
Bulk product duplication can leave multiple variants sharing one SKU, breaking downstream matching. Script scans variants per product for duplicate SKUs and renames or reports them.
soonV3 pagination breaks when options or modifiers are included
Requesting include=options,modifiers on the products list corrupts meta.pagination.total_pages, causing early stop and missed products. Script validates total item count against a plain unfiltered pull.
soonProduct image upload rejects non fully qualified URLs
image_url values that are relative or not http(s) fail validation and leave the product with no image. Script scans for zero image products tied to failed import rows.
soonBulk image API only persists the first image per request
Batch image import calls that assume multiple images per request silently keep only the first. Script counts persisted images against source data and requeues the missing ones.
soonInventory
5 guidesInventory API writes are not channel aware
Bulk inventory adjustments can change stock for products not assigned to the intended sales channel. Script cross checks channel assignments before adjusting and after.
soonConcurrent inventory and catalog or order bulk jobs corrupt stock totals
Running inventory bulk adjustments in parallel with catalog or order bulk calls produces unpredictable on hand quantities. Script serializes these jobs and re-verifies inventory_level afterward.
soonInventory read immediately after write returns stale stock
A GET right after an adjustment can return the pre update quantity due to async processing. Script polls with backoff and confirms via the returned transaction id before trusting the read.
soonVariant inventory sum silently fails to save past int32 max
If summed variant inventory would exceed 2147483647, the write does not persist instead of clamping or erroring. Script detects variants whose inventory_level did not change despite a 200 response.
soonStorefront GraphQL variant inventory returns flaky values
Storefront inventory queries intermittently return stale or wrong stock for a variant, risking oversell prevention gaps. Script diffs storefront API stock against the management API per variant.
soonPricing / Price Lists
5 guidesConcurrent price list bulk upserts fail the whole batch with 429
Only one bulk upsert per store is allowed on price list records at a time. Script detects 429s from parallel jobs and serializes or retries them.
soonPrice list has no entry for a variant so it falls back to catalog price
Missing variant level rows mean special pricing silently does not apply for that variant. Script diffs price list records against all active variant ids to find coverage gaps.
soonLegacy customer group discount blocks a price list from attaching
A price list will not apply to a group while an old percentage or dollar discount still exists on that group. Script detects groups with both configured and clears the legacy discount.
soonPrice list changes fire no product or SKU webhooks
External systems relying on catalog webhooks never see price list driven price changes. Script polls price list records directly instead of waiting on webhooks.
soonOrder created via API bypasses customer group and price list pricing
Orders posted directly to the orders API bill catalog price instead of resolving group or price list pricing. Script pre resolves per customer prices before submitting line items.
soonCoupons / Promotions
5 guidesCoupon applies_to product associations wiped when max_uses is edited
Updating a coupon's usage limits via API silently clears its product associations. Script snapshots and reconciles applies_to entries after any coupon update.
soonPromotion with both group_ids and excluded_group_ids never triggers
Setting both eligibility fields at once on a promotion breaks evaluation so it never applies. Script validates promotions for this conflicting field combination.
soonParent promotion max_uses overrides a coupon's own usage cap
A coupon can lock out early because the parent promotion's usage cap is lower or already reached. Script compares promotion and coupon usage counters to explain unexpected invalid code errors.
soonManually overridden order pricing is excluded from promotions
Orders priced through server to server overrides do not receive automatic promotion discounts by default. Script flags orders where an expected promo discount is absent.
soonApplying an API discount clears existing order discounts
Posting a new checkout discount silently wipes prior product or order level discounts without warning. Script diffs order totals before and after the call to catch unexpected discount loss.
soonCheckout / Carts
5 guidesStale customer group cached in checkout state after a mid session change
Checkout SDK caches the customer group from session start, so a group change mid session is not reflected in pricing. Script compares the customer's current group id to the order's priced group id to flag mispriced orders.
soonShip to multiple addresses produces inconsistent line item to address mapping
Multi address checkouts can leave consignments with items unassigned or duplicated across addresses. Script sums consignment line item quantities against order lines to detect drift.
soonLine item option valueId type is inconsistent across product option types
The option value id returned by the checkout SDK varies between string and null depending on option type, breaking order creation payloads. Script normalizes the type before building the order line items array.
soonCart contents lost across devices or sessions in the B2B buyer portal
A logged in customer's cart disappears after logout or switching device, leaving orphaned active carts behind. Script compares cart_id to customer_id over time to detect and clean up abandoned duplicates.
soonCart stays locked to its original currency after a currency switch
Switching storefront currency after adding items still checks out in the original currency, causing a display or charge mismatch. Script flags carts whose currency_code differs from the customer's selected currency.
soonMulti-Storefront / Channels
2 guidesProduct invisible on a channel despite correct category and visibility flags
Category membership and visibility do not equal channel assignment, so a product can be unreachable on a given storefront. Script diffs each channel's assigned product ids against the full catalog.
soonNew storefront channel starts with an incomplete category tree
Adding a second channel does not copy over the primary storefront's categories, leaving gaps. Script compares category trees per channel and backfills missing nodes.
soonAPI Fundamentals
3 guidesRate limit callback fires only once per session instead of per request
Some client libraries invoke the 429 handling callback a single time then keep sending requests, producing repeated errors. Script tracks the rate limit reset header itself instead of trusting the callback.
soon429 responses sometimes omit rate limit headers under high load
Scripts relying on the reset time header for backoff get throttled responses with no headers present. Script falls back to a default exponential backoff when headers are missing.
soonOAuth token silently stops working after app scopes change
Existing access tokens fail with no clear error tie back once an app's granted scopes change. Script catches 401s, detects scope drift, and forces re-auth instead of blind retry.
soonSEO
1 guidesDeleting a product or category leaves a dangling URL with no redirect
Removing a product via API does not create a 301, breaking inbound links into a generic 404. Script diffs deleted product URLs against the redirects API and bulk creates 301s.
soonFighting a BigCommerce bug right now?
If you have a problem in BigCommerce orders, payments, inventory, webhooks, or fulfillment that you would rather hand off, this is the kind of work I do. Message me and we can work through it together.
Found this useful?
These guides are free and always will be. If one saved you a support ticket or a refund, you can throw a coffee my way. It keeps the notes coming.
Buy me a coffee on Ko-fi