Documentation

POS Transactions

Manage POS inflow transactions and settlements across the platform

Overview

Platform admin endpoints for viewing and analyzing POS transactions and settlements. These endpoints provide comprehensive visibility into payment processing across all tenants.

Transaction Lifecycle

POS transactions flow through a defined lifecycle from initiation to settlement.

StageDescription
InflowTransaction initiated at terminal - card swipe, NFC tap, or bank transfer
ProcessingPayment processed through the card processor or payment provider
ConfirmationTransaction confirmed as completed or failed
SettlementSuccessful transactions batched into settlement jobs based on profile frequency
PayoutSettlement funds transferred to merchant's designated account

Transaction Channels

POS terminals support multiple payment channels, each with unique identifiers and processing flows.

ChannelCodeDescriptionUnique Reference
Debit Cardcard_processorTraditional card swipe or chip insertRRN (Retrieval Reference Number)
NFC Cardnfc_purchaseContactless tap-to-pay transactionsNFC Code
Bank Transferva_pos_paymentTransfer to terminal's virtual accountVA Session ID
Funds Transferfunds_transfer_inflowDirect funds transfer inflowReference ID

Transaction Statuses

Transaction status indicates the current state in the processing lifecycle.

StatusDescriptionSettable
pendingTransaction initiated, awaiting processor confirmationNo
completedTransaction successfully processed and confirmedYes
failedTransaction failed during processingNo
reversedTransaction was reversed after completionNo

Settlement States

Settlement jobs track the batching and payout of transactions.

StateDescription
pendingSettlement job created, awaiting transaction collection
collectingActively collecting transactions for the settlement window
payout_submittedPayout request submitted to the provider
settledFunds successfully transferred to merchant
failedSettlement failed - may require retry or manual review
needs_manual_reviewSettlement flagged for manual intervention

List POS Transactions

Retrieve POS inflow transactions with comprehensive filtering and pagination.

Endpoint

GET/api/v1/admin/pos-transactions

List all POS inflow transactions across the platform. Supports filtering by tenant, terminal, status, channel, date range, and amount range.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID. Omit to view all tenants.
terminal_idstringNoFilter by terminal ID (human code or UUID)
statusstringNoComma-separated statusesValues: pending, completed, failed, reversed
channelstringNoComma-separated channelsValues: card_processor, nfc_purchase, va_pos_payment, funds_transfer_inflow
typestringNoTransaction typeValues: credit, debit
from_datestringNoStart date filter (RFC3339 format: 2024-01-01T00:00:00Z)
to_datestringNoEnd date filter (RFC3339 format)
min_amountstringNoMinimum transaction amount (decimal string)
max_amountstringNoMaximum transaction amount (decimal string)
searchstringNoSearch by RRN, identifier, or reference
sortstringNo (default: registered_at)Values: created_at, amount, completed_at, registered_at, status
orderstringNo (default: desc)Values: asc, desc
pageintegerNo (default: 1)Page number
page_sizeintegerNo (default: 20)Items per page (max 100)

Response- Paginated list of transactions with optional summary

