This SDK allows you to implement ACH payments in your JS app.
Using the SDK
BankPay JS SDK v3.0
Including the BankPay SDK
To use the SDK include the library with a script tag.
<script src="https://js.bankpay.certegy.com/v3"></script>
This will include a BankPay
variable in the global scope with the Sdk
class and EventName
enum.
Using with webpack
Add externals to your webpack configuration pointing to the BankPay
variable.
module.exports = {
externals: {
bankpay: 'BankPay'
},
};
Import BankPay
as if it were included as a module named bankpay
.
import BankPay from 'bankpay';
Creating the BankPay SDK Instance
// Basic instantiation requires a publishable key and uses the production domain.
const sdk = new BankPay.Sdk({publishableKey: 'key'});
Instantiation options
interface BankPaySdkOptions {
// Your publishable key. This is required.
publishableKey: string;
// The environment to call. Can be 'cce' or 'production'.
// Defaults to 'production'.
environment: string;
// The URL to redirect to for open banking flows. This is typically not
// required for browser based implementations.
openBankingRedirect ? : string;
}
Using the Enrollment Flow
Instantiate a new enrollment webview for an enrollment by providing the enrollment_intent_id
you received from the create enrollment intent request made by your server.
const webview = sdk.createEnrollment(enrollmentIntentId);
After instantiating the webview attach the event listeners you need to listen for.
webview.events.addEventListener(BankPay.EventName.ReadyForAuthorization, ({data}) => {
// Authorize enrollment intent using data.intentId
});
Once your observers are attached, open the webview.
webview.open();
Using the Transaction Flow
Instantiate a new transaction webview for a transaction by providing the transaction_intent_id
you received from the create transaction intent request made by your server.
const webview = sdk.createTransaction(transactionIntentId);
After instantiating the webview attach the event listeners you need to listen for.
webview.events.addEventListener(BankPay.EventName.ReadyForAuthorization, ({data}) => {
// Authorize transaction intent using data.intentId
});
Once your observers are attached, open the webview.
webview.open();
Supporting Open Banking
If being used inside a browser nothing needs to be done for Open Banking support. If integrating in a different context see Open Banking and put the return URL in the openBankingRedirect
option.
WKWebView
.Chase Bank cuts off redirects that are initiated through a WKWebView instance. A consent URL should be launched from within a native browser. The URL should not be launched from within unsecured containers that allow the mobile app to intercept user input, and thus intercept user credentials.
Below is an example of the changes required for integrations utilizing React Native. If you use another cross-platform framework, implementation of this change will vary.
If your React Native app is currently opening the consent URL within an instance of WebView, you need to make code changes in your integration.
To ensure your integration will meet the requirements, take the following steps:
1. Ensure you are able to receive events in React Native from the WebView
window.addEventListener('message', (event) => {
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
}, false);
2. Handle the message event, looking for an event with a type property of `oauthUrl`. Once the message is received, open the URL supplied on the `url` property in the native browser.
onMessage={message => {
const {type, data} = JSON.parse(message.nativeEvent.data);
if (type === 'oauthUrl') {
Linking.canOpenURL(data.url).then(supported => {
if (supported) {
Linking.openURL(data.url);
} else {
console.log("Don't know how to open URI: " + data.url);
}
});
}
}}
3. After the user has logged in, they will be sent back to your app’s scheme or universal link that you have previously configured, and the flow will resume.
Continuing to open the consent URL from within a WebView instance will result in blocked request from Chase along with many other data providers due to security vulnerabilities.
Events
The webview will emit events at various points during the enrollment and transaction flows. These are defined with the BankPay.EventName
enum and dispatched through webview.events
.
BankPay.EventName.Cancel
Value: "cancel"
This is called whenever the users leaves the webview without finishing their enrollment or transaction.
Data
N/A
BankPay.EventName.Close
Value: "close"
This is called whenever the users performs an action which should end the WebView. This will be called with "cancel"
, "failure"
, and "success"
.
Data
N/A
BankPay.EventName.Failure
Value: "failure"
This is called when the user leaves the webview after their enrollment or transaction has failed.
Data
interface BankPayFailureEventData {
message: string // A description of the outcome.
status: string // The status of the intent (Example: "declined")
}
BankPay.EventName.ReadyForAuthorization
Value: "readyForAuthorization"
This is called when the user is finished with the enrollment or transaction and the intent is ready for authorization.
Data
interface BankPayReadyForAuthorizationEventData {
intentId: string // The enrollment or transaction intent ID.
}
BankPay.EventName.Success
Value: "success"
This is called when the user leaves the webview after their enrollment or transaction has succeeded.
Data
interface BankPaySuccessEventData {
message: string // A description of the outcome.
status: string // The status of the intent (Example: "accepted")
}
Example
const sdk = new BankPay.Sdk({publishableKey: 'key'});
const webview = sdk.createEnrollment(intentId);
webview.events.addEventListener(BankPay.EventName.Cancel, () => {
// Handle cancel events
});
webview.events.addEventListener(BankPay.EventName.Close, () => {
// Handle close events
});
webview.events.addEventListener(BankPay.EventName.Failure, ({
data
}) => {
// Handle failure events
});
webview.events.addEventListener(BankPay.EventName.ReadyForAuthorization, ({
data
}) => {
// Authorize enrollment intent using data.intentId
});
webview.events.addEventListener(BankPay.EventName.Success, ({
data
}) => {
// Handle success events
});
webview.open();
Upgrading
2.x to 3.x
Instantiating the SDK
The way to instantiate the SDK has changed with version 3. Instead of instantiating BankPay
with new BankPay()
, instantiate with new BankPay.Sdk()
.
// 2.x
const sdk = new BankPay({
publishableKey: 'value',
environmentName: 'production',
});
// 3.x
const sdk = new BankPay.Sdk({
publishableKey: 'value',
environment: 'production',
});
Listening for events
Instead of attaching event handlers to the SDK with BankPay.setEventHandlers
, attach them to the webview controller returned by createEnrollment
or createTransaction
using .events.addEventListener()
.
// 2.x
sdk.setEventHandlers({
close: () => {
// Handle close event
},
// ...
});
// 3.x
const webview = sdk.createEnrollment(enrollmentIntentId);
webview.events.addEventListener(BankPay.EventName.Close, () => {
// Handle close event
});
Launching the webview
Instead of calling BankPay.enroll()
and BankPay.transact()
to start the webview, call .open()
on the webview controller returned by createEnrollment
or createTransaction
after attaching your events.
// 2.x
sdk.enroll(enrollmentIntentId);
// 3.x
webview.open();
Event changes
-
enrollmentError
was replaced withfailure
and theerror
data property was renamed to bestatus
. -
bankAccountAdded
was replaced withreadyForAuthorization
and theintent_id
data property was renamed to beintentId
. -
acceptedTransactionIntentServiceFee
was replaced withreadyForAuthorization
and thetransactionIntentId
data property was renamed to beintentId
.
Types
BankPay.d.ts
declare module "bankpay" {
enum EventName {
Cancel = "cancel",
Close = "close",
Failure = "failure",
ReadyForAuthorization = "readyForAuthorization",
Success = "success"
}
type BankPayEventCallback<EventType extends keyof BankPayEventMap> = (event: BankPayEventMap[EventType]) => void;
interface BankPayOutcomeEventData {
message: string;
status: string;
}
interface BankPayFailureEventData extends BankPayOutcomeEventData {
}
interface BankPaySuccessEventData extends BankPayOutcomeEventData {
}
interface BankPayReadyForAuthorizationEventData {
intentId: string;
}
class BankPayCancelEvent extends Event {
constructor();
}
class BankPayCloseEvent extends Event {
constructor();
}
class BankPayFailureEvent extends Event {
readonly data: BankPayFailureEventData;
constructor(data: BankPayFailureEventData);
}
class BankPayReadyForAuthorizationEvent extends Event {
readonly data: BankPayReadyForAuthorizationEventData;
constructor(data: BankPayReadyForAuthorizationEventData);
}
class BankPaySuccessEvent extends Event {
readonly data: BankPaySuccessEventData;
constructor(data: BankPaySuccessEventData);
}
interface BankPayEventMap {
cancel: BankPayCancelEvent;
close: BankPayCloseEvent;
failure: BankPayFailureEvent;
readyForAuthorization: BankPayReadyForAuthorizationEvent;
success: BankPaySuccessEvent;
}
class BankPayEventTarget implements EventTarget {
addEventListener<EventType extends keyof BankPayEventMap>(type: EventType, callback: BankPayEventCallback<EventType>, options?: AddEventListenerOptions | boolean): void;
dispatchEvent<EventType extends keyof BankPayEventMap>(event: BankPayEventMap[EventType]): boolean;
removeEventListener<EventType extends keyof BankPayEventMap>(type: EventType, callback: BankPayEventCallback<EventType>, options?: EventListenerOptions | boolean): void;
}
interface ModalState {
iFrameUrl: string;
iFrameElement: HTMLIFrameElement;
}
class ModalController {
readonly events: BankPayEventTarget;
close(): void;
open(): ModalState;
}
interface BankPaySdkOptions {
environment: 'cce' | 'production';
openBankingRedirect?: string;
publishableKey: string;
}
type BankPayRequiredOptions = Pick<BankPaySdkOptions, 'publishableKey'> & Partial<BankPaySdkOptions>;
class BankPaySdk {
constructor(options: BankPayRequiredOptions);
destroy(): void;
createEnrollment(intentId: string): ModalController;
createTransaction(intentId: string): ModalController;
}
const _default: {
Sdk: typeof BankPaySdk;
EventName: typeof EventName;
};
export default _default;
}