← all case studies
go-shopify

Mock the Shopify Admin API locally — page_info cursors and webhook HMAC

go-shopify’s paginator follows page_info cursors, and its VerifyWebhookRequest accepts the mock’s HMAC-signed deliveries.

Set up

One service block in stunt.yaml, then stunt up. The webhook_url is your test process — that's where signed deliveries land.

services:
  shopify:
    adapter: ./adapters/shopify-style
    config:
      webhook_url: http://localhost:9090/shopify
stunt catalog add shopify-style
stunt up
# goshopify.NewClient(app, "shop", "shpat_test", WithHTTPClient(rewriteClient), WithVersion("2024-10"))

What the suite proves

Asserted by the conformance suites in stunt's CI — not marketing copy. Every check below is a passing assertion:

  • 01Webhook registration through the SDK (orders/create)
  • 02Order creates with line items and embedded customers — numeric ids round-trip typed
  • 03financial_status derives from the transaction history like production
  • 04Order.ListWithPagination walks page_info cursors through the SDK’s NextPageOptions (Link-header parsing)
  • 05Every orders/create delivery verifies through the SDK’s own App.VerifyWebhookRequest

Bugs the harness caught

Ids arrived as JSON strings

Webhook ids and embedded customer ids rendered as strings; Shopify ids are numeric and go-shopify’s typed fields reject the response. Worse, the first coercion fix crashed on the most common pattern — an order with an embedded customer — because client-sent numeric ids decode differently. The conformance suite pins exactly that create now.

Cursor pagination, derived payment status, signed webhooks: the parts of a Shopify integration that actually break, testable offline.