Skip to content
HeapByte — Senior Shopify Engineering Studio

Architecture · 2 November 2026

Shopify B2B order approval rules: spending limits and purchasing hierarchies

An electrical trade distributor launches on Shopify Plus B2B, granting fifty commercial contractor accounts self-service purchasing. A junior estimator at a commercial mechanical firm logs in, builds a cart with $42,000 of industrial switchgear, and clicks submit. The contractor's internal procurement policy strictly caps junior estimator authority at $2,500, requiring branch manager approval up to $10,000 and corporate CFO approval for anything above. Because Shopify Plus B2B rules were configured with only a single, flat approval threshold linked to a staff contact who left the company three weeks earlier, the order sits indefinitely in approval limbo while wholesale inventory holds expire. When a distributor administrator manually approves the purchase order seventy-two hours later, underlying copper conduit prices have jumped 14% and two critical circuit breaker lines have sold out to competing online buyers.

8 min read
Written by the HeapByte engineering team

Shopify B2B order approval rules spending limits purchasing hierarchies architecture

The unmanaged checkout dilemma: why corporate procurement rejects flat B2B carts

When wholesale merchants migrate to Shopify Plus B2B, they frequently treat corporate customer accounts like glorified retail buyers with price lists.

They assign a trade buyer the native ORDERING_ONLY or LOCATION_ADMIN role on a CompanyLocation, link a negotiated B2B catalog, and grant Net 30 payment terms. Under this naive structure, any authenticated employee possessing checkout access can execute orders up to the company location's entire credit limit.

In enterprise trade relationships, this model collapses under corporate governance:

  • Unbudgeted Maverick Spend: Junior field technicians and apprentices order specialist tools or premium variant finishes that exceed job project budgets.
  • Segregation of Duties Breaches: Financial compliance frameworks strictly require segregation between the individual who requisitions materials and the authority who approves commercial payment.
  • PO Number Integrity: Field staff enter placeholder text like 'TBD' or 'verbal approval' into mandatory purchase order fields, generating uncollectable invoices that accounts payable departments reject.

Multi-tier approval hierarchies and threshold derivation

True procurement governance requires multi-tier approval rules that evaluate order value dynamically against both buyer authority limits and organizational thresholds.

Rather than a binary toggle, enterprise purchasing operates across discrete tiers: Tier 1 Auto-Approval (up to €2,500 for direct checkout), Tier 2 Manager Approval (€2,500.01 to €10,000 requiring Location Admin sign-off), Tier 3 Executive Approval (€10,000.01 to €50,000 requiring dual Company Admin sign-offs), and Tier 4 Board Escalation for capital commitments above €50,000.

Within Shopify Plus B2B, these rules map to GraphQL Admin API mutations (orderApprovalRuleCreate). However, rules must be validated at the cart boundary: line totals must be aggregated in integer cents to prevent single-cent floating-point precision leaks.

Furthermore, the submitter must be strictly excluded from the pool of eligible approvers: a branch manager holding LOCATION_ADMIN credentials cannot approve their own €8,000 requisition.

ts
export type ApprovalTier = "TIER_1_AUTO" | "TIER_2_MANAGER" | "TIER_3_EXECUTIVE";
export type ApprovalState = "AUTO_APPROVED" | "PENDING_APPROVAL" | "APPROVED" | "ESCALATED";

export interface CompanyContact {
  id: string; // gid://shopify/CompanyContact/123
  name: string;
  email: string;
  role: "ORDERING_ONLY" | "LOCATION_ADMIN" | "COMPANY_ADMIN";
  spendingLimitCents: number;
  isActive: boolean;
}

export interface OrderApprovalRuleDefinition {
  ruleId: string;
  minAmountCents: number;
  maxAmountCents: number;
  tier: ApprovalTier;
  requiredRole: "LOCATION_ADMIN" | "COMPANY_ADMIN";
  minApproverCount: number;
}

export interface B2BOrderSubmission {
  orderDraftId: string;
  companyLocationId: string;
  submitter: CompanyContact;
  lineItems: Array<{ variantId: string; sku: string; unitPriceCents: number; quantity: number }>;
  totalAmountCents: number;
}

