# Testing resources

This guide covers everything you need to test your ODUS integration in sandbox before going live: test card numbers, example webhook payloads.

## Test card numbers

Use the card numbers below to simulate different payment outcomes. For all cards:

* Use **any future expiry date** (e.g. `12/40`)
* Use **any CVV** (e.g. `100`)
* Use **any cardholder name** (e.g. `Test User`)

### Stripe

| Card number        | Brand      | Scenario | Description                                          |
| ------------------ | ---------- | -------- | ---------------------------------------------------- |
| `4242424242424242` | Visa       | Success  | Payment is authorized immediately                    |
| `5555555555554444` | Mastercard | Success  | Payment is authorized immediately                    |
| `378282246310005`  | Amex       | Success  | Payment is authorized immediately                    |
| `6011111111111117` | Discover   | Success  | Payment is authorized immediately                    |
| `4000000000003220` | Visa       | 3DS      | Triggers a 3DS redirect; complete to authorize       |
| `4000000000000002` | Visa       | Declined | Card is always declined with a generic decline error |

For the full list, see the [Stripe testing documentation](https://docs.stripe.com/testing#cards).

### Adyen

| Card number        | Brand      | Scenario | Description                                    |
| ------------------ | ---------- | -------- | ---------------------------------------------- |
| `370000000000018`  | Amex       | Success  | Payment is authorized immediately              |
| `5555444433331111` | Mastercard | Success  | Payment is authorized immediately              |
| `6011000000000004` | Discover   | Success  | Payment is authorized immediately              |
| `371449635398431`  | Amex       | 3DS      | Triggers a 3DS redirect; complete to authorize |

For the full list, see the [Adyen test cards documentation](https://docs.adyen.com/development-resources/testing/test-card-numbers/).

### Checkout.com

| Card number        | Brand | Scenario | Description                       |
| ------------------ | ----- | -------- | --------------------------------- |
| `4242424242424242` | Visa  | Success  | Payment is authorized immediately |

For the full list, see the [Checkout.com testing documentation](https://www.checkout.com/docs/testing).

### PayPal

PayPal does not use test card numbers. Instead, you create sandbox buyer and seller accounts in the [PayPal Developer Dashboard](https://developer.paypal.com/). See the [PayPal integration guide](https://docs.odus.com/docs/guides/integrations/gateways/paypal/.md) for setup instructions.

## Test webhook payloads

After [creating a webhook subscriber](https://docs.odus.com/docs/guides/dashboard/webhook-subscriber.md), you will receive events at your configured URL. Below are example payloads for common events. The `data` field structure matches the corresponding API response — see the [Webhooks guide](https://docs.odus.com/docs/guides/api-features/webhooks.md) for full details.

tip

Use [ngrok](https://ngrok.com/) or a similar tool to expose your local server to the internet during development. You can also inspect delivered webhooks in the Dashboard under [Request Logs](https://docs.odus.com/docs/guides/dashboard/request-logs.md).

### payment.created

Sent when a payment is created via `POST /v2/payments`.

```
{

  "eventId": "evt_abc123",

  "eventType": "payment.created",

  "profile": "whs_xyz456",

  "timestamp": "2026-05-12T10:00:00Z",

  "data": {

    "id": "pay_def789",

    "status": "open",

    "displayStatus": "unattempted",

    "amount": 1000,

    "currency": "usd",

    "amountCaptured": 0,

    "amountReversed": 0,

    "isCaptured": false,

    "isReversed": false,

    "isFullyReversed": false,

    "isChargebacked": false,

    "isRetrying": false,

    "isRecovered": false,

    "initiator": "customer",

    "customer": null,

    "paymentMethod": null,

    "metadata": {}

  }

}
```

### payment.succeeded

Sent when a payment is successfully authorized (and captured, if automatic).

```
{

  "eventId": "evt_ghi012",

  "eventType": "payment.succeeded",

  "profile": "whs_xyz456",

  "timestamp": "2026-05-12T10:01:30Z",

  "data": {

    "id": "pay_def789",

    "status": "succeeded",

    "displayStatus": "succeeded",

    "amount": 1000,

    "currency": "usd",

    "amountCaptured": 1000,

    "amountReversed": 0,

    "isCaptured": true,

    "isReversed": false,

    "isFullyReversed": false,

    "isChargebacked": false,

    "isRetrying": false,

    "isRecovered": false,

    "initiator": "customer",

    "customer": {

      "id": "cus_jkl345"

    },

    "paymentMethod": {

      "id": "pm_mno678",

      "type": "card",

      "card": {

        "brand": "visa",

        "lastFour": "4242",

        "expMonth": "12",

        "expYear": "2040"

      }

    },

    "metadata": {}

  }

}
```

### payment.attempt\_failed

Sent when a payment authorization attempt fails (e.g. card declined).

```
{

  "eventId": "evt_pqr901",

  "eventType": "payment.attempt_failed",

  "profile": "whs_xyz456",

  "timestamp": "2026-05-12T10:01:30Z",

  "data": {

    "id": "pay_def789",

    "status": "open",

    "displayStatus": "failed",

    "amount": 1000,

    "currency": "usd",

    "amountCaptured": 0,

    "amountReversed": 0,

    "isCaptured": false,

    "isReversed": false,

    "isFullyReversed": false,

    "isChargebacked": false,

    "isRetrying": false,

    "isRecovered": false,

    "initiator": "customer",

    "customer": {

      "id": "cus_jkl345"

    },

    "paymentMethod": null,

    "metadata": {}

  }

}
```

### payment.requires\_action

Sent when a payment requires customer action, such as 3DS authentication.

```
{

  "eventId": "evt_stu234",

  "eventType": "payment.requires_action",

  "profile": "whs_xyz456",

  "timestamp": "2026-05-12T10:01:15Z",

  "data": {

    "id": "pay_def789",

    "status": "requires_action",

    "displayStatus": "incomplete",

    "amount": 1000,

    "currency": "usd",

    "amountCaptured": 0,

    "amountReversed": 0,

    "isCaptured": false,

    "isReversed": false,

    "isFullyReversed": false,

    "isChargebacked": false,

    "isRetrying": false,

    "isRecovered": false,

    "initiator": "customer",

    "customer": {

      "id": "cus_jkl345"

    },

    "paymentMethod": null,

    "action": {

      "redirectUrl": "https://sandbox-api.odus.com/checkout/redirect/pay_def789"

    },

    "metadata": {}

  }

}
```

### subscription.active

Sent when a subscription becomes active after a successful initial payment.

```
{

  "eventId": "evt_vwx567",

  "eventType": "subscription.active",

  "profile": "whs_xyz456",

  "timestamp": "2026-05-12T10:02:00Z",

  "data": {

    "id": "sub_yza890",

    "status": "active",

    "customer": {

      "id": "cus_jkl345"

    },

    "items": [

      {

        "price": {

          "id": "price_bcd123",

          "amount": 1000,

          "currency": "usd",

          "interval": "month",

          "intervalCount": 1

        },

        "quantity": 1

      }

    ],

    "currentPeriodStart": "2026-05-12T10:02:00Z",

    "currentPeriodEnd": "2026-06-12T10:02:00Z",

    "metadata": {}

  }

}
```
