Key Behavior Differences
1.1 Sandbox: Webhooks Do Not Fire Automatically
In Sandbox, webhook delivery is intentionally limited:
-
Webhooks typically remain in a
Pendingstate and do not automatically transition toSuccessful. -
You must manually resend webhook deliveries to send them to your endpoint.
-
This behavior is by design to prevent unnecessary webhook execution during testing and system adjustments.
-
This Sandbox limitation is fixed and cannot be enabled/disabled per application.
Production: Webhooks Fire Automatically
In Production, webhook events are delivered automatically when the underlying event occurs (assuming the webhook is enabled and configured correctly).
Important Limitation: access_ended-Type Webhooks Are Not Generated in Sandbox
Certain events are not just "not sent"; they may not be generated at all in Sandbox because the scheduler/back-end jobs that create them do not run and access does not expire naturally.
Common examples include:
-
access_ended -
access_revoked(anaccess_ended-type event) -
Other expiry/scheduled-job-driven events
If you must validate true expiration/renewal-failure scenarios, plan to test in a Production-like environment (see Testing Scenarios That Require Production).
How to Manually Trigger (Resend) Webhooks in Sandbox
-
Perform an action that would normally generate a webhook (for example: create a user, make a purchase, modify access).
-
In the Piano dashboard, go to Manage → Webhooks.
-
Find the webhook delivery/event you want to test.
-
Use the Resend option (often in the row menu/ellipsis).
After resending, the webhook will be sent to the endpoint configured in the dashboard.
Some events may not appear as available to resend in Sandbox, especially access_ended-type events (which may not be generated). If an event seems temporarily missing, re-check later after additional test actions.
Troubleshooting Resend and Delivery Issues
"Could Not Connect to Endpoint"
If you see Could not connect to endpoint when resending:
-
Verify the webhook URL is correct.
-
Confirm your endpoint is reachable from the public internet.
-
Retry the resend (transient connectivity issues can occur).
-
If the endpoint is behind a firewall, ensure it allows inbound traffic from Piano (see IP Allowlisting below).
HTTP 302 (Redirect) Responses
A 302 indicates your endpoint is redirecting the request. Webhook receivers should generally accept the POST directly and avoid redirects.
-
Update your endpoint to respond without redirecting.
-
Ensure your handler returns
200 OKupon successful processing.
Endpoint Response Requirements
Your endpoint should return:
-
200 OKto acknowledge receipt and processing (recommended best practice).
Non-200 responses can cause webhook delivery to be marked as failed or retried depending on configuration and event.
IP Allowlisting (Restricted Endpoints)
If your endpoint only accepts traffic from approved sources, you may need to allowlist Piano IP addresses for the relevant environment (Sandbox vs. Production).
-
Use the Piano documentation list of webhook IPs (found in the Webhooks FAQ) and ensure the Sandbox IPs are allowlisted when testing in Sandbox.
Testing Scenarios That Require Production
Some end-to-end tests cannot be realistically simulated in Sandbox because scheduled jobs do not run. For these cases, use Production (or a separate Production instance dedicated to testing).
Recommended approaches:
-
Create a test site/subdomain where purchase flows are not exposed to real users.
-
Protect test entry points (for example, with basic auth).
Example: Triggering subscription_auto_renewed_failure
To test subscription_auto_renewed_failure reliably:
-
Create a renewing subscription with a short billing period (for example, 1 day).
-
Make an initial purchase using a real credit card (in your test area).
-
Before the renewal date, update the card on file to invalid details.
-
When renewal is attempted, the failure will trigger
subscription_auto_renewed_failure.
Environment Parity Considerations
If you observe differences in webhook behavior between Sandbox and Production beyond the known Sandbox limitations:
-
Confirm webhook settings are enabled and consistent across environments.
-
Validate that configuration differences (including account/app settings) are not causing mismatched behavior.
-
If your account uses shared identity behavior across applications (often referred to as "global" user handling), that can influence which user/account events occur and when.