Make a Payment

Learn how to integrate bills payment

Let's begin integrating the Bills Payment API. Follow these simple steps:

Step 1: Get Supported Bills

Use this endpoint to get the list of supported bills available on Bloc.

curl --request GET \
     --url https://api.blochq.io/v1/bills/supported \
     --header 'accept: application/json' \
     --header 'authorization: Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660'

Here's the expected response:

{
  "success": true,
  "data": [
    "electricity",
    "television",
    "telco"
  ],
  "message": "get supported products"
}

📘

Helpful Tip:

telco refers to the airtime/data bills payment product.

Step 2: Get Supported Operators

An operator refers to the service provider of the bill product you want to purchase. The list of operators returned depends on the bill payment product selected.

To get this, use this endpoint and pass a value for the bill parameter.

https://api.blochq.io/v1/bills/operators
curl --request GET \
     --url 'https://api.blochq.io/v1/bills/operators?bill=electricity' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660'
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://api.blochq.io/v1/bills/operators?bill=electricity")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660'

response = http.request(request)
puts response.read_body
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.blochq.io/v1/bills/operators?bill=electricity', [
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660',
  ],
]);

echo $response->getBody();
import requests

url = "https://api.blochq.io/v1/bills/operators?bill=electricity"

headers = {
    "accept": "application/json",
    "authorization": "Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660"
}

response = requests.get(url, headers=headers)

print(response.text)

Here's the expected response:

{
  "success": true,
  "data": [
    {
      "desc": "Smile Nigeria",
      "id": "op_Bq8cVtUufoYZ3SuADZWd6m",
      "name": "Smile",
      "sector": "Telecommunications"
    },
    {
      "desc": "MTN Nigeria",
      "id": "op_xoaaKAWhcZ3RwGfMKjpmag",
      "name": "MTN",
      "sector": "Telecommunications"
    },
    {
      "desc": "Airtel Nigeria",
      "id": "op_j3S5RJ2ZJYvfvchYq3fpFU",
      "name": "Airtel",
      "sector": "Telecommunications"
    },
    {
      "desc": "9Mobile Nigeria",
      "id": "op_6ZwjemDTAYz5mZWJMLFRGc",
      "name": "9Mobile",
      "sector": "Telecommunications"
    },
    {
      "desc": "Globacom (Glo Nigeria)",
      "id": "op_6jYrpyHjJoG2SdeyfzmMSS",
      "name": "Glo",
      "sector": "Telecommunications"
    },
    {
      "desc": "Visafone Nigeria",
      "id": "op_jDMM6BQrbmVfS6eqXytVAL",
      "name": "Visafone",
      "sector": "Telecommunications"
    }
  ],
  "message": "supported operators"
}
{
  "success": true,
  "data": [
    {
      "desc": "Ibadan Electricity Distribution Company",
      "id": "op_deR4dx7V5B28Fn5Pij9ach",
      "name": "IBEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Kano Electricity Distribution Company",
      "id": "op_8uNjD7x8s2SnSwPzquEcQi",
      "name": "KEDCO",
      "sector": "Electricity"
    },
    {
      "desc": "Aba Power Limited Electric",
      "id": "op_7VCucgjYSDXrKKfDBrDey8",
      "name": "APLE",
      "sector": "Electricity"
    },
    {
      "desc": "AES Jos Electricity Distribution Company",
      "id": "op_5rYjsdbMtTkgu7bcnkXuai",
      "name": "AES_JEDC",
      "sector": "Electricity"
    },
    {
      "desc": "CEL Jos Electricity Distribution Company",
      "id": "op_pQJjkwnwhXrRdanyfvrXYB",
      "name": "CEL_JEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Benin Electricity Distribution Company",
      "id": "op_kXdyUvFZVzMgXDoFJabrv4",
      "name": "BEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Eko Electricity Distribution Company",
      "id": "op_xctXVabViUHmyLPdW9fDFJ",
      "name": "EKEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Kaduna Electricity Distribution Company",
      "id": "op_D4M9raYX3QGQ2eXCphkfB2",
      "name": "KAEDCO",
      "sector": "Electricity"
    },
    {
      "desc": "Abuja Electricity Distribution Company",
      "id": "op_sBaoehA7TQCy8igjYKfC6v",
      "name": "AEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Port Harcourt Electricity Distribution Company",
      "id": "op_4NHWfrNyzT5kN8GsQYTZot",
      "name": "PHEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Ikeja Electricity Distribution Company",
      "id": "op_RszwtPMnaooVgCsEcJWcEF",
      "name": "IKEDC",
      "sector": "Electricity"
    },
    {
      "desc": "Enugu Electricity Distribution Company",
      "id": "op_gprNgsEdQFeQ6K4p7ELSwS",
      "name": "EEDC",
      "sector": "Electricity"
    }
  ],
  "message": "supported operators"
}
{
  "success": true,
  "data": [
    {
      "desc": "Digital Satellite Television",
      "id": "op_pspQ6hAfsNd3mfKsY9rCik",
      "name": "DSTV",
      "sector": "Television"
    },
    {
      "desc": "GoTV Nigeria",
      "id": "op_ry32iksGwx6nQQnVAHu8N7",
      "name": "GOTV",
      "sector": "Television"
    },
    {
      "desc": "StarTimes Nigeria",
      "id": "op_BLVi7pAoj2LHbvNS89W8TU",
      "name": "STARTIMES",
      "sector": "Television"
    }
  ],
  "message": "supported operators"
}
AttributeDescription
descThe full legal name of the operator/service provider
idThe unique operator id of the service provider
nameThe abbreviated version of the service provider name.
sectorThe type of bills payment product that they offer.

