Procare Pay Integration Service

Complete API Documentation for Payment Processing

Search Transactions

GET /v1/rest/merchants/{merchantId}/transactions

Description: Searches and retrieves transactions for a given merchant using various query parameters. This endpoint allows you to filter transactions by date range, amount, payment method, and other criteria to find specific transactions or generate reports.

What is this endpoint used for?

Think of this as searching through receipts. You can filter by:

  • Date ranges - "Show me all transactions from last month"
  • Amount ranges - "Show me all transactions over $100"
  • Payment method - "Show me all transactions from a specific credit card"
  • Order ID - "Find the transaction for order #12345"
  • Location - "Show me all transactions from store #5"

Path Parameters

merchantId (required)
Type: string
Description: The merchant identifier (BAM ID or TEID)

Query Parameters

All query parameters are optional, but you should provide at least one to narrow down your search results.

Parameter Type Description
orderid string The order identifier to filter by
transactiondate date-time The start of the transaction date range (format: ISO 8601, e.g., "2026-01-01T00:00:00Z")
transactionenddate date-time The end of the transaction date range
minimumamount decimal The minimum transaction amount to include (e.g., 10.00)
maximumamount decimal The maximum transaction amount to include (e.g., 500.00)
last4 string The last four digits of the account number to filter by (e.g., "1234")
payorid string The payor/profile identifier to filter by
savedpaymentmethodid string The saved payment method/account identifier to filter by
attributename string The custom attribute name to filter by (use with attributevalues)
attributevalues array The list of values for the custom attribute
locationid integer The location/school ID to filter by
returnordeclinedate date-time The start of the return or decline date range
returnordeclineenddate date-time The end of the return or decline date range
sponsorkey string The sponsor key to filter by
pagesize integer (1–500) Maximum number of transactions to return per page (maximum: 500). When provided, the response is wrapped in a PaginatedTransactionResponse envelope instead of a bare array. Omit to retrieve all matching results in a single response (legacy behavior).
pagecursor string Opaque cursor token for fetching the next page. Use the value of pagination.nextCursor from the previous response. Only meaningful when pagesize is also provided.

Authentication

This endpoint requires bearer token authentication using the Authorization header.

Note: The bearer token must be a valid Cognito token.

Code Examples

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Web;

public class TransactionClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl = "https://your-api-domain.com";
    private readonly string _bearerToken;

    public TransactionClient(string bearerToken)
    {
        _bearerToken = bearerToken;
        _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri(_baseUrl);
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", _bearerToken);
        _httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<string> SearchTransactionsAsync(
        string merchantId,
        Dictionary<string, string> filters = null)
    {
        try
        {
            // Build query string from filters
            var queryParams = HttpUtility.ParseQueryString(string.Empty);
            if (filters != null)
            {
                foreach (var filter in filters)
                {
                    queryParams[filter.Key] = filter.Value;
                }
            }

            string queryString = queryParams.ToString();
            string endpoint = $"/v1/rest/merchants/{merchantId}/transactions";
            if (!string.IsNullOrEmpty(queryString))
            {
                endpoint += $"?{queryString}";
            }

            HttpResponseMessage response = await _httpClient.GetAsync(endpoint);
            response.EnsureSuccessStatusCode();

            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Request error: {e.Message}");
            throw;
        }
    }
}

// Example usage: Search by date range
var client = new TransactionClient("your-bearer-token-here");
var filters = new Dictionary<string, string>
{
    { "transactiondate", "2026-01-01T00:00:00Z" },
    { "transactionenddate", "2026-01-31T23:59:59Z" },
    { "minimumamount", "10.00" }
};

string transactions = await client.SearchTransactionsAsync("12345678901", filters);
Console.WriteLine(transactions);

// Example: Search by order ID
var orderFilter = new Dictionary<string, string>
{
    { "orderid", "ORD-2026-001" }
};

string orderTransactions = await client.SearchTransactionsAsync("12345678901", orderFilter);
Imports System
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports System.Collections.Generic
Imports System.Web

