Skip to main content

Web SDK

The Subscription Web SDK enables merchants to integrate recurring payments into their website using the SmartPay Subscription module. It provides a ready-to-use JavaScript widget that securely collects customer payment details, supports billing agreements, and ensures compliance with payment regulations. This SDK simplifies the subscription lifecycle and facilitates seamless onboarding of end customers into predefined subscription plans. It is designed for use cases where recurring billing, trial periods, and automated renewals are required.

Introduction

Include SmartPay Stylesheet

The SmartPay Stylesheet Generator allows merchants to customize the look and feel of SmartPay components to align with their brand guidelines. It provides a pre-configured set of styles that can be adapted without modifying the core SDK code. This ensures a consistent experience across checkout and subscription flows.

To access the Stylesheet Generator, merchants can reach out to their dedicated Product Solution Specialist. Once access is granted, the tool is available at: https://smartpay.cons.stylesheet.jpmmps.com.

After generating the stylesheet using the SmartPay Stylesheet Generator, merchants must download the CSS file and host it directly on their own web server. This ensures full control over availability and performance, and avoids reliance on external resources. To apply the stylesheet to the subscription flow, include it in the following line in the <head> section of the website:

<link href="smartpay-style.css" rel="stylesheet"> 

Make sure the href path points to the correct location of the hosted file on your domain. This stylesheet must be loaded before the SmartPay Widget is rendered, so that styles are applied correctly.

Merchants must ensure that their web server is configured to allow SmartPay Subscription to access any required assets (e.g., fonts) by enabling cross-origin resource sharing (CORS) using the Access-Control-Allow-Origin header.

SmartPay Subscription widgets are styling using predefined CSS classes. These styles are applied automatically if the SmartPay stylesheet is already loaded on the merchant site. Component-level or granular styling is not supported.

Include SmartPay Subscription Web SDK

<script src="https://.../sdk.js" type="text/javascript"></script>
info

Please check Sandbox vs. Production page for latest url.

Render SmartPay Subscription Widget

Create containers

<div id="root_container_id"></div>
<div id="submit_button_container_id"></div>
<div id="selected_payment_container_id"></div> <!-- optional -->
ContainerDescriptionMandatory
root_container_idRoot container where the payment options selector will be rendered.Yes
submit_button_container_idRoot element of the container where the submit button will be rendered.Yes
selected_payment_container_idId of the root element of the container where the currently selected payment option information will be rendered. Use this container if you want to display the selected payment option on a confirmation pageNo

Initialize widget instance

Loading the bundle will initialize the SmartPay Subscription app instance and attach it to the window object.

const smartPaySubscriptionsApp = window.SmartPaySubscriptionsSdk;

Render widget into the container

Calling this function will trigger the SmartPay Subscription widget to load the valid payment methods for the given Subscription or Payment Series and rendering it into the provided container.

subscriptionsSdk.renderWidget({
containerId: 'root_container_id',
selectedPaymentContainerId: 'selected_payment_container_id',
submitButtonContainerId: 'submit_button_container_id',
objectId: 'object-id',
objectType: 'object-type',
termsAndConditionsText: 'Terms and conditions text',
checkboxText: 'I agree with terms and conditions',
buttonText: 'Continue',
successHandler: () => { ... },
errorHandler: (errorCode, message) => { ... },
onBeforeSubmit: (beforeSubmitPaymentData) => { ... },
onBeforeDeleteSpo: (beforeDeleteSpoData) => { ... }
});

Configuration Options

FieldDescriptionData TypeMandatory
containerIdId of the root container where the payment options selector will be rendered.stringYes
submitButtonContainerIdId of the root element of the container where the submit button will be rendered.stringNo
selectedPaymentContainerIdId of the root element of the container where the currently selected payment option information will be rendered. Use this container if you want to display the selected payment option on a confirmation page.stringYes
objectTypetype of the object subject to storing the payment option.
Possible values: subscription, payment-series
stringYes
objectIdId of the subscription or the payment seriesstringYes
termsAndConditionsTextFree text, which will be displayed in the section Terms and Conditions if provided. Additional logic will be activated, where the end-user will be required to agree with these terms and conditions before continuing.stringNo
checkboxTextLabel text which will be displayed next to the checkbox in the section of Terms and ConditionsstringNo
buttonTextText of the button displayed in the section of Terms and ConditionsstringNo
successHandlerUse this function to trigger any logic to be executed upon a successful subscription update (storage of the payment instrument).functionYes
errorHandlerUse this function to trigger any logic to be executed upon an unsuccessful subscription update.functionYes
onBeforeSubmitOptional function to handle additional checks before the storage of the payment option gets started. The callback is triggered when the end-user clicks on the Confirm button on the widget.functionNo
onBeforeDeleteSpoOptional function to handle additional checks before the selected stored payment option gets deleted. The callback is triggered when the end-user clicks the Remove button near the stored payment option he decided to delete.functionNo
onWidgetRenderedWhenever the widget is successfully loaded, this JS callback will be visible in the console log.functionNo
activeSpoEnabledOptional function to activate the label ACTIVE indicating the linked SPO.booleanNo

