@ravenpay/bankbox-me-sdk
Version:
Raven Bankbox JS Payment SDK
330 lines (329 loc) • 14.6 kB
JavaScript
import eventWorker from "./eventWorker";
class BankboxManager {
constructor(config) {
var _a;
this.config = {};
this.windowSize = {
width: window.innerWidth,
height: window.innerHeight
};
this.paymentOption = {};
this.isBluethoothConnected = false;
this.constants = {
success: "success",
fail: "fail",
error: "error",
event_hook: "bankbox_events",
style_config: "style_config",
load: 'load',
sdkOpen: 'sdk:open',
bluethoothConnected: 'sdk:bluetooth_connected',
sdkPaymentData: "sdk:payment_data",
systemReady: "sdk:system_ready",
sdkClose: 'sdk:close',
// appUrl: this.environment === 'development' ? 'http://localhost:3000' : `https://${this.appName ?? 'bankly'}.bankbox.me`
};
this.injectAnimationStyle = () => {
const styleId = "moveBankBoxMeInnerWrapUp-style";
// Check if style already exists
if (!document.getElementById(styleId)) {
const style = document.createElement("style");
style.id = styleId;
style.innerHTML = `
moveBankBoxMeInnerWrapUp {
0% {
transform: translateY(7%) translateX(-50%);
}
100% {
transform: translateY(0%) translateX(-50%);
}
}
`;
document.head.appendChild(style);
}
};
this.appName = config.appName;
this.environment = config.environment;
this.widgetOptions = config.widgetOptions;
this.containerId = (_a = config.containerId) !== null && _a !== void 0 ? _a : 'bankbox-container';
this.iframe = null;
this.container = null;
this.$event = eventWorker;
this.messageHandlers = new Map();
this.targetOrigin = this.getTargetOrigin();
this.isInitialized = false;
this.config = config;
// Register event listeners
this.registerCoreListeners(config);
}
getTargetOrigin(params) {
var _a, _b, _c;
let url = this.environment === 'development' ? 'http://localhost:3000' : this.environment === 'sandbox' ? 'https://bankbox-me.netlify.app' : `https://${(_a = this.appName) !== null && _a !== void 0 ? _a : 'bankly'}.bankbox.me`;
const queryParams = [];
if (params === null || params === void 0 ? void 0 : params.email) {
queryParams.push(`email=${params.email}`);
}
if (params === null || params === void 0 ? void 0 : params.amount) {
queryParams.push(`amount=${params.amount}`);
}
if ((_b = this.widgetOptions) === null || _b === void 0 ? void 0 : _b.isPersistent) {
queryParams.push('persist=true');
}
if ((_c = this.widgetOptions) === null || _c === void 0 ? void 0 : _c.stream) {
queryParams.push('stream=true');
}
else {
queryParams.push('stream=false');
}
if (queryParams.length > 0) {
url += `?${queryParams.join('&')}`;
}
return url;
}
registerCoreListeners(config) {
if (config.onSuccess)
eventWorker.subscribe(this.constants.success, (e) => { var _a; return (_a = config.onSuccess) === null || _a === void 0 ? void 0 : _a.call(config, e.detail); });
if (config.onBluethoothConnected)
eventWorker.subscribe(this.constants.bluethoothConnected, (e) => { var _a; return (_a = config.onBluethoothConnected) === null || _a === void 0 ? void 0 : _a.call(config, e.detail); });
if (config.onFail)
eventWorker.subscribe(this.constants.fail, (e) => { var _a; return (_a = config.onFail) === null || _a === void 0 ? void 0 : _a.call(config, e.detail); });
if (config.onError)
eventWorker.subscribe(this.constants.error, (e) => { var _a; return (_a = config.onError) === null || _a === void 0 ? void 0 : _a.call(config, e.detail); });
if (config.onLoad)
eventWorker.subscribe(this.constants.load, () => { var _a; return (_a = config.onLoad) === null || _a === void 0 ? void 0 : _a.call(config); });
}
initWindowResizeListener() {
// Add an event listener to the window resize event
window.addEventListener('resize', () => {
var _a, _b;
this.windowSize = {
width: window.innerWidth,
height: window.innerHeight,
};
if (this.container) {
this.container.style.width = ((_a = this.widgetOptions) === null || _a === void 0 ? void 0 : _a.width) ? (_b = this.widgetOptions) === null || _b === void 0 ? void 0 : _b.width : (this.windowSize.width > 900) ? '50%' : '100%';
}
});
}
initializeListeners() {
eventWorker.subscribe(this.constants.event_hook, this.handleIncomingMessage.bind(this));
eventWorker.subscribe(this.constants.bluethoothConnected, this.handleBluethoothConnected.bind(this));
eventWorker.subscribe(this.constants.systemReady, this.handleBankboxReady.bind(this));
this.initWindowResizeListener();
this.injectAnimationStyle();
}
initializeIframe(options) {
if (!this.container) {
this.container = document.getElementById(this.containerId);
if (!this.container) {
// The overlay
const overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.id = 'bankbox-overlay';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.display = 'flex';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // Semi-transparent background
overlay.style.backdropFilter = 'blur(10px)'; // Blur effect
overlay.style.zIndex = '9998'; // Ensure it is behind the container
document.body.appendChild(overlay);
// The container
this.container = document.createElement('div');
this.container.id = this.containerId;
this.container.style.position = 'fixed';
this.container.style.bottom = '0';
this.container.style.left = '50%';
this.container.style.width = (this.windowSize.width > 900) ? '50%' : '100%';
this.container.style.transform = 'translateX(-50%)';
this.container.style.height = '98%';
this.container.style.zIndex = '9999';
this.container.style.display = 'none';
this.container.style.overflow = 'hidden';
this.container.style.backgroundColor = 'white';
this.container.style.boxShadow = '0 -2px 10px rgba(0, 0, 0, 0.1)';
this.container.style.borderTopLeftRadius = '30px';
this.container.style.borderTopRightRadius = '30px';
this.container.style.animation = "moveBankBoxMeInnerWrapUp 0.5s ease-in-out backwards";
document.body.appendChild(this.container);
// the close button
const closeButton = document.createElement('span');
closeButton.innerText = '×';
closeButton.style.position = 'absolute';
closeButton.style.top = '10px';
closeButton.style.right = '10px';
closeButton.style.width = '30px';
closeButton.style.height = '30px';
closeButton.style.border = 'none';
closeButton.style.borderRadius = '50%';
closeButton.style.display = 'grid';
closeButton.style.placeItems = 'center';
closeButton.style.backgroundColor = 'black';
closeButton.style.color = 'white';
closeButton.style.fontSize = '20px';
closeButton.style.cursor = 'pointer';
closeButton.style.zIndex = '10000';
// close button event listener
closeButton.addEventListener('click', () => {
this.container.style.display = 'none';
overlay.style.display = 'none';
});
this.container.appendChild(closeButton);
}
}
if (!this.iframe) {
this.iframe = document.createElement('iframe');
this.iframe.style.display = 'none';
this.iframe.style.width = '100%';
this.iframe.style.height = '100%';
this.iframe.style.border = 'none';
this.iframe.src = this.getTargetOrigin(options);
this.iframe.allow = 'bluetooth; usb'; // Allow Bluetooth and USB
this.iframe.onload = () => {
this.isInitialized = true;
this.$event.emit('load', null);
window.addEventListener('message', this.handleIncomingMessage.bind(this));
};
this.iframe.onerror = (error) => {
this.$event.emit('error', {
type: 'iframe_error',
message: 'Failed to load Bankbox iframe',
error
});
};
this.container.appendChild(this.iframe);
}
}
reinjectOverlay() {
const o = document.getElementById('bankbox-overlay');
if (!o) {
// The overlay
const overlay = document.createElement('span');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.id = 'bankbox-overlay';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.display = 'flex';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // Semi-transparent background
overlay.style.backdropFilter = 'blur(10px)'; // Blur effect
overlay.style.zIndex = '9998'; // Ensure it is behind the container
document.body.appendChild(overlay);
}
else {
o.style.position = 'fixed';
o.style.top = '0';
o.id = 'bankbox-overlay';
o.style.left = '0';
o.style.width = '100%';
o.style.display = 'flex';
o.style.height = '100%';
o.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // Semi-transparent background
o.style.backdropFilter = 'blur(10px)'; // Blur effect
o.style.zIndex = '9998'; // Ensure it is behind the container
document.body.appendChild(o);
}
}
mount(options) {
if (options === null || options === void 0 ? void 0 : options.containerId) {
const containerElement = document.getElementById(options === null || options === void 0 ? void 0 : options.containerId);
if (!containerElement) {
throw new Error(`Container element with id '${options === null || options === void 0 ? void 0 : options.containerId}' not found`);
}
this.container = containerElement;
}
else {
this.initializeIframe(options);
}
if (!this.container) {
throw new Error('Container element not found');
}
this.container.style.display = 'block';
if (this.iframe && !this.iframe.parentElement) {
this.container.appendChild(this.iframe);
}
this.iframe.style.display = 'block';
this.reinjectOverlay();
}
open(options) {
this.mount(options);
this.paymentOption = options !== null && options !== void 0 ? options : {};
this.sendMessage({ type: this.constants.sdkOpen, data: undefined });
this.initializeListeners();
setTimeout(() => {
if (!this.paymentOption.amount) {
this.initPayment(options);
}
}, 1000);
return { isBluethoothConnected: this.isBluethoothConnected };
}
initPayment(options) {
this.sendMessage({ type: this.constants.sdkPaymentData, data: options, message: "SDK Payment Data Recieved" });
}
close() {
if (this.container) {
this.container.style.display = 'none';
}
const overlay = document.getElementById('bankbox-overlay');
if (overlay) {
overlay.style.display = 'none';
}
if (this.iframe) {
this.iframe.style.display = 'none';
}
this.sendMessage({ type: this.constants.sdkClose, data: undefined });
}
handleBluethoothConnected(data) {
this.isBluethoothConnected = true;
this.initPayment(this.paymentOption);
}
handleIncomingMessage(event) {
var _a, _b;
if (event.origin !== this.targetOrigin)
return;
const message = (_a = event.details) !== null && _a !== void 0 ? _a : event.data;
if (!(message === null || message === void 0 ? void 0 : message.type))
return;
switch (message.type) {
case 'bankbox:ready':
this.handleBankboxReady();
break;
case 'rrn_data':
this.$event.emit((_b = message.message) === null || _b === void 0 ? void 0 : _b.status, message.data);
break;
case 'bankbox:close':
this.close();
break;
default:
this.$event.emit(message.type, message.data);
}
}
handleBankboxReady() {
this.sendMessage({
type: 'sdk:init',
data: {
environment: this.environment,
...this.widgetOptions
}
});
}
sendMessage(message) {
eventWorker.emit(message.type, message);
}
destroy() {
var _a;
window.removeEventListener('message', this.handleIncomingMessage);
if ((_a = this.iframe) === null || _a === void 0 ? void 0 : _a.parentNode) {
this.iframe.parentNode.removeChild(this.iframe);
}
eventWorker.emit(this.constants.event_hook, null);
this.iframe = null;
this.container = null;
this.config = {};
this.appName = '';
this.isInitialized = false;
}
}
export default BankboxManager;