Public Class TransactionClient
    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _baseUrl As String = "https://your-api-domain.com"
    Private ReadOnly _bearerToken As String

    Public Sub New(bearerToken As String)
        _bearerToken = bearerToken
        _httpClient = New HttpClient()
        _httpClient.BaseAddress = New Uri(_baseUrl)
        _httpClient.DefaultRequestHeaders.Authorization =
            New AuthenticationHeaderValue("Bearer", _bearerToken)
        _httpClient.DefaultRequestHeaders.Accept.Add(
            New MediaTypeWithQualityHeaderValue("application/json"))
    End Sub

    Public Async Function SearchTransactionsAsync(
        merchantId As String,
        Optional filters As Dictionary(Of String, String) = Nothing) As Task(Of String)

        Try
            ' Build query string from filters
            Dim queryParams = HttpUtility.ParseQueryString(String.Empty)
            If filters IsNot Nothing Then
                For Each filter In filters
                    queryParams(filter.Key) = filter.Value
                Next
            End If

            Dim queryString As String = queryParams.ToString()
            Dim endpoint As String = $"/v1/rest/merchants/{merchantId}/transactions"
            If Not String.IsNullOrEmpty(queryString) Then
                endpoint &= $"?{queryString}"
            End If

            Dim response As HttpResponseMessage = Await _httpClient.GetAsync(endpoint)
            response.EnsureSuccessStatusCode()

            Return Await response.Content.ReadAsStringAsync()
        Catch e As HttpRequestException
            Console.WriteLine($"Request error: {e.Message}")
            Throw
        End Try
    End Function
End Class

' Example usage: Search by date range
Dim client As New TransactionClient("your-bearer-token-here")
Dim filters As New Dictionary(Of String, String) From {
    {"transactiondate", "2026-01-01T00:00:00Z"},
    {"transactionenddate", "2026-01-31T23:59:59Z"},
    {"minimumamount", "10.00"}
}

Dim transactions As String = Await client.SearchTransactionsAsync("12345678901", filters)
Console.WriteLine(transactions)
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;

public class TransactionClient {
    private final String baseUrl;
    private final String bearerToken;
    private final HttpClient httpClient;

    public TransactionClient(String baseUrl, String bearerToken) {
        this.baseUrl = baseUrl;
        this.bearerToken = bearerToken;
        this.httpClient = HttpClient.newHttpClient();
    }

    public String searchTransactions(String merchantId, Map<String, String> filters)
            throws IOException, InterruptedException {

        // Build query string from filters
        String queryString = "";
        if (filters != null && !filters.isEmpty()) {
            queryString = "?" + filters.entrySet().stream()
                .map(entry -> URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) +
                             "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
                .collect(Collectors.joining("&"));
        }

        String endpoint = baseUrl + "/v1/rest/merchants/" + merchantId +
                         "/transactions" + queryString;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(endpoint))
            .header("Authorization", "Bearer " + bearerToken)
            .header("Accept", "application/json")
            .GET()
            .build();

        HttpResponse<String> response = httpClient.send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );

        if (response.statusCode() != 200) {
            throw new IOException("HTTP Error: " + response.statusCode());
        }

        return response.body();
    }
}

// Example usage: Search by date range
TransactionClient client = new TransactionClient(
    "https://your-api-domain.com",
    "your-bearer-token-here"
);

Map<String, String> filters = new HashMap<>();
filters.put("transactiondate", "2026-01-01T00:00:00Z");
filters.put("transactionenddate", "2026-01-31T23:59:59Z");
filters.put("minimumamount", "10.00");

String transactions = client.searchTransactions("12345678901", filters);
System.out.println(transactions);
require 'net/http'
require 'uri'
require 'json'
require 'cgi'

class TransactionClient
  def initialize(base_url, bearer_token)
    @base_url = base_url
    @bearer_token = bearer_token
  end

  def search_transactions(merchant_id, filters = {})
    # Build query string from filters
    query_string = ''
    unless filters.empty?
      query_params = filters.map do |key, value|
        "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
      end.join('&')
      query_string = "?#{query_params}"
    end

    endpoint = "#{@base_url}/v1/rest/merchants/#{merchant_id}/transactions#{query_string}"
    uri = URI.parse(endpoint)

    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true

    request = Net::HTTP::Get.new(uri.request_uri)
    request['Authorization'] = "Bearer #{@bearer_token}"
    request['Accept'] = 'application/json'

    response = http.request(request)

    if response.code.to_i != 200
      raise "HTTP Error: #{response.code} - #{response.body}"
    end

    response.body
  end