Step 3: Get List of Operator Products

The next step is to get the list of products offered by a particular operator. To do this, call the endpoint URL below, and pass the following attributes:

https://api.blochq.io/v1/bills/operators/{operatorID}/products
curl --request GET \
     --url 'https://api.blochq.io/v1/bills/operators/op_ry32iksGwx6nQQnVAHu8N7/products?bill=television' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660'
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://api.blochq.io/v1/bills/operators/op_ry32iksGwx6nQQnVAHu8N7/products?bill=television")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660'

response = http.request(request)
puts response.read_body
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.blochq.io/v1/bills/operators/op_ry32iksGwx6nQQnVAHu8N7/products?bill=television', [
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660',
  ],
]);

echo $response->getBody();
import requests

url = "https://api.blochq.io/v1/bills/operators/op_ry32iksGwx6nQQnVAHu8N7/products?bill=television"

headers = {
    "accept": "application/json",
    "authorization": "Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660"
}

response = requests.get(url, headers=headers)

print(response.text)

Make sure to pass both the operatorID and bill.

AttributesRequiredDescription
operatorIDYesThis is the unique operator id of the service provider
billYesThis is the bill type that the service provider offers. It could either be telco, television or electricity.

🚧

Important to Note:

If you pass only the operatorID, you'll get an error.

Below is a sample response for the list of GOTV products on Bloc:

{
  "success": true,
  "data": [
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_F7hKpFmDuw4Vxg6ZGkY4T4",
      "meta": {
        "currency": "NGN",
        "fee": "2100.00"
      },
      "name": "GOtv Smallie - quarterly -- 3 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_aJZYMS7iQEadmmf4ebbhUK",
      "meta": {
        "currency": "NGN",
        "fee": "4200.00"
      },
      "name": "GOtv Smallie - quarterly -- 6 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_hLJh3ZFyF5ubCf9PXXu4SS",
      "meta": {
        "currency": "NGN",
        "fee": "6300.00"
      },
      "name": "GOtv Smallie - quarterly -- 9 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_nco3AvL6zd9dvndADHpocu",
      "meta": {
        "currency": "NGN",
        "fee": "8400.00"
      },
      "name": "GOtv Smallie - quarterly -- 12 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_oKPJRCTEgaJScCkRyqARU2",
      "meta": {
        "currency": "NGN",
        "fee": "9700.00"
      },
      "name": "GOtv Max -- 2 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_jQ8KtEfqQ9vSgmJd8HABV9",
      "meta": {
        "currency": "NGN",
        "fee": "6200.00"
      },
      "name": "GOtv Smallie - yearly -- 12 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_YnGuTg34ipVZwouRdQpL7v",
      "meta": {
        "currency": "NGN",
        "fee": "14550.00"
      },
      "name": "GOtv Max -- 3 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_kMcHRCY2uhoSLHYJw779rM",
      "meta": {
        "currency": "NGN",
        "fee": "2250.00"
      },
      "name": "GOtv Jinja Bouquet -- 3 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_TLauHUdFi7BZjKvZUHPs8z",
      "meta": {
        "currency": "NGN",
        "fee": "2250.00"
      },
      "name": "GOtv Jinja Bouquet -- 1 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_gfb2R3LUGHzWzzv7gDGXhH",
      "meta": {
        "currency": "NGN",
        "fee": "2250.00"
      },
      "name": "GOtv Jinja Bouquet -- 2 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_tAezTjoFAVn4JuaG4Fc9WU",
      "meta": {
        "currency": "NGN",
        "fee": "900.00"
      },
      "name": "GOtv Smallie - monthly -- 1 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_4rzXchYaBz8SRnkuTTDi8f",
      "meta": {
        "currency": "NGN",
        "fee": "2700.00"
      },
      "name": "GOtv Smallie - monthly -- 3 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_HKaaxS5YYyLYAnBFA6ZiVB",
      "meta": {
        "currency": "NGN",
        "fee": "1800.00"
      },
      "name": "GOtv Smallie - monthly -- 2 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_3EQyQPCJ8vYrULZiWeUVYc",
      "meta": {
        "currency": "NGN",
        "fee": "4850.00"
      },
      "name": "GOtv Max -- 1 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_cS8R8cth7gKEyWvHikje38",
      "meta": {
        "currency": "NGN",
        "fee": "6400.00"
      },
      "name": "GOtv Supa -- 1 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_MqhSHyhtD48iLwPWN7LVBe",
      "meta": {
        "currency": "NGN",
        "fee": "12800.00"
      },
      "name": "GOtv Supa -- 2 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_XFnRRggjc7kjsvzqPrYHxc",
      "meta": {
        "currency": "NGN",
        "fee": "19200.00"
      },
      "name": "GOtv Supa -- 3 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_hugwigWp3856xAbPiY9Pi2",
      "meta": {
        "currency": "NGN",
        "fee": "3300.00"
      },
      "name": "GOtv Jolli Bouquet -- 1 month",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_g9PEHTkgvZDJwdrkJDn2hK",
      "meta": {
        "currency": "NGN",
        "fee": "6600.00"
      },
      "name": "GOtv Jolli Bouquet -- 2 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    },
    {
      "category": "pctg_mZY9WG7W8LmkHQYViSFD6k",
      "desc": null,
      "fee_type": "FIXED",
      "id": "prd_rTYHHsFH4Fv39Die3S9sgJ",
      "meta": {
        "currency": "NGN",
        "fee": "9900.00"
      },
      "name": "GOtv Jolli Bouquet -- 3 months",
      "operator": "op_ry32iksGwx6nQQnVAHu8N7"
    }
  ],
  "message": "supported operators"
}
AttributeDescription
categoryThis refers to the type of product. Certain operators have more than one product category. For example, a telco product has both airtime and data
descFull description of the product
fee_typeType of fee. It could be a range (has a minimum and maximum fee), flexible (any amount) or fixed (a specified amount).
idThe unique id of the operator's product.
currencyThe currency that payment is made in.
feeIf it is a fixed fee type, this is how much the product costs.
maximum_feeIf it is a range fee type, this is the maximum amount you can buy per time from that product.
minimum_feeIf it is a range fee type, this is the minimum amount you can buy per time from that product.
data_expiryIf it is a telco product (data), this is how long the product is valid.
data_valueIf it is a telco product (data), this is how much is being bought
nameThis is the name of the product.
operatorThis is the unique operator id of the operator