export function evaluateB2BOrderApprovalRules(
  submission: B2BOrderSubmission,
  rules: OrderApprovalRuleDefinition[],
  locationContacts: CompanyContact[],
  fallbackEscalationAdmin?: CompanyContact
) {
  const reasons: string[] = [];
  const computedTotalCents = submission.lineItems.reduce((acc, l) => acc + l.unitPriceCents * l.quantity, 0);

  const breachesSubmitterLimit = computedTotalCents > submission.submitter.spendingLimitCents;
  if (breachesSubmitterLimit) {
    reasons.push("Order total (€" + Math.round(computedTotalCents / 100) + ") exceeds buyer limit (€" + Math.round(submission.submitter.spendingLimitCents / 100) + ")");
  }

  const sortedRules = [...rules].sort((a, b) => b.minAmountCents - a.minAmountCents);
  const matchedRule = sortedRules.find(r => computedTotalCents >= r.minAmountCents && computedTotalCents <= r.maxAmountCents);

  const matchedTier = matchedRule ? matchedRule.tier : "TIER_1_AUTO";
  const minApprovalsNeeded = matchedRule ? matchedRule.minApproverCount : 0;
  const requiredRole = matchedRule ? matchedRule.requiredRole : "LOCATION_ADMIN";

  const requiresApproval = breachesSubmitterLimit || matchedTier !== "TIER_1_AUTO";
  if (!requiresApproval) {
    return { approvalState: "AUTO_APPROVED" as ApprovalState, matchedTier, requiresApproval: false, eligibleApprovers: [] };
  }

  // Segregation of duties: Submitter cannot approve their own order
  const eligibleApprovers = locationContacts.filter(c => {
    if (!c.isActive || c.id === submission.submitter.id) return false;
    return requiredRole === "COMPANY_ADMIN" ? c.role === "COMPANY_ADMIN" : (c.role === "LOCATION_ADMIN" || c.role === "COMPANY_ADMIN");
  });

  const isOrphan = eligibleApprovers.length < minApprovalsNeeded;
  let approvalState: ApprovalState = "PENDING_APPROVAL";
  let escalationContactId: string | undefined;

  if (isOrphan && fallbackEscalationAdmin?.isActive) {
    approvalState = "ESCALATED";
    escalationContactId = fallbackEscalationAdmin.id;
    reasons.push("No active local approvers with " + requiredRole + ". Escalated to " + fallbackEscalationAdmin.name);
  }

  return { approvalState, matchedTier, requiresApproval: true, reasons, eligibleApprovers, minApprovalsNeeded, escalationContactId };
}
In an earlier implementation for Weldaad's B2B trade ordering, the approval routing checked whether any contact possessed the LOCATION_ADMIN role without verifying isActive status or excluding the submitter. When a purchasing manager submitted a €14,000 order and their branch director was on extended medical leave, the system marked the order as pending director review. Because no fallback escalation path was defined, the order remained un-approvable for eighteen days while seasonal trade inventory sold out. The production architecture filters out inactive staff, strictly enforces segregation of duties, and automatically escalates orphaned approval tickets to root corporate administrators.

Stale price snapshots, inventory expiry, and approval re-validation

The most severe architectural vulnerability in B2B order approval workflows is the approval latency window.

In retail ecommerce, checkout is instantaneous: pricing and inventory are validated in real time. In corporate B2B, the time delta between a junior buyer submitting a requisition and a regional executive approving it typically spans 24 to 72 hours.

During this latency window, commodity catalog prices shift and physical warehouse inventory can sell out to competing online buyers. Because a submitted requisition is merely a draft, it does not lock warehouse stock.

Before an approved requisition transitions into a confirmed order via draftOrderComplete, our synchronization middleware executes an atomic pre-commit validation. If inventory has lapsed or prices have shifted beyond configured tolerance thresholds, the order is locked and returned to the buyer with an annotated revision notice, eliminating uncollectable invoice disputes.

The orphan approver trap and escalation delegation

In commercial contracting and wholesale trade, personnel churn is constant: branch managers resign, project leads relocate, and email accounts are deactivated.

When an approval rule routes to a specific inactive staff account, open requisitions enter an unresolvable terminal state: the buyer cannot approve it, peers cannot view it, and distributor customer service cannot bypass it without violating customer governance.

To eliminate this deadlock, our architecture enforces a hierarchical health-check heartbeat. If the required quorum of active approvers is missing, the engine automatically flags an ESCALATED state and routes the approval ticket to designated root corporate administrators (COMPANY_ADMIN).

For accounts operating with credit facilities, approved orders must simultaneously pass live credit exposure reconciliation. Consult our architecture for Shopify B2B ERP credit limit sync to understand how live ledger ageing prevents over-limit approvals, or review our guide on Shopify B2B trade account onboarding.

When this needs an engineer

You do not need custom order approval rules if your B2B customers are sole proprietors purchasing with credit cards, if your order values rarely exceed €500, or if your trade buyers have uniform, flat purchasing authority across all staff accounts.

You need an engineer when your buyers are enterprise organizations: when purchasing policies mandate multi-tier delegation of authority; when requisitions above €2,500 require branch sign-off and orders above €10,000 require dual corporate sign-off; when submitters must be prevented from self-approving requisitions; when multi-day approval windows risk inventory sell-outs and price drift; and when orphan approver conditions must automatically escalate rather than freezing wholesale cash flow.

Explore our engineering services in Shopify B2B development, inspect our B2B operations case study collection, or examine how supplier governance was architected in the Weldaad Supplier Portal case study.

Send us your procurement hierarchy, spending limit thresholds, and buyer role requirements. We will architect a clean, compliant B2B order approval workflow that respects corporate governance while keeping checkout frictionless.

Insights

Apply this to your store.

An audit turns the general principle into a specific list of changes, ordered by what actually pays back.