json
{
  "transactions": [
    {
      "id": "txn_550e8400-e29b-41d4-a716-446655440000",
      "tenant_id": "tnt_f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "tenant_name": "Acme Payments",
      "terminal_id": "2057TID001",
      "terminal_name": "Store Alpha POS",
      "profile_id": "prof_abc123",
      "processor_id": "proc_xyz789",
      "channel": "card_processor",
      "status": "completed",
      "amount": 15000,
      "currency": "NGN",
      "fee_amount": 150,
      "fee_currency": "NGN",
      "reference": "REF123456789",
      "rrn": "012345678901",
      "identifier": null,
      "nfc_code": null,
      "va_session_id": null,
      "customer_info": {
        "pan": "****1234",
        "card_type": "mastercard",
        "card_name": "JOHN DOE"
      },
      "metadata": {
        "card_pan": "****1234",
        "card_type": "mastercard"
      },
      "registered_at": "2024-01-20T14:30:00Z",
      "confirmed_at": "2024-01-20T14:30:05Z",
      "settled_job_id": "job_def456",
      "settled_at": "2024-01-20T18:00:00Z",
      "created_at": "2024-01-20T14:30:00Z",
      "updated_at": "2024-01-20T18:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 20,
    "total": 1250
  },
  "summary": {
    "total_amount": "18750000.00",
    "transaction_count": 1250,
    "success_rate": 97.5
  }
}

Example Requests

bash
# List all transactions
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions" \
  -H "Authorization: Bearer {admin_token}"

# Filter by tenant and status
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions?tenant_id=tnt_abc123&status=completed,pending" \
  -H "Authorization: Bearer {admin_token}"

# Filter by date range and channel
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions?from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z&channel=card_processor,nfc_purchase" \
  -H "Authorization: Bearer {admin_token}"

# Search by RRN
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions?search=012345678901" \
  -H "Authorization: Bearer {admin_token}"

Transaction Response Fields

FieldTypeDescription
idstringUnique transaction identifier (UUID)
tenant_idstringParent tenant UUID
tenant_namestringTenant display name
terminal_idstringTerminal ID (human code like '2057TID001')
terminal_namestringTerminal display name
profile_idstring | nullAssociated terminal profile UUID
processor_idstringPayment processor UUID
channelstringPayment channel (card_processor, nfc_purchase, va_pos_payment)
statusstringTransaction status
amountnumberTransaction amount in minor units
currencystringCurrency code (NGN)
fee_amountnumberFee charged for transaction
fee_currencystringFee currency code
referencestringUnique transaction reference
rrnstring | nullRetrieval Reference Number (card transactions)
nfc_codestring | nullNFC transaction code (NFC transactions)
va_session_idstring | nullVirtual account session ID (transfer transactions)
customer_infoobjectCustomer/card holder information
registered_atstringWhen transaction was registered (ISO timestamp)
confirmed_atstring | nullWhen transaction was confirmed
settled_job_idstring | nullSettlement job this transaction belongs to
settled_atstring | nullWhen transaction was settled

Customer Info by Channel

The customer_info object varies based on the transaction channel.

ChannelAvailable Fields
card_processorpan (masked), card_type, card_name, card_expiry, issuing_bank
nfc_purchasepan (masked), card_type, card_name, serial_number, stan
va_pos_paymentsender_name, sender_bank, sender_account (masked), session_id

Transaction Analytics

Get aggregated analytics for POS transactions with time series data.

Endpoint

GET/api/v1/admin/pos-transactions/analytics

Retrieve transaction analytics including counts, volumes, and time series data broken down by payment channel. Ideal for dashboards and reporting.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
fromstringYesStart date (RFC3339 format: 2024-01-01T00:00:00Z)
tostringYesEnd date (RFC3339 format)
intervalstringNo (default: day)Time series bucket intervalValues: day, week, month
tenant_idstringNoFilter analytics to a specific tenant
channelstringNoComma-separated channels to include

Response- Analytics response with summary and time series

json
{
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z",
    "interval": "day"
  },
  "summary_by_channel": {
    "card_processor": {
      "count": 15420,
      "volume": 231300000
    },
    "nfc_purchase": {
      "count": 8750,
      "volume": 87500000
    },
    "va_pos_payment": {
      "count": 3280,
      "volume": 164000000
    },
    "funds_transfer_inflow": {
      "count": 120,
      "volume": 12000000
    }
  },
  "series": [
    {
      "bucket": "2024-01-01T00:00:00Z",
      "total_count": 892,
      "total_volume": 15680000,
      "by_channel": {
        "card_processor": {
          "count": 520,
          "volume": 7800000
        },
        "nfc_purchase": {
          "count": 280,
          "volume": 4200000
        },
        "va_pos_payment": {
          "count": 92,
          "volume": 3680000
        }
      }
    },
    {
      "bucket": "2024-01-02T00:00:00Z",
      "total_count": 945,
      "total_volume": 16520000,
      "by_channel": {
        "card_processor": {
          "count": 548,
          "volume": 8220000
        },
        "nfc_purchase": {
          "count": 298,
          "volume": 4470000
        },
        "va_pos_payment": {
          "count": 99,
          "volume": 3830000
        }
      }
    }
  ]
}

Example Request

bash
# Get daily analytics for January 2024
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions/analytics?from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z&interval=day" \
  -H "Authorization: Bearer {admin_token}"

# Get weekly analytics for a specific tenant
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions/analytics?from=2024-01-01T00:00:00Z&to=2024-03-31T23:59:59Z&interval=week&tenant_id=tnt_abc123" \
  -H "Authorization: Bearer {admin_token}"