end

# Example usage: Search by date range
client = TransactionClient.new(
  'https://your-api-domain.com',
  'your-bearer-token-here'
)

filters = {
  transactiondate: '2026-01-01T00:00:00Z',
  transactionenddate: '2026-01-31T23:59:59Z',
  minimumamount: '10.00'
}

transactions = client.search_transactions('12345678901', filters)
puts transactions

Pagination Code Examples

The following examples show how to retrieve all pages of results using pagesize and pagecursor. Each iteration passes the nextCursor from the previous response until hasNextPage is false.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using System.Web;

public class PaginatedTransactionResult
{
    public List<Dictionary<string, object>> Data { get; set; }
    public PaginationMeta Pagination { get; set; }
}

public class PaginationMeta
{
    public bool HasNextPage { get; set; }
    public string NextCursor { get; set; }
}

public class TransactionClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl = "https://your-api-domain.com";

    public TransactionClient(string bearerToken)
    {
        _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri(_baseUrl);
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", bearerToken);
        _httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<List<Dictionary<string, object>>> FetchAllTransactionsAsync(
        string merchantId,
        Dictionary<string, string> filters,
        int pageSize = 100)
    {
        var allTransactions = new List<Dictionary<string, object>>();
        string cursor = null;

        do
        {
            var queryParams = HttpUtility.ParseQueryString(string.Empty);
            foreach (var kv in filters)
                queryParams[kv.Key] = kv.Value;
            queryParams["pagesize"] = pageSize.ToString();
            if (cursor != null)
                queryParams["pagecursor"] = cursor;

            string url = $"/v1/rest/merchants/{merchantId}/transactions?{queryParams}";
            HttpResponseMessage response = await _httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode();

            string json = await response.Content.ReadAsStringAsync();
            var page = JsonSerializer.Deserialize<PaginatedTransactionResult>(json,
                new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            allTransactions.AddRange(page.Data);
            cursor = page.Pagination?.HasNextPage == true ? page.Pagination.NextCursor : null;

        } while (cursor != null);

        return allTransactions;
    }
}

// Usage
var client = new TransactionClient("your-bearer-token-here");
var filters = new Dictionary<string, string>
{
    { "transactiondate", "2026-01-01T00:00:00Z" },
    { "transactionenddate", "2026-01-31T23:59:59Z" }
};

var allTransactions = await client.FetchAllTransactionsAsync("12345678901", filters, pageSize: 100);
Console.WriteLine($"Total transactions: {allTransactions.Count}");
Imports System
Imports System.Collections.Generic
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text.Json
Imports System.Threading.Tasks
Imports System.Web

Public Class PaginationMeta
    Public Property HasNextPage As Boolean
    Public Property NextCursor As String
End Class

Public Class PaginatedTransactionResult
    Public Property Data As List(Of Dictionary(Of String, Object))
    Public Property Pagination As PaginationMeta
End Class

Public Class TransactionClient
    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _baseUrl As String = "https://your-api-domain.com"

    Public Sub New(bearerToken As String)
        _httpClient = New HttpClient()
        _httpClient.BaseAddress = New Uri(_baseUrl)
        _httpClient.DefaultRequestHeaders.Authorization =
            New AuthenticationHeaderValue("Bearer", bearerToken)
        _httpClient.DefaultRequestHeaders.Accept.Add(
            New MediaTypeWithQualityHeaderValue("application/json"))
    End Sub

    Public Async Function FetchAllTransactionsAsync(
        merchantId As String,
        filters As Dictionary(Of String, String),
        Optional pageSize As Integer = 100) As Task(Of List(Of Dictionary(Of String, Object)))

        Dim allTransactions As New List(Of Dictionary(Of String, Object))
        Dim cursor As String = Nothing

        Do
            Dim queryParams = HttpUtility.ParseQueryString(String.Empty)
            For Each kv In filters
                queryParams(kv.Key) = kv.Value
            Next
            queryParams("pagesize") = pageSize.ToString()
            If cursor IsNot Nothing Then
                queryParams("pagecursor") = cursor
            End If

            Dim url As String = $"/v1/rest/merchants/{merchantId}/transactions?{queryParams}"
            Dim response As HttpResponseMessage = Await _httpClient.GetAsync(url)
            response.EnsureSuccessStatusCode()

            Dim json As String = Await response.Content.ReadAsStringAsync()
            Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True}
            Dim page = JsonSerializer.Deserialize(Of PaginatedTransactionResult)(json, options)

            allTransactions.AddRange(page.Data)
            cursor = If(page.Pagination?.HasNextPage = True, page.Pagination.NextCursor, Nothing)

        Loop While cursor IsNot Nothing

        Return allTransactions
    End Function
