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

# Report a payment

> Tell PayPathIQ about money you received outside PayPathIQ, and what to do if the response is lost.

A [Payment observation](/glossary) is a record of money you received outside PayPathIQ. It is immutable evidence. It does not collect or move money. Use the same record type for refunds and reversals. Finish the [quickstart](/quickstart) first so you have a key and a `clientCode`.

## Before you report

* The Receivable must exist. An allocation to a missing Receivable returns `409 dependency_missing`.
* The Receivable's Source balance and working balance must match. If they differ, a new payment, refund or reversal returns `409 financial_operation_required`. Read the Receivable and resolve the difference first.
* Choose the payment's ID once, and reuse it for every retry. See [Safe retries](/idempotency).

## Step 1: Send the payment

Allocate the money to one or more Receivables. A Receivable may appear once in `allocations`, and the total may not exceed `amount`.

<CodeGroup>
  ```bash curl theme={null}
  curl --include \
    --request PUT \
    --url "$PAYPATHIQ_BASE_URL/v1/clients/$PAYPATHIQ_CLIENT_CODE/payment-observations/PAY_B001" \
    --header "Authorization: Bearer $PAYPATHIQ_SANDBOX_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
      "type": "payment",
      "amount": { "amount": "250.00", "currency": "EUR" },
      "allocations": [{
        "externalReceivableId": "REC_B001",
        "amount": { "amount": "250.00", "currency": "EUR" }
      }],
      "effectiveAt": "2026-09-21T12:00:00Z",
      "method": "bank_transfer",
      "sourceReference": "payment-ref-b001"
    }'
  ```

  ```javascript JavaScript theme={null}
  const base = "https://api.sandbox.paypathiq.com";
  const clientCode = process.env.PAYPATHIQ_CLIENT_CODE;

  const response = await fetch(`${base}/v1/clients/${clientCode}/payment-observations/PAY_B001`, {
    method: "PUT",
    headers: {
      Authorization: `Bearer ${process.env.PAYPATHIQ_SANDBOX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      type: "payment",
      amount: { amount: "250.00", currency: "EUR" },
      allocations: [
        { externalReceivableId: "REC_B001", amount: { amount: "250.00", currency: "EUR" } },
      ],
      effectiveAt: "2026-09-21T12:00:00Z",
      method: "bank_transfer",
      sourceReference: "payment-ref-b001",
    }),
  });
  console.log(response.status, await response.json());
  ```

  ```python Python theme={null}
  import os
  import requests

  base = "https://api.sandbox.paypathiq.com"
  client_code = os.environ["PAYPATHIQ_CLIENT_CODE"]

  response = requests.put(
      f"{base}/v1/clients/{client_code}/payment-observations/PAY_B001",
      headers={"Authorization": f"Bearer {os.environ['PAYPATHIQ_SANDBOX_API_KEY']}"},
      json={
          "type": "payment",
          "amount": {"amount": "250.00", "currency": "EUR"},
          "allocations": [
              {"externalReceivableId": "REC_B001", "amount": {"amount": "250.00", "currency": "EUR"}}
          ],
          "effectiveAt": "2026-09-21T12:00:00Z",
          "method": "bank_transfer",
          "sourceReference": "payment-ref-b001",
      },
      timeout=30,
  )
  print(response.status_code, response.json())
  ```
</CodeGroup>

**Expect `201 Created`.** The response lists the resolved `allocations`, an `allocationBasis` of `explicit`, and the `unappliedAmount`. Money you do not allocate stays unapplied and does not reduce any Receivable.

Without `allocations`, a Client-approved allocation rule may apply. Otherwise the whole amount stays unapplied. PayPathIQ never assumes oldest-first.

## Step 2: Check the Receivable

`GET` the Receivable. Its `recoverableAmount` has dropped by the allocated amount. `financialPosition` shows the Source, working and unreconciled amounts.

## Step 3: Handle a lost response

If you got no response, repeat the identical request with the same ID.

| What comes back | What it means |
| - | - |
| `200 OK` | The first request was saved. The money was not applied twice. |
| `201 Created` | The first request was never saved. This one created the observation. |
| `409 payment_observation_conflict` | The ID already exists with different content. Do not change the payload to match; read the record and decide. |
| `429` or `503` | Wait for `Retry-After` or back off, then repeat. |

## Refunds and reversals

Send `"type": "refund"` or `"type": "reversal"` with a new ID and `relatedExternalPaymentObservationId` set to the original payment. The amount can be partial. Its `allocations` return amounts to the Receivables that payment was allocated to. It records evidence and never executes a transfer. See [Payment observations](/concepts#payment-observations).

## Next steps

* [Stay in sync with the change feed](/stay-in-sync)
* [Errors and retries](/errors-and-retries)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.