# Get card-only analytics
curl -X GET "https://api.example.com/api/v1/admin/pos-transactions/analytics?from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z&channel=card_processor,nfc_purchase" \
  -H "Authorization: Bearer {admin_token}"

Analytics Response Fields

FieldTypeDescription
period.fromstringStart of analytics period (ISO timestamp)
period.tostringEnd of analytics period (ISO timestamp)
period.intervalstringBucket interval used (day, week, month)
summary_by_channelobjectAggregated totals by channel for entire period
summary_by_channel.{channel}.countnumberTotal transaction count for channel
summary_by_channel.{channel}.volumenumberTotal transaction volume for channel
seriesarrayTime series data points
series[].bucketstringStart of time bucket (ISO timestamp)
series[].total_countnumberTotal transactions in bucket
series[].total_volumenumberTotal volume in bucket
series[].by_channelobjectBreakdown by channel for this bucket

Use Cases

Use CaseParameters
Daily dashboardinterval=day, last 7-30 days
Weekly trendsinterval=week, last 4-12 weeks
Monthly reportsinterval=month, last 3-12 months
Channel comparisonInclude all channels, compare summary_by_channel
Tenant performanceSet tenant_id to compare individual tenants

List POS Settlements

Retrieve POS settlement jobs with filtering and pagination.

Endpoint

GET/api/v1/admin/pos-settlements

List all POS settlement jobs across the platform. Settlement jobs batch transactions from a settlement window and track the payout process.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
terminal_idstringNoFilter by terminal ID
statestringNoFilter by settlement stateValues: pending, collecting, payout_submitted, settled, failed, needs_manual_review
window_startstringNoFilter by window start date (RFC3339)
window_endstringNoFilter by window end date (RFC3339)
limitintegerNo (default: 20)Page size (max 200)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of settlement jobs

json
{
  "data": [
    {
      "id": "job_550e8400-e29b-41d4-a716-446655440000",
      "tenant_id": "tnt_f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "tenant_name": "Acme Payments",
      "terminal_id": "2057TID001",
      "terminal_name": "Store Alpha POS",
      "profile_id": "prof_abc123",
      "mode": "automatic",
      "settlement_frequency": "end_of_day",
      "state": "settled",
      "amount": 1250000,
      "currency": "NGN",
      "settlement_amount": "1237500.00",
      "transaction_count": 85,
      "attempts": 1,
      "max_attempts": 3,
      "window_start": "2024-01-20T00:00:00Z",
      "window_end": "2024-01-20T23:59:59Z",
      "payout_reference": "PAY_ABC123XYZ",
      "metadata": {
        "settlement_route": "terminal_settlement_account",
        "transaction_total_amount": "1250000",
        "transaction_total_fee": "12500"
      },
      "created_at": "2024-01-21T00:00:00Z",
      "updated_at": "2024-01-21T00:05:00Z"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total_count": 1580
  }
}

Example Requests

bash
# List all settlements
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements" \
  -H "Authorization: Bearer {admin_token}"

# Filter by state
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements?state=failed" \
  -H "Authorization: Bearer {admin_token}"

# Filter by date range
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements?window_start=2024-01-01T00:00:00Z&window_end=2024-01-31T23:59:59Z" \
  -H "Authorization: Bearer {admin_token}"

# Filter by terminal
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements?terminal_id=2057TID001" \
  -H "Authorization: Bearer {admin_token}"

Settlement Response Fields

FieldTypeDescription
idstringUnique settlement job identifier
tenant_idstringParent tenant UUID
tenant_namestringTenant display name
terminal_idstringTerminal ID (human code)
terminal_namestringTerminal display name
profile_idstringAssociated terminal profile UUID
modestringSettlement mode (automatic, manual)
settlement_frequencystringFrequency from profile (instant, hourly, six_hourly, end_of_day)
statestringCurrent settlement state
amountnumberTotal transaction amount before fees
currencystringCurrency code
settlement_amountstringNet amount to settle (after fees)
transaction_countnumberNumber of transactions in this settlement
attemptsnumberNumber of payout attempts made
max_attemptsnumberMaximum allowed payout attempts
window_startstringSettlement window start (ISO timestamp)
window_endstringSettlement window end (ISO timestamp)
payout_referencestring | nullProvider payout reference (when submitted)
metadataobjectAdditional settlement metadata

Settlement Metadata

The metadata object contains additional settlement details.

FieldTypeDescription
settlement_routestringWhere funds are routed (terminal_settlement_account or profile_wallet)
transaction_total_amountstringSum of all transaction amounts
transaction_total_feestringSum of all transaction fees
transaction_idsarrayList of transaction IDs included in settlement
profile_settlement_account_idstringProfile wallet account ID (for profile_wallet route)

Settlement Analytics

Get aggregated analytics for POS settlements with time series data by state.

Endpoint

GET/api/v1/admin/pos-settlements/analytics

Retrieve settlement analytics including counts and time series data broken down by settlement state. Useful for monitoring settlement health and identifying issues.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
fromstringYesStart date (RFC3339 format)
tostringYesEnd date (RFC3339 format)
intervalstringNo (default: day)Time series bucket intervalValues: day, week, month
tenant_idstringNoFilter analytics to a specific tenant
profile_idstringNoFilter analytics to a specific profile
terminal_idstringNoFilter analytics to a specific terminal
statesstringNoComma-separated states to include (e.g., 'settled,pending,failed')

Response- Analytics response with summary and time series by state

json
{
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z",
    "interval": "day"
  },
  "summary_by_state": {
    "settled": 1450,
    "pending": 25,
    "collecting": 12,
    "payout_submitted": 8,
    "failed": 15,
    "needs_manual_review": 3
  },
  "series": [
    {
      "bucket": "2024-01-01T00:00:00Z",
      "total": 52,
      "by_state": {
        "settled": 48,
        "pending": 2,
        "collecting": 1,
        "failed": 1
      }
    },
    {
      "bucket": "2024-01-02T00:00:00Z",
      "total": 55,
      "by_state": {
        "settled": 52,
        "pending": 1,
        "collecting": 2
      }
    }
  ]
}