"onWidgetRendered" optional callback

The onWidgetRendered callback is an optional JavaScript function that signals when the SmartPay widget has been successfully loaded and rendered in the user's browser. This callback is particularly useful for enhancing the integration's reliability on slower connections, ensuring that merchants are informed when the widget is ready.

Upon each successful render of the SmartPay widget, the onWidgetRendered callback is triggered. This callback is logged and returned to the merchant's website, confirming that the widget is operational. In scenarios where there might be network delays or slow connections, merchants can leverage this callback to implement additional UI elements, such as a loading icon or message, to inform users that the transaction process is still ongoing.

To view the onWidgetRendered callback information in the Event Log within the SDK Testing Tool, ensure that the Handle onWidgetRendered callback checkbox is enabled. This will allow you to monitor and verify the callback during the testing phase.

For further details on how to handle the onWidgetRendered callback, refer to the Widget Rendered Handler.

Visual Indication for Expired Widget Session

When the checkout session in the SmartPay widget expires, the widget notifies the merchant's front-end using a JavaScript callback which allows the merchant to handle the session expiration in their application. If the merchant does not handle this event, the widget will automatically grey out all buttons, making them non-clickable, preventing any further interactions with the expired session. Additionally, the widget calculates the session's expiration time based on its creation date, and an error callback is sent to the merchant's system when the checkout session or transaction ID expires with the errorCode = ERROR_CHECKOUT_TIMEOUT. This behavior prevents users from interacting with an expired session and avoids potential errors during checkout.

Introduce success handling

When the payment instrument details has been submitted and added to the Subscription, the user journey is completed. SmartPay Subscription widget notifies the merchant's website about it via the successHandler callback function which needs to be provided.

function successHandler(){

// adding SPO to Subscription completed successfully
console.log("successHandler triggered.");

// add your handler code here

}

subscriptionsSdk.renderWidget({
subscriptionId: subscriptionId,
container: "root_container_id",
successHandler: successHandler
});

Introduce error handling

Errors in the Subscription SmartPay Widget need to be handled through the callback function provided into the renderPaymentSelection method.

The errorCode parameter contains the actual error code as per the table below. The second parameter of the callback provides the exact message of the error to be used in debugging and as reference for our customer support.

function errorHandler(code, message) {
console.error(code + ': ' + message);

// handle the error

}

subscriptionsSdk.renderWidget({
objectId: 'object-id',
objectType: 'object-type',
container: "root_container_id",
successHandler: successHandler,
errorHandler: errorHander
});
Error codeDescription
ERROR_UPDATE_SUBSCRIPTIONError while updating the subscription/payment series
ERROR_VALUE_TYPE'objectType': Incorrect value provided
ERROR_REFERENCECannot find a subscription or a payment-series with the provided value
ERROR_PROCESSINGAn error occurred during the processing

Complete integration sample

(function () {

// SPO registration to Subscription completed unsuccessfully

function errorHandler(errorCode, error) {

// handle failed SPO registration here

console.error({code: errorCode, message: error});
}

function successHandler(){

// adding SPO to Subscription completed successfully

console.log("successHandler triggered.");

// add your handler code here

}

function tryRenderSubscriptionForm(subscriptionId) {

subscriptionsSdk.renderWidget({

containerId: "root_container_id",
selectedPaymentContainerId: "selected_payment_container_id",
submitButtonContainerId: "submit_button_container_id",
objectId: objectId, // could be a subscriptionId or a PaymentSerieId
objectType: objectType, // either "subscription" or "payment-series"
termsAndConditionsText: "Terms and conditions text",
checkboxText: "I agree with terms and conditions",
buttonText: "Continue",
successHandler: successHandler,
errorHandler: errorHandler,
onBeforeSubmit: function(onBeforeSubmit) { return true; },
onBeforeDeleteSpo: function(onBeforeDeleteSpo) { return true; },
onWidgetRendered: function(onWidgetRendered) { return true; },
onBeforeDeleteSpo: function(beforeDeleteSpoData) { return true; }

});

return true;
}

// Loading the bundle will initialize the SmartPay Subscription app
// instance and attach it to the window object.

const smartPaySubscriptionsApp = window.SmartPaySubscriptionsSdk;

document.getElementById("subscribe-button").addEventListener("click", function (e) {

if (e.target) {

// provide here objectId (subscriptionID or paymentSeriesId) received from the back-end

tryRenderSubscriptionForm(objectId);

}
});
})();