Skip to main content
This page shows how to make the sandbox return each outcome you need to handle. Every request here is an ordinary API request with data you choose. Each result comes from the API’s rules, which are linked to the matching problem page or concept.
There are no special test IDs, magic amounts or trigger values in the sandbox yet. No particular externalCustomerId, amount or sourceReference makes the API fail on purpose. You produce each outcome by sending a request that really breaks the rule, as shown below.

Before you start

  • Use a sandbox key and your clientCode. See Get a sandbox key.
  • Make your IDs unique for each run, for example by adding a run number: REC_A_RUN7. The API has no delete operation and no sandbox reset, so a repeat of an ID is a replay of the earlier record. The certification harness does the same.
  • Send requests one at a time. A key allows one request in flight, so a second concurrent request returns 429 rate_limit_exceeded.
  • Feed mode matters. A connection is either transaction (the default) or snapshot_only. It is a setting on your connection, not a field you send. PayPathIQ sets it. If you need the other mode, ask your PayPathIQ Integration administrator. See Source balance snapshots.
The examples use two Receivables you create first, following the sandbox quickstart or the credit union guide: REC_A for EUR 1,000.00 and REC_B for EUR 400.00, both at sourceRevision 1, for one Customer CUS_1.

Replays and conflicts

An identical repeat is a safe replay and returns 200. The same ID with different content is refused. Nothing is saved when a request is refused.

Payments and allocations (transaction mode)

Allocation means saying which Receivable a payment pays. Money you do not allocate stays unapplied, which means it reduces no balance. See Payment observations.
1

Allocate part of a payment

PUT /v1/clients/{clientCode}/payment-observations/PAY_1:
You get 201 with unappliedAmount of EUR 50.00. REC_A now reads EUR 750.00.
2

Allocate more than the balance

A payment of EUR 500.00 allocating EUR 500.00 to REC_B (balance EUR 400.00) returns 409 allocation_exceeds_balance. The payment itself is not saved either.
3

Refund more than was allocated

A refund with relatedExternalPaymentObservationId set to PAY_1 and an amount and allocation of EUR 260.00 to REC_A returns 409 payment_observation_conflict. The total of corrections cannot exceed the EUR 250.00 the payment allocated to REC_A.
4

Refund part of it

A refund of EUR 50.00 with an allocation of EUR 40.00 to REC_A returns 201. EUR 10.00 is unapplied from the refund. REC_A reads EUR 790.00.
In snapshot_only mode every one of these event writes (payments, refunds, reversals, credit notes, adjustments, write-offs) returns 409 financial_operation_required. That is the outcome to test in that mode.

Balance snapshots

A snapshot is an ordered set of Source balances. sourcePosition must rise with every snapshot you send, and asOf is a UTC time that is not in the future. Send PUT /v1/clients/{clientCode}/balance-snapshots/SNAP_n. pending_payment_overlap_unknown is the other hold reason. It needs a Payment that a payment provider confirmed, with an effective time at or before the snapshot’s asOf, that the Source has not yet acknowledged. A hosted payment is confirmed only by a verified provider event, which an API call cannot fake. So you cannot make this hold from the API alone. Test your handling of held with source_balance_mismatch, and treat any held outcome as a hold, whatever holdReason says.

Change feed and webhooks

Other outcomes

Sandbox limits

The only sandbox-specific limit is the per-Client rate limit. The others apply in production too. Sandbox sends messages only to recipients on PayPathIQ’s sandbox allowlist. Payment integrations use test-mode credentials. See Environments.

What is not available yet

  • Special IDs or amounts that trigger specific outcomes.
  • A sandbox reset or delete operation.
  • A test-event endpoint for webhooks.
  • A way to expire a change-feed cursor early.
  • A way to switch your own connection between transaction and snapshot_only.