Skip to main content

Collection API

Author: Josh S. Sakweli,Lead Backend Lead Team
Last Updated: 2025-10-272026-03-06
Version: v1.0

Base URL: https://api.nextgate.com/co.tz/api/v1

Short Description: The Payment MethodsCollection API enableshandles wallet top-up flows for NextGate users. It allows users to managedeposit money into their paymentNextGate instrumentswallet including credit/debit cards,via mobile money (M-Pesa,USSD Airtelpush) Money),or bank transfers, PayPal, cryptocurrencies, wallets, gift cards, and cash on delivery options. This API provides secure storage, retrieval, updating, and deletion ofcard payment methodsthrough withSelcom. built-inAll validationsubsequent andplatform duplicatepayments detection.(events, products) are made from the wallet balance.

Hints:

  • AllAlways endpointsprovide requirea authenticationunique viaidempotencyKey Bearerper tokenrequest into prevent duplicate charges
  • For USSD channels the Authorizationuser headerreceives a PIN prompt on their phone — poll /status/{id} to track completion
  • SensitiveFor dataCARD (cardchannel numbers,the accountresponse numbers,contains PINs)a arepaymentUrl — redirect the user to complete payment
  • Selcom webhooks automatically tokenized and masked in responses
  • Only one payment method can be set as default at a time; setting a new default automatically unsetscredit the previouswallet one
  • on
  • Paymentconfirmation methods supportno softmanual verificationstep status tracking (isVerified, isActive flags)
  • The API uses ISO 8601 format for timestamps (YYYY-MM-DDTHH:mm:ss)
  • Metadata fields accept custom JSON objects for storing gateway-specific information
  • Duplicate payment methods (same card number, email, phone number, etc.) are automatically detected and rejectedneeded

Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": {
    // Actual response data goes here
  }
}

Error Response Structure

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Error description",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": "Error description"
}

Standard Response Fields

Field Type Description
success boolean Always true for successful operations,success, false for errors
httpStatus string HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.)
message string Human-readable messageresult describing the operation resultdescription
action_time string ISO 8601 timestamp of when the response was generated
data object/string Response payload for success,or error details for failures

HTTPFlow Method Badge StandardsDiagram

For

User
 better|
 visual|--- clarity,POST all endpoints use colored badges for HTTP methods with the following standard colors:

  • GET/collection/initiate --------> GETCollectionController | (channel, amount, msisdn) | | Validate request | Check idempotency | Save CollectionRequest (PENDING) | | | .----------------. | | | | USSD CARD | | | | Push USSD to Create Selcom | Selcom API Checkout Order | | | | Status: AWAITING Status: AWAITING | CUSTOMER_ACTION CUSTOMER_ACTION | | | |<-- Response (requestId) ------'----------------' Green| | [USSD: User enters PIN on phone] | [CARD: User pays on paymentUrl ] | | Selcom Webhook ---------> /api/selcom/webhook | (Safe,payment read-onlyconfirmed) operations)
  • |
  • POST| creditWallet() | Status: COMPLETED | |--- GET /collection/status/{id} -------> POSTStatus: COMPLETED |<-- Blue{ (Createstatus, newtransactionRef, resources)
  • ...
  • PUT} - PUT - Yellow (Update/replace entire resource)
  • PATCH - PATCH - Orange (Partial updates)
  • DELETE - DELETE - Red (Remove resources)

Available Enums

Payment Method Types

Use these exact values for the paymentMethodType field:

Enum ValueDescriptionCommon Use Cases
CREDIT_CARDCredit card paymentsVisa, Mastercard, Amex, Discover
DEBIT_CARDDebit card paymentsVisa Debit, Mastercard Debit
PAYPALPayPal account paymentsPayPal email-based payments
BANK_TRANSFERDirect bank account transfersACH, Wire transfers, local bank payments
CRYPTOCURRENCYCrypto wallet paymentsBitcoin, Ethereum, USDT, etc.
MOBILE_PAYMENTMobile payment servicesApple Pay, Google Pay, Samsung Pay
MNO_PAYMENTMobile Network Operator paymentsM-Pesa, Airtel Money, Tigo Pesa
WALLETDigital wallet servicesSkrill, Neteller, PayTM
GIFT_CARDGift card paymentsStore gift cards, prepaid cards
CASH_ON_DELIVERYCash payment upon deliveryCOD orders

Mobile Network Operators (Tanzania)

Use these exact values for the mccMnc field when paymentMethodType is MNO_PAYMENT:

Enum ValueOperator NameNetwork
M_PESAM-PesaVodacom Tanzania
AIRTEL_MONEYAirtel MoneyAirtel Tanzania
TIGO_PESATigo PesaTigo Tanzania
HALO_PESAHalo PesaHalotel Tanzania
AZAM_PESAAzam PesaAzam Telecom
EZY_PESAEzy PesaZantel

Banks (Tanzania)

Use these exact values for the bankName field when paymentMethodType is BANK_TRANSFER:

Enum ValueBank Name
CRDB_BANKCRDB Bank PLC
NMB_BANKNational Microfinance Bank
EXIM_BANKEXIM Bank Tanzania
KCB_BANKKenya Commercial Bank
NBC_BANKNational Bank of Commerce
STANBIC_BANKStanbic Bank Tanzania
DIAMOND_BANKDiamond Trust Bank
ACCESS_BANKAccess Bank Tanzania
AZANIA_BANKAzania Bank
EQUITY_BANKEquity Bank Tanzania
FNB_BANKFirst National Bank

Note: While these enum values are available, you can also use free-text bank names if your bank is not listed.

Card Types

Common values for the cardType field (free-text, not strictly enforced):

ValueDescription
VisaVisa credit/debit cards
MastercardMastercard credit/debit cards
American ExpressAmerican Express cards
DiscoverDiscover cards
Diners ClubDiners Club cards
JCBJCB cards
UnionPayChina UnionPay cards

Cryptocurrency Types

Common values for the cryptoType field (free-text, not strictly enforced):

ValueDescription
BitcoinBitcoin (BTC)
EthereumEthereum (ETH)
TetherTether USDT
USD CoinUSDC stablecoin
Binance CoinBNB
CardanoADA
SolanaSOL
PolkadotDOT

Account Types

Common values for the accountType field in bank transfers (free-text):

ValueDescription
CheckingChecking/Current account
SavingsSavings account
BusinessBusiness account
Money MarketMoney market account

Mobile Payment Providers

Common values for the provider field (free-text, not strictly enforced):

ValueDescription
Apple PayApple Pay mobile payments
Google PayGoogle Pay mobile payments
Samsung PaySamsung Pay mobile payments
WeChat PayWeChat Pay
AlipayAlipay

Wallet Types

Common values for the walletType field (free-text, not strictly enforced):

ValueDescription
SkrillSkrill digital wallet
NetellerNeteller e-wallet
PayTMPayTM wallet
PayUPayU wallet
PayoneerPayoneer account

Currency Codes

Use ISO 4217 3-letter currency codes for the currency field:

CodeCurrency
USDUS Dollar
EUREuro
GBPBritish Pound
TZSTanzanian Shilling
KESKenyan Shilling
UGXUgandan Shilling
ZARSouth African Rand
NGNNigerian Naira

Endpoints


1. CreateInitiate Payment MethodCollection

Purpose: CreateInitiates a newwallet paymenttop-up methodrequest forvia themobile authenticatedmoney user(USSD) withor supportcard for multiple payment typespayment.

Endpoint: POST {base_url}/payment-methodscollection/initiate

Access Level: 🔒 Protected (Requires Bearer Token Authentication)

Authentication: Bearer Token

Quick Reference - Required Fields by Payment Type:

Payment TypeRequired Fields in methodDetails
CREDIT_CARD / DEBIT_CARDcardType, cardNumber, expiry, cardholderName
PAYPALemail
BANK_TRANSFERbankName, accountNumber, accountHolderName
CRYPTOCURRENCYcryptoType, walletAddress
MOBILE_PAYMENTprovider
MNO_PAYMENTphoneNumber
WALLETNone (all optional, but walletType or walletId recommended)
GIFT_CARDpin, balance, currency
CASH_ON_DELIVERYNone (all optional)

Request Headers:

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token for authentication (format: "Bearer {token}")
Content-TypestringYesMust be "application/json"

Request JSON Sample - Credit/Debit Card:

{
  "paymentMethodType": "CREDIT_CARD",
  "methodDetails": {
    "cardType": "Visa",
    "cardNumber": "4532015112830366",
    "expiry": "12/2027",
    "cardholderName": "John Doe"
  },
  "billingAddress": {
    "street": "123 Main Street",
    "city": "Dar es Salaam",
    "state": "Dar es Salaam",
    "postalCode": "12345",
    "country": "Tanzania"
  },
  "metadata": {
    "preferred": true,
    "notes": "Primary business card"
  },
  "isDefault": true
}

Request JSON Sample - Mobile Money (M-Pesa):

{
  "paymentMethodType": "MNO_PAYMENT",
  "methodDetails": {
    "phoneNumber": "+255712345678",
    "mccMnc": "M-PESA"
  },
  "isDefault": true
}

Request JSON Sample - PayPal:

{
  "paymentMethodType": "PAYPAL",
  "methodDetails": {
    "email": "john.doe@example.com",
    "paypalId": "johndoe123"
  },
  "isDefault": false
}

Request JSON Sample - Bank Transfer:

{
  "paymentMethodType": "BANK_TRANSFER",
  "methodDetails": {
    "bankName": "CRDB Bank",
    "accountNumber": "1234567890",
    "routingNumber": "021000021",
    "accountType": "Checking",
    "accountHolderName": "John Doe"
  },
  "billingAddress": {
    "street": "456 Bank Avenue",
    "city": "Dar es Salaam",
    "country": "Tanzania"
  },
  "isDefault": false
}

Request JSON Sample - Cryptocurrency:

{
  "paymentMethodType": "CRYPTOCURRENCY",
  "methodDetails": {
    "cryptoType": "Bitcoin",
    "walletAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
    "network": "BTC Mainnet"
  },
  "isDefault": false
}

Request JSON Sample - Mobile Payment (Apple Pay/Google Pay):

{
  "paymentMethodType": "MOBILE_PAYMENT",
  "methodDetails": {
    "provider": "Apple Pay",
    "deviceId": "iPhone-12-Pro-XYZ123"
  },
  "isDefault": false
}

Request JSON Sample - Digital Wallet:

{
  "paymentMethodType": "WALLET",
  "methodDetails": {
    "walletType": "Skrill",
    "walletId": "john.doe@example.com"
  },
  "isDefault": false
}

Request JSON Sample - Gift Card:

{
  "paymentMethodType": "GIFT_CARD",
  "methodDetails": {
    "pin": "1234567890123456",
    "balance": 50.00,
    "currency": "USD"
  },
  "isDefault": false
}

Request JSON Sample - Cash on Delivery:

{
  "paymentMethodType": "CASH_ON_DELIVERY",
  "methodDetails": {
    "instructions": "Please call 30 minutes before delivery"
  },
  "isDefault": false
}

Request Body Parameters:

ParameterTypeRequiredDescriptionValidation
paymentMethodTypestring (enum)YesType of payment methodREQUIRED ENUM: Must be one of: CREDIT_CARD, DEBIT_CARD, PAYPAL, BANK_TRANSFER, CRYPTOCURRENCY, MOBILE_PAYMENT, MNO_PAYMENT, WALLET, GIFT_CARD, CASH_ON_DELIVERY (See Payment Method Types section)
methodDetailsobjectYesPayment method specific detailsVaries by payment type (see nested fields)
methodDetails.cardTypestringConditionalCard brand (e.g., Visa, Mastercard)Required for CREDIT_CARD/DEBIT_CARD. See Card Types for common values
methodDetails.cardNumberstringConditionalFull card numberRequired for CREDIT_CARD/DEBIT_CARD. Pattern: ^[0-9]{13,19}$
methodDetails.expirystringConditionalCard expiration dateRequired for CREDIT_CARD/DEBIT_CARD. Format: MM/YY or MM/YYYY
methodDetails.cardholderNamestringConditionalName on cardRequired for CREDIT_CARD/DEBIT_CARD. Min: 2, Max: 100 characters
methodDetails.emailstringConditionalPayPal email addressRequired for PAYPAL. Must be valid email format
methodDetails.paypalIdstringNoPayPal account IDOptional for PAYPAL
methodDetails.bankNamestringConditionalName of bankRequired for BANK_TRANSFER. See Banks (Tanzania) for enum values or use free-text. Min: 2, Max: 100 characters
methodDetails.accountNumberstringConditionalBank account numberRequired for BANK_TRANSFER
methodDetails.routingNumberstringNoBank routing numberOptional for BANK_TRANSFER
methodDetails.accountTypestringNoAccount typeOptional for BANK_TRANSFER. See Account Types for common values
methodDetails.accountHolderNamestringConditionalAccount holder's nameRequired for BANK_TRANSFER. Min: 2, Max: 100 characters
methodDetails.cryptoTypestringConditionalCryptocurrency nameRequired for CRYPTOCURRENCY. See Cryptocurrency Types for common values
methodDetails.walletAddressstringConditionalCrypto wallet addressRequired for CRYPTOCURRENCY
methodDetails.networkstringNoBlockchain network (e.g., "BTC Mainnet", "Ethereum Mainnet")Optional for CRYPTOCURRENCY
methodDetails.providerstringConditionalPayment provider nameRequired for MOBILE_PAYMENT. See Mobile Payment Providers for common values
methodDetails.deviceIdstringNoDevice identifierOptional for MOBILE_PAYMENT
methodDetails.walletTypestringNoWallet service nameOptional for WALLET. See Wallet Types for common values
methodDetails.walletIdstringNoWallet account identifierOptional for WALLET
methodDetails.pinstringConditionalGift card PINRequired for GIFT_CARD
methodDetails.balancenumberConditionalGift card balanceRequired for GIFT_CARD. Min: 0.01
methodDetails.currencystringConditionalCurrency codeRequired for GIFT_CARD. REQUIRED: ISO 4217 3-letter code (e.g., USD, EUR, TZS). See Currency Codes
methodDetails.instructionsstringNoDelivery instructionsOptional for CASH_ON_DELIVERY
methodDetails.phoneNumberstringConditionalMobile money phone numberRequired for MNO_PAYMENT. Pattern: ^+[1-9]\d{8,14}$ (E.164 format, e.g., +255712345678)
methodDetails.mccMncstringNoMobile network operatorOptional for MNO_PAYMENT. ENUM: See Mobile Network Operators for available values: M_PESA, AIRTEL_MONEY, TIGO_PESA, HALO_PESA, AZAM_PESA, EZY_PESA
methodDetails.gatewayMetadataobjectNoAdditional gateway-specific metadataOptional, accepts any JSON object
billingAddressobjectNoBilling address informationOptional
billingAddress.streetstringConditionalStreet addressRequired if billingAddress provided
billingAddress.citystringConditionalCity nameRequired if billingAddress provided
billingAddress.statestringNoState or provinceOptional
billingAddress.postalCodestringNoPostal or ZIP codeOptional
billingAddress.countrystringConditionalCountry nameRequired if billingAddress provided
metadataobjectNoCustom metadata as key-value pairsOptional, accepts any JSON object
isDefaultbooleanNoSet as default payment methodDefault: false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Payment method created successfully",
  "action_time": "2025-10-27T10:30:45",
  "data": {
    "paymentMethodId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "ownerId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "ownerUserName": "johndoe",
    "paymentMethodType": "CREDIT_CARD",
    "methodDetails": {
      "cardType": "Visa",
      "maskedCardNumber": "**** **** **** 0366",
      "expiry": "12/2027",
      "cardholderName": "John Doe"
    },
    "billingAddress": {
      "street": "123 Main Street",
      "city": "Dar es Salaam",
      "state": "Dar es Salaam",
      "postalCode": "12345",
      "country": "Tanzania"
    },
    "metadata": {
      "preferred": true,
      "notes": "Primary business card"
    },
    "isDefault": true,
    "isActive": true,
    "isVerified": false,
    "createdAt": "2025-10-27T10:30:45",
    "updatedAt": "2025-10-27T10:30:45"
  }
}

