Skip to content

List Pending Transactions (Banks API)

Banks use this endpoint to retrieve debit transactions for a specific customer. By default, it returns pending transactions awaiting bank approval, but supports filtering by status.

Endpoint

http
GET /api/v1/banks/debit-transactions

Authentication

Requires a valid Bearer token in the Authorization header.

http
Authorization: Bearer YOUR_BANK_API_TOKEN

Query Parameters

ParameterTypeRequiredDescription
phone_numberstringYesCustomer's phone number in E.164 format (e.g., +233241234567)
statusstringNoFilter by transaction status (defaults to "pending")

Valid Status Values

StatusDescription
pendingTransactions awaiting bank approval (default)
processingTransactions currently being processed by bank
completedSuccessfully completed transactions
failedFailed or declined transactions
allAll transactions regardless of status

Phone Number Format

Phone numbers must be in E.164 international format:

  • Include country code with + prefix
  • No spaces, hyphens, or parentheses
  • Example: +233241234567 (Ghana)

Example Request

bash
# Get pending transactions (default)
curl --request GET \
  --url 'https://api.fluid-network.com/api/v1/banks/debit-transactions?phone_number=%2B233241234567' \
  --header 'Authorization: Bearer YOUR_BANK_API_TOKEN' \
  --header 'Content-Type: application/json'
bash
# Get transactions with status filter
curl --request GET \
  --url 'https://api.fluid-network.com/api/v1/banks/debit-transactions?phone_number=%2B233241234567&status=completed' \
  --header 'Authorization: Bearer YOUR_BANK_API_TOKEN' \
  --header 'Content-Type: application/json'

Response

Success Response

Status Code: 200 OK

json
{
  "success": true,
  "data": {
    "customer": "John Doe",
    "phone_number": "+233241234567",
    "bank": {
      "name": "Example Bank Ghana",
      "identifier": "EXB",
      "country_code": "GH"
    },
    "transactions": [
      {
        "id": 12345,
        "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "reference": "FLU123456789",
        "amount": 100.00,
        "currency": "GHS",
        "narration": "Payment for Order #12345",
        "status": "pending",
        "created_at": "2025-01-05T10:30:00Z",
        "account": {
          "account_number": "0241234567",
          "account_name": "John Doe",
          "account_type": "mobile_money"
        },
        "payment_partner": {
          "name": "Shopify Store XYZ",
          "partner_reference": "shop_order_12345"
        }
      },
      {
        "id": 12346,
        "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
        "reference": "FLU123456790",
        "amount": 50.00,
        "currency": "GHS",
        "narration": "Subscription payment",
        "status": "pending",
        "created_at": "2025-01-05T10:25:00Z",
        "account": {
          "account_number": "0241234567",
          "account_name": "John Doe",
          "account_type": "mobile_money"
        },
        "payment_partner": {
          "name": "SaaS Platform ABC",
          "partner_reference": "subscription_2025_01"
        }
      }
    ],
    "total_count": 2,
    "total_amount": 150.00,
    "status_filter": "pending"
  },
  "meta": {
    "timestamp": "2025-01-05T10:35:00Z",
    "request_id": "xyz-789",
    "api_version": "v1"
  }
}

Response Fields

FieldTypeDescription
successbooleanIndicates if the request was successful
data.customerstringCustomer's full name
data.phone_numberstringCustomer's phone number in E.164 format
data.bank.namestringBank's full name
data.bank.identifierstringFLUID Network bank identifier (fluidcode)
data.bank.country_codestringISO 3166-1 alpha-2 country code
data.transactionsarrayArray of transaction objects
data.transactions[].idintegerInternal transaction database ID
data.transactions[].uuidstringUnique transaction identifier (use for updates)
data.transactions[].referencestringFLUID Network transaction reference
data.transactions[].amountdecimalTransaction amount
data.transactions[].currencystringISO 4217 currency code
data.transactions[].narrationstringTransaction description/narration
data.transactions[].statusstringCurrent transaction status
data.transactions[].created_atstringTransaction creation timestamp (ISO 8601)
data.transactions[].account.account_numberstringCustomer's account number
data.transactions[].account.account_namestringAccount holder name
data.transactions[].account.account_typestringAccount type (e.g., "mobile_money")
data.transactions[].payment_partner.namestringPayment partner/merchant name
data.transactions[].payment_partner.partner_referencestringPartner's transaction reference
data.total_countintegerTotal number of transactions returned
data.total_amountdecimalSum of all transaction amounts
data.status_filterstringApplied status filter

Error Responses

Customer Not Found

Status Code: 422 Unprocessable Content

json
{
  "success": false,
  "error": {
    "code": 1007,
    "message": "Validation failed",
    "category": "validation",
    "details": {
      "customer": ["account not found"]
    }
  }
}

Common Causes:

  • Phone number not registered in your bank's system
  • Customer has no accounts with your bank
  • Invalid phone number format

Invalid Status Filter

Status Code: 422 Unprocessable Content

json
{
  "success": false,
  "error": {
    "code": 1007,
    "message": "Validation failed",
    "category": "validation",
    "details": {
      "status_filter": ["must be one of: pending, completed, failed, processing, all"]
    }
  }
}

Common Causes:

  • Invalid status parameter value
  • Typo in status name

Unauthorized

Status Code: 401 Unauthorized

