Amit Gharat
Feb 22, 2018 · 3 min read

for scalable and reusable code in Simpl JSSDK

So, I was asked to write a Javascript SDK for Simpl Integration. It was a time when our very first big merchant named Faas️❤️s had agreed to integrate Simpl in their apps/websites — Android platform in the beginning and then Web and iOS. So we wanted to be ready with our arsenal.

After weeks of reiteration on the API and overall architecture since we wanted to make the Simpl integration a breeze, we came up with the simplest SDK integration ever. All merchant had to do was add the following script tag in their checkout page:

<script
id="getsimpl"
data-env="sandbox"
data-merchant-id="123"
src="http://cdn.getsimpl.com/oneclick-v1.min.js">
</
script>

When going live with the Simpl integration, all the merchant had to do was change the data-env attribute to production. That’s it!

Standard Javascript Class with Prototypal Inheritance

The added Javascript SDK would expose a global object window.Simpl — having a bunch of methods on it — using which the merchant could verify if the Simpl payment option was supposed to be shown and ask users to generate a transaction token if okay. We thought of using Javascript function/class along with IIFE (jQuery inspired):

(function (window, document, undefined) {
'use strict';
var tempTarget = document.getElementById('getsimpl');
var merchantId = tempTarget.getAttribute('data-merchant-id') || '';
/**
* Represents a simpl button instance
* @param options an object consisting merchant_id/phone_number/email
* @constructor
* @public
* @class
* @returns {Object}
*/
function SimplJS(options) {
this.charges = { amount_in_paise: 0 };
this.merchant_id = options.merchant_id;
this.phone_number = '';
this.email = '';
return {
setTransactionAmount: this.setTransactionAmount.bind(this),
setApprovalConfig: this.setApprovalConfig.bind(this),
authorizeTransaction: this.authorizeTransaction.bind(this)
};
}
SimplJS.prototype.setTransactionAmount = function(amount_in_paise) {
this.charges.amount_in_paise = amount_in_paise;
};
SimplJS.prototype.setApprovalConfig = function(options) {
this.phone_number = options.phone_number;
this.email = options.email;
};
SimplJS.prototype.authorizeTransaction = function() {
// Launch Simpl Popup with phone/email/amount in the URL
// Ask for OTP before handing over a transaction token
};
// Expose a global object
window.Simpl = new SimplJS({ "merchant_id": merchantId });
})(window, document);

The pseudo-code is pretty self-explanatory and it simply launches the Simpl popup for OTP or confirmation every time the Simpl payment option is clicked. It served us well until we grew to 10+ merchants and few big merchants were really desperate to come onboard. That time we were exploring a possibility of subscription-based checkout so recurrent transactions would not even have to go through the Simpl popup. Simpl payment option Click and Boom — just like magic! Hence, we named it, ZeroClick SDK.

It was almost similar to the earlier One Click SDK with a slight modification (NDA 😅). There was no other way than to clone the original SDK and roll out the new one as zero-click-v1.min.js. Similarly, we had to port it to Cordova platform as well. Eventually, we ended up maintaining 3 variants of the Simpl SDK and that too without tree-shaking. Later we decided to rearchitect it.

Composition a.k.a. Concatenative Inheritance

Unlike Prototypal inheritance with standard ES5 classes, the composition allows us to copy the properties from one object to another, without retaining a reference from the original object. Here, we are dealing with ES6 imports and Destructuring assignments to compose the window.Simpl object.

import { setTransactionAmount } from "./set-transaction-amount";
import { setApprovalConfig } from "./set-approval-config";
import { authorizeTransaction } from "./authorize-transaction";
const target = document.getElementById("getsimpl");
const environment = target.getAttribute("data-env");
window.Simpl = {
merchantId: target.getAttribute("data-merchant-id") || "",
setTransactionAmount,
setApprovalConfig,
setAuthorizeConfig,
authorizeTransaction
};

There are two immediate benefits with this approach:
1. The methods are reusable by other variants of the SDKs. So no more redundant or duplicate code.
2. The imports are tree-shakable with Webpack + Babel pipeline. So non-imported methods such as authorizeCordovaTransaction or authorizeZeroClickTransaction from authorize-transaction.ts file used by other SDKs would be excluded from this SDK build.

Wrap ups

With these settings in mind, the SDK source code is now much more maintainable and easy to reason about. Additionally, I wrote a multi-compiler Webpack config for Webpacker to improve the tree-shaking further (saved 14% bundle size in our case). Chao!!

Simpl - Under The Hood

Stuff we do and learn at Simpl

Amit Gharat

Written by

Simpl - Under The Hood

Stuff we do and learn at Simpl

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade