P3 MEDIA
The Shopify agency for category-leading brands
SOLUTION BRIEF · CONFIDENTIAL
Spectrum Brands × P3 × Shopify
Prepared 06 / 08 / 2026
Inbound order architecture · To-be

Order ingest, rebuilt around the API.

The current design pushes every order to middleware over a synchronous webhook with a five-second response window — and times out, duplicating orders and forwarding fraud before payment clears. The redesign moves fraud and payment decisioning entirely into Shopify. Middleware pulls only orders tagged Shopify:Approved, so nothing unverified ever reaches SAP.

5s → 0
No webhook response window
100%
Fraud screened before ingest
2
Decoupled flows: tag, then pull
2026-04
Admin API, schema-validated
01

Risk tagging, inside Shopify

Risk is not known the instant an order is created — Shopify resolves it asynchronously, passing through a PENDING state. So tagging runs off the risk assessment, not off order creation. Shopify Flow reads riskLevel and writes exactly one of three tags.

Order created
orders/create
Risk assessed
order.risk → riskLevel
Shopify Flow branch
evaluates riskLevel
Risk = Low
Auto-tag
Shopify:Approved
Risk = Medium / High
Tag for review
Shopify:Pending
Business user reviews
finance / CS team
Shopify:Approved
Shopify:Rejected
Low auto-tag and a manual approval reach the same Shopify:Approved state
02

API-pull ingest, Shopify → SAP

This replaces the webhook push. The middleware polls the orders query filtered to the approved tag and paid status, dedupes on the Shopify global ID, accepts each order onto a JMS queue, and processes one-by-one into S/4HANA. Unapproved orders are never returned — so they are structurally impossible to import.

Shopify stores
Remington · Black & Decker · Emeril · Power XL
Approved orders
tag = Shopify:Approved
Other orders
Pending / Rejected
↳ not approved = never pulled,
   never imported
API request
(poll)
Middleware pulls
orders query · filtered
Dedupe
on Shopify global ID
queue
JMS queue
accept, then process
one by one
S/4HANA
ERP
03

The verified API surface

Every operation below was checked against the Shopify Admin GraphQL schema, version 2026-04 — no hallucinated fields. Tap any node in the flows above to highlight the operation it maps to.

3 / 3 operations validated against Admin API 2026-04
01
Read risk level
query · order.risk
query OrderRisk($orderId: ID!) { order(id: $orderId) { risk { assessments { riskLevel provider { title } } recommendation } } }
Enum riskLevel: LOW · MEDIUM · HIGH · NONE · PENDINGscope: read_orders
02
Apply the tag
mutation · tagsAdd
mutation ApproveOrder($id: ID!) { tagsAdd( id: $id, tags: ["Shopify:Approved"] ) { node { id } userErrors { field message } } }
tagsAdd officially supports the Order resource. Low auto-applies; Med/High → Pending → manual.resource: Order
03
Pull approved only
query · orders (filtered)
query Approved($cursor: String) { orders( first: 50, after: $cursor, query: "tag:Shopify:Approved financial_status:paid" ) { edges { node { id name tags } } pageInfo { hasNextPage endCursor } } }
Dedupe on node.id (the Shopify global ID). Paginate via endCursor.scope: read_orders
04

One decision left for the room

The flows are settled. What remains is how Flow B is triggered — a tradeoff between latency and resilience that belongs to the architecture review, not to us to assume.

Open · trigger mechanism for Flow B

The diagram shows a middleware poll of the orders query, which matches the accept-and-queue preference raised in the working session. Two alternatives are worth weighing before the build locks.

Scheduled poll shown
Most resilient. No dependency on delivery guarantees; the queue absorbs spikes. Slight latency floor set by poll interval.
Webhook on order update
Lower latency, tag-filtered. But webhooks can self-disable on repeated failure — the original fragility.
Shopify Events
The newer webhook successor. Promising, still stabilizing — Shopify is sending the developer reference.