Appearance
Example Code Walkthrough
This doc will break down how the example index.html works, and how changes can be made to customize it to your implementation needs.
Lines from this file will be referenced throughout the doc.
index.html
html
<!--
Copyright (c) 2023 Five9, Inc. The content presented herein may not, under any
circumstances, be reproduced in whole or in any part or form without written
permission from Five9, Inc.
-->
<!DOCTYPE html>
<html lang="en">
<!-- #region head-style -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://www.five9.com/favicon.ico" rel="shortcut icon" />
<title>Five9 SecurePay API Library Sample App</title>
<!-- The sample uses Bootstrap for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
crossorigin="anonymous"></script>
</head>
<!-- #endregion head-style -->
<body class="container">
<form class="col-12">
<!-- #region form -->
<h3 class="mt-3">Five9 Secure Payment <small class="text-muted" id="secure-ivr-version-number"></small></h3>
<div class="row">
<div class="col">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" placeholder="" value="John" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" placeholder="" value="Smith" />
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label for="invoiceNumber">Invoice Number</label>
<input type="text" class="form-control" id="invoiceNumber" placeholder="" value="12345" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="paymentAmount">Payment Amount</label>
<input type="text" class="form-control" id="paymentAmount" placeholder="" value="12.34" />
</div>
</div>
</div>
<div class="row my-2">
<div class="col">
<h4 id="status-state">
<span id="status-state-chip" class="badge bg-secondary">UNINITIALIZED</span>
</h4>
</div>
</div>
<!-- #endregion form -->
<!-- -->
<!-- #region bridge -->
<div class="row">
<div class="col">
<div id="bridge-message-div" class="form-group alert alert-success col-sm-12 col-md-12 col-lg-12 d-none"
role="alert">
<div id="bridge-message"><strong>IVR Message:</strong></div>
<div id="bridge-result"><strong>IVR Result:</strong></div>
</div>
</div>
</div>
<!-- #endregion bridge -->
<!-- #region buttons -->
<div class="row">
<div class="col">
<div class="form-group">
<button type="button" id="btn-start" class="btn btn-primary" disabled="disabled">Start</button>
<button type="button" id="btn-cancel" class="btn btn-danger" disabled="disabled">
<span id="cancelsecurepay-text">Cancel</span>
</button>
</div>
</div>
</div>
<!-- #endregion buttons -->
<!-- #region toast -->
<!-- Toast -->
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div id="toast-element" class="toast align-items-center text-white bg-secondary border-0" role=" alert"
aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toast-message"></div>
</div>
</div>
<!-- #endregion toast -->
</form>
<!-- #region script -->
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
const $ = jQuery;
const initButton = $('#btn-init');
const reconnectButton = $('#btn-reconnect');
const startButton = $('#btn-start');
const cancelButton = $('#btn-cancel');
const bridgeMessageDiv = $('#bridge-message-div');
const statusChip = $('#status-state-chip');
const bridgeMessageElement = $('#bridge-message');
const bridgeResultElement = $('#bridge-result');
const versionNumberTag = $('#secure-ivr-version-number');
const toastMessage = $('#toast-message');
var toastEl = document.getElementById('toast-element');
var toast = new bootstrap.Toast(toastEl, { autohide: true });
// #region cavs
/**********************************************************
* Call Variable Definitions
**********************************************************/
function getCallVariablesFromFields() {
var firstName = $('#firstName').val();
var lastName = $('#lastName').val();
var paymentAmount = $('#paymentAmount').val();
var invoiceNumber = $('#invoiceNumber').val();
var cavFields = {
'SecurePay.FirstName': firstName,
'SecurePay.LastName': lastName,
'SecurePay.InvoiceNumber': paymentAmount,
'SecurePay.PaymentAmount': invoiceNumber,
};
return cavFields;
}
// #endregion cavs
// #region ui-controls
/**********************************************************
* DOM / UI State Control
**********************************************************/
function showNotification(message) {
toastMessage.text(message);
toast.show();
}
function showBridgeMessage(messsage) {
bridgeMessageElement.html('<strong>IVR Message:</strong> ' + messsage);
}
function showBridgeResult(result) {
bridgeResultElement.html('<strong>IVR Result:</strong> ' + result);
}
function showConnectedUi() {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
}
function showFinishedUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
bridgeMessageDiv.addClass('d-none');
}
function showReadyUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
}
function showInactiveUi() {
initButton.removeAttr('disabled');
startButton.attr('disabled', 'disabled');
}
function showTriggerStartUi() {
showBridgeMessage('');
showBridgeResult('');
startButton.attr('disabled', 'disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showReconnectedUi(result) {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showStatus(state) {
if (state === undefined) {
return;
}
statusChip.text(state);
}
// #endregion ui-controls
// #region client-initialize
const secureIvrClient = new SecureIvrClient();
// #endregion client-initialize
versionNumberTag.text(secureIvrClient.version);
// #region events
/**********************************************************
* Secure IVR Event Listeners
**********************************************************/
secureIvrClient.on('secureivr.ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ready', event.data);
showReadyUi();
});
secureIvrClient.on('secureivr.not_ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.not_ready', event.data);
showInactiveUi();
});
secureIvrClient.on('secureivr.started', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.started', event.data);
if (event.status === 'ERROR') {
const errMessage = `There was an issue starting Secure Pay. ${event.data?.error ? event.data.error : ''}`;
showNotification(errMessage);
return;
}
showConnectedUi();
});
secureIvrClient.on('secureivr.ended', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ended', event.data);
showFinishedUi();
});
secureIvrClient.on('secureivr.message', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.message', event.data);
switch (event.data.type) {
case 'RESULT':
showBridgeResult(event.data.message);
case 'MESSAGE':
showBridgeMessage(event.data.message);
}
});
secureIvrClient.on('status.changed', (event) => {
console.log('SecureIVRClient Incoming Event: status.changed', event.data);
showStatus(event.data.status);
});
secureIvrClient.on('connection.changed', (event) => {
console.log('SecureIVRClient Incoming Event: connection.changed', event.data);
switch (event.data.type) {
case 'RECONNECTED':
showNotification('Successfully reconnected to Secure Payment IVR...');
showReconnectedUi();
showStatus('RECONNECTED');
break;
}
});
// #endregion events
// #region button-action-logic
/**********************************************************
* UI Action Support Functions
**********************************************************/
startButton.click(function (evt) {
showTriggerStartUi();
secureIvrClient.startSecurePay({
withEvents: true,
callVariables: getCallVariablesFromFields(),
});
});
cancelButton.click(function (evt) {
if (secureIvrClient.five9BridgeClient.isOpen()) {
secureIvrClient.five9BridgeClient.close();
}
secureIvrClient.cancelSecurePay();
});
// #endregion button-action-logic
});
</script>
<!-- #endregion script -->
<!-- ================================= -->
<!-- Secure Payment specific libraries -->
<!-- ================================= -->
<!-- Load one, but not both. -->
<!-- #region js-lib-url -->
<!-- Five9 SecureIVR Library URL Script Include -->
<script type="text/javascript"
src="http://secure-pay.ps.five9.com/lib/d/us/YOUR_ORG_PATH/secureivr-client.min.js?accessKey=YOUR_ACCESS_TOKEN"
defer></script>
<!-- #endregion js-lib-url -->
<!-- Five9 SecureIVR Library -->
<!-- <script type="text/javascript" src="libs/five9-secureivr.min.js" defer></script> -->
</body>
</html><!--
Copyright (c) 2023 Five9, Inc. The content presented herein may not, under any
circumstances, be reproduced in whole or in any part or form without written
permission from Five9, Inc.
-->
<!DOCTYPE html>
<html lang="en">
<!-- #region head-style -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://www.five9.com/favicon.ico" rel="shortcut icon" />
<title>Five9 SecurePay API Library Sample App</title>
<!-- The sample uses Bootstrap for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
crossorigin="anonymous"></script>
</head>
<!-- #endregion head-style -->
<body class="container">
<form class="col-12">
<!-- #region form -->
<h3 class="mt-3">Five9 Secure Payment <small class="text-muted" id="secure-ivr-version-number"></small></h3>
<div class="row">
<div class="col">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" placeholder="" value="John" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" placeholder="" value="Smith" />
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label for="invoiceNumber">Invoice Number</label>
<input type="text" class="form-control" id="invoiceNumber" placeholder="" value="12345" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="paymentAmount">Payment Amount</label>
<input type="text" class="form-control" id="paymentAmount" placeholder="" value="12.34" />
</div>
</div>
</div>
<div class="row my-2">
<div class="col">
<h4 id="status-state">
<span id="status-state-chip" class="badge bg-secondary">UNINITIALIZED</span>
</h4>
</div>
</div>
<!-- #endregion form -->
<!-- -->
<!-- #region bridge -->
<div class="row">
<div class="col">
<div id="bridge-message-div" class="form-group alert alert-success col-sm-12 col-md-12 col-lg-12 d-none"
role="alert">
<div id="bridge-message"><strong>IVR Message:</strong></div>
<div id="bridge-result"><strong>IVR Result:</strong></div>
</div>
</div>
</div>
<!-- #endregion bridge -->
<!-- #region buttons -->
<div class="row">
<div class="col">
<div class="form-group">
<button type="button" id="btn-start" class="btn btn-primary" disabled="disabled">Start</button>
<button type="button" id="btn-cancel" class="btn btn-danger" disabled="disabled">
<span id="cancelsecurepay-text">Cancel</span>
</button>
</div>
</div>
</div>
<!-- #endregion buttons -->
<!-- #region toast -->
<!-- Toast -->
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div id="toast-element" class="toast align-items-center text-white bg-secondary border-0" role=" alert"
aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toast-message"></div>
</div>
</div>
<!-- #endregion toast -->
</form>
<!-- #region script -->
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
const $ = jQuery;
const initButton = $('#btn-init');
const reconnectButton = $('#btn-reconnect');
const startButton = $('#btn-start');
const cancelButton = $('#btn-cancel');
const bridgeMessageDiv = $('#bridge-message-div');
const statusChip = $('#status-state-chip');
const bridgeMessageElement = $('#bridge-message');
const bridgeResultElement = $('#bridge-result');
const versionNumberTag = $('#secure-ivr-version-number');
const toastMessage = $('#toast-message');
var toastEl = document.getElementById('toast-element');
var toast = new bootstrap.Toast(toastEl, { autohide: true });
// #region cavs
/**********************************************************
* Call Variable Definitions
**********************************************************/
function getCallVariablesFromFields() {
var firstName = $('#firstName').val();
var lastName = $('#lastName').val();
var paymentAmount = $('#paymentAmount').val();
var invoiceNumber = $('#invoiceNumber').val();
var cavFields = {
'SecurePay.FirstName': firstName,
'SecurePay.LastName': lastName,
'SecurePay.InvoiceNumber': paymentAmount,
'SecurePay.PaymentAmount': invoiceNumber,
};
return cavFields;
}
// #endregion cavs
// #region ui-controls
/**********************************************************
* DOM / UI State Control
**********************************************************/
function showNotification(message) {
toastMessage.text(message);
toast.show();
}
function showBridgeMessage(messsage) {
bridgeMessageElement.html('<strong>IVR Message:</strong> ' + messsage);
}
function showBridgeResult(result) {
bridgeResultElement.html('<strong>IVR Result:</strong> ' + result);
}
function showConnectedUi() {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
}
function showFinishedUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
bridgeMessageDiv.addClass('d-none');
}
function showReadyUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
}
function showInactiveUi() {
initButton.removeAttr('disabled');
startButton.attr('disabled', 'disabled');
}
function showTriggerStartUi() {
showBridgeMessage('');
showBridgeResult('');
startButton.attr('disabled', 'disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showReconnectedUi(result) {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showStatus(state) {
if (state === undefined) {
return;
}
statusChip.text(state);
}
// #endregion ui-controls
// #region client-initialize
const secureIvrClient = new SecureIvrClient();
// #endregion client-initialize
versionNumberTag.text(secureIvrClient.version);
// #region events
/**********************************************************
* Secure IVR Event Listeners
**********************************************************/
secureIvrClient.on('secureivr.ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ready', event.data);
showReadyUi();
});
secureIvrClient.on('secureivr.not_ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.not_ready', event.data);
showInactiveUi();
});
secureIvrClient.on('secureivr.started', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.started', event.data);
if (event.status === 'ERROR') {
const errMessage = `There was an issue starting Secure Pay. ${event.data?.error ? event.data.error : ''}`;
showNotification(errMessage);
return;
}
showConnectedUi();
});
secureIvrClient.on('secureivr.ended', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ended', event.data);
showFinishedUi();
});
secureIvrClient.on('secureivr.message', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.message', event.data);
switch (event.data.type) {
case 'RESULT':
showBridgeResult(event.data.message);
case 'MESSAGE':
showBridgeMessage(event.data.message);
}
});
secureIvrClient.on('status.changed', (event) => {
console.log('SecureIVRClient Incoming Event: status.changed', event.data);
showStatus(event.data.status);
});
secureIvrClient.on('connection.changed', (event) => {
console.log('SecureIVRClient Incoming Event: connection.changed', event.data);
switch (event.data.type) {
case 'RECONNECTED':
showNotification('Successfully reconnected to Secure Payment IVR...');
showReconnectedUi();
showStatus('RECONNECTED');
break;
}
});
// #endregion events
// #region button-action-logic
/**********************************************************
* UI Action Support Functions
**********************************************************/
startButton.click(function (evt) {
showTriggerStartUi();
secureIvrClient.startSecurePay({
withEvents: true,
callVariables: getCallVariablesFromFields(),
});
});
cancelButton.click(function (evt) {
if (secureIvrClient.five9BridgeClient.isOpen()) {
secureIvrClient.five9BridgeClient.close();
}
secureIvrClient.cancelSecurePay();
});
// #endregion button-action-logic
});
</script>
<!-- #endregion script -->
<!-- ================================= -->
<!-- Secure Payment specific libraries -->
<!-- ================================= -->
<!-- Load one, but not both. -->
<!-- #region js-lib-url -->
<!-- Five9 SecureIVR Library URL Script Include -->
<script type="text/javascript"
src="http://secure-pay.ps.five9.com/lib/d/us/YOUR_ORG_PATH/secureivr-client.min.js?accessKey=YOUR_ACCESS_TOKEN"
defer></script>
<!-- #endregion js-lib-url -->
<!-- Five9 SecureIVR Library -->
<!-- <script type="text/javascript" src="libs/five9-secureivr.min.js" defer></script> -->
</body>
</html>HTML
Styling
The example html file is just a regular HTML file. In the sample, bootstrap is used for styling, which is referenced in the <head> tag. This is where you can make customizations to your styling.
Styling
html
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://www.five9.com/favicon.ico" rel="shortcut icon" />
<title>Five9 SecurePay API Library Sample App</title>
<!-- The sample uses Bootstrap for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
crossorigin="anonymous"></script>
</head><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://www.five9.com/favicon.ico" rel="shortcut icon" />
<title>Five9 SecurePay API Library Sample App</title>
<!-- The sample uses Bootstrap for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
crossorigin="anonymous"></script>
</head>Form
Form fields are included in the sample app, which each expect a matching Call Variable to be defined in your Five9 VCC.
Form Fields
html
<h3 class="mt-3">Five9 Secure Payment <small class="text-muted" id="secure-ivr-version-number"></small></h3>
<div class="row">
<div class="col">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" placeholder="" value="John" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" placeholder="" value="Smith" />
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label for="invoiceNumber">Invoice Number</label>
<input type="text" class="form-control" id="invoiceNumber" placeholder="" value="12345" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="paymentAmount">Payment Amount</label>
<input type="text" class="form-control" id="paymentAmount" placeholder="" value="12.34" />
</div>
</div>
</div>
<div class="row my-2">
<div class="col">
<h4 id="status-state">
<span id="status-state-chip" class="badge bg-secondary">UNINITIALIZED</span>
</h4>
</div>
</div><h3 class="mt-3">Five9 Secure Payment <small class="text-muted" id="secure-ivr-version-number"></small></h3>
<div class="row">
<div class="col">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" placeholder="" value="John" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" placeholder="" value="Smith" />
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label for="invoiceNumber">Invoice Number</label>
<input type="text" class="form-control" id="invoiceNumber" placeholder="" value="12345" />
</div>
</div>
<div class="col">
<div class="form-group">
<label for="paymentAmount">Payment Amount</label>
<input type="text" class="form-control" id="paymentAmount" placeholder="" value="12.34" />
</div>
</div>
</div>
<div class="row my-2">
<div class="col">
<h4 id="status-state">
<span id="status-state-chip" class="badge bg-secondary">UNINITIALIZED</span>
</h4>
</div>
</div>Bridge Events
Events that occur when starting SecurePay with events are appended here.
Bridge
html
<div class="row">
<div class="col">
<div id="bridge-message-div" class="form-group alert alert-success col-sm-12 col-md-12 col-lg-12 d-none"
role="alert">
<div id="bridge-message"><strong>IVR Message:</strong></div>
<div id="bridge-result"><strong>IVR Result:</strong></div>
</div>
</div>
</div><div class="row">
<div class="col">
<div id="bridge-message-div" class="form-group alert alert-success col-sm-12 col-md-12 col-lg-12 d-none"
role="alert">
<div id="bridge-message"><strong>IVR Message:</strong></div>
<div id="bridge-result"><strong>IVR Result:</strong></div>
</div>
</div>
</div>Action Buttons
Action buttons are included in the sample to demonstrate use of each supported SecureIVR method.
Action Buttons
html
<div class="row">
<div class="col">
<div class="form-group">
<button type="button" id="btn-start" class="btn btn-primary" disabled="disabled">Start</button>
<button type="button" id="btn-cancel" class="btn btn-danger" disabled="disabled">
<span id="cancelsecurepay-text">Cancel</span>
</button>
</div>
</div>
</div><div class="row">
<div class="col">
<div class="form-group">
<button type="button" id="btn-start" class="btn btn-primary" disabled="disabled">Start</button>
<button type="button" id="btn-cancel" class="btn btn-danger" disabled="disabled">
<span id="cancelsecurepay-text">Cancel</span>
</button>
</div>
</div>
</div>Toast
A simple toast is configured to render error or information messages to the user
Toast Messages
html
<!-- Toast -->
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div id="toast-element" class="toast align-items-center text-white bg-secondary border-0" role=" alert"
aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toast-message"></div>
</div>
</div><!-- Toast -->
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div id="toast-element" class="toast align-items-center text-white bg-secondary border-0" role=" alert"
aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toast-message"></div>
</div>
</div>JS
SecureIVR Client Initialization
Client Initialization
js
const secureIvrClient = new SecureIvrClient();const secureIvrClient = new SecureIvrClient();Call Variables
The getCallVariablesFromFields function is responsible for retrieving call variables prior to starting a secure payment flow. These call variable definitions are then used to set the call variables in the secure IVR session.
In this case, the "key" refers to the call variable name in the Five9 VCC system (with "SecurePay" representing the call variable group and the value after the period representing the specific call variable name). The "value" is obtained from each form field using jQuery.
If you add call variables to be set for the Secure Payment flow, be sure those Call Variables exist in your Five9 VCC.
Client Initialization
js
/**********************************************************
* Call Variable Definitions
**********************************************************/
function getCallVariablesFromFields() {
var firstName = $('#firstName').val();
var lastName = $('#lastName').val();
var paymentAmount = $('#paymentAmount').val();
var invoiceNumber = $('#invoiceNumber').val();
var cavFields = {
'SecurePay.FirstName': firstName,
'SecurePay.LastName': lastName,
'SecurePay.InvoiceNumber': paymentAmount,
'SecurePay.PaymentAmount': invoiceNumber,
};
return cavFields;
}/**********************************************************
* Call Variable Definitions
**********************************************************/
function getCallVariablesFromFields() {
var firstName = $('#firstName').val();
var lastName = $('#lastName').val();
var paymentAmount = $('#paymentAmount').val();
var invoiceNumber = $('#invoiceNumber').val();
var cavFields = {
'SecurePay.FirstName': firstName,
'SecurePay.LastName': lastName,
'SecurePay.InvoiceNumber': paymentAmount,
'SecurePay.PaymentAmount': invoiceNumber,
};
return cavFields;
}Action Button Logic
Each button interacts with the secureIvrClient to perform the specified action.
See the Api Reference for definitions of each operation.
Button Action Logic
js
/**********************************************************
* UI Action Support Functions
**********************************************************/
startButton.click(function (evt) {
showTriggerStartUi();
secureIvrClient.startSecurePay({
withEvents: true,
callVariables: getCallVariablesFromFields(),
});
});
cancelButton.click(function (evt) {
if (secureIvrClient.five9BridgeClient.isOpen()) {
secureIvrClient.five9BridgeClient.close();
}
secureIvrClient.cancelSecurePay();
});/**********************************************************
* UI Action Support Functions
**********************************************************/
startButton.click(function (evt) {
showTriggerStartUi();
secureIvrClient.startSecurePay({
withEvents: true,
callVariables: getCallVariablesFromFields(),
});
});
cancelButton.click(function (evt) {
if (secureIvrClient.five9BridgeClient.isOpen()) {
secureIvrClient.five9BridgeClient.close();
}
secureIvrClient.cancelSecurePay();
});Event Listener
Event Listeners
js
/**********************************************************
* Secure IVR Event Listeners
**********************************************************/
secureIvrClient.on('secureivr.ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ready', event.data);
showReadyUi();
});
secureIvrClient.on('secureivr.not_ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.not_ready', event.data);
showInactiveUi();
});
secureIvrClient.on('secureivr.started', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.started', event.data);
if (event.status === 'ERROR') {
const errMessage = `There was an issue starting Secure Pay. ${event.data?.error ? event.data.error : ''}`;
showNotification(errMessage);
return;
}
showConnectedUi();
});
secureIvrClient.on('secureivr.ended', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ended', event.data);
showFinishedUi();
});
secureIvrClient.on('secureivr.message', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.message', event.data);
switch (event.data.type) {
case 'RESULT':
showBridgeResult(event.data.message);
case 'MESSAGE':
showBridgeMessage(event.data.message);
}
});
secureIvrClient.on('status.changed', (event) => {
console.log('SecureIVRClient Incoming Event: status.changed', event.data);
showStatus(event.data.status);
});
secureIvrClient.on('connection.changed', (event) => {
console.log('SecureIVRClient Incoming Event: connection.changed', event.data);
switch (event.data.type) {
case 'RECONNECTED':
showNotification('Successfully reconnected to Secure Payment IVR...');
showReconnectedUi();
showStatus('RECONNECTED');
break;
}
});/**********************************************************
* Secure IVR Event Listeners
**********************************************************/
secureIvrClient.on('secureivr.ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ready', event.data);
showReadyUi();
});
secureIvrClient.on('secureivr.not_ready', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.not_ready', event.data);
showInactiveUi();
});
secureIvrClient.on('secureivr.started', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.started', event.data);
if (event.status === 'ERROR') {
const errMessage = `There was an issue starting Secure Pay. ${event.data?.error ? event.data.error : ''}`;
showNotification(errMessage);
return;
}
showConnectedUi();
});
secureIvrClient.on('secureivr.ended', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.ended', event.data);
showFinishedUi();
});
secureIvrClient.on('secureivr.message', (event) => {
console.log('SecureIVRClient Incoming Event: secureivr.message', event.data);
switch (event.data.type) {
case 'RESULT':
showBridgeResult(event.data.message);
case 'MESSAGE':
showBridgeMessage(event.data.message);
}
});
secureIvrClient.on('status.changed', (event) => {
console.log('SecureIVRClient Incoming Event: status.changed', event.data);
showStatus(event.data.status);
});
secureIvrClient.on('connection.changed', (event) => {
console.log('SecureIVRClient Incoming Event: connection.changed', event.data);
switch (event.data.type) {
case 'RECONNECTED':
showNotification('Successfully reconnected to Secure Payment IVR...');
showReconnectedUi();
showStatus('RECONNECTED');
break;
}
});Ui Controls
This code simply changes the state of the UI to reflect different state in the application. For example, after the agent has been initialized and joins a call, we need to show the "talking" ui.
- reconnect ui: shown if an agent should be shown the "reconnect" button to reconnect to a bridge session
- connected ui: shown right after a secure ivr flow is started
- finished ui: shown right after a secure ivr flow has ended or is cancelled
- ready ui: shown when secure ivr is ready to be used, and agent is allowed to press start
- inactive ui: shown before initialization has happened
- trigger start ui: shown right after the start button is pressed, but before secure-ivr call connects
- reconnected ui: shown right after a bridge reconnection is successful
The "showStatus", "showBridgeMessage", "showBridgeResult", and "showNotification" functions are used to render data on the ui. For example when an agent joins a call.
UI Controls
js
/**********************************************************
* DOM / UI State Control
**********************************************************/
function showNotification(message) {
toastMessage.text(message);
toast.show();
}
function showBridgeMessage(messsage) {
bridgeMessageElement.html('<strong>IVR Message:</strong> ' + messsage);
}
function showBridgeResult(result) {
bridgeResultElement.html('<strong>IVR Result:</strong> ' + result);
}
function showConnectedUi() {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
}
function showFinishedUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
bridgeMessageDiv.addClass('d-none');
}
function showReadyUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
}
function showInactiveUi() {
initButton.removeAttr('disabled');
startButton.attr('disabled', 'disabled');
}
function showTriggerStartUi() {
showBridgeMessage('');
showBridgeResult('');
startButton.attr('disabled', 'disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showReconnectedUi(result) {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showStatus(state) {
if (state === undefined) {
return;
}
statusChip.text(state);
}/**********************************************************
* DOM / UI State Control
**********************************************************/
function showNotification(message) {
toastMessage.text(message);
toast.show();
}
function showBridgeMessage(messsage) {
bridgeMessageElement.html('<strong>IVR Message:</strong> ' + messsage);
}
function showBridgeResult(result) {
bridgeResultElement.html('<strong>IVR Result:</strong> ' + result);
}
function showConnectedUi() {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
}
function showFinishedUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
bridgeMessageDiv.addClass('d-none');
}
function showReadyUi() {
startButton.removeAttr('disabled');
cancelButton.attr('disabled', 'disabled');
}
function showInactiveUi() {
initButton.removeAttr('disabled');
startButton.attr('disabled', 'disabled');
}
function showTriggerStartUi() {
showBridgeMessage('');
showBridgeResult('');
startButton.attr('disabled', 'disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showReconnectedUi(result) {
startButton.attr('disabled', 'disabled');
cancelButton.removeAttr('disabled');
bridgeMessageDiv.removeClass('d-none');
}
function showStatus(state) {
if (state === undefined) {
return;
}
statusChip.text(state);
}