Example Request

bash
# Get daily settlement analytics
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements/analytics?from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z&interval=day" \
  -H "Authorization: Bearer {admin_token}"

# Get analytics for failed settlements only
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements/analytics?from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z&states=failed,needs_manual_review" \
  -H "Authorization: Bearer {admin_token}"

# Get analytics for a specific terminal
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements/analytics?from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z&terminal_id=2057TID001" \
  -H "Authorization: Bearer {admin_token}"

Monitoring Use Cases

ScenarioWhat to MonitorAction
Settlement HealthRatio of settled vs failedAlert if failure rate exceeds threshold
Pending BacklogCount of pending/collecting statesInvestigate if backlog grows
Manual Review QueueCount of needs_manual_reviewPrioritize manual intervention
Payout DelaysCount of payout_submitted over timeCheck provider status if stuck

Get Settlement Transactions

Retrieve the individual transactions that make up a settlement job.

Endpoint

GET/api/v1/admin/pos-settlements/{jobID}/transactions

Get the list of transactions included in a specific settlement job. Useful for settlement reconciliation and dispute resolution.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
jobIDstringYesUUID of the settlement job

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringYesUUID of the tenant (required for authorization)

Response- List of transactions in the settlement

json
{
  "transactions": [
    {
      "id": "txn_550e8400-e29b-41d4-a716-446655440000",
      "reference": "REF123456789",
      "amount": 15000,
      "fee": 150,
      "net": 14850,
      "currency": "NGN",
      "channel": "card_processor",
      "terminal_id": "2057TID001",
      "terminal_name": "Store Alpha POS",
      "created_at": "2024-01-20T14:30:00Z"
    },
    {
      "id": "txn_660f9511-f39c-52e5-b827-557766551111",
      "reference": "REF987654321",
      "amount": 8500,
      "fee": 85,
      "net": 8415,
      "currency": "NGN",
      "channel": "nfc_purchase",
      "terminal_id": "2057TID001",
      "terminal_name": "Store Alpha POS",
      "created_at": "2024-01-20T15:45:00Z"
    }
  ]
}

Example Request

bash
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements/job_550e8400-e29b-41d4-a716-446655440000/transactions?tenant_id=tnt_f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer {admin_token}"

Transaction Fields

FieldTypeDescription
idstringTransaction UUID
referencestringUnique transaction reference
amountnumberGross transaction amount
feenumberFee deducted from transaction
netnumberNet amount (amount - fee)
currencystringCurrency code
channelstringPayment channel
terminal_idstringTerminal ID
terminal_namestringTerminal display name
created_atstringTransaction timestamp

