Skip to main content

Payment form SDK

SmartPay offers a lightweight Web SDK that provides a simple solution to collect credit card data. The integration is similar to the regular Checkout WebSDK, i.e. renderWidget method triggers seamless credit card data collection form rendering and accepts the following options:

  • html-container id
  • js-callbacks: success/error
  • styling options

Payment Form SDK supports custom styling and all payment flows: guest payment, storing a new payment option and CIT-stored payment.

info

In case of CIT-Stored payments, stored payment option selection should be provided by integrator.

Include stylesheet and SmartPay JavaScript Library

Include SmartPay Stylesheet

The SmartPay Stylesheet Generator is used for customizing SmartPay to match the brand's styling requirements. Contact your dedicated Product Solution Specialist to grant you the access. The Stylesheet generator can be accessed here: https://smartpay.cons.stylesheet.jpmmps.com.

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

The SmartPay Stylesheet file must be hosted on your server.

Please make sure SmartPay can access resources related to the SmartPay stylesheet (e.g. fonts) by configuring cross-origin resource sharing in your webserver (Access-Control-Allow-Origin).

info

SmartPay Widget Components are rendered using SmartPay CSS classes. This assumes that the SmartPay stylesheets are already loaded by the merchant site. Contact your Product Solution Specialist for the SmartPay Frontend Library.

Include SmartPay WebSDK

<script src="https://.../light-sdk/smp-bundle.js" type="text/javascript"></script> 

Please check Sandbox vs. Production page for latest URL.

Render SmartPay Widget

Create containers

<div id="main-container"></div> 

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

const app = window.SmpLibrary.SmartPayAppInstance; 

Render widget

void renderWidget ( options ); 

Calling 'renderWidget' function will trigger the SmartPay to render the credit card payment form for the given payment checkout token into the provided container(s).

// Guest CIT
app.renderWidget({
paymentCheckoutToken: '<payment checkout token here>',
container: '<html container id here>',
paymentFormOnly: true,
purpose: 'PAYMENT_TRANSACTION',
paymentOptionCode: 'CC',
successHandler: function (data) {...},
errorHandler: function (errorCode, error) {...}
});

// Card-on-File Registration for MIT
app.renderWidget({
subscriptionCheckoutToken: '<subscription checkout token here>',
container: '<html container id here>',
paymentFormOnly: true,
purpose: 'REGISTRATION',
paymentOptionCode: 'CC',
successHandler: function (data) {...},
errorHandler: function (errorCode, error) {...}
});

// CIT-Stored (one-click payment)
app.renderWidget({
paymentCheckoutToken: '<payment checkout token here>',
container: '<html container id here>',
paymentFormOnly: true,
purpose: 'PAYMENT_TRANSACTION',
storedPaymentOptionReference: '<stored card on file reference here>'
successHandler: function (data) {...},
errorHandler: function (errorCode, error) {...}
});

Configuration Options

The rendering method requires the configuration object containing the parameters reflecting your rendering choice.

FieldDescriptionData TypeMandatory
paymentCheckoutTokenUse the checkoutToken received in your checkout API response.stringYes, if 'subscriptionCheckoutToken' is not provided, provide paymentOptionCode
subscriptionCheckoutTokenAlternatively to 'paymentCheckoutToken', provide subscriptionCheckoutToken received as part of the response of Create Subscription Checkout API to register new payment card.stringYes, if 'paymentCheckoutToken' is not provided, and purpose is Registration
containerHTML element id of the selector-container. In multipage scenario, it is mandatory only for the first initialization, until the payment option is selected.stringYes
successHandlerUse this function to trigger any logic to be executed upon the transaction having been successfully processed.functionYes
errorHandlerUse this function to trigger any logic to be executed upon the transaction having been unsuccessfully processed.functionYes
paymentFormOnlyThe parameter shows if the payment selector page should be rendered or not.booleanNo
paymentOptionCodeThe payment option code associated with the payment option chosen by the customer. Possible values:
  • Credit Card = 'CC',
  • VISA = 'VISA',
  • MASTERCARD = 'MSTRCRD',
  • JCB = 'JCB',
  • American Express = 'AMEX'.
enumConditional (required if:
  • paymentFormOnly=true and purpose=REGISTRATION
 OR
 
  • purpose=PAYMENT_TRANSACTION and storedPaymentOptionReference=null and paymentFormOnly=true)
