8. Transaction History
GET /api/v1/transactions
Returns PayIn and PayOut operations for the authenticated merchant and selected EPT VND shop.
The endpoint reads one merchant shop. Set shop_code to select it, or use the configured default shop. There is no currency filter: the returned rows use the selected shop's currency. The examples below use VND.
Authentication
Transaction history uses the canonical v2 HMAC-SHA256 request signature.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | API key issued to the merchant. |
X-Timestamp | Yes | ISO-8601 UTC timestamp, for example 2026-09-21T10:00:00Z. The default allowed skew is +/-60 seconds. |
X-Request-Id | Yes | Unique value of 1-128 characters matching [A-Za-z0-9._:-]+. |
X-Signature | Yes | Lowercase hexadecimal HMAC-SHA256 signature. |
The canonical payload consists of these seven lines, joined with one LF byte (0x0A) and without a trailing LF:
v2
GET
/api/v1/transactions
CANONICAL_QUERY
X_TIMESTAMP
X_REQUEST_ID
SHA256_HEX_OF_EMPTY_BODY
CANONICAL_QUERY is recursively sorted by key and encoded using RFC 3986. For the request below it is:
date_from=2026-09-01&date_to=2026-09-21&pagination_mode=cursor&per_page=5&shop_code=your_ept_vnd_shop&transaction_type=all
The SHA-256 hex digest of an empty GET body is e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
transaction_type | string | No | payout, payin, or all. Default: payout. |
shop_code | string | No | Merchant shop code, maximum 64 characters. The default shop is used when omitted. |
status | string | No | Public merchant status from Statuses. It must be valid for the selected transaction type. |
ids | CSV | No | 1-100 unique positive Payfield operation IDs. |
transaction_ids | CSV | No | 1-100 unique merchant external_id values. |
cards | CSV | No | 1-100 exact recipient card or account numbers, each 6-19 digits. |
date_from, date_to | YYYY-MM-DD | No | Inclusive operation creation-date range in UTC. |
finalization_from, finalization_to | YYYY-MM-DD | No | Inclusive finalization-date range in UTC. |
amount_min, amount_max | decimal string | No | Inclusive non-negative VND amount range. |
pagination_mode | string | No | offset (default) or cursor. |
page | integer | No | Offset page, starting from 1. Not allowed in cursor mode. |
cursor | string | No | Opaque cursor from a preceding cursor-mode response. |
per_page | integer | No | Records per page. Default: 50; maximum: 100. |
Unknown parameters, invalid ranges, duplicate or empty CSV values, and amount_min > amount_max return HTTP 422.
Recommended request
GET /api/v1/transactions?transaction_type=all&shop_code=your_ept_vnd_shop&date_from=2026-09-01&date_to=2026-09-21&pagination_mode=cursor&per_page=5
Accept: application/json
X-API-Key: YOUR_API_KEY
X-Timestamp: 2026-09-21T10:00:00Z
X-Request-Id: 019f6b40-c562-77b2-bc42-11b9ac4db85c
X-Signature: CALCULATED_HMAC_SHA256
Example response
{
"transactions": {
"data": [
{
"id": 105,
"status": "success",
"external_id": "PIN-VND-EPT-002",
"amount": "750000",
"currency": "VND",
"shop_code": "your_ept_vnd_shop",
"transaction_type": "payin",
"created_at": "2026-09-21T09:05:00+00:00",
"updated_at": "2026-09-21T09:06:00+00:00",
"finalization_date": "2026-09-21T09:06:00+00:00",
"type": "payIn"
},
{
"id": 104,
"status": "pending",
"external_id": "POUT-VND-EPT-001",
"amount": "250000",
"currency": "VND",
"shop_code": "your_ept_vnd_shop",
"card_number": "0123456789",
"transaction_type": "payout",
"created_at": "2026-09-21T09:04:00+00:00",
"updated_at": "2026-09-21T09:04:00+00:00",
"type": "payOut"
}
],
"path": "https://api.payfield.io/api/v1/transactions",
"per_page": 5,
"next_cursor": "OPAQUE_CURSOR",
"next_page_url": "https://api.payfield.io/api/v1/transactions?...",
"prev_cursor": null,
"prev_page_url": null
}
}
Rows are ordered by created_at descending and then by id descending. status is a public merchant status, not an internal EPT workflow status. Optional fields with no value are omitted. type is always payIn or payOut.
Pagination
| Mode | Request | Response |
|---|---|---|
| Offset | Omit pagination_mode or send offset; use page. | Includes Laravel offset pagination metadata and total. |
| Cursor | Send pagination_mode=cursor; repeat all filters with the returned cursor. | Includes next_cursor, prev_cursor, and cursor URLs without calculating total. |
Use a fresh X-Timestamp, X-Request-Id, and signature for every page request. If the cards filter is used, pagination URLs are omitted to avoid reflecting recipient data into URLs; repeat the filter explicitly with page or cursor.
Response fields
| Field | Applies to | Description |
|---|---|---|
id | Both | Payfield operation ID. |
external_id | Both | Merchant operation identifier. |
status | Both | Public merchant status. |
amount, old_amount | Both | Decimal strings in VND; old_amount is omitted when unavailable. |
currency | Both | ISO currency code (VND). |
shop_code | Both | Shop that owns the operation. |
card_number | PayOut | Recipient account number when configured in the merchant response schema. |
merchant_user_id, merchant_user_ip | Both | Merchant-side user references when supplied. |
callback_url | Both | Callback URL when supplied. |
transaction_type | Both | Technical value: payin or payout. |
type | Both | Canonical value: payIn or payOut. |
created_at, updated_at, finalization_date | Both | ISO-8601 timestamps; finalization_date is omitted when unavailable. |
paymentData, payment_page_url, payment_page_expires_at | PayIn | Merchant-visible payment data and hosted-page fields when configured. |
Errors
| HTTP | Condition |
|---|---|
401 | Missing or invalid API key, timestamp, signature, or request ID; expired timestamp; or replay. |
403 | Source IP is not allowed when the merchant IP whitelist is enabled. |
422 | Invalid filters or shop resolution failure. |
429 | Rate limit exceeded. |
503 | Replay-protection storage is unavailable. |
See API Errors for errors shared with other merchant endpoints.