> ## Documentation Index
> Fetch the complete documentation index at: https://developers.ingopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing

> Scenario-based testing guide for the Embedded Account Capture iFrame plugin — session management, account tokenization, and payment processing.

## Sandbox Environment

Your sandbox mirrors production behavior including account verification services, OFAC screening, and webhook delivery. Sandbox credentials and velocity limits are provisioned during onboarding.

<Info>
  Sandbox velocity limits are client-specific and configured by your Ingo integration manager during onboarding.
</Info>

***

## Test Categories

| Category         | Description                                             | How to initiate                              |
| ---------------- | ------------------------------------------------------- | -------------------------------------------- |
| **Self-Service** | Complete independently in the sandbox at your own pace  | Your sandbox credentials                     |
| **Controlled**   | Requires an enablement flag or pre-loaded test accounts | Contact your integration manager to schedule |

***

## Understanding Soft Failures

**Soft failure** — A partial match that does not stop the flow. The recipient experiences no interruption and proceeds transparently. Your system is notified of the result in the background via the correlated **success** webhook carrying the soft-fail status code. No failure webhook emits.

**Hard failure** — A mismatch on a field your configuration has designated as requiring a hard failure. How each verification field's mismatch is treated is defined during your implementation setup via the configuration form. When a hard failure occurs, the recipient is stopped and must retry. If maximum attempts are exhausted, the session or transaction terminates.

***

## How EAC Testing Works

The Embedded Account Capture flow has two distinct phases, each with its own API call and webhook events:

**Phase 1 — Session API + iFrame Plugin**
Call `POST /api/v1/sessions/point-in-time/plugin` to create a session. Mount the plugin in your application. The recipient interacts with the iFrame — RVDM verification and account tokenization happen within the session. Plugin events use `plugin.*` webhook topics.

**Phase 2 — Process API**
After the recipient's account is tokenized, call `POST /gateway/process` to initiate the disbursement. Payment status events use `gateway.*` webhook topics.

***

## Self-Service Scenarios

<AccordionGroup>
  <Accordion title="Session Management">
    <Card title="Successful Session Creation" icon="key">
      **Category:** Self-Service

      **Scenario:** Send a Session API request with valid recipient information. Mount the plugin successfully in your application.

      **Success criteria:** Session created, `authorized_url` returned, plugin mounts
    </Card>

    <Card title="Idempotent Session Request" icon="rotate">
      **Category:** Self-Service

      **Scenario:** Resend the same Session API request using the same `Idempotency-Key` header. Confirms that no duplicate session is created.

      **Success criteria:** Response `status: 101` — existing session returned, no new session created
    </Card>

    <Card title="Failed Idempotent Session Request" icon="circle-xmark">
      **Category:** Self-Service

      **Scenario:** Resend a Session API request using the same `Idempotency-Key` but with modified request body parameters. Confirms that idempotency key mismatch is rejected.

      **Success criteria:** Error response indicating idempotency key conflict
    </Card>

    <Card title="Session Expiration" icon="clock">
      **Category:** Self-Service

      **Scenario:** Create a session and mount the plugin. Allow the session to expire without any recipient input. Confirms your system handles session expiry correctly.

      **Success criteria:** Session expired event fires

      **Key webhook sequence to verify:**

      | # | Event           | Topic                                        | Expected Status |
      | - | --------------- | -------------------------------------------- | --------------- |
      | — | Session Expired | `plugin.transaction.session.request.expired` | 1128            |
    </Card>
  </Accordion>

  <Accordion title="Account Tokenization — Card">
    <Card title="Card — Successful Tokenization" icon="credit-card">
      **Category:** Self-Service

      **Scenario:** Create a session. Mount the plugin. The recipient enters card details with session recipient information that fully matches. Account is tokenized successfully.

      **Success criteria:** RVDM success and tokenization success events fire

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status |
      | - | -------------------- | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1103            |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | 100             |
    </Card>

    <Card title="Card — RVDM Soft Failure" icon="credit-card">
      **Category:** Self-Service

      **Scenario:** The recipient enters card details with partially matching session recipient information. The recipient experiences no interruption and proceeds transparently. Your system is notified of the partial match in the background via the RVDM success webhook carrying the soft-fail status code. Tokenization still succeeds.

      **Success criteria:** RVDM success fires with soft-fail code; tokenization success follows

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status |
      | - | -------------------- | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1104            |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | 100             |
    </Card>

    <Card title="Card — RVDM Hard Failure" icon="circle-xmark">
      **Category:** Self-Service

      **Scenario:** The recipient enters card details with non-matching session recipient information. The RVDM hard failure stops the flow. The recipient may retry until max attempts are reached, at which point the session terminates.

      **Success criteria:** RVDM failure fires; session terminates after max attempts

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                    | Expected Status |
      | - | ------------------ | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Failure       | `plugin.transaction.recipient.verification.rvdm.failure` | 1105            |
      | 2 | Session Terminated | `plugin.transaction.session.request.terminated`          | 1127            |
    </Card>

    <Card title="Card — Account Not Available" icon="ban">
      **Category:** Self-Service

      **Scenario:** The recipient enters a card account number not supported for disbursement. The plugin stops the recipient and the session eventually terminates.

      **Success criteria:** CNS/CD failure fires; session terminates

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                         | Expected Status |
      | - | ------------------ | ------------------------------------------------------------- | --------------- |
      | 1 | CNS/CD Failure     | `plugin.transaction.account.verification.card.cns_cd.failure` | 700             |
      | 2 | Session Terminated | `plugin.transaction.session.request.terminated`               | 1127            |
    </Card>

    <Card title="Card — Session Termination (Max Attempts)" icon="circle-stop">
      **Category:** Self-Service

      **Scenario:** The recipient exhausts all attempts across verification failures. The session terminates.

      **Success criteria:** Session terminated event fires

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                           | Expected Status |
      | - | ------------------ | ----------------------------------------------- | --------------- |
      | — | Session Terminated | `plugin.transaction.session.request.terminated` | 1127            |
    </Card>
  </Accordion>

  <Accordion title="Account Tokenization — ACH">
    <Card title="ACH — Successful Tokenization" icon="building-columns">
      **Category:** Self-Service

      **Scenario:** Create a session. Mount the plugin. The recipient enters a valid routing and account number with fully matching session recipient information. Account is tokenized successfully.

      **Success criteria:** RVDM success and tokenization success events fire

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status |
      | - | -------------------- | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1103            |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | 100             |
    </Card>

    <Card title="ACH — RVDM Soft Failure" icon="building-columns">
      **Category:** Self-Service

      **Scenario:** The recipient enters ACH details with partially matching session recipient information. The recipient experiences no interruption. Your system is notified of the partial match in the background. Tokenization still succeeds.

      **Success criteria:** RVDM success fires with soft-fail code; tokenization success follows

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status |
      | - | -------------------- | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1104            |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | 100             |
    </Card>

    <Card title="ACH — RVDM Hard Failure & Session Termination" icon="circle-xmark">
      **Category:** Self-Service

      **Scenario:** The recipient enters ACH details with non-matching session recipient information until max attempts are reached. The session terminates.

      **Success criteria:** RVDM failure fires; session terminates

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                    | Expected Status |
      | - | ------------------ | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Failure       | `plugin.transaction.recipient.verification.rvdm.failure` | 1105            |
      | 2 | Session Terminated | `plugin.transaction.session.request.terminated`          | 1127            |
    </Card>
  </Accordion>

  <Accordion title="Account Tokenization — BillPay">
    <Card title="BillPay — Successful Tokenization (Single Match)" icon="receipt">
      **Category:** Self-Service

      **Scenario:** Create a session. Mount the plugin. The recipient searches for and selects a biller, enters their account number, and a single biller match is found. Account is tokenized successfully.

      **Success criteria:** Tokenization success event fires

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                             | Expected Status |
      | - | -------------------- | ------------------------------------------------- | --------------- |
      | — | Tokenization Success | `plugin.transaction.account.tokenization.success` | 100             |
    </Card>

    <Card title="BillPay — Successful Tokenization (Multiple Matches)" icon="list-check">
      **Category:** Self-Service

      **Scenario:** The biller search returns multiple matches. The recipient selects the correct biller and the account is tokenized successfully.

      **Success criteria:** Tokenization success event fires

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                             | Expected Status |
      | - | -------------------- | ------------------------------------------------- | --------------- |
      | — | Tokenization Success | `plugin.transaction.account.tokenization.success` | 100             |
    </Card>

    <Card title="BillPay — No Match Found (Session Termination)" icon="magnifying-glass-minus">
      **Category:** Self-Service

      **Scenario:** The biller search returns no matches for the account data entered. The session terminates.

      **Success criteria:** Session terminated event fires

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                           | Expected Status |
      | - | ------------------ | ----------------------------------------------- | --------------- |
      | — | Session Terminated | `plugin.transaction.session.request.terminated` | 1127            |
    </Card>
  </Accordion>

  <Accordion title="Process API — Payment">
    <Note>
      Process API testing — including successful payments, idempotency, velocity limits, and mocked issuer responses — is documented in the [IngoPay API testing guide](/ingopay/testing). The `customer_account_token` returned from the iFrame plugin is used directly in the IngoPay Process API request.
    </Note>
  </Accordion>
</AccordionGroup>

***

## Controlled Scenarios

<Warning>
  The following scenarios require your Ingo integration manager to enable a specific configuration or pre-load test accounts before testing can begin. Contact your integration team to schedule these.
</Warning>

