This implementation guide will walk you through the process of building a Chargifyjs payment page that collects new payment methods in your web application.
Summary
- Feature
- Chargifyjs
- You Need
- A web app; developer experience with Javascript and APIs
- Code
- Yes
- Difficulty
- ◉◉◉◎◎
Implementation Samples Diagram
In this walkthrough, we'll build a functioning Chargifyjs form that allows your logged-in end user to add a credit card.
- Know your Subdomain
In your Advanced Billing Site URL, you'll see:https://SUBDOMAIN.chargify.com
- Get your Chargifyjs Public Key
In your Advanced Billing Site, go to Config > Integrations > Chargify.js - Get your Advanced Billing API Key
In your Advanced Billing Site, go to Config > Integrations > API Keys
HTML
JS
CSS
- Set up your file directory
yourfolder - index.html - load.js - submit.js - styles.css
- Add your code
When you're done, load on localhost. Keep in mind, the form will not render until you add your real credentials in the next step.
<!doctype html>
<html lang="en">
<head>
<!-- meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- include chargifyjs -->
<script src="https://js.chargify.com/latest/chargify.js"></script>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- Chargifyjs custom CSS (modify as needed) -->
<link rel="stylesheet" href="styles.css" />
</head>
<!-- begin body -->
<body>
<div class="form-box">
<h2 align="left">Chargifyjs for Credit Cards with Billing Address</h2>
<hr style="margin-top:16px; margin-bottom:32px; border-bottom: 4px solid #e0e1ec;">
<!-- load spinner -->
<div id="load_spinner" class="d-flex justify-content-center">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<!-- error banner -->
<div class="alert alert-danger" role="alert" id="chargify-error-message" style="display:none;"></div>
<form id="chargify-form" action="create.js" method="POST" style="display:none;">
<!-- Card Details Section -->
<h5 style="margin-bottom:32px;">Card Details</h5>
<div class="form-row">
<div class="form-group col-md-6">
<div id="first_name"></div>
</div>
<div class="form-group col-md-6">
<div id="last_name"></div>
</div>
<div class="form-group col-md-6">
<div id="cc_number"></div>
</div>
<div class="form-group col-md-6">
<span id="cc_month"></span>
<span id="cc_year"></span>
<span id="cc_cvv"></span>
</div>
</div>
<hr>
<h5 style="margin-bottom:32px;">Billing Address</h5>
<!-- billing address -->
<div class="form-row">
<div class="form-group col-md-6">
<div id="billing_address"></div>
</div>
<div class="form-group col-md-6">
<div id="billing_address2"></div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<div id="billing_city"></div>
</div>
<div class="form-group col-md-6">
<div id="billing_zip"></div>
</div>
</div>
<!-- billing address -->
<div class="form-row">
<div class="form-group col-md-6">
<div id="billing_country"></div>
</div>
<div class="form-group col-md-6">
<div id="billing_state"></div>
</div>
</div>
<!-- Form Submit -->
<button type="submit" class="btn btn-primary">Save Card</button>
<!-- Display Chargifyjs Token (make this input hidden in production) -->
<hr>The Chargify Token is: <input id="chargify-token" type="text" /></br>
Use this token in your backend to perform an action with the Chargify API
</form>
</div>
<!-- end body -->
<!-- JavaScript (jquery/bootstrap) -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<!-- Javascript (Chargifyjs load and submit files) -->
<script src="load.js"></script> <!-- This contains your Chargify.js file -->
<script src="submit.js"></script> <!-- This pauses form submission to create a token -->
<!-- Smooth form load -->
<script>
setTimeout(function () {
$("#load_spinner").remove();
$("#chargify-form").show();
}, 2000);
</script>
</body>
</html>
//load.js
var chargify = new Chargify();
//**********
//AVAILABLE STYLES
//https://developer.chargify.com/content/chargify-js/configurations.html#styles
//**********
chargify.load({
publicKey: 'chjs_hy39j8rc2krnhdx9db73ynmb',
serverHost: 'https://demo-integrations2.chargify.com',
type: 'card',
hideCardImage: false,
optionalLabel: ' ',
requiredLabel: '*',
addressDropdowns: true,
style: {
field: {
maxWidth: '100%',
backgroundColor: null,
paddingTop: null,
paddingBottom: null,
borderRadius: '.25rem',
color: null,
border: null,
fontSize: null,
fontWeight: null
},
input: {
maxWidth: '100%',
backgroundColor: null,
paddingTop: null,
paddingBottom: null,
borderRadius: '.25rem',
color: null,
border: '1px solid #ced4da',
fontSize: '16px',
fontWeight: null
},
label: {
maxWidth: null,
backgroundColor: '#ffffff',
paddingTop: '2px',
paddingBottom: '1px',
borderRadius: null,
color: null,
border: null,
fontSize: '16px',
fontWeight: '400'
},
message: {
maxWidth: null,
backgroundColor: null,
paddingTop: '2px',
paddingBottom: '1px',
borderRadius: null,
color: null,
border: null,
fontSize: null,
fontWeight: null
}
},
fields: {
firstName: {
selector: '#first_name',
label: 'First Name on Card',
placeholder: 'John',
message: 'Invalid First Name',
maxlength: '30',
required: true
},
lastName: {
selector: '#last_name',
label: 'Last Name on Card',
placeholder: 'Smith',
message: 'Invalid Last Name',
maxlength: '30',
required: true
},
number: {
selector: '#cc_number',
label: 'Card Number',
placeholder: 'Card Number',
message: 'Invalid Card',
required: true
},
month: {
selector: '#cc_month',
label: 'Month',
placeholder: 'MM',
message: 'Invalid Month',
required: true
},
year: {
selector: '#cc_year',
label: 'Year',
placeholder: 'YYYY',
message: 'Invalid Year',
required: true
},
cvv: {
selector: '#cc_cvv',
label: 'CVV',
placeholder: 'CVV',
message: 'Invalid CVV',
required: true
}
}
});
//submit.js
document.querySelector('#chargify-form').addEventListener('submit', function() {
var form = this;
event.preventDefault();
chargify.token(
form,
function success(token) {
console.log('{host} token SUCCESS - token: ', token);
// host will write token in hidden input
document.querySelector('#chargify-token').value = token;
// uncomment to initiate form submission
//form.submit();
console.log('{host} form submitted');
},
function error(err) {
//define error message (occurs before token generation attempt)
if (err.message === undefined) { var message = ""; }
else { var message = err.message; }
//define actual error message (occurs after token generation attempt)
if (err.errors === undefined) { var chargify_errors = ""; }
else { var chargify_errors = err.errors; }
//construct error message to display
$("#chargify-error-message").show().text(message + " " + chargify_errors);
}
);
});
/* styles.css */
.form-control {
padding: 16px;
}
.form-box {
padding: 20px 5%;
margin-right: 0;
margin-left: 0;
border-width: .2rem;
margin: 1rem -15px 0;
border: solid #f7f7f9;
position: relative;
margin: 0 auto;
max-width: 900px;
}
#first_name iframe,
#last_name iframe,
#cc_number iframe {
width: 100% !important;
}
#cc_month iframe {
width: 30% !important;
}
#cc_year iframe {
width: 30% !important;
}
#cc_cvv iframe {
width: 30% !important;
}
- Add your Chargifyjs credentials in the load.js file
In load.js, update these:
a) UpdatePublicKey
with the Chargifyjs Public Key you created in Step 1.1, and
b) UpdateServerHost
with the Subdomain from Step 1.1 - Customize chargify.load (as needed)
View more documented examples - Configure Styling (as needed)
Withinchargify.load
, there is astyle
object, which controls the styling of the iframed fields. In the load.js example file, you will see many values set tonull
to help guide you. Replace the null values, with real values, as needed, once your form is fully functional. - Add secure iframed fields (as needed)
The load.js file tells Chargifyjs what iframed fields to display on your web form. This is done by includingfields
(billing address, billing city, etc) in yourchargify.load
function, and those fields map to div IDs in your frontend form. Use the image below, alongside the 5 steps, to guide you.
1. Add a supported field to the load.js file, such asnumber
. You will add these fields in thefields
object.
2. Set theselector
to any ID you’d like, such as#cc_number
.
3. In the signup.html file, add a div with the matching selector, such as<div id="cc_number"></div>
4. When you load your page, assuming no errors in your chargify.load function, the secure field will be iframed into your web form.
5. Repeat for any field you would like to add. For full examples, see below.
If using example from Frontend Implementation section
1. Go into submit.js and uncomment form.submit();
2. Go into signup.html, find the input chargify-token
and change 'text' to 'hidden'
If not
If you are not using the example code, just make sure your form can successfully submit and POST to your servers.
Server-side
API
Next, create a payment profile and save the card to the existing customer.
// EXAMPLE: Chargifyjs for Create Payment Method for Customer
// ENDPOINT: POST /payment_profiles.json
// DOCS: https://developers.chargify.com/docs/api-docs/b3A6MTQxMDgzNTU-create-payment-profile
// REQUEST BODY
{
"payment_profile": {
"customer_id": 12345, //valid customer ID
"chargify_token": "tok_w68qcpnftyv53jk33jv6wk3w" //the chargifyjs token generated from your form
}
}
Then, set the newly created payment method as the default.
If you want to set it as the default in real time
You’ll need the subscription id and the payment profile id in your code, then set the payment method as the default for the subscription by performing POST /subscriptions/:id/payment_profiles/:id/change_payment_profile.json. There is no json body for this API call.
If you want to let the user set the default manually
Continue to the next section, and build a UI to let your customer manage multiple payment methods.
- Test the frontend
The form should load, a token should generate, and you should test token generation errors. If you are connected to the Advanced Billing Test Gateway, use a card number of2
or3
to simulate an error. - Add payment method errors and test
Test a failed API call to Advanced Billing. For example, break the API call on purpose, to test how your implementation responds to that error. Pass the error back to your front end. This is how your users will see errors such as 'declined card', etc. - Add a redirect and test success
On success, a user should be redirected successfully, and the entire flow should make sense start to finish.
- Read the customer’s payment methods
You’ll need the customer id, and then read the payment profiles for the customer by performing GET /payment_profiles.json?customer_id=:id. Since this endpoint reads all payment profiles and returns a max of 20 as a default, be sure you have a value set as the customer_id to ensure you are fetching the intended customer’s data. - Parse the data you want to display
For example, the payment profile id would be similar toresponse[0].payment_profile.id
. Maybe you want the payment profile first name, which would beresponse[0].payment_profile.first_name
. - Pass the data to your frontend, and display it
Here is a sample image that shows what an end result might look like in a basic table/list layout: - Let the user set a payment method as the default
You’ll need the subscription id and the payment profile id, then set the payment method as the default for the subscription by performing POST /subscriptions/:id/payment_profiles/:id/change_payment_profile.json. There is no json body for this API call.