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

# Testing Guide

> Complete testing scenarios and requirements before moving to production.

## Overview

Complete both scenarios in the test environment before moving to production: report accounts for a year, then correct one of them.

See [Testing](/regulatory/rrc/testing) for the test environment and the practices shared by every report.

## Test Scenarios

<Tabs>
  <Tab title="Report Accounts">
    Create a submission for a reporting year, push your accounts, then submit.

    <AccordionGroup>
      <Accordion title="Test Case 1: Create Submission" icon="plus">
        **Objective**: Create a new submission for a reporting year.

        **Request**: `POST /reports/crs/v1/submissions`

        **Request Body**:

        ```json theme={null}
        {
          "reportingYear": 2025,
          "webhookUrl": "https://example.com/crs/webhook"
        }
        ```

        <Info>
          `webhookUrl` is optional. Include it and the connector calls it with the final verdict once the submission finishes processing:

          ```json theme={null}
          {"submissionId": "6f1b0c1e-6c0b-4c39-9a2e-1d9d2f0f7a11", "status": "ACCEPTED"}
          ```

          Whitelist the sending IP addresses first. They are listed under [Webhook](/regulatory/rrc/crs/overview#webhook). Test whichever route you plan to use in production.
        </Info>

        **Expected Response**: `HTTP 201 Created`

        ```json theme={null}
        {
          "submissionId": "6f1b0c1e-6c0b-4c39-9a2e-1d9d2f0f7a11",
          "kind": "SUBMISSION"
        }
        ```

        <Info>
          Confirm `kind` is `SUBMISSION`. Store the `submissionId`. It scopes every call in Test Cases 2 to 4.
        </Info>
      </Accordion>

      <Accordion title="Test Case 2: Push Accounts" icon="building-columns">
        **Objective**: Add the accounts you report for the year. Call this as many times as you need.

        The example below pushes three: a reportable entity, a passive entity with a controlling person, and a closed individual account.

        **Request**: `POST /reports/crs/v1/submissions/{submissionId}/accounts`

        **Request Body**:

        ```json theme={null}
        [
          {
            "accountNumber": "LT601010012345678901",
            "accountNumberType": "IBAN",
            "balance": 15320.44,
            "currency": "EUR",
            "accountType": "DEPOSITORY_ACCOUNT",
            "openingType": "PREEXISTING_ACCOUNT",
            "accountHolder": {
              "selfCertification": "PROVIDED",
              "organisation": {
                "type": "REPORTABLE_PERSON",
                "name": "UAB Inventi",
                "nameType": "LEGAL",
                "residenceCountryCodes": [
                  "LV"
                ],
                "tins": [
                  {
                    "number": "39001011234",
                    "issuedBy": "LV"
                  }
                ],
                "addresses": [
                  {
                    "addressFree": "Riga, Riga st. 1",
                    "countryCode": "LV",
                    "type": "REGISTRATION"
                  }
                ]
              }
            },
            "payments": [
              {
                "type": "INTEREST",
                "amount": 142.75,
                "currency": "EUR"
              }
            ]
          },
          {
            "accountNumber": "LT121000011101001000",
            "accountNumberType": "IBAN",
            "balance": 248900.0,
            "currency": "EUR",
            "accountType": "CUSTODIAL_ACCOUNT",
            "openingType": "NEW_ACCOUNT",
            "jointAccountHolders": 2,
            "accountHolder": {
              "selfCertification": "PROVIDED",
              "organisation": {
                "type": "PASSIVE_NFE_WITH_REPORTABLE_CONTROLLING_PERSONS",
                "name": "UAB Inventi",
                "nameType": "LEGAL",
                "residenceCountryCodes": [
                  "LV"
                ],
                "tins": [
                  {
                    "number": "39001011234",
                    "issuedBy": "LV"
                  }
                ],
                "addresses": [
                  {
                    "addressFree": "Riga, Riga st. 1",
                    "countryCode": "LV",
                    "type": "REGISTRATION"
                  }
                ]
              }
            },
            "controllingPersons": [
              {
                "names": [
                  {
                    "firstName": "Jonas",
                    "lastName": "Jonaitis"
                  }
                ],
                "residenceCountryCodes": [
                  "LV"
                ],
                "tins": [
                  {
                    "number": "39001011234",
                    "issuedBy": "LV"
                  }
                ],
                "addresses": [
                  {
                    "addressFree": "Riga, Alberta st. 1",
                    "countryCode": "LV",
                    "type": "RESIDENTAL_OR_HABITATION"
                  }
                ],
                "birthInfo": {
                  "birthDate": "1990-05-15",
                  "city": "Riga",
                  "countryCode": "LV"
                },
                "roles": [
                  "LEGAL_PERSON_CONTROL_BY_OWNERSHIP"
                ],
                "selfCertification": "PROVIDED"
              }
            ],
            "payments": [
              {
                "type": "DIVIDENDS",
                "amount": 5400.0,
                "currency": "EUR"
              },
              {
                "type": "GROSS_PROCEEDS_OR_REDEMPTIONS",
                "amount": 122000.0,
                "currency": "EUR"
              }
            ]
          },
          {
            "accountNumber": "LT407300010002061111",
            "accountNumberType": "IBAN",
            "balance": 0.0,
            "currency": "EUR",
            "closed": true,
            "accountType": "DEPOSITORY_ACCOUNT",
            "openingType": "PREEXISTING_ACCOUNT",
            "accountHolder": {
              "selfCertification": "NOT_PROVIDED",
              "individual": {
                "names": [
                  {
                    "firstName": "Jonas",
                    "lastName": "Jonaitis"
                  }
                ],
                "residenceCountryCodes": [
                  "LV"
                ],
                "tins": [
                  {
                    "number": "39001011234",
                    "issuedBy": "LV"
                  }
                ],
                "addresses": [
                  {
                    "addressFree": "Riga, Riga st. 1",
                    "countryCode": "LV",
                    "type": "RESIDENTAL_OR_HABITATION"
                  }
                ],
                "birthInfo": {
                  "birthDate": "1990-05-15",
                  "city": "Riga",
                  "countryCode": "LV"
                }
              }
            }
          }
        ]
        ```

        <Info>
          Send the optional `Idempotency-Key` header so a retry returns the original response instead of pushing the batch twice.
        </Info>

        **Expected Response**: `HTTP 201 Created`

        ```json theme={null}
        [
          {
            "status": "SUCCESS",
            "accountNumber": "LT601010012345678901"
          },
          {
            "status": "SUCCESS",
            "accountNumber": "LT121000011101001000"
          },
          {
            "status": "SUCCESS",
            "accountNumber": "LT407300010002061111"
          }
        ]
        ```
      </Accordion>

      <Accordion title="Test Case 3: Submit" icon="paper-plane">
        **Objective**: Hand the submission off to be reported to the tax authority.

        **Request**: `POST /reports/crs/v1/submissions/{submissionId}:submit`

        No request body.

        **Expected Response**: `HTTP 200 OK`

        <Warning>
          After this call the submission is no longer editable. Push all accounts first.
        </Warning>
      </Accordion>

      <Accordion title="Test Case 4: Track Progress" icon="chart-line">
        **Objective**: Follow the submission until the tax authority accepts it.

        <Info>
          Use these calls instead of the webhook, or alongside it whenever you want to check a submission by hand.
        </Info>

        **Request**: `GET /reports/crs/v1/submissions/{submissionId}/status`

        **Expected Response**: `HTTP 200 OK`

        ```json theme={null}
        {
          "submissionId": "6f1b0c1e-6c0b-4c39-9a2e-1d9d2f0f7a11",
          "status": "PROCESSING"
        }
        ```

        Poll until `status` becomes `REPORTED`

        To check whether any accounts failed CRS validation, call `GET /reports/crs/v1/submissions/{submissionId}/accounts/errors`.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Correct Reported Account">
    To change a year you have already reported, open a correction of it. Corrections use the same endpoints, keyed by `accountNumber`, but each call acts on what the tax authority already holds.

    <AccordionGroup>
      <Accordion title="Test Case 1: Create Correction" icon="rotate">
        **Objective**: Create a correction round for a year you have already reported.

        **Request**: `POST /reports/crs/v1/submissions`

        **Request Body**:

        ```json theme={null}
        {
          "reportingYear": 2025
        }
        ```

        **Expected Response**: `HTTP 201 Created`

        ```json theme={null}
        {
          "submissionId": "b3c9a4d2-1f77-4f0e-8d3a-5c6b7e8f9a01",
          "kind": "CORRECTION"
        }
        ```

        <Info>
          Confirm that `kind` is now `CORRECTION` and use this `submissionId` for the subsequent requests.
        </Info>

        <Warning>
          Only one round per year runs at a time. If the first submission is still being processed, this call returns `HTTP 409`. Wait for it to reach `REPORTED` and try again.
        </Warning>
      </Accordion>

      <Accordion title="Test Case 2: Update Account" icon="pen-to-square">
        **Objective**: Update an already-reported account. Here the balance and the interest changed.

        Send the complete account, not just the changed fields.

        **Request**: `PUT /reports/crs/v1/submissions/{submissionId}/accounts/{accountNumber}`

        **Request Body**:

        ```json theme={null}
        {
          "accountNumber": "LT601010012345678901",
          "accountNumberType": "IBAN",
          "balance": 16980.10,
          "currency": "EUR",
          "accountType": "DEPOSITORY_ACCOUNT",
          "openingType": "PREEXISTING_ACCOUNT",
          "accountHolder": {
            "selfCertification": "PROVIDED",
            "organisation": {
              "type": "REPORTABLE_PERSON",
              "name": "UAB Inventi",
              "nameType": "LEGAL",
              "residenceCountryCodes": ["LV"],
              "tins": [{"number": "39001011234", "issuedBy": "LV"}],
              "addresses": [
                {
                  "addressFree": "Riga, Riga st. 1",
                  "countryCode": "LV",
                  "type": "REGISTRATION"
                }
              ]
            }
          },
          "payments": [
            {"type": "INTEREST", "amount": 205.30, "currency": "EUR"}
          ]
        }
        ```

        **Expected Response**: `HTTP 200 OK`

        ```json theme={null}
        {
          "status": "SUCCESS",
          "accountNumber": "LT601010012345678901"
        }
        ```
      </Accordion>

      <Accordion title="Test Case 3: Submit Correction" icon="paper-plane">
        **Objective**: Send the correction to the tax authority.

        Like the first submission, a correction only reaches the tax authority once you submit it.

        **Request**: `POST /reports/crs/v1/submissions/{submissionId}:submit`

        **Expected Response**: `HTTP 200 OK`

        Track it with `GET .../status` as in the first scenario. You can open as many correction rounds for a year as you need, one at a time.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
