Start with the Stripe payment path that already causes support pain. SendPromptly adds two HTTP calls to your existing webhook handler. You do not need to change how Stripe delivers events or how your endpoint works.
Prerequisites
- Active SendPromptly account — start a 14-day trial
- An existing Stripe webhook handler in your app
- A dedicated repair endpoint you control (used only for reprocess callbacks)
Step 1 — Create a project
In app.sendpromptly.com, create a project. Copy the API key and store it server-side only — never expose it in client code.
Configure your repair callback URL. This is the endpoint SendPromptly will POST to when you trigger a reprocess from the incident console.
Step 2 — Choose one event to instrument first
Start with one Stripe event type:
checkout.session.completed— for access unlock failuresinvoice.paid— for credit grant or subscription-state failures
Do not try to instrument every Stripe event at once. One flow first, then expand.
Step 3 — Send receipt
After your webhook handler verifies the Stripe signature and durably accepts the work (for example, enqueues a job), send a receipt to SendPromptly:
| |
| |
Send the receipt before your job queue runs the business effect — not after.
Supported effect_type values: access_unlock, credit_grant, seat_update, subscription_state_apply, access_revocation, credit_deduction.
Step 4 — Send result
After your app attempts the business effect, send the result. For success:
| |
For failure:
| |
If no result arrives within the configured timeout (default 30 minutes), SendPromptly opens an incident automatically. You can override the timeout per event using "timeout_minutes" in the receipt payload.
Step 5 — Implement your repair endpoint
SendPromptly POSTs a signed callback to your repair endpoint when you trigger a reprocess from the incident console. Verify the signature before processing.
Signature headers:
| |
The signature is HMAC-SHA256 over timestamp + "." + nonce + "." + raw_body using your project’s signing secret.
Reject callbacks with a timestamp older than 5 minutes. Your repair endpoint must be idempotent — it will receive the same replay_id on retries.
Callback payload:
| |
After running your repair logic, send a result with the replay_id included:
| |
Step 6 — Test the integration
- Send a test
checkout.session.completedevent via Stripe’s test dashboard - Confirm your app sends a receipt — check the SendPromptly console
- Force a failure result to trigger an incident
- Confirm the email alert arrives
- Click Reprocess from the incident console
- Confirm your repair endpoint receives the signed callback
- Send a success result
- Confirm the incident resolves
Language examples
Node.js:
| |
PHP (Laravel):
| |
Python:
| |
What not to instrument first
- Every Stripe event type — instrument one, validate it, then expand
- Full subscription lifecycle edge cases —
invoice.paidandcheckout.session.completedcover the highest-risk paths at launch - Generic webhook logging — that is not what SendPromptly does
Related
- How the recovery workflow works — full workflow walkthrough
- What SendPromptly catches — failure types and fit guide
- Pricing — Starter at $29/month, 14-day trial