Accept orders from Shopify
Attach neolife's provider-gated fulfillment to a Shopify store without replacing the storefront — the certificate handshake, checkout gating, and order reconciliation.
The neolife Shopify app attaches provider-gated fulfillment to a store you already run — it never replaces your storefront or your checkout. The doctrine is simple: gate the prescription, not the shopping cart. An opaque certificate id travels on the Shopify order, neolife re-verifies it server-side, and the fulfillment layer is the hard gate. No pharmacy order leaves neolife without a valid certificate — so the Shopify surface is an enhancement, not the promise.
What the app installs#
The app is a public Shopify app you install onto your store from the theme editor. It adds three surfaces, all fronting the same orders engine:
| Surface | Where it runs | What it does |
|---|---|---|
| Intake app block | Rx-tagged product pages | Renders the neolife intake widget so the shopper completes a compliance questionnaire in place. |
| Checkout validation | Every checkout | Blocks completion of an Rx line item unless the customer holds a valid certificate. Runs server-side on Shop Pay, Apple Pay, Google Pay, and PayPal express — it can't be bypassed client-side. |
| App proxy + webhooks | Server-to-server | Serves neolife same-origin on your store, and reconciles the Shopify order to the neolife order on orders/create. |
You mark which products require approval with an rx product tag. The app gates exactly those lines and leaves everything else (supplements, retail) alone.
The certificate handshake#
The only thing that ever crosses onto Shopify is an opaque certificate id — never patient answers, never a diagnosis, never PHI. The lifecycle:
- A shopper opens an Rx-tagged product page. The intake app block renders the questionnaire.
- The shopper submits answers. They post browser-direct to neolife — they never touch Shopify's page, cart attributes, or order note-attributes. The page only ever receives an opaque
{verdict, submissionId, certificate}result. - A licensed provider reviews and approves the intake inside neolife.
- On approval, neolife writes the certificate to an app-reserved customer metafield on Shopify:
{ certificateId, productIds, expiresAt }as an opaque token. Only the app can read or write it. - At checkout, Shopify's validation surface reads that metafield against the Rx-tagged cart lines. A valid, unexpired certificate that covers the products lets checkout proceed; anything else is blocked, fail-closed.
Fail-closed by design. A missing certificate, an expired one, or a parse error blocks checkout — the gate never fails open on an Rx line. The certificate is written server-side by neolife on provider approval; it is never minted by client-side code.
Reconciling the order#
Storefront-side blocking is a conversion optimization, not the guarantee. The authoritative reconciliation happens when Shopify fires orders/create:
- neolife re-verifies the certificate server-side — it does not trust the checkout-time metafield alone.
- The Shopify order is linked onto the neolife order so you have one order of record across both systems.
- Fulfillment is armed. From here the flow is the standard neolife lifecycle: a provider-approved, certificate-backed order is routed to a compounding pharmacy, and status flows back over webhooks and events.
Because refill and subscription renewals can bill without ever re-running checkout, the fulfillment-layer gate — not the Shopify checkout — is what actually holds the line. See Subscriptions for how renewals are gated.
PHI never touches Shopify#
This is the load-bearing property, and it's worth stating plainly to your compliance team:
- Patient answers post directly to neolife. They never enter the Shopify page DOM, Liquid, cart attributes, or order note-attributes.
- Only the opaque certificate token lives on Shopify (in the app-reserved metafield and, after
orders/create, as a link to the neolife order). It carries no clinical content. - All PHI stays on neolife's covered infrastructure. Shopify sees an id and a status, nothing more.
This mirrors the platform-wide PHI boundary: ids and status cross the wire; clinical detail stays server-side and is hydrated only over authenticated GETs.
Wire up the reconciliation#
Point a webhook endpoint at neolife's PHI-free event stream so your systems learn when a Shopify order is approved, routed, and fulfilled — without polling and without pulling PHI into your callback:
curl -X POST https://api.neolife.health/v1/developer/webhooks \
-H "Authorization: Bearer $NEOLIFE_API_KEY" \
-H "Idempotency-Key: 6b9d0e42-3f1b-4a51-8b2f-1c7e5a9d0e42" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourstore.example/hooks/neolife",
"events": ["order.submitted", "order.fulfilled"]
}'
Every event payload is ids + status only. Hydrate order detail when you need it over an authenticated GET — see Orders.
Next steps#
- The PHI boundary — why events stay out of PHI scope.
- Orders — the approve → submit → fulfill lifecycle behind the certificate.
- Webhooks & events — the reconciliation model you subscribe to.