# Airwallex Webhooks

## When to Use This Skill

* How do I receive Airwallex webhooks?
* How do I verify Airwallex webhook signatures (`x-signature` / `x-timestamp`)?
* How do I handle `payment_intent.succeeded`, `refund.settled`, or `payment_dispute.*` events?
* Why is my Airwallex webhook signature verification failing?

## Verification (core)

Airwallex signs every webhook with HMAC-SHA256. Two headers arrive with each request:

* `x-timestamp` — the send time as a Unix timestamp in milliseconds
* `x-signature` — the HMAC-SHA256 hex digest

The signed message is `x-timestamp` concatenated with the raw request body (timestamp first), keyed with the endpoint's unique secret. There is no Node SDK helper for this — verify manually and always use the original, unmodified raw body. Verify before parsing JSON.

```javascript
const crypto = require('crypto');

// value_to_digest = x-timestamp + raw_body  (timestamp first, then the raw bytes)
function verifyAirwallexSignature(rawBody, timestamp, signature, secret) {
  if (!timestamp || !signature) return false;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(timestamp)          // string, e.g. "1712345678000"
    .update(rawBody)            // raw request body Buffer/bytes — never re-serialized JSON
    .digest('hex');
  const a = Buffer.from(expected, 'utf8');
  const b = Buffer.from(signature, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b); // constant-time compare
}

```

> For complete handlers with route wiring, event dispatch, and tests, see:
> 
> * [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/airwallex-webhooks/examples/express/)
> * [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/airwallex-webhooks/examples/nextjs/)
> * [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/airwallex-webhooks/examples/fastapi/)

## Common Event Types

Airwallex event types are dot-namespaced. The event type is in the payload's `name` field (not `type`); the resource is in `data.object`.

| Event | Triggered When |
| --- | --- |
| `payment_intent.succeeded` | A PaymentIntent is fully paid |
| `payment_intent.requires_payment_method` | A payment attempt failed; a new method is needed |
| `payment_attempt.authorized` | A payment attempt is authorized |
| `payment_attempt.paid` | A payment attempt is captured/paid |
| `refund.settled` | A refund has settled to the customer |
| `refund.failed` | A refund failed |
| `payment_consent.verified` | A payment consent (for recurring/MIT) is verified |
| `payment_dispute.requires_response` | A dispute needs evidence submitted |
| `payment_dispute.won` / `payment_dispute.lost` | A dispute is resolved |

> For the full event list (all `payment_intent.*`, `payment_attempt.*`, `refund.*`, `payment_consent.*`, `payment_dispute.*`), see [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/airwallex-webhooks/references/overview.md) and the [Airwallex webhook events docs](https://www.airwallex.com/docs/developer-tools/webhooks/listen-for-webhook-events/online-payments).

## Environment Variables

```bash
# Unique secret for THIS webhook URL (Web app > Settings > Developer > Webhooks)
AIRWALLEX_WEBHOOK_SECRET=whsec_xxxxx

```

Each webhook URL has its own secret — if you register multiple endpoints, each has a distinct secret.

## Local Development

```bash
# Start a tunnel (no account needed) — inspect and replay Airwallex webhooks locally
npx hookdeck-cli listen 3000 airwallex --path /webhooks/airwallex

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/airwallex-webhooks/references/overview.md) - What Airwallex webhooks are, full event list, payload structure
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/airwallex-webhooks/references/setup.md) - Dashboard configuration, getting the endpoint secret, IP allowlist
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/airwallex-webhooks/references/verification.md) - Signature verification details, gotchas, debugging