> ## 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 payees and payments for a quarter, 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 Payments">
    Create a submission for a quarter and country, push your payees, attach their payments, then submit.

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

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

        **Request Body**:

        ```json theme={null}
        {
          "year": 2025,
          "quarter": 1,
          "countryCode": "DE",
          "webhookUrl": "https://example.com/cesop/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/cesop/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"
        }
        ```

        <Info>
          Store the `submissionId`. It scopes every call in Test Cases 2 to 5.
        </Info>
      </Accordion>

      <Accordion title="Test Case 2: Push Payees" icon="users">
        **Objective**: Add the payees you report for the quarter. Call this as many times as you need.

        **Request**: `POST /reports/cesop/v1/submissions/{submissionId}/payees`

        **Request Body**:

        ```json theme={null}
        [
          {
            "clientPayeeId": "PAYEE-001",
            "names": [
              {
                "value": "Muster Handel GmbH",
                "type": "LEGAL"
              }
            ],
            "countryCode": "DE",
            "addresses": [
              {
                "countryCode": "DE",
                "addressFree": "Berlin, Musterstrasse 1",
                "type": "REGISTERED_OFFICE"
              }
            ],
            "emails": [
              "info@muster-handel.de"
            ],
            "webPages": [
              "https://muster-handel.de"
            ],
            "taxes": [
              {
                "number": "DE123456789",
                "issuedBy": "DE",
                "type": "VAT"
              }
            ],
            "accounts": [
              {
                "number": "DE89370400440532013000",
                "type": "IBAN",
                "countryCode": "DE"
              },
              {
                "number": "DE75512108001245126199",
                "type": "IBAN",
                "countryCode": "DE"
              },
              {
                "number": "COBADEFFXXX",
                "type": "BIC",
                "countryCode": "DE"
              }
            ]
          },
          {
            "clientPayeeId": "PAYEE-002",
            "names": [
              {
                "value": "Beispiel Markt",
                "type": "TRADE"
              }
            ],
            "countryCode": "DE",
            "addresses": [],
            "emails": [],
            "webPages": [],
            "taxes": [
              {
                "number": "DE987654321",
                "issuedBy": "DE",
                "type": "VAT"
              }
            ],
            "accounts": [],
            "representative": {
              "representativeId": "DEUTDEFFXXX",
              "type": "BIC",
              "names": [
                {
                  "value": "Deutsche Bank AG",
                  "type": "LEGAL"
                }
              ]
            }
          }
        ]
        ```

        <Info>
          `clientPayeeId` is your own key. It must be unique within the submission, and it is how you attach payments and update or delete the payee later. 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",
            "clientPayeeId": "PAYEE-001",
            "errors": []
          },
          {
            "status": "SUCCESS",
            "clientPayeeId": "PAYEE-002",
            "errors": []
          }
        ]
        ```
      </Accordion>

      <Accordion title="Test Case 3: Push Payments" icon="money-bill-transfer">
        **Objective**: Attach payments to a payee you pushed.

        **Request**: `POST /reports/cesop/v1/submissions/{submissionId}/payments`

        **Request Body**:

        ```json theme={null}
        [
          {
            "payeeClientId": "PAYEE-001",
            "payeeAccountNumber": "DE89370400440532013000",
            "transactionId": "TX-2025-0001",
            "refund": false,
            "amount": 100.21,
            "currency": "EUR",
            "paymentDates": [
              {
                "dateTime": "2025-02-14T10:15:30Z",
                "type": "EXECUTION"
              }
            ],
            "paymentMethodType": "CARD",
            "initiatedOnPremises": false,
            "payerCountryCode": "FR",
            "payerAccountType": "IBAN",
            "pspRoleType": "ACQUIRER"
          },
          {
            "payeeClientId": "PAYEE-001",
            "payeeAccountNumber": "DE89370400440532013000",
            "transactionId": "TX-2025-0002",
            "refund": true,
            "refundedTransactionId": "TX-2025-0001",
            "amount": -100.21,
            "currency": "EUR",
            "paymentDates": [
              {
                "dateTime": "2025-02-20T09:00:00Z",
                "type": "EXECUTION"
              }
            ],
            "paymentMethodType": "CARD",
            "initiatedOnPremises": false,
            "payerCountryCode": "FR",
            "payerAccountType": "IBAN",
            "pspRoleType": "ACQUIRER"
          }
        ]
        ```

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

        ```json theme={null}
        [
          {
            "status": "SUCCESS",
            "transactionId": "TX-2025-0001",
            "errors": []
          },
          {
            "status": "SUCCESS",
            "transactionId": "TX-2025-0002",
            "errors": []
          }
        ]
        ```

        <Info>
          The second entry is a refund: `"refund": true` with `refundedTransactionId` naming the transaction it reverses.
        </Info>
      </Accordion>

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

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

        No request body.

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

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

      <Accordion title="Test Case 5: Track Progress" icon="chart-line">
        **Objective**: Follow the submission until the regulatory 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/cesop/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 payees failed CESOP validation, call `GET /reports/cesop/v1/submissions/{submissionId}/payees/errors`.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Correct Reported Payee">
    To correct a payee you already reported, create a submission for the same period and country again. The same endpoints now act on what the regulatory authority already holds.

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

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

        **Request Body**:

        ```json theme={null}
        {
          "year": 2025,
          "quarter": 1,
          "countryCode": "DE"
        }
        ```

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

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

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

      <Accordion title="Test Case 2: Update Payee" icon="pen-to-square">
        **Objective**: Update a payee you already reported.

        Send the complete payee with your corrected values, not just the changed fields.

        **Request**: `PUT /reports/cesop/v1/submissions/{submissionId}/payees/{clientPayeeId}`

        **Request Body**:

        ```json theme={null}
        {
          "clientPayeeId": "PAYEE-001",
          "names": [
            {
              "value": "Muster Handel GmbH",
              "type": "LEGAL"
            }
          ],
          "countryCode": "DE",
          "addresses": [
            {
              "countryCode": "DE",
              "addressFree": "Berlin, Musterstrasse 1",
              "type": "REGISTERED_OFFICE"
            }
          ],
          "emails": [
            "info@muster-handel.de"
          ],
          "webPages": [
            "https://muster-handel.de"
          ],
          "taxes": [
            {
              "number": "DE123456789",
              "issuedBy": "DE",
              "type": "VAT"
            }
          ],
          "accounts": [
            {
              "number": "DE89370400440532013000",
              "type": "IBAN",
              "countryCode": "DE"
            },
            {
              "number": "DE75512108001245126199",
              "type": "IBAN",
              "countryCode": "DE"
            },
            {
              "number": "COBADEFFXXX",
              "type": "BIC",
              "countryCode": "DE"
            }
          ]
        }
        ```

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

        ```json theme={null}
        {
          "status": "SUCCESS",
          "clientPayeeId": "PAYEE-001",
          "errors": []
        }
        ```
      </Accordion>

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

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

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

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

        Track it with `GET .../status` as in the first scenario. You can check whether any payees had errors with `GET .../payees/errors`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
