Introduction
This tutorial covers how you can create a pricing table for returning users using Chargebee Pricing Tables to support plan upgrades, downgrades, and so on for your customers by providing relevant inputs.
Setup
- Connect your Chargebee account to Pricing Tables by referring to this video. 
- Customize your pricing table further by referring to these Tutorials. 
Setup Client Library
Import Chargebee SDK
Download and import the client library of your choice and configure the client library with your Chargebee TEST site name and API key.
Environment.configure("your_site_domain","your_api_key");
ChargeBee.configure(:site => "your_site_domain", :api_key => "your_api_key")
const chargebee = new Chargebee({
  site : "{your_site_domain}",
  apiKey : "{your_api_key}",
});
import chargebee
chargebee.configure("your_site_domain", "your_api_key")
ChargeBee_Environment::configure("your_site_domain", "your_api_key");
Create a pricing table session
On the server side, use Chargebee’s pricing table session API to create a pricing table session object.
@WebServlet(name = "pricing_page_session", value = {"generate_pricing_page_session"})
public class GeneratePricingPageSession extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        Result result = null;
        try {
            result = PricingPageSession.createForNewSubscription()
                    .pricingPageId("your_atomicpricing_pricing_page_id")
                    .customerId("customer_id") // new or existing customer id
                    .subscriptionId("new_subscription_id")
                    .request(new Environment("your_site_domain", "your_api_key"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        PricingPageSession pricingPageSession = result.pricingPageSession();
        // Don't add the below header in production. This is only for demo
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setContentType("application/json");
        response.getWriter().print(pricingPageSession.jsonObj);
    }
}
# routes.rb
post "/api/generate_pricing_page_session" => "chargebee#generate_pricing_page_session"
# controller
def generate_pricing_page_session
  result = ChargeBee::PricingPageSession.create_for_new_subscription({
    :pricing_page => { :id => params[:id] },
    :customer     => { :id => params[:id] },
    :subscription => { :id => params[:id] }
  })
  render :json => result.pricing_page_session.to_s
end
app.post("/api/generate_pricing_page_session", (req, res) => {
chargebee.pricing_page_session
  .create_for_new_subscription({
    pricing_page: {
      id: "your_atomicpricing_pricing_page_id"
    },
    customer: {
      id: "customer_id", // new or existing customer id
    },
    subscription: {
      id: "new_subscription_id",
    }
  })
  .request(function(error, result) {
    if (error) {
      //handle error
      console.log(error);
    } else {
      res.send(result.pricing_page_session);
    }
  });
});
@app.route('/api/generate_pricing_page_session', methods=['POST'])
def generate_pricing_page_session():
    result = chargebee.PricingPageSession.create_for_new_subscription({
        "pricing_page": {
            "id": "your_atomicpricing_pricing_page_id"
        },
        "customer": {
            "id": "customer_id", // new or existing customer id
        },
        "subscription": {
            "id": "new_subscription_id",
        }
    })
    pricing_page_session = result._response['pricing_page_session']
    return jsonify(pricing_page_session)
# routes
Route::post('generate_pricing_page_session', 'ChargebeeController@generatePricingPageSession');
# controller
public function generatePricingPageSession(Request $request)
{
    $result = ChargeBee_PricingPageSession::createForNewSubscription(array(
        "pricing_page" => array(
            "id" => "your_atomicpricing_pricing_page_id"
        ),
        "customer" => array(
            "id" => "customer_id", // new or existing customer id
        ),
        "subscription" => array(
            "id" => "new_subscription_id",
        )
    ));
    $pricingPageSession = $result->pricingPageSession();
    return response()->json($pricingPageSession->getValues(), 200);
}
Setup your frontend
On the client side, you can use the Pricing Tables object in the Chargebee.js and call pricingTable.open() function. The pricingTable parameter passed to this method expects a function that returns a Promise. This Promise can be a result of an API call that creates a pricing table session (as shown in the previous step), and this promise must resolve to a pricing table session object.
<script src="https://js.chargebee.com/v2/chargebee.js" onload="onLoad()"></script>
<script>
async function onLoad() {
const chargebee = Chargebee.init({
    site: "YOUR-CHARGEBEE-SUBDOMAIN",
})
const pricingTable = await chargebee.pricingTable();
pricingTable.open({
  pricingTable: function() {
    return fetch('https://YOUR_DOMAIN/create_pricing_table', {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    }).then(response => response.json());
  },
});
</script>
<div
  id="chargebee-pricing-table"
  data-pricing-table-integration-type="api"
></div>
import React, { useEffect } from 'react';
import Chargebee from 'chargebee';
function PricingPage() {
useEffect(() => {
  const cbInstance = Chargebee.init({
      site: "YOUR-CHARGEBEE-SUBDOMAIN",
  })
  const pricingTable = await cbInstance.pricingTable();
    
  pricingTable.open({
      pricingTable: function() {
          return fetch('https://YOUR_DOMAIN/create_pricing_table', {
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
          }).then(response => response.json()),
      },
  });
}, []);
return (
  <div className="App">
    <div
      id="chargebee-pricing-table"
      data-pricing-table-integration-type="api"
    ></div>
  </div>
);
}
export default PricingPage;
<script setup lang="tsx">
import Chargebee from 'chargebee';
import { onMounted } from 'vue';
onMounted(() => {
    const cbInstance = Chargebee.init({
        site: "YOUR-CHARGEBEE-SUBDOMAIN",
    })
    const pricingTable = await cbInstance.pricingTable();
    pricingTable.open({
    pricingTable: function() {
      return fetch('https://YOUR_DOMAIN/create_pricing_table', {
              method: "POST",
              headers: {
                "Content-Type": "application/json"
              },
              body: JSON.stringify(data)
            }).then(response => response.json()),
          },
      });
});
</script>
<template>
    <div
        id="chargebee-pricing-table"
        data-pricing-table-integration-type="api"
    ></div>
</template>
import { Component } from '@angular/core';
import Chargebee from 'chargebee';
@Component({
    selector: 'pricing-page-component',
    templateUrl: './pricing-page.component.html',
    styleUrls: ['./pricing-page.component.css'],
})
export class PricingPageComponent {
    title = 'pricing-page-component';
    params: { [index: string]: any } = {};
    ngOnInit() {
        const cbInstance = Chargebee.init({
            site: "YOUR-CHARGEBEE-SUBDOMAIN",
        })
        const pricingTable = await cbInstance.pricingTable();
            pricingTable.open({
                pricingTable: function() {
                    return fetch('https://YOUR_DOMAIN/create_pricing_table', {
                              method: "POST",
                              headers: {
                                "Content-Type": "application/json"
                              },
                              body: JSON.stringify(data)
                      }).then(response => response.json()),
                  },
              });
    }
}
We're always happy to help you with any questions you might have! Click here to reach out to us.