End Class

' Usage
Dim client As New TransactionClient("your-bearer-token-here")
Dim filters As New Dictionary(Of String, String) From {
    {"transactiondate", "2026-01-01T00:00:00Z"},
    {"transactionenddate", "2026-01-31T23:59:59Z"}
}

Dim allTransactions = Await client.FetchAllTransactionsAsync("12345678901", filters, pageSize:=100)
Console.WriteLine($"Total transactions: {allTransactions.Count}")
// Maven:  com.fasterxml.jackson.core:jackson-databind:2.17.x
// Gradle: implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.+'
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class TransactionClient {
    private final String baseUrl;
    private final String bearerToken;
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public TransactionClient(String baseUrl, String bearerToken) {
        this.baseUrl = baseUrl;
        this.bearerToken = bearerToken;
        this.httpClient = HttpClient.newHttpClient();
    }

    public List<Map<String, Object>> fetchAllTransactions(
            String merchantId, Map<String, String> filters, int pageSize)
            throws IOException, InterruptedException {

        List<Map<String, Object>> allTransactions = new ArrayList<>();
        String cursor = null;

        do {
            Map<String, String> params = new LinkedHashMap<>(filters);
            params.put("pagesize", String.valueOf(pageSize));
            if (cursor != null) params.put("pagecursor", cursor);

            String queryString = params.entrySet().stream()
                .map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) + "=" +
                          URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
                .collect(java.util.stream.Collectors.joining("&"));

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/v1/rest/merchants/" + merchantId +
                                "/transactions?" + queryString))
                .header("Authorization", "Bearer " + bearerToken)
                .header("Accept", "application/json")
                .GET()
                .build();

            HttpResponse<String> response =
                httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() != 200)
                throw new IOException("HTTP " + response.statusCode());

            Map<String, Object> page = objectMapper.readValue(
                response.body(), new TypeReference<Map<String, Object>>() {});
            List<Map<String, Object>> data =
                (List<Map<String, Object>>) page.get("data");
            allTransactions.addAll(data);

            Map<String, Object> pagination =
                (Map<String, Object>) page.get("pagination");
            boolean hasNextPage = pagination != null &&
                Boolean.TRUE.equals(pagination.get("hasNextPage"));
            cursor = hasNextPage ? (String) pagination.get("nextCursor") : null;

        } while (cursor != null);

        return allTransactions;
    }
}

// Usage
TransactionClient client = new TransactionClient(
    "https://your-api-domain.com", "your-bearer-token-here");

Map<String, String> filters = new LinkedHashMap<>();
filters.put("transactiondate", "2026-01-01T00:00:00Z");
filters.put("transactionenddate", "2026-01-31T23:59:59Z");

List<Map<String, Object>> all = client.fetchAllTransactions("12345678901", filters, 100);
System.out.println("Total transactions: " + all.size());
require 'net/http'
require 'uri'
require 'json'
require 'cgi'

