Confirm If A Chargebee Customer Has Already Purchased An AddOn

A workaround to overcome Chargebee's less-than-ideal querying options and non-existing email uniqueness constraint

This post contains affiliate links at no cost to you.

I got to work with Chargebee integration recently, and my overall experience was good. However, I felt two obvious things were missing.

First, email is not unique in Chargebee. You can add multiple customers with same email. Though it could be a well thought out decision on Chargebee’s part, I can’t imagine an application where you can have as many users as you like against a single email. Just to handle this unnatural scenario, the developer has to add an extra field in database user to keep Chargebee’s “unique” id, which could easily have been managed with already existing email. This is just so pointless.

Second, nearly non-existing search and querying options. A case in point, and the main purpose for this post, is that there’s no direct way I can search if a customer has already purchased an add on. Because that’s exactly what I would like if I need my add on to be bought only once.

Following is the code snippet in Node, that fetches all the invoices of the customer/user (up to the given limit) in descending order. It then loops through them all to see if one of the invoice was for the given add on.

const chargebee = require('chargebee');

  site: "whatever",
  api_key: "live_fYG8PwoZGXitGWI5maXLggpsogPfnEU1"

  limit: 30, //just an arbitrary limit. Usually a customer will have way less total invoices
  "customer_id[is]": "12345678",
  "recurring[is]": false, //optional
  "status[is]": "paid",   //optional
  "sort_by[desc]": "date" //optional
}).request(function (error, result) {
  if (error) {
  else {
    let addOnFound = false;
    for (let i = 0; i < result.list.length && !addOnFound; i++) {
      let invoice = result.list[i].invoice;
      if (invoice.line_items) {
        for (let j = 0; j < invoice.line_items.length && !addOnFound; j++) {
          if (invoice.line_items[j].entity_type === "addon" && invoice.line_items[j].entity_id === "liveChatSupport") {
            addOnFound = true;
    if (addOnFound) {
      //customer has already purchased the add on
    else {
      //add on most probably not purchased. Buy it...

See also