WistfareWistfare Docs

Collections

Collect customer payments via mobile money, create reusable payment requests, and track collection status.

The collections flow is usually the first production feature teams implement with Wistfare. It is also the easiest place to validate that your API key, request serialization, and response handling are all wired correctly.

Install

npm install @wistfare/core @wistfare/payments
pip install wistfare
go get github.com/wistfare/wistfare-go
dependencies:
  wistfare_core: ^0.1.0
  wistfare_payments: ^0.1.0
cargo add wistfare
dependencies: [
  .package(path: "../sdks/swift")
]
implementation("com.wistfare:sdk:0.1.0")
dotnet add package Wistfare.Core
dotnet add package Wistfare.Payments

Get the Collections Client

import { Wistfare } from '@wistfare/core';
import { PaymentsClient } from '@wistfare/payments';

const wf = new Wistfare({
  apiKey: process.env.WISTFARE_API_KEY!,
});

const collections = new PaymentsClient(wf);
from wistfare import Wistfare

wf = Wistfare(api_key="wf_live_xxx")

collections = wf.payments
import (
  "os"

  "github.com/wistfare/wistfare-go/core"
  "github.com/wistfare/wistfare-go/payments"
)

client := core.New(os.Getenv("WISTFARE_API_KEY"))
collections := payments.New(client)
import 'package:wistfare_core/wistfare_core.dart';
import 'package:wistfare_payments/wistfare_payments.dart';

final wf = Wistfare(apiKey: 'wf_live_xxx');
final collections = PaymentsClient(wf);
use wistfare::Wistfare;

let client = Wistfare::new("wf_live_xxx")?;
let collections = client.payments();
import Wistfare

let client = try Wistfare(apiKey: "wf_live_xxx")
let collections = client.payments
import com.wistfare.sdk.Wistfare
import com.wistfare.sdk.WistfareConfig

val client = Wistfare(WistfareConfig(apiKey = "wf_live_xxx"))
val collections = client.payments
using Wistfare.Core;
using Wistfare.Payments;

var client = new WistfareClient(new WistfareOptions
{
    ApiKey = Environment.GetEnvironmentVariable("WISTFARE_API_KEY")!,
});

var collections = new PaymentsClient(client);

Choose the Right Flow

Collections and payment requests are related, but they are not the same thing.

Use caseAPIWhat happens
Charge a customer immediatelycollectionsWistfare creates a real payment transaction right away.
Create a QR, link, or reusable promptpayment-requestsWistfare creates a payable artifact that can later lead to one or more collections.

In practice:

  • Use a collection when your app already knows the wallet, amount, and customer phone, and you want to charge now.
  • Use a payment request when you need to show a QR code, generate a payment link, or hand a customer a reusable way to pay later.
  • A collection can reference a payment request, but it does not have to.

Collect a Payment

const collection = await collections.initiateCollection({
  businessId: 'biz_123',
  walletId: 'wal_456',
  customerPhone: '250788000000',
  amount: '10000',
  paymentMethod: 'mtn',
  currency: 'RWF',
  referenceId: 'inv_1234',
  description: 'Invoice #1234',
});
collection = collections.initiate_collection(
    business_id="biz_123",
    wallet_id="wal_456",
    customer_phone="250788000000",
    amount="10000",
    payment_method="mtn",
    currency="RWF",
    reference_id="inv_1234",
    description="Invoice #1234",
)
result, err := collections.InitiateCollection(ctx, &payments.InitiateCollectionParams{
  BusinessID:    "biz_123",
  WalletID:      "wal_456",
  CustomerPhone: "250788000000",
  Amount:        "10000",
  PaymentMethod: "mtn",
  Currency:      "RWF",
  ReferenceID:   "inv_1234",
  Description:   "Invoice #1234",
})
final collection = await collections.initiateCollection(
  InitiateCollectionParams(
    businessId: 'biz_123',
    walletId: 'wal_456',
    customerPhone: '250788000000',
    amount: '10000',
    paymentMethod: 'mtn',
    currency: 'RWF',
    referenceId: 'inv_1234',
    description: 'Invoice #1234',
  ),
);
use wistfare::InitiateCollectionParams;

let collection = collections
    .initiate_collection(InitiateCollectionParams {
        business_id: "biz_123".into(),
        wallet_id: Some("wal_456".into()),
        customer_phone: "250788000000".into(),
        amount: "10000".into(),
        payment_method: "mtn".into(),
        currency: Some("RWF".into()),
        reference_id: Some("inv_1234".into()),
        description: Some("Invoice #1234".into()),
        payment_request_id: None,
    })
    .await?;