Reconciliation Tips

Use this endpoint for settlement reconciliation:

CheckFormula/Comparison
Transaction TotalSum of all transaction.amount should match settlement.amount
Fee TotalSum of all transaction.fee should match metadata.transaction_total_fee
Net TotalSum of all transaction.net should match settlement.settlement_amount
CountArray length should match settlement.transaction_count

Get Settlement Payout

Retrieve payout details for a settlement job.

Endpoint

GET/api/v1/admin/pos-settlements/{jobID}/payout

Get detailed payout information for a settlement job including provider response, bank details, and transfer status.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
jobIDstringYesUUID of the settlement job

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringYesUUID of the tenant (required for authorization)

Response- Payout details for the settlement

json
{
  "settlement_id": "job_550e8400-e29b-41d4-a716-446655440000",
  "payout_reference": "PAY_ABC123XYZ",
  "status": "success",
  "amount": "1237500.00",
  "currency": "NGN",
  "destination": {
    "bank_code": "058",
    "bank_name": "GTBank",
    "account_number": "0123456789",
    "account_name": "Acme Store Ltd"
  },
  "provider": "paystack",
  "provider_reference": "PSK_TRF_abc123xyz",
  "provider_response": {
    "status": "success",
    "message": "Transfer successful",
    "transfer_code": "TRF_abc123xyz"
  },
  "submitted_at": "2024-01-21T00:01:00Z",
  "completed_at": "2024-01-21T00:05:00Z",
  "created_at": "2024-01-21T00:00:00Z"
}

Example Request

bash
curl -X GET "https://api.example.com/api/v1/admin/pos-settlements/job_550e8400-e29b-41d4-a716-446655440000/payout?tenant_id=tnt_f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer {admin_token}"

Payout Response Fields

FieldTypeDescription
settlement_idstringParent settlement job ID
payout_referencestringInternal payout reference
statusstringPayout status (pending, success, failed)
amountstringPayout amount (decimal string)
currencystringCurrency code
destinationobjectRecipient bank account details
destination.bank_codestringBank CBN code
destination.bank_namestringBank display name
destination.account_numberstringBank account number
destination.account_namestringAccount holder name
providerstringPayout provider used
provider_referencestringProvider's transaction reference
provider_responseobjectRaw response from provider
submitted_atstringWhen payout was submitted to provider
completed_atstring | nullWhen payout completed (if successful)

Payout Status Reference

StatusDescriptionNext Steps
pendingPayout queued but not yet submittedWait for system to process
successFunds successfully transferredNo action required
failedPayout failedReview provider_response, investigate, retry settlement

Error Responses

StatusCodeDescription
404SETTLEMENT_NOT_FOUNDSettlement job does not exist
404PAYOUT_NOT_FOUNDSettlement has no payout record (may not have reached payout stage)
403ACCESS_DENIEDAdmin not authorized to view this tenant's data

Best Practices

Recommended patterns for working with POS transactions and settlements.

Efficient Querying

Optimize your API usage for better performance.

PracticeRecommendation
Use Date FiltersAlways include from_date/to_date or window_start/window_end to limit result sets
Paginate Large ResultsUse page/page_size or limit/offset for lists over 100 items
Filter EarlyApply tenant_id, terminal_id, and status filters to reduce data transfer
Cache AnalyticsAnalytics responses are stable for historical periods - cache appropriately

Monitoring & Alerting

Key metrics to monitor for healthy POS operations.

MetricSourceAlert Threshold
Transaction Success Ratetransactions summary.success_rate< 95%
Settlement Failure Ratesettlements analytics failed/(total)> 5%
Pending Settlement Backlogsettlements analytics pending count> 100 or growing
Manual Review Queuesettlements analytics needs_manual_review> 10

Reconciliation Workflow

Steps for daily reconciliation of POS transactions.

StepActionEndpoint
1. Get Day's TransactionsList all completed transactions for the dayGET /pos-transactions?status=completed&from_date=...
2. Get Day's SettlementsList all settlements for the dayGET /pos-settlements?window_start=...
3. Match TotalsCompare transaction totals with settlement amountsManual calculation
4. Drill Down DiscrepanciesGet transactions for specific settlementsGET /pos-settlements/{id}/transactions
5. Verify PayoutsCheck payout status for each settlementGET /pos-settlements/{id}/payout