The webhook handling and multi-tenancy sections are where most Shopify app tutorials fall short, so kudos for covering both. OAuth token refresh is another area that bites developers in production — tokens expire, and if your refresh logic isn't bulletproof, merchants lose access silently. One approach I've used in similar integration projects is queuing webhook payloads before processing them, so you never lose events during traffic spikes. Laravel's job queues make this pretty seamless. Are you using database-per-tenant or shared schema with scoping for the multi-tenancy piece?
Thanks for the kind words, Archit! 🙌
Great point about OAuth token refresh — it's definitely one of those "gotcha" areas. We handle it by storing the refresh token securely and implementing a middleware that checks token expiry before each API call. If it's close to expiring, we refresh proactively rather than waiting for a 401.
And yes, queuing webhook payloads is absolutely the way to go! We use Laravel's job queues exactly as you described — webhook hits the endpoint, gets queued immediately (returns 200 to Shopify), and processes asynchronously. This way we never lose events during traffic spikes. We also add retry logic with exponential backoff for failed jobs.
For multi-tenancy, we went with shared schema with tenant scoping (using a
shop_idcolumn on each table + global scopes). Database-per-tenant was overkill for our use case since we're dealing with Shopify shops that have similar data structures. The shared approach keeps migrations simpler and reduces infrastructure costs, while the scoping ensures complete data isolation.Appreciate the thoughtful comment!