storedPaymentOptionReferenceThe stored payment reference showing the registered payment option. Only for payment to distinguish between 'guest' and 'CIT Stored flow'stringConditional (required if:
purpose=PAYMENT_TRANSACTION and paymentOptionCode=null and paymentFormOnly=true)
purposeIndicates the purpose of the checkout. Possible values:
  • REGISTRATION
  • PAYMENT_TRANSACTION
If "REGISTRATION", register a new payment card
enumConditional (required if paymentFormOnly=true)

Introduce success handling

When payment data has been submitted and processed by payment provider, the user journey is completed. SmartPay widget notifies merchant's website about it via 'successHandler' callback function which needs to be provided.

Once received, the actual transaction status should be checked via getPaymentStatus API. To differentiate between regular payment completed and payment option registered, use 'kind' value provided in data object.

function successHandler(data){ 
if (data.kind === "CALLBACK"){
// Process payment completed

// Request transaction status via Get Payment Status API
// Link: https://documentation.jpmmps.com/docs/smartpay/get-payment-status-api/
}
if (data.kind === "ADD_METHOD_CALLBACK"){
// Process Card-on-File registration completed
// Request updated payment options list via 'Get Payment Options' API.
// Link: https://documentation.jpmmps.com/docs/smartpay/payment-option-management-apis/get-payment-options/

// Note: there is no any payment processed yet, no need to check status.
}
}
// Render payment form for Card-on-File Registration for MIT
app.renderWidget({
successHandler: successHandler,
...
...
});

Introduce error handling

Errors in the SmartPay Widget need to be handled through the callback function provided into the renderWidget 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
// Request transaction status via Get Payment Status API
// Link: https://documentation.jpmmps.com/docs/smartpay/get-payment-status-api/
}

app.renderWidget({
...
...
errorHandler: errorHandler
});
Error codeDescriptionConsumer to select another payment method and retry
ERROR_INIT_PAYMENTError on payment initialization, consumer need to choose a different payment option.Yes
ERR_CONFIGError while loading payment methods configuration or widget.No
ERROR_INVALID_INPUTInvalid configuration passed to renderWidget method.No
ERR_PAYMENT_CALLBACKPayment failed during Authorization or Capturing. This is a hard failure, recreation of transaction is required.No
ERROR_INIT_STORE_PAYMENT_OPTIONError while storing payment option, consumer need to choose a different payment option.Yes
ERRORAny other unhandled error.No
ERROR_CHECKOUT_TIMEOUTcheckoutToken or transactionId is expired. Refer here for more details.No

Please associate the transactionId, checkoutToken and possible error messages with your business transaction / order inside your systems and make it available to your support / operation staff. It will be valuable input for any ticket to our support team.

Complete integration sample

<!DOCTYPE html> 
<html lang="en">
<head>
<script src="https://sdk.cons.smartpay.jpmmps.com/light-sdk/smp-bundle.js"></script>
<link rel="stylesheet" type="text/css" href="https://your-domain.com/style.css" class="none_scoped">
<meta charset="UTF-8">
<title>Light SDK integration</title>
</head>
<body>
<div style="display: flex;justify-content: center;margin-top: 12px">
<div style="display: flex;flex-direction: column;width: 80%">
<div style="display:flex"><label for="checkoutTokenId" style="margin-right: 4px">CheckoutToken</label><input
type="text"
id="checkoutTokenId"
style="width: 100%">
</div>
<input type="button" style="margin: 6px 0 6px 0" onclick="renderForm()" value="Render payment form">
<div id="main-container"></div>
</div>
</div>
</body>
<script>
function renderForm() {
const app = window.SmpLibrary.SmartPayAppInstance;
app.renderWidget({
paymentCheckoutToken: document.getElementById('checkoutTokenId').value,
container: 'main-container',
purpose: 'PAYMENT_TRANSACTION',
paymentOptionCode: 'CC',
successHandler: function (data) {
// Cleanup payment form container
if (data.kind === 'CALLBACK') {
// process payment completed
// Requests transaction status via Get Payment Status API
console.log(data);
}
if (data.kind === 'ADD_METHOD_CALLBACK') {
// optionally process payment option registration.
// Note: there is no any payment processed yet, no need to check status.
console.log(data);
}
},
errorHandler: function (errorCode, error) {
// Cleanup payment form container
// Requests transaction status via Get Payment Status API
console.error(errorCode, error);
},
paymentFormOnly: true,
});
}
</script>
</html>