When a new customer signs up, you can run the signup through Chargebee Checkout. Checkout is PCI DSS compliant, so sensitive card information never reaches your servers.
Honey Comics is a fictitious online comic book store that sends comic books to its subscribers every week. Customers sign up for a subscription by providing their payment details. Try the demo, then follow the steps below to build something similar.
To keep the sample code short, it uses no database and has no real login.
Prerequisites
- Sign up for a Chargebee account.
- Create a plan with a trial period on your Chargebee test site.
- Get the API key for your Chargebee test site.
Build the signup page
This tutorial uses a two-step checkout. Your page collects the customer's account information first, and Chargebee Checkout opens when they click subscribe.
A sample input element looks like this.
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="company">Company</label>
<input type="text" class="form-control" name="company">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="last_name">Last Name</label>
<input type="text" class="form-control" v-model="last_name">
</div>
</div>
<div class="form-group">
<label for="last_name">Last Name</label>
<input type="text" class="form-control" [(ngModel)]="last_name">
</div>
<div className="row">
<div className="col-sm-6">
<div className="form-group">
<label htmlFor="company">Company</label>
<input type="text" name="company" className="form-control" value={this.state.company} onChange={this.handleChange}/>
</div>
</div>
</div>
Set up the client library
Download and import the client library for your language, then configure it with your Chargebee test site name and API key.
ChargeBee.configure(:site => "honeycomics-v3-test",
:api_key => "<full-access-key>")
const chargebee = new Chargebee({
site : "honeycomics-v3-test",
apiKey : "<full-access-key>",
});
Environment.configure("honeycomics-v3-test","<full-access-key>");
import chargebee
chargebee.configure("<full-access-key>", "honeycomics-v3-test")
/*
* Sets the environment for calling the Chargebee API.
* You need to sign up at the Chargebee app to get this credential.
* It is better if you fetch configuration from the environment
* properties instead of hard coding it in code.
*/
ChargeBee_Environment::configure("honeycomics-v3-test",
"<full-access-key>");
Add an endpoint that returns a hosted page object
On your server, call the checkout new subscription API with the information you collected on the client. It returns a hosted page object for the new subscription.
# routes.rb
post "/api/generate_checkout_new_url" => "chargebee#checkout_new"
# controller
def checkout_new
result = ChargeBee::HostedPage.checkout_new_for_items({
:subscription_items => [{:item_price_id => params[:item_price_id] }],
:customer => {:first_name => params[:first_name],
:last_name => params[:last_name],
:company => params[:company],
:phone => params[:phone],
:email => params[:email]
},
:embed => false
})
render :json => result.hosted_page.to_s
end
app.post("/api/generate_checkout_new_url", (req, res) => {
chargebee.hosted_page.checkout_new_for_items({
subscription_items : [{
item_price_id : req.body.item_price_id
}],
customer: {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
phone: req.body.phone,
company: req.body.company,
}
}).request(function(error,result){
if(error){
//handle error
console.log(error);
}else{
res.send(result.hosted_page);
}
});
});
@WebServlet(name = "checkout_new_for_items", value = {"generate_checkout_new_url"})
public class CheckoutNewForItems extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String item_price_id = request.getParameter("item_price_id");
Result result = null;
try {
result = HostedPage.checkoutNewForItems()
.subscriptionItemItemPriceId(item_price_id).request(new Environment("honeycomics-v3-test", "<full-access-key>"));
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json");
response.getWriter().print("{\"error\":\"Failed to create hosted page\"}");
return;
}
HostedPage hostedPage = result.hostedPage();
// Dont add the below header in production. This is only for demo
response.addHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/json");
response.getWriter().print(hostedPage.jsonObj);
}
}
@app.route('/api/generate_checkout_new_url', methods=['POST'])
def generate_checkout_new_url():
result = chargebee.HostedPage.checkout_new_for_items({
"subscription_items" : [{
"item_price_id" : request.form.get("item_price_id")
}],
"customer" : {
"first_name" : request.form.get("first_name"),
"last_name" : request.form.get("last_name"),
"company" : request.form.get("company"),
"phone" : request.form.get("phone"),
"email" : request.form.get("email")
}
})
hosted_page = result._response['hosted_page']
return jsonify(hosted_page)
# routes
Route::post('generate_checkout_new_url', 'ChargebeeController@generateCheckoutNewUrl');
# controller
public function generateCheckoutNewUrl(Request $request) {
$result = ChargeBee_HostedPage::checkoutNewForItems(array(
"subscriptionItems" => array(
array(
"itemPriceId" => $request->get('item_price_id')
)
),
"customer" => array(
"first_name" => $request->get('first_name'),
"last_name" => $request->get('last_name'),
"company" => $request->get('company'),
"phone" => $request->get('phone'),
"email" => $request->get('email')
)
));
$hostedPage = $result->hostedPage();
return response()->json($hostedPage->getValues(), 200);
}
To use PayPal, GoCardless, or Plaid, pass embed as false when you create the hosted page.
Open Checkout on click
On the client, openCheckout takes a hostedPage callback that returns a promise. Make it call the endpoint you created above and resolve to the hosted page object.
cbInstance.openCheckout({
hostedPage: function() {
// Hit your end point that returns hosted page JSON object as response
// This sample end point will call checkout new api
// https://apidocs.chargebee.com/docs/api/hosted_pages/create-checkout-for-a-new-subscription
// If you want to use paypal, go cardless and plaid, pass embed parameter as false
return $.ajax({
method: "post",
url: "http://localhost:8000/api/generate_checkout_new_url",
data: $("#subscribe-form").serialize()
});
},
loaded: function() {
console.log("checkout opened");
},
error: function() {
$("#loader").hide();
$("#errorContainer").show();
},
close: function() {
$("#loader").hide();
$("#errorContainer").hide();
console.log("checkout closed");
},
success: function(hostedPageId) {
console.log(hostedPageId);
// Hosted page id will be unique token for the checkout that happened
// You can pass this hosted page id to your backend
// and then call our retrieve hosted page api to get subscription details
// https://apidocs.chargebee.com/docs/api/hosted_pages/retrieve-a-hosted-page
},
step: function(value) {
// value -> which step in checkout
console.log(value);
}
});
this.cbInstance.openCheckout({
hostedPage: () => {
// Hit your end point that returns hosted page JSON object as response
// This sample end point will call the below api
// https://apidocs.chargebee.com/docs/api/hosted_pages/create-checkout-for-a-new-subscription
// If you want to use paypal, go cardless and plaid, pass embed parameter as false
var data = {
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
company: this.company,
item_price_id: "cbdemo_scale"
}
return axios.post("http://localhost:8000/api/generate_checkout_new_url", urlEncode(data)).then((response) => response.data);
},
loaded: function() {
console.log("checkout opened");
},
close: () => {
this.loading = false;
console.log("checkout closed");
},
success: function(hostedPageId) {
console.log(hostedPageId);
// Hosted page id will be unique token for the checkout that happened
// You can pass this hosted page id to your backend
// and then call our retrieve hosted page api to get subscription details
// https://apidocs.chargebee.com/docs/api/hosted_pages/retrieve-a-hosted-page
},
step: function(value) {
// value -> which step in checkout
console.log(value);
},
error: function(error) {
this.errorMsg = error;
}
});
this.cbInstance.openCheckout({
hostedPage: () => {
this.loading = true;
// Hit your end point that returns hosted page JSON object as response
// This sample end point will call checkout new api
// https://apidocs.chargebee.com/docs/api/hosted_pages/create-checkout-for-a-new-subscription
// If you want to use paypal, go cardless and plaid, pass embed parameter as false
let data = {
item_price_id: "cbdemo_scale",
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
company: this.company
}
return this.http.post("http://localhost:8000/api/generate_checkout_new_url", this.getFormUrlEncoded(data), {headers: new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'})}).toPromise();
},
loaded: () => {
console.log("checkout opened");
},
error: () => {
this.loading = false;
this.ref.markForCheck();
this.errMsg = true;
},
close: () => {
this.loading = false;
this.ref.detectChanges();
console.log("checkout closed");
},
success: (hostedPageId) => {
console.log(hostedPageId);
// Hosted page id will be unique token for the checkout that happened
// You can pass this hosted page id to your backend
// and then call our retrieve hosted page api to get subscription details
// https://apidocs.chargebee.com/docs/api/hosted_pages/retrieve-a-hosted-page
},
step: (value) => {
// value -> which step in checkout
console.log(value);
}
});
this.state.cbInstance.openCheckout({
hostedPage: () => {
var data = {
first_name: this.state.first_name,
last_name: this.state.last_name,
email: this.state.email,
phone: this.state.phone,
company: this.state.company,
item_price_id: "cbdemo_scale"
};
// Hit your end point that returns hosted page JSON object as response
// This sample end point will call checkout new api
// https://apidocs.chargebee.com/docs/api/hosted_pages/create-checkout-for-a-new-subscription
// If you want to use paypal, go cardless and plaid, pass embed parameter as false
return axios.post("http://localhost:8000/api/generate_checkout_new_url", urlEncode(data)).then((response) => response.data)
},
success(hostedPageId) {
console.log(hostedPageId);
},
close:() => {
this.setState({loading: false});
console.log("checkout new closed");
},
step(step) {
console.log("checkout", step);
}
});
The success callback receives a hosted page ID, a unique token for that checkout. Pass it to your backend and call the retrieve a hosted page API to get the subscription details.
Reference
For every openCheckout option and callback, see the Chargebee instance reference in the Chargebee.js Reference.
To upgrade an existing subscription instead of creating a new one, see Upgrade an existing subscription with Chargebee Checkout.
We're always happy to help you with any questions you might have! Click here to reach out to us.