class TransactionClient
  def initialize(base_url, bearer_token)
    @base_url = base_url
    @bearer_token = bearer_token
  end

  def fetch_all_transactions(merchant_id, filters = {}, page_size: 100)
    all_transactions = []
    cursor = nil

    loop do
      params = filters.merge(pagesize: page_size.to_s)
      params[:pagecursor] = cursor if cursor

      query_string = params.map do |k, v|
        "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
      end.join('&')

      uri = URI.parse("#{@base_url}/v1/rest/merchants/#{merchant_id}/transactions?#{query_string}")
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true

      request = Net::HTTP::Get.new(uri.request_uri)
      request['Authorization'] = "Bearer #{@bearer_token}"
      request['Accept'] = 'application/json'

      response = http.request(request)
      raise "HTTP #{response.code}" unless response.code.to_i == 200

      page = JSON.parse(response.body)
      all_transactions.concat(page['data'])

      pagination = page['pagination']
      break unless pagination&.dig('hasNextPage')
      cursor = pagination['nextCursor']
    end

    all_transactions
  end
end

# Usage
client = TransactionClient.new('https://your-api-domain.com', 'your-bearer-token-here')
filters = {
  transactiondate: '2026-01-01T00:00:00Z',
  transactionenddate: '2026-01-31T23:59:59Z'
}

all_transactions = client.fetch_all_transactions('12345678901', filters, page_size: 100)
puts "Total transactions: #{all_transactions.size}"

Common Search Scenarios

Scenario 1: Find All Transactions for a Specific Date

// Search for all transactions on January 15, 2026
var filters = new Dictionary<string, string>
{
    { "transactiondate", "2026-01-15T00:00:00Z" },
    { "transactionenddate", "2026-01-15T23:59:59Z" }
};

Scenario 2: Find Transactions by Amount Range

// Search for transactions between $100 and $500
var filters = new Dictionary<string, string>
{
    { "minimumamount", "100.00" },
    { "maximumamount", "500.00" }
};

Scenario 3: Find Transactions by Last 4 Digits of Card

// Search for transactions made with card ending in 1234
var filters = new Dictionary<string, string>
{
    { "last4", "1234" }
};

Scenario 4: Find Transactions by Order ID

// Search for transactions associated with a specific order
var filters = new Dictionary<string, string>
{
    { "orderid", "ORD-2026-12345" }
};

Scenario 5: Find Transactions by Location

// Search for all transactions from location/school ID 5
var filters = new Dictionary<string, string>
{
    { "locationid", "5" }
};

Scenario 6: Find Returned or Declined Transactions

// Search for transactions returned or declined in January 2026
var filters = new Dictionary<string, string>
{
    { "returnordeclinedate", "2026-01-01T00:00:00Z" },
    { "returnordeclineenddate", "2026-01-31T23:59:59Z" }
};

Scenario 7: Page Through a Large Result Set Using Pagination

Pagination works with all existing filter parameters — date ranges, amount ranges, location, order ID, custom attributes, sponsor key, and more. Add pagesize to any search to receive results in manageable pages rather than a single potentially large response.

// Page through all transactions for a location in January 2026, 50 at a time
var allTransactions = new List<object>();
string cursor = null;