json
{
  "success": false,
  "error": {
    "code": 1401,
    "message": "Unauthorized",
    "category": "authentication"
  }
}

Common Causes:

  • Missing or invalid Bearer token
  • Expired API token
  • Token belongs to different entity (not a bank)

Transaction Statuses Explained

Pending

  • Description: New transaction awaiting bank approval
  • Bank Action Required: Prompt customer for approval (USSD/App/Web)
  • Next Status: processing (automatic), completed, or failed

Processing

  • Description: Customer approved, payment being processed
  • Bank Action Required: Complete the debit and update status
  • Next Status: completed or failed

Completed

  • Description: Transaction successfully completed
  • Bank Action Required: None (final status)
  • Note: Customer's account has been debited

Failed

  • Description: Transaction failed or declined
  • Bank Action Required: None (final status)
  • Note: Customer's account was not debited

All

  • Description: Returns all transactions regardless of status
  • Use Case: Historical reporting, reconciliation

Best Practices

1. Poll for Pending Transactions

Poll every 30 seconds for pending transactions to avoid excessive API calls and stay within rate limits.

2. Filter by Status for Reporting

Use status filters to get specific transaction types:

  • status=completed for reconciliation
  • status=failed for error analysis
  • status=pending for active processing
  • status=all for comprehensive reporting

3. Handle Empty Results

When no transactions match the filter criteria, the API returns an empty transactions array. Check the array length before processing.

4. Use UUID for Status Updates

Always use the uuid field (not id) when updating transaction status. The UUID is the unique transaction identifier across the FLUID Network.

5. Implement Error Handling

Implement retry logic with exponential backoff for server errors. Don't retry validation errors (422 status). Handle customer-not-found errors gracefully.

Common Integration Patterns

Pattern 1: Polling for Pending Transactions

Set up a background worker that polls the endpoint every 30 seconds to fetch pending transactions for active customers. When pending transactions are found, send approval prompts to customers via USSD or mobile app.

Pattern 2: Customer-Initiated Check

When a customer opens their mobile banking app or USSD menu, query the endpoint with their phone number to check for pending payments. Display the count, total amount, and transaction list if any exist.

Pattern 3: Webhook-Triggered Fetch

When FLUID sends a webhook notification about a new transaction, use the phone number from the webhook payload to fetch full transaction details. Locate the specific transaction by UUID and immediately send an approval prompt to the customer.

Pattern 4: Reconciliation Flow

For daily reconciliation, fetch all transactions for each customer using status=all, filter by date, and reconcile against internal bank records. Track totals by status (completed, failed, pending) for reporting.

Use Cases

1. Real-Time Transaction Processing

Poll this endpoint to fetch pending transactions and prompt customers for approval via USSD, mobile app, or web.

2. Customer Account Dashboard

Display pending payments when customer logs into mobile banking app or USSD menu.

3. Transaction Reconciliation

Fetch completed and failed transactions for daily reconciliation with internal bank records.

4. Reporting & Analytics

Retrieve all transactions for specific customers to generate reports, analyze patterns, or track volumes.

5. Customer Support

Lookup customer transactions when handling support inquiries about specific payments.

Rate Limits

  • Production: 200 requests per minute per bank
  • Sandbox: 60 requests per minute per bank

Rate Limiting: For polling use cases, implement exponential backoff and avoid polling more frequently than every 30 seconds to stay within rate limits.

Security Considerations

  1. Protect Customer Privacy: Only fetch transactions for customers registered with your bank
  2. Secure API Tokens: Store bank API tokens securely, never commit to source control
  3. Log Access: Audit all transaction queries for compliance
  4. URL Encode Phone Numbers: Always URL-encode phone numbers to prevent injection attacks
  5. Validate Phone Format: Verify phone numbers are in E.164 format before querying

Performance Tips

Optimize Polling Frequency

Avoid polling too frequently (e.g., every 5 seconds) as this exceeds rate limits. Instead, poll at reasonable intervals (every 30 seconds) to stay within the 200 requests per minute limit.

Cache Customer Data

Maintain a cache of customer data to avoid repeated lookups. Store phone numbers and last checked timestamps to reduce redundant API calls.

Batch Processing

Process multiple customers in parallel while respecting rate limits. Use batch sizes of 10 customers, add delays between batches (1-2 seconds), and ensure total requests stay within rate limits.

Troubleshooting

"Customer account not found" Error

Cause: Phone number not registered in your bank's system

Solution:

  • Verify phone number format is E.164 (+233241234567)
  • Confirm customer has an active account with your bank
  • Check customer is properly registered in FLUID system

Empty Transactions Array

Cause: No transactions match the filter criteria

Solution: Check if the customer has any transactions by querying with status=all. If no transactions exist at all, the customer has never had any FLUID transactions. If transactions exist but none match the filter, they simply don't have any in that status.

Rate Limit Exceeded

Cause: Too many requests in short time period

Solution:

  • Implement exponential backoff
  • Reduce polling frequency
  • Cache results when possible
  • Use webhooks instead of polling for real-time updates

Unauthorized Error

Cause: Invalid or missing API token

Solution:

  • Verify Bearer token is included in Authorization header
  • Check token hasn't expired
  • Confirm token belongs to a bank (not payment provider)
  • Regenerate token if necessary

Next Steps