let collection = try await collections.initiateCollection(
  .init(
    businessId: "biz_123",
    walletId: "wal_456",
    customerPhone: "250788000000",
    amount: "10000",
    paymentMethod: "mtn",
    currency: "RWF",
    referenceId: "inv_1234",
    description: "Invoice #1234"
  )
)
val collection = collections.initiateCollection(
    businessId = "biz_123",
    walletId = "wal_456",
    customerPhone = "250788000000",
    amount = "10000",
    paymentMethod = "mtn",
    currency = "RWF",
    referenceId = "inv_1234",
    description = "Invoice #1234",
)
var result = await collections.InitiateCollectionAsync(new InitiateCollectionParams
{
    BusinessId = "biz_123",
    WalletId = "wal_456",
    CustomerPhone = "250788000000",
    Amount = "10000",
    PaymentMethod = "mtn",
    Currency = "RWF",
    ReferenceId = "inv_1234",
    Description = "Invoice #1234",
});
curl -X POST https://api-production.wistfare.com/v1/collections \
  -H "X-API-Key: wf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "businessId": "biz_123",
    "walletId": "wal_456",
    "customerPhone": "250788000000",
    "amount": "10000",
    "paymentMethod": "mtn",
    "currency": "RWF",
    "referenceId": "inv_1234",
    "description": "Invoice #1234"
  }'

Response

A successful collection request returns a Collection object:

{
  "id": "col_abc123",
  "businessId": "biz_123",
  "walletId": "wal_456",
  "customerPhone": "250788000000",
  "amount": "10000",
  "currency": "RWF",
  "paymentMethod": "mtn",
  "referenceId": "inv_1234",
  "status": "pending",
  "description": "Invoice #1234",
  "createdAt": "2026-03-19T10:30:00Z",
  "updatedAt": "2026-03-19T10:30:00Z"
}
FieldTypeDescription
idstringUnique collection identifier
businessIdstringThe business that initiated the collection
walletIdstringDestination wallet for collected funds
customerPhonestringCustomer phone number charged
amountstringCollection amount
currencystringCurrency code (e.g. RWF)
paymentMethodstringPayment rail used (mtn, airtel_Rw)
referenceIdstringYour reference ID for this collection
statusstringOne of pending, completed, failed
descriptionstringHuman-readable description
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp

List

Retrieve collections with optional filters. All filter fields are optional — pass only what you need.

FilterTypeDescription
businessIdstringFilter by business
referenceIdstringFind the collection matching your reference ID
statusstringFilter by status (pending, completed, failed)
fromDatestringStart of date range (ISO 8601)
toDatestringEnd of date range (ISO 8601)
pagenumberPage number for pagination
perPagenumberResults per page
// List all collections for a business
const result = await collections.listCollections({
  businessId: 'biz_123',
});

// Find by reference ID
const result = await collections.listCollections({
  businessId: 'biz_123',
  referenceId: 'inv_1234',
});

// Filter by status and date range
const result = await collections.listCollections({
  businessId: 'biz_123',
  status: 'completed',
  fromDate: '2026-03-01T00:00:00Z',
  toDate: '2026-03-19T23:59:59Z',
  page: 1,
  perPage: 20,
});
# List all collections for a business
result = collections.list_collections(business_id="biz_123")

# Find by reference ID
result = collections.list_collections(
    business_id="biz_123",
    reference_id="inv_1234",
)

# Filter by status and date range
result = collections.list_collections(
    business_id="biz_123",
    status="completed",
    from_date="2026-03-01T00:00:00Z",
    to_date="2026-03-19T23:59:59Z",
    page=1,
    per_page=20,
)
// List all collections for a business
result, err := collections.ListCollections(ctx, &payments.ListCollectionsParams{
  BusinessID: "biz_123",
})

// Find by reference ID
result, err := collections.ListCollections(ctx, &payments.ListCollectionsParams{
  BusinessID:  "biz_123",
  ReferenceID: "inv_1234",
})

// Filter by status and date range
result, err := collections.ListCollections(ctx, &payments.ListCollectionsParams{
  BusinessID: "biz_123",
  Status:     "completed",
  FromDate:   "2026-03-01T00:00:00Z",
  ToDate:     "2026-03-19T23:59:59Z",
  Page:       1,
  PerPage:    20,
})
// List all collections for a business
final result = await collections.listCollections(
  businessId: 'biz_123',
);

