Skip to main content

PDV — My sales

History of the PDV's own charges — unifies both methods (printed QR + PIN and dynamic QR/NFC) into one list, ordered by date. Self-service: always your own sales, never another PDV's — identified from your own token, no parameter to see someone else's.

EndpointWhat it does
GET /v1/events/{eventId}/pdv/transactionsLists this PDV's sales/attempts, cursor-paginated.
curl "http://127.0.0.1:8787/v1/events/{eventId}/pdv/transactions?limit=20" \
-H "Authorization: Bearer <PDV accessToken>"
Response
{
"items": [
{
"transactionId": "018f26d7-...",
"channel": "dynamic_qr",
"amountMinor": 2500,
"status": "approved",
"declineReason": null,
"occurredAt": "2026-09-10T18:30:00.000Z",
"resolvedAt": "2026-09-10T18:30:12.000Z"
},
{
"transactionId": "018f26d7-...",
"channel": "printed_qr_pin",
"amountMinor": 1200,
"status": "declined",
"declineReason": "CREDENTIAL_LOCKED",
"occurredAt": "2026-09-10T18:25:00.000Z",
"resolvedAt": "2026-09-10T18:25:00.000Z"
}
],
"nextCursor": null
}

channel tells which of the two methods produced that row — dynamic_qr (dynamic QR/NFC) or printed_qr_pin (printed QR + PIN). status is pending | approved | declined | expired; only dynamic_qr can ever be pending — a printed-QR sale is already resolved (approved or declined) the moment it's created, there's no intermediate state in that flow. declineReason is only set when status is declined, using the same codes already documented on each method's own page (INSUFFICIENT_BALANCE, CREDENTIAL_LOCKED, CREDENTIAL_EXPIRED, CREDENTIAL_NOT_ACTIVE, WALLET_NOT_ACTIVE).

resolvedAt is only null while a dynamic_qr transaction is still pending (waiting on the participant) — everything else already has it set. An intent nobody ever resolved takes up to ~15 seconds after expiresAt to show up here as expired — that's when an internal process notices it's overdue (see Dynamic payment via QR/NFC for the detail).

What doesn't show up here​

  • A printed QR with a wrong PIN that hasn't locked the credential yet (attempts 1 through 4 of 5) doesn't create a row at all — only the attempt that actually locks the credential (the 5th wrong one) shows up, as declined / CREDENTIAL_LOCKED.
  • A QR (printed or dynamic) for the wrong or an unknown event also doesn't show up — that case stays deliberately ambiguous for security reasons (see Payment via printed QR + PIN).

Filters and pagination​

Cursor-paginated (not numbered pages): when nextCursor comes back non-null, call again with ?cursor=<value> for the next batch — keep the same sortDirection/filters as the original call, or the API rejects with PDV_TRANSACTIONS_CURSOR_SORT_MISMATCH.

ParameterWhat it does
channeldynamic_qr or printed_qr_pin — one method at a time.
statuspending, approved, declined, or expired.
occurredAfter / occurredBeforeDate range, ISO 8601, inclusive on both ends.
sortDirectionasc or desc (default: desc, newest first).
limit1 to 100 (default 50).

All optional and combinable — with no filter at all, returns everything (both methods), newest first.