Letting the Outside In
Some things cannot be tested on localhost: a payment provider's webhook, an OAuth callback, a client who wants to see it. This chapter is about opening a door, and about not having to knock twice.
The problem
Third-party integrations are the worst part of local development, and the reason is a loop that cannot close. Stripe needs to send a webhook to a URL it can reach. Your machine is not reachable. So you either deploy to a staging environment to test each change — minutes per iteration — or you fake the payload and discover on launch day that the real one has a field you did not expect.
A public URL
grove share freddy
A public HTTPS address that forwards to your local site. The provider can reach it, the client can open it on their phone, the OAuth callback resolves. Your code stays on your machine with your debugger attached and your breakpoints in place.
Two things to be deliberate about. It is a door into your
laptop: share the site you are working on, close it when
you are done. And your app must produce correct absolute
URLs when reached by another name — the usual cause
of a share that loads but whose assets and redirects point
back at .test.
The webhooks bucket
Sharing solves reachability. It does not solve the second problem, which is that every test costs a real event: another payment, another push, another form filled in on a provider's dashboard.
grove hooks
Grove captures incoming webhooks in a bucket you can inspect and, crucially, deliver again. So the loop becomes:
- Trigger the event once, for real.
- Read the payload — the actual one, with the fields the provider actually sends, not the one in their documentation.
- Deliver it to your app. Watch it fail.
- Fix the code. Deliver the same payload again.
- Repeat until it passes.
One real event, twenty iterations. The alternative is twenty real events, which for a payment provider means twenty test charges and a great deal of clicking.
And because the payload is the real one, you are debugging against what the provider sends rather than against what you believe they send. The gap between those two is where integration bugs live.
What you learned
- grove share gives a local site a public HTTPS URL, so the provider can reach you while the code stays here.
- Close the door when you are done, and make sure your app builds absolute URLs from the request.
- Webhooks are captured and re-deliverable. One real event, twenty iterations.
- Debug against the payload they actually send, not the one in the documentation.
- A payload that found a bug is a fixture. Turn it into a test and it never comes back.