Skip to content
DLTdevelopers
Sign in
DLT Merchant Portal/Collections Public documentation

Collection transactions

For DLT Merchant Portal developers · DLT maintainers · Contract v1.7

Configured API origin: https://stage-checkout.dxp.dtic.com.ph

Build with the right credentials. API access requires the documented authentication and permissions. Examples use synthetic data and placeholder origins.

8. Collection transactions — Read-only

8.1 Portal transaction APIs

Both roles may call these endpoints with a user PAT:

Method and path Purpose
GET /portal/collections/transactions Paginated merchant transactions
GET /portal/collections/transactions/{transaction_id} One transaction by internal numeric ID

transaction_id is the internal numeric ID. Both endpoints require environment, exactly test or live; the server combines the authenticated merchant, stored is_production flag, and detail ID. A mismatch returns 404 NOT_FOUND. Legacy transaction_type and APN context labels do not override the stored environment flag. Missing/invalid environment returns 422 VALIDATION_ERROR. Positive canonical decimal IDs accept at most 20 digits; malformed or inaccessible IDs return 404. The detail Form Request validates the route ID and accepts only the environment query, rejecting caller-supplied ID/filter overrides.

Both endpoints require the signed-in Portal user to have merchant-portal-read permission.

Query Contract
environment Required: test or live
from, to Optional paired calendar ISO 8601 instants with seconds, Z or explicit ±HH:MM, and optional 1–6 fractional digits; from < to; creation-time interval [from, to)
status Optional PAID, PENDING, or REJECTED
merchant_transaction_id Optional exact match, maximum 100 characters
query Optional reference substring search, maximum 100 characters
currency Optional three-letter uppercase code in the existing currency catalogue
payment_brand Optional exact stored brand value, maximum 100 characters
page, per_page Common pagination limits

Supplied filters combine using AND on the server. If dates are omitted, list all stored collection transactions in the environment, including archived records. Sort by created_at DESC, id DESC; page defaults to 1, page size to 25, with per_page 1–100. Empty or out-of-range pages return 200, empty data, and normal meta. Unexpected fields and invalid filters return 422 VALIDATION_ERROR; conflicting merchant selectors are rejected earlier with 403 MERCHANT_SCOPE_MISMATCH.

Dates require real calendar instants and offsets up to ±14:00. Offsetless/date-only values, impossible dates, unmatched bounds, and equal/reversed instants are rejected. Bounds are converted to config('app.timezone') (currently Asia/Singapore) to compare against the existing offsetless Laravel database timestamps. The start is inclusive and end exclusive; fractional bounds are preserved. This assumes existing stored timestamps follow that application timezone, which must be checked before deployment against imported/legacy data.

query searches merchant references; %, _ and ! are literal characters. Reference/brand/currency matching follows database collation. Unsupported currencies return 422; an unavailable catalogue returns 503 SERVICE_UNAVAILABLE for currency-filtered reads. Reads without the currency filter remain available.

Example request:

GET /api/v1/portal/collections/transactions?environment=test&from=2026-09-01T00%3A00%3A00Z&to=2026-10-01T00%3A00%3A00Z&status=PAID&page=1&per_page=25
Authorization: Bearer <user_pat>

Transaction data object:

{
  "id": 1001,
  "merchant_transaction_id": "ORDER202610010001",
  "environment": "test",
  "amount": "1500.00",
  "currency": "PHP",
  "status": "PAID",
  "payment_brand": "Example brand",
  "payment_method": null,
  "created_at": "2026-10-01T08:00:00+08:00",
  "updated_at": "2026-10-01T08:01:00+08:00",
  "history_available": true
}

List uses the standard Portal success/message/data/meta envelope; detail uses success/message/data, message Success. Both project exactly the fields above and return Cache-Control: no-store, private. Amount is a two-decimal string via BCMath, or null when the legacy value is missing. Other missing legacy values/timestamps remain null. The current collection schema has no payment_method column; The API returns null rather than inferring it from a provider or gateway. Customer identifiers, raw callback/return URLs, provider credentials/context, payloads, fees, and arbitrary legacy reference data are excluded.

Status is normalized to PAID, PENDING or REJECTED. Recognized payment_status wins case-insensitively; otherwise legacy S means paid, R means rejected, and other values mean pending. Lists and reporting use the same status rules.

history_available is true when unpurged, permitted merchant ↔ DLT evidence exists for that transaction/environment. It does not guarantee readable bodies or complete history. Expired retention still counts until actual purge.