Success Response Fields:

FieldDescription
paymentMethodIdUnique identifier for the payment method (UUID)
ownerIdUser account ID who owns this payment method
ownerUserNameUsername of the payment method owner
paymentMethodTypeType of payment method created
methodDetailsPayment-specific details with sensitive data masked
methodDetails.maskedCardNumberCard number with only last 4 digits visible (format: "**** **** **** 1234")
methodDetails.maskedAccountNumberBank account with only last 4 digits visible (format: "****1234")
methodDetails.maskedPhoneNumberPhone number partially masked (format: "+254****5678")
methodDetails.maskedWalletAddressCrypto wallet showing first and last 4 characters (format: "1A1z...fNa")
methodDetails.maskedPinPIN completely masked (format: "****")
billingAddressBilling address if provided
metadataCustom metadata object if provided
isDefaultWhether this is the default payment method
isActiveWhether the payment method is currently active
isVerifiedWhether the payment method has been verified
createdAtTimestamp when payment method was created
updatedAtTimestamp of last update

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Payment method with similar details already exists for your account",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method with similar details already exists for your account"
}

Standard Error Types:

Application-Level Exceptions (400-499)

  • 400 BAD_REQUEST: Invalid payment details, duplicate payment method, or missing required fields
  • 401 UNAUTHORIZED: Missing, invalid, or expired authentication token
  • 404 NOT_FOUND: Authenticated user account not found
  • 422 UNPROCESSABLE_ENTITY: Validation errors with detailed field information

Server-Level Exceptions (500+)

  • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

Error Response Examples:

Bad Request - Missing Required Fields (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Card number is required",
  "action_time": "2025-10-27T10:30:45",
  "data": "Card number is required"
}

Bad Request - Duplicate Payment Method (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Payment method with similar details already exists for your account",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method with similar details already exists for your account"
}

Unauthorized - Invalid Token (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Invalid or expired authentication token",
  "action_time": "2025-10-27T10:30:45",
  "data": "Invalid or expired authentication token"
}

Not Found - User Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "User not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "User not found"
}

Validation Error (422):

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-10-27T10:30:45",
  "data": {
    "cardNumber": "Invalid card number",
    "expiry": "Invalid expiry format (MM/YY)",
    "email": "must be a well-formed email address"
  }
}

2. Get Payment Method by ID

Purpose: Retrieve detailed information about a specific payment method

Endpoint: GET {base_url}/payment-methods/{paymentMethodId}

Access Level: 🔒 Protected (RequiresAuthorization: Bearer Token, Owner only)

Authentication: Bearer Token<token>

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication (format: "Bearer {token}")

Path Parameters:

ParameterTypeRequiredDescriptionValidation
paymentMethodIdUUIDYesUnique identifier of the payment methodValid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Payment method retrieved successfully",
  "action_time": "2025-10-27T10:30:45",
  "data": {
    "paymentMethodId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "ownerId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "ownerUserName": "johndoe",
    "paymentMethodType": "MNO_PAYMENT",
    "methodDetails": {
      "maskedPhoneNumber": "+255****5678",
      "mccMnc": "M-PESA"
    },
    "isDefault": true,
    "isActive": true,
    "isVerified": true,
    "createdAt": "2025-10-20T08:15:30",
    "updatedAt": "2025-10-27T10:30:45"
  }
}

Success Response Fields:

FieldDescription
paymentMethodIdUnique identifier of the payment method
ownerIdUser account ID who owns this payment method
ownerUserNameUsername of the payment method owner
paymentMethodTypeType of payment method
methodDetailsPayment-specific details with sensitive information masked
billingAddressBilling address if available
metadataCustom metadata if available
isDefaultWhether this is the default payment method
isActiveWhether the payment method is currently active
isVerifiedWhether the payment method has been verified
createdAtCreation timestamp
updatedAtLast update timestamp

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found, or you do not have access to it",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found, or you do not have access to it"
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found, or you do not have access to it",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found, or you do not have access to it"
}

Unauthorized (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Authentication required",
  "action_time": "2025-10-27T10:30:45",
  "data": "Authentication required"
}

3. Get My Payment Methods

Purpose: Retrieve all payment methods belonging to the authenticated user with summary statistics

Endpoint: GET {base_url}/payment-methods/my-payment-methods

Access Level: 🔒 Protected (Requires Bearer Token)

Authentication: Bearer Token

Request Headers:

HeaderTypeRequiredDescription
AuthorizationstringYesBearerJWT token for authentication (format: "Bearer {token}")

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Payment methods retrieved successfully",
  "action_time": "2025-10-27T10:30:45",
  "data": {
    "paymentMethods": [
      {
        "paymentMethodId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "paymentMethodType": "CREDIT_CARD",
        "displayName": "Visa ****0366",
        "isDefault": true,
        "isActive": true,
        "isVerified": true,
        "createdAt": "2025-10-15T09:20:15",
        "details": {
          "cardType": "Visa",
          "lastFourDigits": "0366",
          "status": "Active"
        }
      },
      {
        "paymentMethodId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
        "paymentMethodType": "MNO_PAYMENT",
        "displayName": "M-Pesa +255****5678",
        "isDefault": false,
        "isActive": true,
        "isVerified": true,
        "createdAt": "2025-10-20T14:45:30",
        "details": {
          "maskedPhoneNumber": "+255****5678",
          "status": "Active"
        }
      },
      {
        "paymentMethodId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
        "paymentMethodType": "PAYPAL",
        "displayName": "PayPal (john.doe@example.com)",
        "isDefault": false,
        "isActive": true,
        "isVerified": false,
        "createdAt": "2025-10-22T11:30:00",
        "details": {
          "email": "john.doe@example.com",
          "status": "Pending"
        }
      }
    ],
    "totalCount": 3,
    "activeCount": 3,
    "defaultPaymentMethod": {
      "paymentMethodId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "paymentMethodType": "CREDIT_CARD",
      "displayName": "Visa ****0366",
      "isDefault": true,
      "isActive": true,
      "isVerified": true,
      "createdAt": "2025-10-15T09:20:15",
      "details": {
        "cardType": "Visa",
        "lastFourDigits": "0366",
        "status": "Active"
      }
    }
  }
}

Success Response Fields:

FieldDescription
paymentMethodsArray of payment method summaries
paymentMethods[].paymentMethodIdUnique identifier of the payment method
paymentMethods[].paymentMethodTypeType of payment method
paymentMethods[].displayNameHuman-readable name (e.g., "Visa 1234", "M-Pesa +2545678")
paymentMethods[].isDefaultWhether this is the default payment method
paymentMethods[].isActiveWhether the payment method is active
paymentMethods[].isVerifiedWhether the payment method is verified
paymentMethods[].createdAtCreation timestamp
paymentMethods[].detailsEssential details for list display
paymentMethods[].details.cardTypeCard brand (for cards)
paymentMethods[].details.lastFourDigitsLast 4 digits (for cards/accounts)
paymentMethods[].details.emailEmail address (for PayPal/email-based)
paymentMethods[].details.providerProvider name (for mobile payments)
paymentMethods[].details.bankNameBank name (for bank transfers)
paymentMethods[].details.cryptoTypeCryptocurrency type (for crypto)
paymentMethods[].details.maskedPhoneNumberMasked phone (for MNO)
paymentMethods[].details.currencyCurrency code (for gift cards)
paymentMethods[].details.balanceCurrent balance (for gift cards)
paymentMethods[].details.statusStatus indicator (Active, Inactive, Pending)
totalCountTotal number of payment methods
activeCountNumber of active payment methods
defaultPaymentMethodThe default payment method object (null if none set)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "User not authenticated",
  "action_time": "2025-10-27T10:30:45",
  "data": "User not authenticated"
}

Error Response Examples:

Unauthorized (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "User not authenticated",
  "action_time": "2025-10-27T10:30:45",
  "data": "User not authenticated"
}

Not Found - User Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "User not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "User not found"
}

4. Update Payment Method

Purpose: Update an existing payment method with partial or complete changes

Endpoint: PUT {base_url}/payment-methods/{paymentMethodId}

Access Level: 🔒 Protected (Requires Bearer Token, Owner only)

Authentication: Bearer Token

Request Headers:

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token for authentication (format: "Bearer {token}")
Content-Type string Yes Must be "application/json"

Path Parameters:

ParameterTypeRequiredDescriptionValidation
paymentMethodIdUUIDYesUnique identifier of the payment method to updateValid UUID formatjson

Request JSON Sample - Update Card Expiry(USSD):

{
  "paymentMethodType"channel": "CREDIT_CARD"MPESA",
  "methodDetails"amount": {50000,
  "expiry"msisdn": "06/2028"255712345678",
  }"idempotencyKey": "usr-123-topup-1741234567"
}

Request JSON Sample - Update Mobile Money Number(CARD):

{
  "paymentMethodType"channel": "MNO_PAYMENT"CARD",
  "methodDetails"amount": {50000,
  "phoneNumber"idempotencyKey": "+255723456789"
  }
}

Request JSON Sample - Update Billing Address:

{
  "paymentMethodType": "CREDIT_CARD",
  "billingAddress": {
    "street": "789 New Avenue",
    "city": "Arusha",
    "country": "Tanzania"
  }
}

Request JSON Sample - Set as Default:

{
  "paymentMethodType": "CREDIT_CARD",
  "isDefault": trueusr-123-topup-1741234568"
}

Request Body Parameters:

uniqueper
Parameter Type Required Description Validation
paymentMethodTypechannel string (enum) NoYes TypePayment of payment methodchannel Mustenum: matchMPESA, existingAIRTEL, typeTIGO, orHALOPESA, beSELCOM_PESA, a valid payment typeCARD
methodDetailsamount objectnumber NoYes Payment method detailsAmount to updatetop up in TZS OnlyMin: provided fields will be updated1000
billingAddressmsisdn objectstring NoConditional BillingMobile addressphone to updatenumber PartialRequired updatesfor supportedall channels except CARD. Format: 255XXXXXXXXX (12 digits)
metadataidempotencyKey objectstring NoYes MetadataUnique key to updateprevent duplicate requests ReplacesMax existing200 metadatachars, completely
isDefaultbooleanNoUpdate default statusSetting to true unsets other defaultsrequest

Note: All nested fields from the Create endpoint are supported. Only provided fields will be updated; null or missing fields retain their existing values.

Success Response JSON Sample (USSD):

{
  "success": true,
  "httpStatus": "OK",
  "message": "PaymentCollection method updatedinitiated successfully",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": {
    "paymentMethodId"collectionRequestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "ownerId"channel": "b2c3d4e5-f6a7-8901-bcde-f12345678901"MPESA",
    "ownerUserName"amount": 50000,
    "currency": "johndoe"TZS",
    "paymentMethodType"status": "CREDIT_CARD"AWAITING_CUSTOMER_ACTION",
    "methodDetails"msisdnDisplay": "2557****678",
    "paymentUrl": null,
    "message": "Please enter your PIN on your phone to complete payment."
  }
}

Success Response JSON Sample (CARD):

{
  "success": true,
  "httpStatus": "OK",
  "message": "Collection initiated successfully",
  "action_time": "2026-03-06T10:30:45",
  "data": {
    "cardType"collectionRequestId": "Visa"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "maskedCardNumber"channel": "**** **** **** 0366"CARD",
    "expiry"amount": 50000,
    "currency": "06/2028"TZS",
    "cardholderName"status": "John Doe"
    }AWAITING_CUSTOMER_ACTION",
    "billingAddress"msisdnDisplay": {null,
    "street"paymentUrl": "123 Main Street"https://checkout.selcom.net/pay/abc123",
    "city"message": "DarRedirect esuser Salaam",to payment URL."state": "Dar es Salaam",
      "postalCode": "12345",
      "country": "Tanzania"
    },
    "isDefault": true,
    "isActive": true,
    "isVerified": false,
    "createdAt": "2025-10-15T09:20:15",
    "updatedAt": "2025-10-27T10:30:45"
  }
}

Success Response Fields:

Field Description
paymentMethodIdcollectionRequestId UniqueUUID identifier ofuse thethis updatedto paymentpoll method/status/{id}
ownerIdchannel UserChannel accountused ID who ownsfor this payment methodcollection
ownerUserNameamount UsernameAmount ofin the payment method ownerTZS
paymentMethodTypecurrency TypeAlways of payment methodTZS
methodDetailsstatus UpdatedCurrent payment-specificstatus details withsee sensitivestatus datatable maskedbelow
billingAddressmsisdnDisplay UpdatedMasked billingphone addressnumber ife.g. modified2557****678
metadatapaymentUrl UpdatedCard metadatapayment ifURL modified— redirect user here (null for USSD)
isDefaultmessage UpdatedHuman-readable defaultinstruction statusfor the user

Collection Status Values:

StatusDescription
PENDINGRequest created, not yet sent to Selcom
isActiveAWAITING_CUSTOMER_ACTION CurrentSent activeto statusSelcom, waiting for user PIN or card payment
isVerifiedCOMPLETED CurrentPayment verificationconfirmed, statuswallet credited
createdAtFAILED OriginalPayment creationfailed timestampor rejected
updatedAtEXPIRED TimestampRequest ofexpired thisbefore updateuser acted (30 min window)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found"
}

Error Response ExamplesResponses:

NotMissing Foundphone (404):

for
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found"
}

Bad Request - DuplicateUSSD (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "ThisPhone paymentnumber methodis already existsrequired for yourMPESA account"payments.",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": "ThisPhone paymentnumber methodis already existsrequired for yourMPESA account"payments."
}

ValidationInvalid Errorphone format (422)400):

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY"BAD_REQUEST",
  "message": "ValidationInvalid failed"phone number format.",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": {
    "phoneNumber": "Invalid phone number"number format."
}

Selcom rejection (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "expiry"message": "InvalidPayment expiryinitiation formatfailed: (MM/YY)Subscriber not found",
  "action_time": }"2026-03-06T10:30:45",
  "data": "Payment initiation failed: Subscriber not found"
}

5.2. DeleteGet PaymentCollection MethodStatus

Purpose: PermanentlyReturns deletethe current status of a paymentcollection methodrequest. fromPoll this after initiating to know when the systemwallet has been credited.

Endpoint: DELETEGET /collection/status/{base_url}/payment-methods/{paymentMethodId}collectionRequestId}

Access Level: 🔒 Protected (Requires Bearer Token, Owner only)Token

Authentication: Authorization: Bearer Token<token>

Request Headers:

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token for authentication (format: "Bearer {token}")

Path Parameters:

Parameter Type Required Description Validation
paymentMethodIdcollectionRequestId UUID Yes UniqueID identifierreturned offrom the payment method to deleteValid UUID format/initiate

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "PaymentCollection methodstatus deleted successfully"retrieved",
  "action_time": "2025-10-27T10:30:45",
  "data": null
}

Success Response Fields:

FieldDescription
dataAlways null for delete operations

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found"
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment method not found",
  "action_time": "2025-10-27T10:30:45",
  "data": "Payment method not found"
}

Unauthorized (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Authentication required",
  "action_time": "2025-10-27T10:30:45",
  "data": "Authentication required"
}

6. Set Payment Method as Default

Purpose: Set a specific payment method as the default for the authenticated user

Endpoint: PATCH {base_url}/payment-methods/{paymentMethodId}/set-default

Access Level: 🔒 Protected (Requires Bearer Token, Owner only)

Authentication: Bearer Token

Request Headers:

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token for authentication (format: "Bearer {token}")

Path Parameters:

ParameterTypeRequiredDescriptionValidation
paymentMethodIdUUIDYesUnique identifier of the payment method to set as defaultValid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Payment method set as default successfully",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": {
    "paymentMethodId"collectionRequestId": "b2c3d4e5-f6a7-8901-bcde-f12345678901"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "ownerId"channel": "b2c3d4e5-f6a7-8901-bcde-f12345678901"MPESA",
    "ownerUserName"amount": 50000,
    "currency": "johndoe"TZS",
    "paymentMethodType"status": "MNO_PAYMENT"COMPLETED",
    "methodDetails": {
      "maskedPhoneNumber"msisdnDisplay": "+255*2557****5678"678",
    "mccMnc"failureReason": null,
    "transactionRef": "M-PESA"
    }NXT-TXN-20260306-ABCD1234",
    "isDefault": true,
    "isActive": true,
    "isVerified": true,
    "createdAt": "2025-10-20T08:15:30"2026-03-06T10:30:00",
    "updatedAt"completedAt": "2025-10-27T10:30:2026-03-06T10:31:45"
  }
}

Success Response Fields:

timestamp
Field Description
paymentMethodIdcollectionRequestId Unique identifierUUID of thethis paymentcollection method now set as defaultrequest
isDefaultchannel NowChannel set to trueused
updatedAtamount UpdatedAmount toin currentTZS
currencyAlways TZS
statusCurrent status — see status table above
msisdnDisplayMasked phone number
failureReasonPopulated if status is FAILED
transactionRefWallet transaction reference — available when COMPLETED
createdAtWhen the request was created
completedAtWhen the wallet was credited — null if not yet completed

Note: All previously default payment methods are automatically set to isDefault: false.

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Cannot set inactive payment method as default",
  "action_time": "2025-10-27T10:30:45",
  "data": "Cannot set inactive payment method as default"
}

Error Response ExamplesResponses:

BadNot Requestfound -or Inactivenot Paymentowned Methodby user (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "CannotCollection set inactive payment method as default",
  "action_time": "2025-10-27T10:30:45",
  "data": "Cannot set inactive payment method as default"
}

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Payment methodrequest not found",
  "action_time": "2025-10-27T10:2026-03-06T10:30:45",
  "data": "PaymentCollection methodrequest not found"
}

Unauthorized (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Authentication required",
  "action_time": "2025-10-27T10:30:45",
  "data": "Authentication required"
}

Quick Reference Guide

HTTP BadgeCodeTemplates

GET

Badge:



style="background-color:logicviolation
  • Unauthorized:
  • 403
  • Forbidden:Insufficient
    Method Endpoint Description
    POST<span/collection/initiate Start #28a745;a color:top-up white;via padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span>

    POST Badge:

    <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span>
    

    PUT Badge:

    <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span>
    

    PATCH Badge:

    <span style="background-color: #fd7e14; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PATCH</span>
    

    DELETE Badge:

    <span style="background-color: #dc3545; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">DELETE</span>
    

    Common HTTP Status Codes

    • 200 OK: Successful GET/PUT/PATCH request
    • 201 Created: Successful POST request
    • 204 No Content: Successful DELETE request
    • 400 Bad Request: Invalid request data, duplicate payment method,USSD or businesscard
    GET401/collection/status/{id} Check Authenticationtop-up required/failedstatus
    permissions
  • 404 Not Found: Payment method or user not found
  • 422 Unprocessable Entity: Validation errors
  • 500 Internal Server Error: Server error
  • Authentication Types

    • Bearer Token: Include Authorization: Bearer your_token in headers

    Data Format Standards

    • Dates: Use ISO 8601 format (2025-10-27T14:30:00)
    • Currency: Use standard 3-letter codes (USD, EUR, TZS)
    • Phone Numbers: Use E.164 format (+[country code][number])
    • Card Numbers: 13-19 digits (automatically tokenized and masked)
    • UUIDs: Standard UUID v4 format (8-4-4-4-12 hexadecimal)

    Payment Method Types

    • CREDIT_CARD: Credit card payments
    • DEBIT_CARD: Debit card payments
    • PAYPAL: PayPal account payments
    • BANK_TRANSFER: Direct bank account transfers
    • CRYPTOCURRENCY: Crypto wallet payments (Bitcoin, Ethereum, etc.)
    • MOBILE_PAYMENT: Mobile payment services (Apple Pay, Google Pay)
    • MNO_PAYMENT: Mobile Network Operator payments (M-Pesa, Airtel Money, Tigo Pesa, etc.)
    • WALLET: Digital wallet services (Skrill, Neteller, etc.)
    • GIFT_CARD: Gift card payments
    • CASH_ON_DELIVERY: Cash payment upon delivery

    Supported Mobile Network Operators (Tanzania)

    • M-Pesa (Vodacom)
    • Airtel Money
    • Tigo Pesa
    • Halo Pesa
    • Azam Pesa
    • Ezy Pesa

    Supported Banks (Tanzania)

    • CRDB Bank
    • NMB Bank
    • EXIM Bank
    • KCB Bank
    • NBC Bank
    • Stanbic Bank
    • Diamond Bank
    • Access Bank
    • Azania Bank
    • Equity Bank
    • FNB Bank

    Data Masking Rules

    • Card Numbers: Shows only last 4 digits (e.g., "**** **** **** 1234")
    • Account Numbers: Shows only last 4 digits (e.g., "****1234")
    • Phone Numbers: Masks middle digits (e.g., "+255****5678")
    • Wallet Addresses: Shows first and last 4 characters (e.g., "1A1z...fNa")
    • PINs: Completely masked (e.g., "****")

    Security Notes

    • Sensitive data (card numbers, account numbers, PINs) should be tokenized before storage
    • All responses mask sensitive information
    • Duplicate detection prevents storing multiple identical payment methods
    • Only payment method owners can view, update, or delete their payment methods
    • Setting a payment method as default requires it to be active

    Business Rules

    • Only one payment method can be default at a time
    • Setting a new default automatically unsets the previous default
    • Inactive payment methods cannot be set as default
    • Payment methods can be created without verification (isVerified: false)
    • Partial updates are supported - only provided fields are updated
    • Delete operations are permanent (hard delete)

    Payment Method Type Examples

    Credit/Debit Card Example

    {
      "paymentMethodType": "CREDIT_CARD",
      "methodDetails": {
        "cardType": "Visa",
        "cardNumber": "4532015112830366",
        "expiry": "12/2027",
        "cardholderName": "John Doe"
      },
      "billingAddress": {
        "street": "123 Main Street",
        "city": "Dar es Salaam",
        "country": "Tanzania"
      },
      "isDefault": true
    }
    

    Mobile Money (M-Pesa) Example

    {
      "paymentMethodType": "MNO_PAYMENT",
      "methodDetails": {
        "phoneNumber": "+255712345678",
        "mccMnc": "M-PESA"
      },
      "isDefault": true
    }
    

    PayPal Example

    {
      "paymentMethodType": "PAYPAL",
      "methodDetails": {
        "email": "john.doe@example.com",
        "paypalId": "johndoe123"
      }
    }
    

    Bank Transfer Example

    {
      "paymentMethodType": "BANK_TRANSFER",
      "methodDetails": {
        "bankName": "CRDB Bank",
        "accountNumber": "1234567890",
        "routingNumber": "021000021",
        "accountType": "Checking",
        "accountHolderName": "John Doe"
      },
      "billingAddress": {
        "street": "456 Bank Avenue",
        "city": "Dar es Salaam",
        "country": "Tanzania"
      }
    }
    

    Cryptocurrency Example

    {
      "paymentMethodType": "CRYPTOCURRENCY",
      "methodDetails": {
        "cryptoType": "Bitcoin",
        "walletAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
        "network": "BTC Mainnet"
      }
    }
    

    Mobile Payment (Apple Pay) Example

    {
      "paymentMethodType": "MOBILE_PAYMENT",
      "methodDetails": {
        "provider": "Apple Pay",
        "deviceId": "iPhone-12-Pro-XYZ123"
      }
    }
    

    Digital Wallet Example

    {
      "paymentMethodType": "WALLET",
      "methodDetails": {
        "walletType": "Skrill",
        "walletId": "john.doe@example.com"
      }
    }
    

    Gift Card Example

    {
      "paymentMethodType": "GIFT_CARD",
      "methodDetails": {
        "pin": "1234567890123456",
        "balance": 50.00,
        "currency": "USD"
      }
    }
    

    Cash on Delivery Example

    {
      "paymentMethodType": "CASH_ON_DELIVERY",
      "methodDetails": {
        "instructions": "Please call 30 minutes before delivery"
      }
    }