> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uw.stargate.is/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Payments

> Retrieve a paginated list of merchant payments with optional search

## Endpoint

```
GET /api/v1/merchants/{merchantID}/payments
```

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token with your API key. Must have **Read Transactions** permission.
</ParamField>

## Path Parameters

<ParamField path="merchantID" type="string" required>
  The unique identifier of the merchant. Must match the merchant ID associated with the API key.
</ParamField>

## Query Parameters

<ParamField query="limit" type="integer" default="100">
  Maximum number of payments to return. Maximum value: 1000.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Number of payments to skip for pagination.
</ParamField>

<ParamField query="search" type="string">
  Optional search query. Matches against sender phone number and payment memo.
</ParamField>

## Response

Returns an array of payment objects, sorted by creation date (newest first).

<ResponseField name="payments" type="array">
  <Expandable title="Payment Object">
    <ResponseField name="operationID" type="string">
      Unique identifier for the wallet operation
    </ResponseField>

    <ResponseField name="type" type="string">
      Operation type: `payment` (from individual or merchant) or `cash-in` (from distributor)
    </ResponseField>

    <ResponseField name="amount" type="string">
      Payment amount as decimal string
    </ResponseField>

    <ResponseField name="from" type="string">
      Sender identifier: phone number (individual), merchant name, or distributor name
    </ResponseField>

    <ResponseField name="fromType" type="string">
      Source type: `individual`, `merchant`, or `distributor`
    </ResponseField>

    <ResponseField name="fromShortCode" type="integer">
      Sender merchant short code (only present when `fromType` is `merchant`)
    </ResponseField>

    <ResponseField name="memo" type="string | null">
      Optional payment memo/reference
    </ResponseField>

    <ResponseField name="blockchainID" type="string">
      Blockchain transaction identifier
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp of payment
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.yourdomain.com/api/v1/merchants/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/payments?limit=10&offset=0" \
    -H "Authorization: Bearer uwk_YOUR_API_KEY_HERE"
  ```

  ```bash cURL (with search) theme={null}
  curl -X GET "https://api.yourdomain.com/api/v1/merchants/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/payments?search=8123456781&limit=10&offset=0" \
    -H "Authorization: Bearer uwk_YOUR_API_KEY_HERE"
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const response = await axios.get(
    'https://api.yourdomain.com/api/v1/merchants/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/payments',
    {
      params: {
        limit: 10,
        offset: 0,
        search: '8123456781' // optional
      },
      headers: {
        'Authorization': 'Bearer uwk_YOUR_API_KEY_HERE'
      }
    }
  );

  console.log('Payments:', response.data);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.yourdomain.com/api/v1/merchants/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/payments',
      params={'limit': 10, 'offset': 0, 'search': '8123456781'},
      headers={'Authorization': 'Bearer uwk_YOUR_API_KEY_HERE'}
  )

  print('Payments:', response.json())
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Success theme={null}
  [
    {
      "operationID": "wo_8b7c9d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e",
      "type": "payment",
      "amount": "5000.00",
      "from": "+234 8123456781",
      "fromType": "individual",
      "memo": "Invoice #1234",
      "blockchainID": "tx_abc123...",
      "createdAt": "2026-02-12T10:30:00Z"
    },
    {
      "operationID": "wo_7a6b5c4d-3e2f-1a0b-9c8d-7e6f5a4b3c2d",
      "type": "payment",
      "amount": "15000.00",
      "from": "XYZ Trading",
      "fromType": "merchant",
      "fromShortCode": 100001,
      "memo": "Wholesale order",
      "blockchainID": "tx_ghi789...",
      "createdAt": "2026-02-12T11:00:00Z"
    },
    {
      "operationID": "wo_9c8d0e4f-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
      "type": "cash-in",
      "amount": "50000.00",
      "from": "PAPSS Distributor",
      "fromType": "distributor",
      "memo": "Monthly deposit",
      "blockchainID": "tx_def456...",
      "createdAt": "2026-02-12T09:15:00Z"
    }
  ]
  ```

  ```json 403 Forbidden - Missing Permission theme={null}
  {
    "type": "/problems/access-forbidden",
    "status": 403,
    "title": "Access Forbidden",
    "detail": "API key does not have Read Transactions permission"
  }
  ```
</ResponseExample>

## Pagination Example

```javascript theme={null}
async function getAllPayments(merchantID, apiKey) {
  const allPayments = [];
  let offset = 0;
  const limit = 100;
  let hasMore = true;

  while (hasMore) {
    const response = await axios.get(
      `https://api.yourdomain.com/api/v1/merchants/${merchantID}/payments`,
      {
        params: { limit, offset },
        headers: { 'Authorization': `Bearer ${apiKey}` }
      }
    );

    const payments = response.data;
    allPayments.push(...payments);

    // If we got fewer results than the limit, we've reached the end
    hasMore = payments.length === limit;
    offset += limit;
  }

  return allPayments;
}
```

## Filtering Payments

You can use the `search` query parameter for server-side filtering by phone number or memo. For additional client-side filtering:

```javascript theme={null}
// Get payments from the last 24 hours
const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);
const recentPayments = payments.filter(p =>
  new Date(p.createdAt) > yesterday
);

// Get payments above a certain amount
const largePayments = payments.filter(p =>
  parseFloat(p.amount) > 10000
);

// Get payments for a specific phone number
const userPayments = payments.filter(p =>
  p.phoneFrom === '+234 8123456781'
);
```
