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