Webhooks
PayLinks uses Stripe webhooks to process payment events in real time.
Webhook URL
https://paylinks.ro/webhooks/stripe
This endpoint is registered with Stripe and receives all relevant events for connected accounts.
Event Types
PayLinks processes the following Stripe webhook events:
Payment Events
| Event | Description |
|---|---|
payment_intent.succeeded | Payment completed successfully. Creates a transaction record. |
payment_intent.payment_failed | Payment failed. Updates transaction status to FAILED. |
Subscription Events
| Event | Description |
|---|---|
customer.subscription.created | New subscription started. |
customer.subscription.updated | Subscription status changed (e.g., active, past_due). |
customer.subscription.deleted | Subscription canceled and ended. |
invoice.payment_succeeded | Recurring payment collected successfully. |
invoice.payment_failed | Recurring payment failed. |
Dispute Events
| Event | Description |
|---|---|
charge.dispute.created | New dispute opened by cardholder. |
charge.dispute.updated | Dispute status changed. |
charge.dispute.closed | Dispute resolved (won or lost). |
Payout Events
| Event | Description |
|---|---|
payout.paid | Payout arrived in bank account. |
payout.failed | Payout failed. |
Account Events
| Event | Description |
|---|---|
account.updated | Connected account details changed (verification, capabilities). |
Signature Verification
All webhook events are verified using Stripe's webhook signature:
Stripe-Signature: t=timestamp,v1=signature
The webhook handler verifies the signature against the webhook secret before processing any event. Events with invalid signatures are rejected with a 400 status.
Event Processing
Events are processed synchronously for critical paths (payment success, dispute creation) and asynchronously via pg-boss workers for non-critical operations (analytics updates, email notifications).
Idempotency
All webhook handlers are idempotent. Processing the same event multiple times produces the same result. Stripe may deliver events more than once, and this is handled gracefully.
Testing Webhooks Locally
Use the Stripe CLI to forward webhooks to your local development server:
stripe listen --forward-to localhost:4000/webhooks/stripe
The CLI prints a webhook signing secret — set it as STRIPE_WEBHOOK_SECRET in your .env.