📘

Helpful Tip:

Make sure to note the category and product ids when implementing Bills Payment in your application, or when trying to present it to your customers.

You can use the category to filter what your customers see when they want to make a bill payment on your app.

Here's a table of all product categories available on Bloc:

Bills TypeName of categoryCategoryID
TelcoAirtimepctg_xkf8nz3rFLjbooWzppWBG6
Datapctg_ftZLPijqrVsTan5Ag7khQx
Electricitypctg_kviHAHztWv35SJUXgcMJcb
Televisionpctg_mZY9WG7W8LmkHQYViSFD6k

Step 04: Customer Validation

The next step is to validate the customer's details. This step is only required for Electricity and TV Subscription products that must verify that the customer exists before processing payment.

To do this, call the endpoint below and pass the following attributes in the URL:

https://api.blochq.io/v1/bills/customer/validate/
AttributesRequired?Description
operatorIDYesThis is the unique operator id of the service provider
meter_typeYes (if electricity)This is the type of meter, if it is an electricity payment. It is either prepaid or postpaid. Leave it blank if you are verifying for Television.
billYesThis is the bill type that the service provider offers. It could either be telco, television or electricity.
device_numberYesThis is the device number (Electricity) or smart card number (TV subscription)

The only response you get here is the customer's name.

Step 05: Make Payment

Whenever you successfully pass a Bills Payment transaction, we deduct the amount from your Main Balance. This means you always have to keep your Main Balance funded to continue to process Bills Payment transactions successfully.

To make a payment, call the endpoint URL below and pass the following attributes:

curl --request POST \
     --url https://api.blochq.io/v1/bills/payment \
     --header 'accept: application/json' \
     --header 'authorization: Bearer sk_live_64520e0201478f5cd412865f64520e0201478f5cd4128660' \
     --header 'content-type: application/json' \
     --data '
{
  "amount": 280000,
  "product_id": "prd_hugwigWp3856xAbPiY9Pi2",
  "operator_id": "op_ry32iksGwx6nQQnVAHu8N7",
  "account_id": "626bcf4141c5e8423568750e",
  "device_details": {
    "meter_type": "prepaid",
    "device_number": "20200000000",
    "beneficiary_msisdn": "08100000000"
  }
}
'
AttributesRequiredTypeDescription
amountYesIntegerThis is the amount to be paid. It should always be passed in kobo. You can do this by multiplying the NGN amount by 100.
product_idYesStringThis is the unique id of the product being bought. Refer to Step 3.
operator_idYesStringThis is the unique operator id of the service provider.
account_idNoStringYou can leave this blank if you want to. However, if you want the amount to be debited from another fixed account created in your workspace, provide the account_id here.
device_detailsYesObjectDepending on the type of bill being paid, the required attributes differ. See the next table for details
billYesStringThis is the bill type that the service provider offers. It could either be telco, television or electricity.

🚧

Important to Note:

You cannot pass account_id for a Collection Account or Wallet here.

For Telco (Airtime/Data)

AttributesRequired?TypeDescription
beneficiary_msisdnYesStringThis field represents the phone number of the intended recipient.

For Electricity

AttributesRequired?TypeDescription
meter_typeYesStringThis field represents the type of supported meter for the service. The accepted values for this field are postpaid or prepaid
device_numberYesStringThis field represents the unique identifier for the selected meter type. This is mostly the meter number.

For Television

AttributesRequired?TypeDescription
device_numberYesStringThis field represents the unique identifier for the decoder. This is mostly the decoder/smartcard number.

And you're done!

Payment is usually processed within seconds, and the value is delivered to the recipient.

Sometimes, successful payments may not deliver value instantly due to the service provider experiencing downtime or an infrastructure upgrade. We make sure to inform you ahead of time so that this is avoided.

Do not hesitate to contact Support if you encounter any problems.