Webhooks & APIIntegrations

Stripe

Receive Stripe payment events in Wexio flows

Wexio has native Stripe signature verification. Paste the signing secret from Stripe's dashboard and Wexio handles the Stripe-Signature header — including timestamp tolerance and multi-v1 signature rotation.

Provider docs: Setting up webhooks in Stripe

Setup

1. Create an inbound Wexio connection

Settings → Webhooks & API → New connection → Inbound. Use the Stripe preset (or pick Auth mode: Stripe manually).

You'll need the signing secret from Stripe next — come back here and paste it into Signing secret.

Copy the Wexio endpoint URL: https://api.wexio.io/webhooks/in/{connectionId}.

2. Register the endpoint in Stripe

In Stripe → Developers → Webhooks → Add endpoint.

FieldValue
Endpoint URLThe Wexio endpoint URL
Events to sendPick the ones you care about — checkout.session.completed, invoice.paid, customer.subscription.created, etc.

Stripe shows the signing secret (starts with whsec_) after the endpoint is created. Copy it and paste into Wexio's Signing secret field.

3. Configure contact resolution

Stripe's payloads use emails or customer IDs — either works:

Identifier typeJSON pathNotes
Email$.data.object.customer_emailEasiest — matches Wexio contacts by their email field
Email$.data.object.receipt_emailAlternative for Payment Intent events

If you store stripe_customer_id on your Wexio contacts, you can also map by custom field using a flow variable lookup after the trigger fires.

4. Capture the schema

Tap Capture schema in Wexio. In Stripe → Webhooks → your endpoint, click Send test webhook and pick the event type you want. Wexio absorbs the sample and populates the field picker.

5. Bind a flow

Add a Webhook Received trigger on a flow and pick this connection. Combine with a Condition card on webhook.type if you want one flow per Stripe event type.

Example — Invoice Paid → WhatsApp Receipt

  • Stripe event: invoice.paid
  • Wexio connection: identifier Email + $.data.object.customer_email
  • Flow:
    1. Webhook Received
    2. Condition — branch on {{webhook.type}} EQUALS invoice.paid
    3. WA Template "invoice_receipt" with {{webhook.data.object.amount_paid}}, {{webhook.data.object.number}}

Timestamp Tolerance & Replays

Stripe signs each event with a timestamp and Wexio rejects anything outside ±5 minutes. This is by design — it prevents replay attacks.

Stripe replays events up to ~3 days if your endpoint returns non-2xx. If the replay arrives after the tolerance window, Wexio logs UNAUTHORIZED: Stripe signature timestamp outside ±5 min tolerance. That's correct behaviour — Stripe will eventually stop retrying. If you need to recover missed events, use the Events API in Stripe to fetch them manually.

Rotation

Stripe supports dual signing during rotation — they display two valid secrets for a configurable window.

Recommended flow:

  1. In Stripe, click Roll signing secret on the endpoint.
  2. Copy the new secret.
  3. In Wexio, Rotate secret on the connection (opens a modal to paste the new value).
  4. Stripe continues signing with both secrets until the rollover window elapses — you get zero downtime.

Troubleshooting

SymptomCauseFix
UNAUTHORIZED: Stripe signature mismatchWrong signing secretRe-copy from Stripe, make sure you're on the right endpoint (test vs live)
UNAUTHORIZED: Stripe signature timestamp outside ±5 min toleranceClock skew or old replayCheck NTP on your clock; accept that very old replays are rejected
Live events in history, but flow doesn't runIDENTIFIER_NOT_FOUNDCustomer doesn't have a matching contact in Wexio yet — create them via People API or add a branch to create-on-miss
Missing eventsStripe endpoint not subscribed to that event typeEdit the endpoint in Stripe and add the event

On this page