Partner & Payment Methods Service
Manages payment partners, customer payment methods, and transaction processing.
List Partners
GET /v1/partners
Lists all available payment partners and their configurations.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
type | string | Filter by partner type (optional) |
Response:
{
"object": "list",
"data": [
{
"name": "Kulpay Mobile Wallet",
"partner_id": "partner_kulpay",
"pm_types": [
{
"type": "mobile_wallet",
"attributes": [
{
"label": "Phone Number",
"field_name": "phone_number",
"required": true,
"prefix": "+258",
"regex": "^\\d{9}$",
"sufix": "",
"minsize": 9,
"maxsize": 9
}
]
}
]
}
],
"has_more": false
}
Get Partner
GET /v1/partners/{id}
Retrieves a single partner and its configuration.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Partner ID |
Response:
{
"object": "partner",
"partner": {
"name": "Card Simo",
"partner_id": "partner_simo",
"pm_types": [
{
"type": "card",
"attributes": [
{
"label": "Card Number",
"field_name": "card_number",
"required": true,
"prefix": "",
"regex": "^\\d{16}$",
"sufix": "",
"minsize": 16,
"maxsize": 16
},
{
"label": "Expiration Date",
"field_name": "expiration_date",
"required": true,
"prefix": "",
"regex": "^\\d{2}/\\d{2}$",
"sufix": "",
"minsize": 5,
"maxsize": 5
}
]
}
]
}
}
Dynamic UI Configuration
Partners define how client applications render payment method forms through the Attribute model. When a mobile app or portal needs to display a form for adding a payment method, it fetches the partner configuration and dynamically builds the UI from the attributes list.
How It Works
Each Attribute defines a single form field:
| Field | Type | Description |
|---|---|---|
label | string | Display label shown to the user (e.g., "Phone Number", "Card Number") |
field_name | string | JSON key name used in the details object when creating a payment method |
required | boolean | Whether the field must be filled |
prefix | string | Pre-filled prefix (e.g., +258 for Mozambican phone numbers) |
regex | string | Validation pattern the input must match |
sufix | string | Display suffix (if any) |
minsize | integer | Minimum character length |
maxsize | integer | Maximum character length |
Example: Rendering a Mobile Wallet Form
Given this partner response:
{
"type": "mobile_wallet",
"attributes": [
{
"label": "Phone Number",
"field_name": "phone_number",
"required": true,
"prefix": "+258",
"regex": "^\\d{9}$",
"minsize": 9,
"maxsize": 9
}
]
}
The app would render:
- A text input labeled "Phone Number"
- Pre-filled with +258
- Accepting exactly 9 digits after the prefix
- Validated against
^\d{9}$before submission
The resulting POST /v1/customers/{id}/payment_methods body would use the field_name as the key:
{
"partner_id": "partner_kulpay",
"type": "mobile_wallet",
"details": {
"phone_number": "+258830000000"
}
}
Technical Decision: The attribute-driven form system was designed so that new payment partners can be onboarded without any mobile app changes. When a new partner is added to Kulpay API with its attribute configuration, the app automatically renders the correct form fields. This decouples partner onboarding from app release cycles.
Create Payment Method
POST /v1/customers/{id}/payment_methods
Creates a new payment method for a customer.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
Request Body:
{
"partner_id": "partner_kulpay",
"type": "mobile_wallet",
"details": {
"phone_number": "+258830000000"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
partner_id | string | Yes | Partner ID |
type | string | Yes | card, mobile_wallet, or bank_account |
details | object | Yes | Payment method details (varies by type) |
Details by Type:
| Type | Fields |
|---|---|
card | card_number, expiration_date, cvv, holder_name |
mobile_wallet | phone_number |
bank_account | account_number, nib, holder_name, bank_name |
Response:
{
"object": "payment_method",
"payment_method": {
"id": "pm_abc123",
"account_id": "cus_abc12345",
"type": "mobile_wallet",
"partner_id": "partner_kulpay",
"details": {
"phone_number": "+258830000000"
},
"status": "active"
}
}
List Payment Methods
GET /v1/customers/{id}/payment_methods
Lists all payment methods for a customer.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
Response:
{
"object": "list",
"data": [
{
"id": "pm_abc123",
"account_id": "cus_abc12345",
"type": "mobile_wallet",
"partner_id": "partner_kulpay",
"details": { ... },
"status": "active"
}
]
}
Get Payment Method
GET /v1/customers/{id}/payment_methods/{payment_method_id}
Retrieves a specific payment method.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
payment_method_id | string | Payment method ID |
Response:
{
"object": "payment_method",
"payment_method": { ... }
}
Set Payment Method Status
POST /v1/customers/{id}/payment_methods/{payment_method_id}/status
Activates or deactivates a payment method.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
payment_method_id | string | Payment method ID |
Request Body:
{
"status": "inactive"
}
| Field | Type | Required | Values |
|---|---|---|---|
status | string | Yes | active or inactive |
Response:
{
"object": "payment_method",
"payment_method": {
"id": "pm_abc123",
"status": "inactive",
...
}
}
Process Transaction
POST /v1/customers/{id}/payment_methods/{payment_method_id}/transactions
Processes a financial transaction through a payment method.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
payment_method_id | string | Payment method ID |
Request Body:
{
"transaction_type": "transfer",
"amount": 500.00,
"currency": "MZN",
"description": "Transfer to Jane",
"destination": "+258830000001",
"notify_customer": true,
"metadata": {
"reference": "TRF-001"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
transaction_type | string | Yes | Transaction type (see table below) |
amount | number | Conditional | Amount (required for payment transactions) |
currency | string | No | ISO currency code |
description | string | No | Transaction description |
destination | string | No | Destination phone number or account |
notify_customer | boolean | No | Send SMS notification |
metadata | map | No | Additional key-value data |
Transaction Types:
| Type | Description |
|---|---|
check_balance | Query account balance |
transfer | Send funds to another account |
deposit | Deposit funds |
pay_in | Process incoming payment |
pay_out | Process outgoing payment |
pay_bill | Pay a bill |
get_authorization | Get transaction authorization code |
validata | Validate payment method |
Response:
{
"object": "transaction",
"transaction_id": "txn_abc123",
"transaction_type": "TRANSFER",
"status": "succeeded",
"balance": null,
"authorization": null,
"processed_at": "2025-01-15T10:30:00Z",
"error_code": null,
"error_message": null
}
For check_balance transactions:
{
"object": "transaction",
"transaction_type": "BALANCE_QUERY",
"status": "succeeded",
"balance": {
"available": 15000.00,
"pending": 500.00,
"currency": "MZN"
}
}
Get Transaction History
GET /v1/customers/{id}/transactions
Retrieves transaction history for a customer.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
payment_method_id | string | Filter by payment method |
type | string | Filter by type: mobile_wallet, card, bank_account |
status | string | Filter by status |
description | string | Filter by description |
partner | string | Filter by partner |
page | integer | Page number |
limit | integer | Results per page |
Response:
{
"object": "list",
"data": [
{
"reference": "ref_abc123",
"instruction_id": "ins_abc123",
"transaction_type": "TRANSFER",
"amount": 500.00,
"currency": "MZN",
"description": "Transfer to Jane",
"destination": "+258830000001",
"status": "succeeded",
"role": "sender",
"created_at": "2025-01-15T10:30:00Z",
"processed_at": "2025-01-15T10:30:05Z"
}
],
"has_more": false
}
Get Transaction Details
GET /v1/customers/{id}/transactions/{instruction_id}
Retrieves details of a specific transaction.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Customer ID |
instruction_id | string | Transaction instruction ID |
Response:
{
"object": "transaction",
"transaction": {
"reference": "ref_abc123",
"instruction_id": "ins_abc123",
"transaction_type": "TRANSFER",
"amount": 500.00,
"currency": "MZN",
"status": "succeeded",
...
}
}
Get Card Logo
POST /v1/partners/get-logo
Retrieves the logo for a card based on the card number (BIN lookup).
Request Body:
{
"card_number": "4111111111111111"
}
Response:
{
"object": "image file",
"logo": "base64_encoded_logo",
"card_number": "4111111111111111"
}