# Frequently Asked Questions

Quick answers to the most common questions merchants ask about ODUS.

## 1. What does the `requires_action` status mean?

A payment moves to `requires_action` when the customer must complete an additional step before processing can continue — most commonly a 3D Secure (3DS) authentication redirect. The payment object will include an `action.redirectUrl` that points the customer to the authentication page.

Once the customer completes the action, the payment transitions to `succeeded`. If the action is not completed within 24 hours, the payment resets to `open` so a new attempt can be made.

See [Payment Statuses](https://docs.odus.com/docs/guides/payments/payment-statuses.md) for the full state machine.

## 2. Why was my payment declined?

Every failed payment includes an `outcome` object on the transaction with a standardized `errorCode`, a `declineType` (`soft_decline`, `hard_decline` or `not_attempted`), and a `safeErrorMessage` suitable for display to customers.

Common reasons:

| Code                      | Meaning                                                          |
| ------------------------- | ---------------------------------------------------------------- |
| `insufficient_funds`      | The card does not have enough balance.                           |
| `expired_card`            | The card is past its expiry date.                                |
| `invalid_card_details`    | The card number, CVV, or other details are incorrect.            |
| `authentication_failed`   | Authentication was required but could not be completed.          |
| `fraud_suspected`         | The processor flagged the transaction as potentially fraudulent. |
| `generic_processor_error` | A transient processor error — retrying may succeed.              |

Hard declines (`fraud_suspected`, `card_restricted`, `generic_hard_decline`, `authentication_rejected`) will not succeed on retry with the same card. Soft declines may succeed if retried or if the customer updates their payment method. A third type, `not_attempted`, means this payment was never authorized against the card, so the issuer refused nothing — read `errorCode` for the cause and the remedy.

See [Error Codes](https://docs.odus.com/docs/guides/payments/error-codes.md) for the full reference.

## 3. How do I set up webhooks?

1. In the Dashboard, go to **Developers > Webhook Subscribers** and create a subscriber.
2. Save the generated shared secret — it is used to verify payload authenticity.
3. Expose a publicly accessible HTTPS endpoint that accepts POST requests.
4. Validate incoming requests by computing the HMAC-SHA256 of the request body using your shared secret and comparing it to the `X-Webhook-HMAC` header.
5. Respond with a `2xx` status code to acknowledge receipt.

Webhooks are delivered at least once and retried up to 10 times over 3 days with exponential backoff. Use the `eventId` field to deduplicate.

See [Webhooks](https://docs.odus.com/docs/guides/api-features/webhooks.md) for the full guide.

## 4. How do cascades work?

A cascade defines which gateway profiles process your payments and in what order. When one gateway fails, ODUS automatically routes to the next gateway — no action required from you.

Three routing algorithms are available:

* **Round-robin** — distributes payments evenly across gateways.
* **Weighted round-robin** — distributes by percentage weight (e.g., 70/30).
* **Priority queue** — always tries the highest-priority gateway first, falling back on failure.

Each gateway in a cascade can have optional transaction limits and caps per day, week, or month.

See [How Cascade Routing Works](https://docs.odus.com/docs/guides/routing/cascade-overview.md) and [Configuring Cascades](https://docs.odus.com/docs/guides/routing/configuring-cascades.md).

## 5. How does the retry policy work for failed subscription payments?

When a subscription renewal charge fails, ODUS automatically retries according to your retry policy. A policy contains ordered steps, each with:

* **`retryDelay`** — days to wait before retrying.
* **`useInitialGateway`** — whether to retry on the same gateway or target a different one.
* **`priceReductionPercentage`** — optionally reduce the charge amount for that attempt.

Your account has one retry policy, and it applies to every failed renewal. Read it with `GET /v2/retry-policy` and set it with `POST /v2/retry-policy`. Until you set one, a failed renewal is not retried.

See [Configure a Payment Retry Policy](https://docs.odus.com/docs/guides/subscriptions/retry-policy.md).

## 6. How do I authenticate API requests?

Include your secret key as a Bearer token in the `Authorization` header:

```
Authorization: Bearer skey_your_secret_key_here
```

Secret keys (`skey_` prefix) are for server-side use only. Create and manage them in the Dashboard under **Developers > Access Keys**.

See [Authentication](https://docs.odus.com/docs/guides/api-features/authentication.md).

## 7. What is the difference between `status` and `displayStatus`?

`status` is the core lifecycle field with four values: `open`, `requires_action`, `succeeded`, and `cancelled`. Use it in your integration logic.

`displayStatus` is a derived, human-friendly label (e.g., `uncaptured`, `retrying`, `partially_reversed`) computed from `status` and the boolean lifecycle flags. It is useful for UI display but should not drive business logic — new values may be added in future releases.

See [Payment Statuses](https://docs.odus.com/docs/guides/payments/payment-statuses.md).

## 8. How do I capture a payment manually?

If your payment was created with `captureMethod: "manual"`, the payment will move to `succeeded` with `isCaptured: false` (displayStatus: `uncaptured`) after authorization. To capture:

```
POST /v2/payments/{id}/capture
```

You can capture the full authorized amount or a partial amount. Uncaptured authorizations expire according to the processor's hold period (typically 7 days).

See [Capture](https://docs.odus.com/docs/guides/payments/capture.md).

## 9. How do I test payments without processing real charges?

ODUS provides a test mode where you can simulate payments, declines, and 3DS flows without hitting live gateways. Use your test-mode API keys (available in the Dashboard) to make requests against the same API endpoints.

See [Testing Resources](https://docs.odus.com/docs/guides/testing.md) for test card numbers and simulation scenarios.

## 10. How do I handle 3DS redirects in my checkout flow?

When a payment returns `status: "requires_action"` with an `action.redirectUrl`:

1. Redirect the customer to the URL (or open it in an iframe/popup).
2. The customer completes authentication with their bank.
3. The bank redirects back to your configured return URL.
4. ODUS automatically finalizes the payment — poll or listen for the `payment.updated` webhook to confirm the outcome.

If you use the ODUS Checkout SDK, 3DS handling is built in automatically.

See [3DS and Redirect Handling](https://docs.odus.com/docs/guides/checkout/3ds-and-redirect-handling.md).