// Find by reference ID
final result = await collections.listCollections(
  businessId: 'biz_123',
  referenceId: 'inv_1234',
);

// Filter by status and date range
final result = await collections.listCollections(
  businessId: 'biz_123',
  status: 'completed',
  fromDate: '2026-03-01T00:00:00Z',
  toDate: '2026-03-19T23:59:59Z',
  page: 1,
  perPage: 20,
);
// List all collections for a business
var result = await collections.ListCollectionsAsync(new ListCollectionsParams
{
    BusinessId = "biz_123",
});

// Find by reference ID
var result = await collections.ListCollectionsAsync(new ListCollectionsParams
{
    BusinessId = "biz_123",
    ReferenceId = "inv_1234",
});

// Filter by status and date range
var result = await collections.ListCollectionsAsync(new ListCollectionsParams
{
    BusinessId = "biz_123",
    Status = "completed",
    FromDate = "2026-03-01T00:00:00Z",
    ToDate = "2026-03-19T23:59:59Z",
    Page = 1,
    PerPage = 20,
});
# List all collections for a business
curl -X GET "https://api-production.wistfare.com/v1/collections?businessId=biz_123" \
  -H "X-API-Key: wf_live_xxx"

# Find by reference ID
curl -X GET "https://api-production.wistfare.com/v1/collections?businessId=biz_123&referenceId=inv_1234" \
  -H "X-API-Key: wf_live_xxx"

# Filter by status and date range
curl -X GET "https://api-production.wistfare.com/v1/collections?businessId=biz_123&status=completed&fromDate=2026-03-01T00:00:00Z&toDate=2026-03-19T23:59:59Z&page=1&perPage=20" \
  -H "X-API-Key: wf_live_xxx"

Create a Payment Request

If you need a QR code, link, or reusable payment prompt, use a payment request instead of charging the customer immediately.

const request = await collections.createPaymentRequest({
  businessId: 'biz_123',
  walletId: 'wal_456',
  requestType: 'one_time',
  amount: '5000',
  currency: 'RWF',
  referenceId: 'table_4_lunch',
  description: 'Table 4 - Lunch',
});
request = collections.create_payment_request(
    business_id="biz_123",
    wallet_id="wal_456",
    request_type="one_time",
    amount="5000",
    currency="RWF",
    reference_id="table_4_lunch",
    description="Table 4 - Lunch",
)
request, err := collections.CreatePaymentRequest(ctx, &payments.CreatePaymentRequestParams{
  BusinessID:  "biz_123",
  WalletID:    "wal_456",
  RequestType: "one_time",
  Amount:      "5000",
  Currency:    "RWF",
  ReferenceID: "table_4_lunch",
  Description: "Table 4 - Lunch",
})
final request = await collections.createPaymentRequest(
  CreatePaymentRequestParams(
    businessId: 'biz_123',
    walletId: 'wal_456',
    requestType: PaymentRequestType.oneTime,
    amount: '5000',
    currency: 'RWF',
    referenceId: 'table_4_lunch',
    description: 'Table 4 - Lunch',
  ),
);
var request = await collections.CreatePaymentRequestAsync(new CreatePaymentRequestParams
{
    BusinessId = "biz_123",
    WalletId = "wal_456",
    RequestType = "one_time",
    Amount = "5000",
    Currency = "RWF",
    ReferenceId = "table_4_lunch",
    Description = "Table 4 - Lunch",
});
curl -X POST https://api-production.wistfare.com/v1/payment-requests \
  -H "X-API-Key: wf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "businessId": "biz_123",
    "walletId": "wal_456",
    "requestType": "one_time",
    "amount": "5000",
    "currency": "RWF",
    "referenceId": "table_4_lunch",
    "description": "Table 4 - Lunch"
  }'

Response

{
  "id": "pr_xyz789",
  "businessId": "biz_123",
  "walletId": "wal_456",
  "requestType": "one_time",
  "amount": "5000",
  "currency": "RWF",
  "referenceId": "table_4_lunch",
  "status": "active",
  "description": "Table 4 - Lunch",
  "createdAt": "2026-03-19T11:00:00Z",
  "updatedAt": "2026-03-19T11:00:00Z"
}

Preview SDK coverage

Rust, Swift, and Kotlin currently expose collection-first flows but do not yet ship a first-class payment-request helper. Use the cURL example above if you need payment-request creation from those stacks today.

Where Fees Fit In

Collections and payment requests both interact with your fee configuration, but fee inspection belongs on its own page. Use Fees when you need to read the current fee setup or preview the fee before you charge the customer.

On this page