logo-dp-on-tp

Constructing a bill on Collect#

How to customise the Setu bill object for any business use case#

At the very core of Collect, is the Setu bill object. It facilitates a vast number of business scenarios—such as recurring payments for insurance premiums or school fee collections with multiple line items. It does this by having a generic, modular information structure that can be constructed to your needs.

Explore the full object on the API reference ↗.


Basic bill structure#

The data object houses 2 types of data—

  • billDetails—the components are explained in the following sections.
  • customer—these are the customer details required by NPCI, as per biller category. Read about special cases ↗.
"data" : {
"customer": {
"name": "Shailesh"
},
"billDetails" : {
"billFetchStatus" : "AVAILABLE",
"bills" : [
{
"generatedOn" : "2020-06-04T06:59:04Z" // bill generation / fee start date,
"dueDate" : "2020-06-04T06:59:04Z" // last date for fee payment,
"recurrence" : "ONE_TIME",
"amountExactness" : "EXACT",
"billerBillID" : "string", // bill identifier, sent with each payment
"customerAccount" : {},
"amount" : {}, //amount against the bill
"items" : [], // array of line items
"aggregates" : {} // details on final amount that the customer needs to pay
}
]
}
}

Bill components#

In the bill object, the details are broken down into simple logical units, that follow the same pattern and structure where ever they appear.


Amount#
"amount" : {
"currencyCode" : "INR", // ISO 4217
"value" : 10000 // in paise, so this means 100 rupees
}

amount is made of two attributes—

  • currencyCode The currency used in the bill its three-letter ISO 4217 format.
  • value The money value of the bill, in paise.

This same object structure is re-used whenever there is a need to denote amounts against any item such as fees, taxes, discounts etc.


Items#
"items" : [
{
"code" : "string",
"displayName" : "string",
"description" : "string",
"measurementUnit" : "ENUM",
"quantity" : 0,
"unitPrice" : {},
"discounts" : [],
"fees" : [],
"taxes" : [],
"aggregates" :
{
"discount" : {},
"subTotal" : {},
"tax" : {},
"total" : {}
},
}
],

This array is where the individual prices against services or products (for which the bill has been raised) are listed out.


Fees#
"fees" : [
{
"quantity" : 0,
"displayName" : "string",
"description" : "string",
"unitCost" : {},
"discounts" : [],
"taxes" : [],
"aggregates" : {
"discount" : {},
"subTotal" : {},
"tax" : {},
"total" : {}
}
}
],

The fees array is used to bundle information on any additional charges in the Setu bill object—for example, processing fees. It has a taxes child array component, which can be used to provide a breakdown of the individual tax elements on each of the fees elements.

The amounts against any item such as taxes, discounts replicate the same object structure as described in the amount object.


Taxes#
"taxes" : [
{
"type" : "string"
"displayName" : "string",
"amount" : {},
"computation" : {},
"components" : [
{
"type" : "string",
"displayName" : "string",
"amount" : {},
"computation" : {},
}
],
}
],

The taxes array is used to bundle all the tax-related information in the Setu bill object. It has a components child, which can be used to provide a breakdown of the individual tax elements of the bill. This, in turn, contains a similar structure as the parent object, to be consistent.

The amounts against any item such as taxes, discounts replicate the same object structure as described in the amount object. The amount and the computation objects displayed are replicated in the same way as within other objects.


Discounts#
"discounts" : [
{
"code" : "string",
"reason" : "string",
"amount" : {},
"computation" : {}
}
]

The discounts array is used to bundle all the discounts-related information in the Setu bill object. You can also pass a discount code, and the reason for why the discount is being applied.

It has the amount and the computation as children.


Computation#
"computation" : {
"currencyCode" : "string",
"value" : int,
"method" : "PERCENTAGE" | "VALUE",
},

Sometimes, values are calculated dynamically, and is dependant on the rest of the elements in the bill. This is where the computation object comes into the picture. It is very similar to the amount object, but with an additional method attribute which describes how that value was arrived at.


Aggregates#
"aggregates" : {
"itemQuantity" : {},
"discount" : {
"displayName" : "string",
"amount" : {
"currencyCode" : "string",
"value" : 0
},
},
"fee" : {},
"tax" : {},
"subTotal" : {},
"total" : {}
},

The aggregates object is used to display the cumulative total value from all of the above components. Each of these attributes have the same structure—containing the amount object inside of them, along with the displayName string.


Sample bill#

Using all these components, we can now create a bill for a real-world use case. Let’s say you want to create for an EMI payment with the below details—

Line item
Amount
EMI — June ₹ 6000
EMI — July ₹ 6000
Total EMI
₹ 12,000
Convenience fees ₹ 15
Late fees ₹ 200
Total payable
₹ 12,215

 

Here, we need to process two line items for the EMIs, and two types of fees, and one total amount for the entire bill. The EMIs can be constructed using the items object, like so—

"items" : [
{
"displayName" : "EMI — June",
"description" : "Missed installment payment for June",
"aggregates" : {
"total" : {
"currencyCode" : "INR",
"value" : 600000 // INR6000 in paise
}
}
},
{
"displayName" : "EMI — July",
"description" : "Installment for July",
"aggregates" : {
"total" : {
"currencyCode" : "INR",
"value" : 600000 // INR6000 in paise
}
}
}
]

And for the fees included, we can use the fees object, like so—

"fees" : [
{
"displayName" : "Late fees",
"description" : "Extra charge for missing the June payment",
"aggregates" : {
"total" : {
"currencyCode" : "INR",
"value" : 20000 // in paise
}
}
},
{
"displayName" : "Convenience fees",
"description" : "Online processing charges",
"aggregates" : {
"total" : {
"currencyCode" : "INR",
"value" : 1500 // in paise
}
}
}
]

Filling the other attributes and putting it all together, the bill object now looks something like this—

// ENTIRE BILL OBJECT
{
"billerBillID" : "CXR5JEQO8K",
"recurrence" : "ONE_TIME",
"generatedOn" : "2019-07-27T12:56:39Z",
"dueDate" : "2019-08-26T12:56:39Z",
"amountExactness" : "EXACT",
"fees" : [
<late fees object>,
<convenience fees object>
],
"items" : [
<june fee object>,
<july fee object>
],
"customerAccount" : {
"id" : "asha.dev@gmail.com"
},
"aggregates" : {
"subtotal" : {
"amount" : {
"displayName" : "EMI amount",
"value" : 1200000 // in paise
}
},
"total": {
"amount" : {
"displayName" : "Total payable amount",
"value" : 1221500 // in paise
}
}
}
}

Finally, wrap the bill object in the following pattern, and send it across to us as the fetchCustomerBills response to Setu—

// FETCH CUSTOMER BILLS API RESPONSE
{
"status" : 200,
"success" : true,
"data" : {
"customer" : {
"name" : "Asha Dev"
},
"billDetails" : {
"billFetchStatus" : "AVAILABLE",
"bills" : [
<bill object>
]
}
}
}

Was this page helpful?