<AccordionGroup>
  <Accordion title="Card — AVS & CVV Risk Management">
    <Card title="AVS Soft Fail" icon="location-crosshairs">
      **Category:** Controlled

      **Scenario:** A card account tokenization where the AVS check returns a soft failure. The recipient experiences no interruption and proceeds transparently. Your system is notified of the partial address match in the background via the tokenization success webhook carrying the soft-fail status code.

      **Success criteria:** Tokenization success fires with AVS soft-fail status code

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status |
      | - | -------------------- | -------------------------------------------------------- | --------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1103 or 1104    |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | 111–119 range   |
    </Card>

    <Card title="AVS Decline" icon="location-dot-slash">
      **Category:** Controlled

      **Scenario:** A card account tokenization where the AVS check returns a hard decline. Your system is notified via the AVS/CVV failure webhook. The session terminates.

      **Success criteria:** AVS/CVV failure fires; session terminates

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                          | Expected Status |
      | - | ------------------ | -------------------------------------------------------------- | --------------- |
      | 1 | AVS/CVV Failure    | `plugin.transaction.account.verification.card.avs_cvv.failure` | 753–759 range   |
      | 2 | Session Terminated | `plugin.transaction.session.request.terminated`                | 1127            |
    </Card>

    <Card title="CVV Decline" icon="shield-slash">
      **Category:** Controlled

      **Scenario:** A card account tokenization where the CVV check returns a hard decline. Your system is notified via the AVS/CVV failure webhook. The session terminates.

      **Success criteria:** AVS/CVV failure fires; session terminates

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                          | Expected Status |
      | - | ------------------ | -------------------------------------------------------------- | --------------- |
      | 1 | AVS/CVV Failure    | `plugin.transaction.account.verification.card.avs_cvv.failure` | —               |
      | 2 | Session Terminated | `plugin.transaction.session.request.terminated`                | 1127            |
    </Card>
  </Accordion>

  <Accordion title="ACH — Account Verification">
    <Card title="ANV / NAV Soft Fail" icon="building-columns">
      **Category:** Controlled

      **Scenario:** An ACH account verification returns a soft failure on account number (ANV) or name/address (NAV) validation. The recipient experiences no interruption. Your system is notified of the partial match in the background via the tokenization success webhook carrying the soft-fail status code.

      **Success criteria:** Tokenization success fires with soft-fail status code

      **Key webhook sequence to verify:**

      | # | Event                | Topic                                                    | Expected Status       |
      | - | -------------------- | -------------------------------------------------------- | --------------------- |
      | 1 | RVDM Success         | `plugin.transaction.recipient.verification.rvdm.success` | 1103 or 1104          |
      | 2 | Tokenization Success | `plugin.transaction.account.tokenization.success`        | Soft-fail status code |
    </Card>

    <Card title="RNV / ANV / NAV Hard Decline" icon="ban">
      **Category:** Controlled

      **Scenario:** ACH account verification returns a hard decline on routing number, account number, or name/address validation. Your system is notified via the appropriate failure webhook. The session terminates.

      **Success criteria:** Applicable failure event fires; session terminates

      **Key webhook sequence to verify:**

      | # | Event              | Topic                                                     | Expected Status |
      | - | ------------------ | --------------------------------------------------------- | --------------- |
      | — | RNV Failure        | `plugin.transaction.account.verification.ach.rnv.failure` | 743             |
      | — | *or* ANV Failure   | `plugin.transaction.account.verification.ach.anv.failure` | 767–769         |
      | — | *or* NAV Failure   | `plugin.transaction.account.verification.ach.nav.failure` | 776–778         |
      | — | Session Terminated | `plugin.transaction.session.request.terminated`           | 1127            |
    </Card>
  </Accordion>
</AccordionGroup>

***

## Webhook Events Reference

<AccordionGroup>
  <Accordion title="Plugin Session Events">
    | Event              | Topic                                           | Expected Status |
    | ------------------ | ----------------------------------------------- | --------------- |
    | Session Expired    | `plugin.transaction.session.request.expired`    | 1128            |
    | Session Terminated | `plugin.transaction.session.request.terminated` | 1127, 1129      |
  </Accordion>

  <Accordion title="Recipient Verification Events">
    | Event        | Topic                                                    | Expected Status               |
    | ------------ | -------------------------------------------------------- | ----------------------------- |
    | RVDM Success | `plugin.transaction.recipient.verification.rvdm.success` | 1103 (full), 1104 (soft fail) |
    | RVDM Failure | `plugin.transaction.recipient.verification.rvdm.failure` | 1105                          |
  </Accordion>

  <Accordion title="Account Verification Events">
    | Event                | Topic                                                          | Expected Status |
    | -------------------- | -------------------------------------------------------------- | --------------- |
    | Card CNS/CD Failure  | `plugin.transaction.account.verification.card.cns_cd.failure`  | 700             |
    | Card AVS/CVV Failure | `plugin.transaction.account.verification.card.avs_cvv.failure` | 753–759         |
    | ACH RNV Failure      | `plugin.transaction.account.verification.ach.rnv.failure`      | 743             |
    | ACH ANV Failure      | `plugin.transaction.account.verification.ach.anv.failure`      | 767–769         |
    | ACH NAV Failure      | `plugin.transaction.account.verification.ach.nav.failure`      | 776–778         |
    | PayPal AV Failure    | `plugin.transaction.account.verification.paypal.failure.av`    | 1150            |
  </Accordion>

  <Accordion title="Account Tokenization Events">
    | Event                | Topic                                             | Expected Status                     |
    | -------------------- | ------------------------------------------------- | ----------------------------------- |
    | Tokenization Success | `plugin.transaction.account.tokenization.success` | 100 (full), 111–119 (AVS soft fail) |
  </Accordion>
</AccordionGroup>
