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>
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 -->
Container | Description | Mandatory |
---|---|---|
root_container_id | Root container where the payment options selector will be rendered. | Yes |
submit_button_container_id | Root element of the container where the submit button will be rendered. | Yes |
selected_payment_container_id | Id 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 | No |
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
Field | Description | Data Type | Mandatory |
---|---|---|---|
containerId | Id of the root container where the payment options selector will be rendered. | string | Yes |
submitButtonContainerId | Id of the root element of the container where the submit button will be rendered. | string | No |
selectedPaymentContainerId | Id 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. | string | Yes |
objectType | type of the object subject to storing the payment option. Possible values: subscription , payment-series | string | Yes |
objectId | Id of the subscription or the payment series | string | Yes |
termsAndConditionsText | Free 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. | string | No |
checkboxText | Label text which will be displayed next to the checkbox in the section of Terms and Conditions | string | No |
buttonText | Text of the button displayed in the section of Terms and Conditions | string | No |
successHandler | Use this function to trigger any logic to be executed upon a successful subscription update (storage of the payment instrument). | function | Yes |
errorHandler | Use this function to trigger any logic to be executed upon an unsuccessful subscription update. | function | Yes |
onBeforeSubmit | Optional 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. | function | No |
onBeforeDeleteSpo | Optional 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. | function | No |
onWidgetRendered | Whenever the widget is successfully loaded, this JS callback will be visible in the console log. | function | No |
activeSpoEnabled | Optional function to activate the label ACTIVE indicating the linked SPO. | boolean | No |
"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 code | Description |
---|---|
ERROR_UPDATE_SUBSCRIPTION | Error while updating the subscription/payment series |
ERROR_VALUE_TYPE | 'objectType': Incorrect value provided |
ERROR_REFERENCE | Cannot find a subscription or a payment-series with the provided value |
ERROR_PROCESSING | An 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);
}
});
})();