Payouts (Transfer to Bitnob Customers)

Other businesses can transfer funds to a Bitnob customer, or local mobile money and bank accounts in supported African countries. The funds ultimately ends up getting settled in 3 ways.

  1. The customer receives it in their Bitnob account's USD stables balance
  2. The customer's mobile money is automatically settled in their local currency by Bitnob.
  3. The customer's bank account is automatically settled in their local currency by Bitnob

πŸ“˜

Currently supported currencies

Fiat payments are currently available for the following African countries:

  1. Nigeria - Payments to all Nigerian bank accounts and mobile money networks
  2. Ghana - Payments to MTN and Vodafone cash mobile money networks
  3. Kenya - Mpesa, Airtel Money and T-kash

In order to make a successful transfer, you will need to first perform a lookup using the recipient's phone number. Recipient phone numbers are the unique identifiers to be used for these transfers.

FieldDescription
country codethe country code of the currently supported country. Supported countries include

Nigeria 234
Kenya 254
Ghana 233
PhoneThe beneficiary's registered phone number with Bitnob

Sample Request


{
 "countryCode": "234",
 "accountNumber": "8059403848"
} 

A handshake is done with the Bitnob API to return the recipient's details. A sample response is shared below

Sample Response

{
    "status": true,
    "message": "account lookup successful",
    "data": {
        "kycLevel": 1,
        "countryCode": "234",
        "accountNumber": "8059403848",
        "emailVerified": true,
        "beneficiaryName": "Berlin Lucado"
    }
}

Account Not Found

If the phone number lookup returns a 404 error with account not found as the message, it means the phone number has not been indexed, and we will need you to collect more information from the sender for us to complete the transfer.

Part of the payment information you will need to collect is the payment method, we support different payment methods for different countries, and the payment methods API returns the available methods and the supporting information required to initiate and complete payment.

Sample Request

{
    "countryCode": "254",
    "accountNumber": "8131121212"
}

Sample Response

{
    "status": true,
    "message": "account lookup successful",
    "data": [
        {
          {
            "name": "Mobile Money",
            "identifier": "MOBILEMONEY",
            "settlement_time": "5 minutes",
            "required_details": [
                "network",
                "account_name",
                "phone_number"
            ],
            "networks": [
                {
                    "name": "MPESA",
                    "logo": "https://res.cloudinary.com/munirat96/image/upload/v1666336496/mpesa_tbnned.png"
                },
                {
                    "name": "TKASH",
                    "logo": "https://res.cloudinary.com/munirat96/image/upload/v1666336504/tkash_pkklpt.png"
                },
                {
                    "name": "AIRTELMONEY",
                    "logo": "https://res.cloudinary.com/munirat96/image/upload/v1666336571/airtel_y4kpec.png"
                }
            ]
           },
            "name": "Bank Account",
            "identifier": "BANK",
            "settlement_time": "60 minutes",
            "required_details": [
                "bank_name",
                "bank_number",
                "bank_code",
                "account_name"
            ],

            "bank_list": {
                "status": true,
                "message": "Banks retrieved",
                "data": [
                    {
                        "name": "Kenya Commercial Bank",
                        "code": "1"
                    },
                    {
                        "name": "Family Bank Limited",
                        "code": "70"
                    },
                    {
                        "name": "Gulf African Bank",
                        "code": "72"
                    },
                    {
                        "name": "First Community Bank",
                        "code": "74"
                    },
                    {
                        "name": "Kenya Women's Finance Trust",
                        "code": "78"
                    }
                ]
            }
        },

    ]
}

Account Resolution

In order to prevent sending payments to the wrong account numbers, it is important to resolve the account numbers. By resolving the account number, you will get details of the account.

This only works for Nigerian bank accounts and Mpesa accounts. For Nigerian bank accounts resolution, you will first have to get the banks code from the banks endpoint. For Mpesa accounts you only need to pass country as KE and MOBILEMONEY as the type

Resolving Account details
In order to make proper use of the endpoint, You should always pass correct bank codes and valid account numbers. You should check the banks endpoint to get the bank code before resolving the account details.

Sample requests for Nigerian accounts lookup and Mpesa accounts lookup are provided below

Sample Request

{
    "bankCode": "033",
    "type": "BANK",
    "accountNumber": "2081021857"
}
{
    "type": "MPESA",
    "accountNumber": "0712207518"
}

Sample Response

{
    "status": true,
    "message": "account detail lookup successful",
    "data": {
        "account_number": "254712207518",
        "account_name": "JOHN DOE"
    }
}

After getting the payment methods and confirming the required details for that country, the next thing is to initiate a transfer by requesting payment details from Bitnob

πŸ“˜

Skipping Number Lookup

You can skip the number lookup and send a direct request for a payment invoice. This is good for situations where the customer has already sent funds to the same phone number. It's recommended to perform a lookup the first time of sending payments

FielddescriptionRequired
countryCodethe country code of the receiving phone numbertrue
amountthe $ amount you want to send, it should be represented in cents. To send $5, send 500 (cents) instead of just 5true
accountNumberthe recipient's phone numbertrue
senderthe full name of the sendertrue
paymentRequiredDetailsthe required details to complete a payment to a bank account or mobile money account. This is only needed if the phone number has not been indexed or has never been used for a transaction with Bitnobfalse
paymentMethodIdentifierused to indicate if the payment channel to be used is a bank transfer or mobile money transfer. only needed if the phone number wasn't indexedfalse
descriptionoptional narration of the payment. if None is given, Bitnob will generate an invoice with a description that reads like "Send money to Berlin"false
callbackUrlthe url you want to receive the webhook on, if this isn't specified, then the webhook url set on your account will be used.

Sample Request

{
    "countryCode": "234",
    "accountNumber": "8131121212",
    "senderName": "Jack Daniels",
    "paymentMethodIdentifier": "BANK",
    "paymentRequiredDetails": {
        "bank_name": "GT Bank",
        "bank_number": "01218895004",
        "bank_code": "058",
        "account_name": "Sam Meni"
    },
    "amount": 500,
    "description": "I am paying you to change the world son", 
    "callbackUrl": "https://webhook.site/9f3d56a5-971a-4294-a09d-5ecccb36a258"
}

Bitnob will return an invoice and payment details for the payment to be paid. Pay the lightning invoice attached to the payment invoice

Sample Response

{
    "status": true,
    "message": "payment invoice generated successfully",
    "data": {
        "id": "94f6d222-88bc-4049-95b3-7d0f252b3a66",
        "amount": 5, //this is the actual $ amount
        "reference": "bd4a5621657b",
        "status": "unpaid",
        "satoshis": 497554,
        "beneficiaryName": "Sam Meni",
        "amountToBeReceived": 50000,
        "paymentRequest": "lntb4975540n1p3nadkppp57c6tgarz0uuvtn05cwmu4pjtk3fvsxd80avaf6vsl3psq0av080sdpcv3jhxcmjd9c8g6t0dcsxgetnvdexjur5d9hkugryv4ekxunfwp6xjmmwcqzpgxqzursp5kej50s2n6u54camm0gmehzlyq24z6z2kqfnqwsnplatdd8j7rt7s9qyyssqq3vh6uerlfhsucptgqnn7jx00868av2ye24tqgntsanhmh6srtqpg7yvm6xl8yd6wxnpcx23ue7nrf5hc9xv4vvygcy7lcf4etz0nncp6c6xz6",
        "expiresAt": "2022-10-06T11:21:40.000Z",
        "currencyPair": "USD_NGN",
        "emailVerified": true,
        "kycLevel": 1,
        "exchangeRate": {
            "rate": 500,
            "source": {
                "amount": 100,
                "currency": "USD"
            },
            "destination": {
                "currency": "NGN",
                "amount": 50000
            }
        },
        "updatedAt": "2022-08-06T11:06:41.837Z",
        "created": "2022-08-06T11:06:41.837Z"
    }
}

A webhook response will be returned to you with the status and details of the payment

Webhook Body

{
  "event": "mobilepayment.paid.success",
  "data": {
      isSettled: false,
      id: 'uuid...',
      reference: '<company unique reference>',
      companyId: '<company id uuid>',
      status: paid | unpaid,
      callbackUrl: 'https://callback.com/...',
      satAmount: '10000',
  }
}

Refer to the webhooks page on our to handle the webhooks. The webhook to use here is the mobilepayment.paid.success webhook.

In the event of an outage where the webhook delivery fails, use the payment reference or payment idto query the payment details. Even though a lightning invoice getting paid from your end validates the payment.

Refund Process

In a case where making payments fails, a webhook mobilepayment.settlement.failedis sent which also includes the satAmountof the payment. To initiate a refund, the satAmountis used to generate an paymentRequest and a uniquereference is sent together to the mobile refund endpoint.

Sample Request

{
  "paymentRequest": "lntb19300n1ps5xzcypp5jcksjkjpupn7pfzkqacm8tpsyz9dd24akpcmv3rvyljx7fqqnh8sdpsd4hkueteypehgmmswvsxummwwdjkuum9yphkugrnw4hxgctecqzpgxqr23sfppqwnu34jgs5j07h2k55vue7w9fctu7r7g4sp5ffjp2mnr3x3kjrfm678twu0agnk5hpf4n7st7u72q9r43d5nwwrs9qyyssqswxaw2au37dyzdgs7rkvllrlel4dnn68z7tkd8m4tfgmytwv23mrma7zh505szyy6u5tlydtujcljfeppfv7q2mvxuzlys5r4javcrqpvxdphm",
  "reference": "ggjajjakakkakak"
}

Paying the invoice using Bitnob

Businesses can also pay the generated invoice from their USD or BTC Wallet balance. To do this, use the pay mobile payment endpoint. After the payment is successful you will receive a mobilepayment.paid.success webhook and if it fails you mobilepayment.paid.failed webhook. Once the receiver is credited to their bank or momo you will receive a mobilepayment.settlement.success webhook otherwise you will receive a mobilepayment.settlement.failed webhook.

Sample Request

{
    "customerEmail": "[email protected]",
    "reference": "401bb0da4f56721ea",
    "wallet": "USD"
}

Sample Response

{
    "status": true,
    "message": "payment invoice summary",
    "data": {
        "id": "6adc8125-8320-4bcd-a87b-401bb0da4f56",
        "createdAt": "2023-01-30T06:04:03.373Z",
        "updatedAt": "2023-01-30T06:04:03.373Z",
        "reference": "b13b68f0f645",
        "description": "Transfer funds to moses in Ikeja",
        "amount": 5,
        "centAmount": 500,
        "fees": 0,
        "centFees": 0,
        "btcFees": 0.00000001,
        "satFees": 1,
        "satAmount": 21289,
        "spotPrice": 23485.89,
        "action": "usd_pay_mobilepaymet",
        "type": "debit",
        "status": "pending",
        "channel": "lightning",
        "paymentRequest": "lnbc212890n1p3...",
        "companyId": "c1d55a85-3914-43c0-9815-dfedf6a5823c",
        "customerId": "cd363089-748a-4d52-80c8-8cb871473bee"
    }
}