Skip to main content

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

EventDescription
payment_intent.succeededPayment completed successfully. Creates a transaction record.
payment_intent.payment_failedPayment failed. Updates transaction status to FAILED.

Subscription Events

EventDescription
customer.subscription.createdNew subscription started.
customer.subscription.updatedSubscription status changed (e.g., active, past_due).
customer.subscription.deletedSubscription canceled and ended.
invoice.payment_succeededRecurring payment collected successfully.
invoice.payment_failedRecurring payment failed.

Dispute Events

EventDescription
charge.dispute.createdNew dispute opened by cardholder.
charge.dispute.updatedDispute status changed.
charge.dispute.closedDispute resolved (won or lost).

Payout Events

EventDescription
payout.paidPayout arrived in bank account.
payout.failedPayout failed.

Account Events

EventDescription
account.updatedConnected 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.