Skip to main content

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:

ParameterTypeDescription
typestringFilter 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:

ParameterTypeDescription
idstringPartner 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:

FieldTypeDescription
labelstringDisplay label shown to the user (e.g., "Phone Number", "Card Number")
field_namestringJSON key name used in the details object when creating a payment method
requiredbooleanWhether the field must be filled
prefixstringPre-filled prefix (e.g., +258 for Mozambican phone numbers)
regexstringValidation pattern the input must match
sufixstringDisplay suffix (if any)
minsizeintegerMinimum character length
maxsizeintegerMaximum 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:

ParameterTypeDescription
idstringCustomer ID

Request Body:

{
"partner_id": "partner_kulpay",
"type": "mobile_wallet",
"details": {
"phone_number": "+258830000000"
}
}
FieldTypeRequiredDescription
partner_idstringYesPartner ID
typestringYescard, mobile_wallet, or bank_account
detailsobjectYesPayment method details (varies by type)

Details by Type:

TypeFields
cardcard_number, expiration_date, cvv, holder_name
mobile_walletphone_number
bank_accountaccount_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:

ParameterTypeDescription
idstringCustomer 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:

ParameterTypeDescription
idstringCustomer ID
payment_method_idstringPayment 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:

ParameterTypeDescription
idstringCustomer ID
payment_method_idstringPayment method ID

Request Body:

{
"status": "inactive"
}
FieldTypeRequiredValues
statusstringYesactive 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:

ParameterTypeDescription
idstringCustomer ID
payment_method_idstringPayment 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"
}
}
FieldTypeRequiredDescription
transaction_typestringYesTransaction type (see table below)
amountnumberConditionalAmount (required for payment transactions)
currencystringNoISO currency code
descriptionstringNoTransaction description
destinationstringNoDestination phone number or account
notify_customerbooleanNoSend SMS notification
metadatamapNoAdditional key-value data

Transaction Types:

TypeDescription
check_balanceQuery account balance
transferSend funds to another account
depositDeposit funds
pay_inProcess incoming payment
pay_outProcess outgoing payment
pay_billPay a bill
get_authorizationGet transaction authorization code
validataValidate 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:

ParameterTypeDescription
idstringCustomer ID

Query Parameters:

ParameterTypeDescription
payment_method_idstringFilter by payment method
typestringFilter by type: mobile_wallet, card, bank_account
statusstringFilter by status
descriptionstringFilter by description
partnerstringFilter by partner
pageintegerPage number
limitintegerResults 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:

ParameterTypeDescription
idstringCustomer ID
instruction_idstringTransaction instruction ID

Response:

{
"object": "transaction",
"transaction": {
"reference": "ref_abc123",
"instruction_id": "ins_abc123",
"transaction_type": "TRANSFER",
"amount": 500.00,
"currency": "MZN",
"status": "succeeded",
...
}
}

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"
}