These GETs only read stored data. They do not write transaction/evidence records, create payments, inquire with providers, reconcile, or replay callbacks; no Portal mutation route is introduced. The existing API-wide 60/minute throttle applies. Both roles require an active merchant membership, authorized ecosystem PAT, and merchant-portal scope.

8.2 Request validation reference

These tables reflect the current implementation’s request rules. See input conventions for required/optional/null behavior and error formats.

Validation: GET /api/v1/portal/collections/transactions

Field Location Requirement Validation rules
page Query Optional; default 1 Integer, minimum 1. Null/empty values are invalid.
per_page Query Optional; default 25 Integer, 1–100 inclusive. Null/empty values are invalid.
environment Query Required String; exactly test or live, case-sensitive.
from Query Optional pair; required with to String in YYYY-MM-DDTHH:mm:ss[.ffffff]Z or YYYY-MM-DDTHH:mm:ss[.ffffff]±HH:MM format; real calendar date/time, nonzero year, seconds required, optional 1–6 fractional digits, offset up to ±14:00. Date-only, offsetless and impossible instants are invalid.
to Query Optional pair; required with from String in YYYY-MM-DDTHH:mm:ss[.ffffff]Z or YYYY-MM-DDTHH:mm:ss[.ffffff]±HH:MM format; real calendar date/time, nonzero year, seconds required, optional 1–6 fractional digits, offset up to ±14:00. Date-only, offsetless and impossible instants are invalid. Must be strictly later than from.
status Query Optional; required if supplied String; exactly PAID, PENDING or REJECTED.
merchant_transaction_id Query Optional; required if supplied Nonempty string, maximum 100 characters; exact reference match.
query Query Optional; required if supplied Nonempty string, maximum 100 characters; reference substring search; %, _ and ! are literal characters.
currency Query Optional; required if supplied String; exactly three uppercase ASCII letters and present in DLT’s currency catalogue. Unsupported code returns 422; unavailable catalogue returns 503.
payment_brand Query Optional; required if supplied Nonempty string, maximum 100 characters; exact stored-brand match.

Send no request body. Send both date bounds or neither; from < to; no reporting-specific ten-year or bucket limit is applied to this list. Filters combine with AND. Unlisted payload/query fields are rejected with 422 VALIDATION_ERROR. A conflicting merchant selector may instead be rejected earlier with 403 MERCHANT_SCOPE_MISMATCH.

Validation: GET /api/v1/portal/collections/transactions/{transaction}

Field Location Requirement Validation rules
transaction Path Required Positive canonical decimal ID, 1–20 digits; pattern [1-9][0-9]{0,19}. No leading zero, sign or decimal point. Malformed, missing or inaccessible resources return 404 NOT_FOUND.
environment Query Required String; exactly test or live, case-sensitive.

Send no request body. Only environment is accepted as input outside the path. Do not resend route IDs or list filters in JSON/query. Unlisted payload/query fields are rejected with 422 VALIDATION_ERROR. A conflicting merchant selector may instead be rejected earlier with 403 MERCHANT_SCOPE_MISMATCH. The transaction must belong to this merchant and the selected environment.

8.3 Complete transaction read examples

The following are synthetic request/response pairs. Replace IDs and credential placeholders with values from your environment. GET requests have no body; filters belong in the query string. Examples show successful operations; validation and access rules above still apply.

GET /portal/collections/transactions

Request (no body):

GET /api/v1/portal/collections/transactions?environment=test&page=1&per_page=25
Accept: application/json
Authorization: Bearer <user_pat>

Response: 200.

{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": 1001,
      "merchant_transaction_id": "ORDER202610010001",
      "environment": "test",
      "amount": "1500.00",
      "currency": "PHP",
      "status": "PAID",
      "payment_brand": "Example brand",
      "payment_method": null,
      "created_at": "2026-10-01T08:00:00+08:00",
      "updated_at": "2026-10-01T08:01:00+08:00",
      "history_available": true
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 25,
    "total": 1,
    "last_page": 1
  }
}

GET /portal/collections/transactions/1001

Request (no body):

GET /api/v1/portal/collections/transactions/1001?environment=test
Accept: application/json
Authorization: Bearer <user_pat>

Response: 200.

{
  "success": true,
  "message": "Success",
  "data": {
    "id": 1001,
    "merchant_transaction_id": "ORDER202610010001",
    "environment": "test",
    "amount": "1500.00",
    "currency": "PHP",
    "status": "PAID",
    "payment_brand": "Example brand",
    "payment_method": null,
    "created_at": "2026-10-01T08:00:00+08:00",
    "updated_at": "2026-10-01T08:01:00+08:00",
    "history_available": true
  }
}
DLT Developer Documentation · Updated October 2, 2026