Guides

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:

  1. A shopper opens an Rx-tagged product page. The intake app block renders the questionnaire.
  2. 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.
  3. A licensed provider reviews and approves the intake inside neolife.
  4. 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.
  5. 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.