Z Zise Developers 简体中文

Card transactions (cursor pagination)

GET /v1/cards/{id}/transactions scope: cards:read
On behalf of a member · x-on-behalf-of required

Always read direction as well. amount is an absolute value, guaranteed nonnegative by a database CHECK. Looking only at the amount makes a refund indistinguishable from a purchase.

amount is the displayed amount in the card currency, an integer string in the smallest unit with precision scale: it uses the card balance movement when available, otherwise the authorization hold. Its meaning is unchanged.

Additive fields that do not change amount:

  • original_amount / original_currency: the upstream transaction's original amount and currency, preserving txn_amount exactly as stored. Cross-border POS transactions often use IDR/HKD, etc.; this is not the card currency.
  • bill_amount: the card-currency bill, an integer string in the smallest unit using the same currency/scale as amount. Uses only stored card-currency figures from the upstream: the settlement amount when settle_currency matches the card currency, otherwise the authorization hold, otherwise the stored card-currency figure used for amount. It never converts the original currency to dollars using a current exchange rate. Omitted when no bill amount is known (returns "0" only when amount is also "0").

Transaction updates are announced by card.transaction.updated; this endpoint also supports querying the current state. bank_fee is the bank fee; zinfra_fee is the zinfra fee (currently "0" for all cards). Both fee fields are integer strings in the smallest unit; use fee_currency for the currency and fee_scale for precision. Fees are cumulative snapshots for the transaction, not additional debits introduced by this notification. Authorization shows currently known fees; settlement may update them. Do not add fees again to card amounts that already include them.

Path Parameters

FieldTypeRequiredDescription
id string Required Card ID

Query Parameters

FieldTypeRequiredDescription
cursor string Optional The previous page's next_cursor (an opaque string).
limit integer Optional Defaults to 20, maximum 100.
FieldTypeRequiredDescription
x-on-behalf-of string Required The member on whose behalf to call.

Response

200OK (ordered by occurrence time descending).
{
  "data": [
    {
      "id": "ctx_2c9e4b10-77af-4d3a-8e51-b0d6c2f9a134",
      "kind": "auth",
      "status": "succeed",
      "direction": "debit",
      "amount": "12990000",
      "currency": "USD",
      "scale": 6,
      "original_amount": "199000.00",
      "original_currency": "IDR",
      "bill_amount": "12990000",
      "bank_fee": "30000",
      "zinfra_fee": "0",
      "fee_currency": "USD",
      "fee_scale": 6,
      "merchant_name": "NETFLIX.COM",
      "mcc": "4899",
      "auth_code": "084217",
      "occurred_at": "2026-08-09T10:55:02.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
404not_found: the card does not exist or does not belong to this member/merchant.
500api_error: service error.
Request
curl -X GET 'https://api.zinfra.vip/v1/cards/{id}/transactions' \
  -H 'x-auth-token: Bearer $TOKEN' \
  -H 'x-on-behalf-of: $MEMBER_ID'
const res = await fetch("https://api.zinfra.vip/v1/cards/{id}/transactions", {
  method: "GET",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
    "x-on-behalf-of": "$MEMBER_ID",
  },
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.get(
    "https://api.zinfra.vip/v1/cards/{id}/transactions",
    headers={
        "x-auth-token": "Bearer $TOKEN",
        "x-on-behalf-of": "$MEMBER_ID",
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("GET", "https://api.zinfra.vip/v1/cards/{id}/transactions",
    nil)
req.Header.Set("x-auth-token", "Bearer $TOKEN")
req.Header.Set("x-on-behalf-of", "$MEMBER_ID")
res, err := http.DefaultClient.Do(req)
// Decode amount fields as string, not float64.
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.zinfra.vip/v1/cards/{id}/transactions"))
    .header("x-auth-token", "Bearer $TOKEN")
    .header("x-on-behalf-of", "$MEMBER_ID")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/cards/{id}/transactions');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
    'x-on-behalf-of: $MEMBER_ID',
  ],
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
200
{
  "data": [
    {
      "id": "ctx_2c9e4b10-77af-4d3a-8e51-b0d6c2f9a134",
      "kind": "auth",
      "status": "succeed",
      "direction": "debit",
      "amount": "12990000",
      "currency": "USD",
      "scale": 6,
      "original_amount": "199000.00",
      "original_currency": "IDR",
      "bill_amount": "12990000",
      "bank_fee": "30000",
      "zinfra_fee": "0",
      "fee_currency": "USD",
      "fee_scale": 6,
      "merchant_name": "NETFLIX.COM",
      "mcc": "4899",
      "auth_code": "084217",
      "occurred_at": "2026-08-09T10:55:02.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}