do
{
    var queryParams = HttpUtility.ParseQueryString(string.Empty);
    queryParams["transactiondate"]    = "2026-01-01T00:00:00Z";
    queryParams["transactionenddate"] = "2026-01-31T23:59:59Z";
    queryParams["locationid"]         = "5";
    queryParams["pagesize"]           = "50";
    if (cursor != null)
        queryParams["pagecursor"] = cursor;

    string url = $"/v1/rest/merchants/12345678901/transactions?{queryParams}";
    var response = await httpClient.GetAsync(url);
    response.EnsureSuccessStatusCode();

    var page = JsonSerializer.Deserialize<PaginatedTransactionResult>(
        await response.Content.ReadAsStringAsync(),
        new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

    allTransactions.AddRange(page.Data);
    cursor = page.Pagination?.HasNextPage == true ? page.Pagination.NextCursor : null;

} while (cursor != null);

Console.WriteLine($"Total transactions retrieved: {allTransactions.Count}");
Pagination works with all filters.

You can combine pagesize and pagecursor with any of the available filter parameters — date ranges, amount ranges, locationid, orderid, last4, payorid, savedpaymentmethodid, attributename/attributevalues, sponsorkey, and return/decline date ranges. The cursor automatically preserves your filter context across pages — you do not need to re-validate or re-specify filters between requests.

Response Format

The response shape depends on whether pagesize is included in the request.

Without pagesize — bare array (legacy)

When pagesize is omitted, the endpoint returns a flat JSON array of transaction objects, identical to the pre-pagination behavior.

[
  {
    "transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "retref": 123456789,
    "merchid": "12345678901",
    "locationid": 5,
    "transactionAmount": "150.00",
    "authAmount": "150.00",
    "cardExpiry": "1225",
    "accttype": "VISA",
    "maskedAccountNumber": "************1234",
    "lastfour": "1234",
    "accountHolderName": "John Doe",
    "orderid": "ORD-2026-001",
    "responseStatus": "TransactionApproved",
    "responseMessage": "Approved",
    "responseCode": "000",
    "responseResult": "success",
    "requestDate": "2026-01-15T10:30:00Z",
    "authDate": "2026-01-15T10:30:05Z",
    "settlementDate": "2026-01-16T03:00:00Z",
    "settlementStatus": "Accepted",
    "transtype": "Ecomm",
    "transinit": "Consumer",
    "recurring": false
  }
]

With pagesize — paginated envelope

When pagesize is provided, the response is wrapped in a PaginatedTransactionResponse object with two top-level fields:

  • data — array of TransactionResponse objects for this page
  • pagination — pagination metadata (see table below)

First / intermediate page (more results available)

{
  "data": [
    {
      "transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "retref": 123456789,
      "merchid": "12345678901",
      "transactionAmount": "150.00",
      "accttype": "VISA",
      "lastfour": "1234",
      "responseStatus": "TransactionApproved",
      "requestDate": "2026-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "hasNextPage": true,
    "nextCursor": "eyJBZnRlclJlcXVlc3REYXRlIjoiMjAyNi0wMS0xNVQxMDozMDowMFoiLCJBZnRlclRyYW5zYWN0aW9uSWQiOiIxMjM0NTY3ODkifQ=="
  }
}

Final page (no more results)

{
  "data": [
    {
      "transactionId": "z9y8x7w6-v5u4-3210-zyxw-vu9876543210",
      "retref": 123456795,
      "merchid": "12345678901",
      "transactionAmount": "42.00",
      "accttype": "ECHK",
      "lastfour": "5678",
      "responseStatus": "TransactionApproved",
      "requestDate": "2026-01-15T23:55:00Z"
    }
  ],
  "pagination": {
    "hasNextPage": false,
    "nextCursor": null
  }
}

Pagination fields

Field Type Description
pagination.hasNextPage boolean True when additional results exist beyond this page; false on the final page.
pagination.nextCursor string | null Opaque cursor token. Pass as pagecursor on the next request. Null when hasNextPage is false.

Response Fields

Each transaction object in the array contains the following fields:

Field Type Description
transactionId string (UUID) The internal unique transaction ID
retref integer Retrieval reference number used to track the authorization request
merchid string The merchant ID
locationid integer The location/school ID
transactionAmount string The transaction amount
authAmount string The authorized amount (same as transaction amount for most approvals)
cardExpiry string The card expiration date (for credit cards)
accttype string The account type (VISA, MC, DISC, AMEX, SAV, ECHK)
maskedAccountNumber string The masked account number showing only last 4 digits
lastfour string Last 4 digits of the account number
abaRoutingNumber string The bank routing number (for ACH transactions)
payorId string The payor ID (if transaction used a saved payor profile)
savedPaymentMethodId string The saved payment method ID (if transaction used a saved payment method)
accountHolderName string Name on the account
orderid string Source system order number
responseStatus string Status of the transaction (TransactionApproved, TransactionDeclined, etc.)
responseMessage string Human-readable response message
responseCode string Response code
responseResult string Result: success, failure, or retry
requestDate date-time Date/time the request was made (UTC)
authDate date-time Date/time of authorization (UTC)
settlementDate date-time Date/time of settlement (UTC)
settlementStatus string Current settlement status (Authorized, Accepted, Declined, etc.)
transtype string Transaction type: Ecomm, Moto, or Retail
transinit string Transaction initiator: Consumer or Merchant
recurring boolean Whether this is a recurring/installment payment

HTTP Status Codes

Status Code Description
200 Success — Returns a PaginatedTransactionResponse envelope when pagesize is specified; otherwise returns a bare array of transactions (may be empty if no matches found)
400 Bad Request - Invalid filter parameters or date format
404 Not Found - Merchant not found
503 Service Unavailable - Transaction service temporarily unavailable

Best Practices

1. Always Use Date Ranges

When searching by date, always provide both transactiondate and transactionenddate to avoid retrieving too many results.

2. Combine Filters for Better Results

Use multiple filters together to narrow down results. For example, combine date range with location ID to find transactions for a specific store during a specific time period.

3. Handle Empty Results

A 200 status with an empty array [] means no transactions matched your filters. This is not an error - adjust your search criteria and try again.

4. Use ISO 8601 Date Format

Always use ISO 8601 format for dates: 2026-01-15T00:00:00Z. The 'Z' indicates UTC time.

5. Be Specific with Amount Searches

When searching by amount, use decimal format with two decimal places: 10.00 not 10.

Common Use Cases

1. Daily Transaction Report

Get all transactions for a specific day for reconciliation:

var filters = new Dictionary<string, string>
{
    { "transactiondate", "2026-01-15T00:00:00Z" },
    { "transactionenddate", "2026-01-15T23:59:59Z" }
};

2. Find Specific Order

Locate a transaction by order number for customer service:

var filters = new Dictionary<string, string>
{
    { "orderid", "ORD-2026-12345" }
};

3. High-Value Transaction Report

Find all large transactions for audit purposes:

var filters = new Dictionary<string, string>
{
    { "minimumamount", "1000.00" },
    { "transactiondate", "2026-01-01T00:00:00Z" },
    { "transactionenddate", "2026-01-31T23:59:59Z" }
};

4. Customer Transaction History

Find all transactions for a specific customer using their saved payment method:

var filters = new Dictionary<string, string>
{
    { "payorid", "5513027774438108364" }
};

5. Failed Transaction Analysis

Find all declined or returned transactions for a date range:

var filters = new Dictionary<string, string>
{
    { "returnordeclinedate", "2026-01-01T00:00:00Z" },
    { "returnordeclineenddate", "2026-01-31T23:59:59Z" }
};

Troubleshooting

Issue: Getting empty array [] but expecting results
  • Verify the merchant ID is correct
  • Check your date format is correct (ISO 8601 with 'Z' for UTC)
  • Ensure date ranges are inclusive (start at 00:00:00, end at 23:59:59)
  • Verify the filter values match exactly (order IDs are case-sensitive)
  • Try broadening your search by removing some filters
Issue: Getting 400 Bad Request error
  • Check date format - must be ISO 8601 (YYYY-MM-DDTHH:mm:ssZ)
  • Verify amount values are decimal numbers (10.00, not "ten dollars")
  • Ensure location ID is a number, not a string
  • Check that parameter names are spelled correctly (lowercase)
Issue: Too many results returned
  • Add more filters to narrow down the search
  • Use smaller date ranges
  • Combine filters (e.g., date range + location ID)
  • Use the pagesize parameter to page through large result sets — the API returns a PaginatedTransactionResponse with a pagination.nextCursor token; keep requesting pages until pagination.hasNextPage is false

Additional Notes

  • All date/time values in the response are in UTC timezone.
  • The search is performed against settled and pending transactions.
  • Results are not guaranteed to be in any specific order - sort them in your application as needed.
  • There may be limits on how far back you can search (e.g., last 12 months). Check with your account settings.
  • Custom attributes can be used for advanced filtering specific to your business needs.
  • The last4 parameter searches across all payment types (credit cards and ACH accounts).
  • Settlement dates may be null for very recent transactions that haven't settled yet.