I would like to get some Input a my problem I am trying to solve transferring my standalone php function and js script into a working WordPress format. I am stuck to transfer this into a working format for my WordPress page and need some input.
I have created a script for a chained API call to 2 different endpoints In php.
Call 1 to Endpoint a) is sending 3 static body params (api key, user id, password etc) to the API and 1 dynamic value, (userIP adress). In response the API POST a orderREF string and a url to a QR code which should be displayed on the screen. In addition to this, the QR code shall be refreshed every 5 secs.
Once the user scans the QR code successfully the Call 2 to Endpoint b) returns customer name and social security number and some other values which are not so relevant atm. For the user the authentication process has been completed and I want to transfer the obtained data into my customer database.
As you will see in my script I created a working prototype of this in a standalone script but need help to transfer it into a working WordPress (plugin or shortcode) so I can use this function on specific parts of our page. I would like to send the user to go through this process before signing up on our website in order to fully verify the identity of the user.
The code I created successfully to carry out the 2 chained API calls and to refresh the QR code by javascript. I have just for simplicity hardcoded the credentials for testing, these will be stored in a .env file
<?php
// Handle AJAX requests for the second API call
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['checkStatus'])) {
$orderRef = $_POST['orderRef'];
$apiUser = 'aaa';
$password = ' xxx ';
$companyApiGuid = 'yyy ';
$url = 'https://url/endpoint/2';
$requestData = array(
'apiUser' => $apiUser,
'password' => $password,
'companyApiGuid' => $companyApiGuid,
'orderRef' => $orderRef
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($requestData));
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
exit;
}
// Initial QR code generation if not a POST request
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$apiUser = 'aaa';
$password = 'xxx';
$companyApiGuid = 'yyy';
$url = 'https://url/endpoint1';
$data = array(
'apiUser' => $apiUser,
'password' => $password,
'companyApiGuid' => $companyApiGuid,
'endUserIp' => $_SERVER['REMOTE_ADDR'],
'getQr' => true
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
));
$response = curl_exec($curl);
if (!$response) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
curl_close($curl);
$responseData = json_decode($response, true);
$apiResponse = $responseData['apiCallResponse']['Response'] ?? [];
$qrImageUrl = $apiResponse['QrImage'] ?? 'No QR code URL available.';
$orderRef = $apiResponse['OrderRef'] ?? 'No order reference available.';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>QR Code and Status Check</title>
<script>
var refreshInterval; // Interval for refreshing the QR code
function refreshQRCode(qrImageUrl) {
var qrImage = document.getElementById('qrImage');
if (qrImage) {
qrImage.src = qrImageUrl + '?' + new Date().getTime(); // Appending timestamp to avoid cache issues
}
}
function checkStatus(orderRef) {
fetch('index.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'checkStatus=true&orderRef=' + orderRef
})
.then(response => response.json())
.then(data => {
console.log(data); // For debugging purposes, log the data received from the server
// Update the logs with detailed status from the second API call
document.getElementById('detailedLogs').innerHTML = `
<p>Auth Success: ${data.authResponse && data.authResponse.Success}</p>
<p>Auth Error Message: ${data.authResponse && data.authResponse.ErrorMessage}</p>
<p>API Call Success: ${data.apiCallResponse && data.apiCallResponse.Success}</p>
<p>Status Message: ${data.apiCallResponse && data.apiCallResponse.StatusMessage}</p>
<p>Order Reference: ${data.apiCallResponse && data.apiCallResponse.Response && data.apiCallResponse.Response.OrderRef}</p>
<p>Completion Status: ${data.apiCallResponse && data.apiCallResponse.Response && data.apiCallResponse.Response.Status}</p>
<p>Hint Code: ${data.apiCallResponse && data.apiCallResponse.Response && data.apiCallResponse.Response.HintCode}</p>
`;
if (data.apiCallResponse.Response.Status === "complete") {
clearInterval(refreshInterval); // Stop refreshing the QR code
var user = data.apiCallResponse.Response.CompletionData.user;
document.getElementById('qrImageContainer').innerHTML = `
<p>SUCCESS</p>
<p>Personal Number: ${user.personalNumber}</p>
<p>Name: ${user.name}</p>
<p>Given Name: ${user.givenName}</p>
<p>Surname: ${user.surname}</p>
`;
} else {
// If conditions are not met, keep polling every 5 seconds
setTimeout(function() { checkStatus(orderRef); }, 5000);
}
})
.catch(error => {
console.error('Error:', error);
setTimeout(function() { checkStatus(orderRef); }, 5000);
});
}
window.onload = function() {
var orderRef = '<?php echo $orderRef; ?>';
var qrImageUrl = '<?php echo $qrImageUrl; ?>';
refreshQRCode(qrImageUrl);
refreshInterval = setInterval(function() { refreshQRCode(qrImageUrl); }, 5000); // Set up the interval to refresh QR code every 5 seconds
checkStatus(orderRef);
}
</script>
</head>
<body>
<h1>QR Code</h1>
<div id="qrImageContainer">
<?php if (isset($qrImageUrl) && $qrImageUrl !== 'No QR code URL available.') { ?>
<img id="qrImage" src="<?php echo $qrImageUrl; ?>" alt="QR Code"><br>
<?php } else { ?>
<p>QR Code URL not available.</p>
<?php } ?>
</div>
<div id="logs"></div>
<h2>Log Call Endpoint 1</h2>
<p>Auth Success: <?php echo $responseData['authResponse']['Success'] ?? 'No data'; ?></p>
<p>Auth Error Message: <?php echo $responseData['authResponse']['ErrorMessage'] ?? 'No error message'; ?></p>
<p>API Call Success: <?php echo $responseData['apiCallResponse']['Success'] ?? 'No data'; ?></p>
<p>Status Message: <?php echo $responseData['apiCallResponse']['StatusMessage'] ?? 'No status message'; ?></p>
<p>Order Reference: <?php echo $orderRef; ?></p>
<div id="messageContainer"></div>
<h2>Log Call Endpoint 2</h2>
<div id="detailedLogs"></div>
</body>
</html>
For getting this functionality into WordPress I thought about creating a simple plugin and populate the script so WordPress can process it (also in regards to JS and AJAX functionality)
I created a simple plugin structure with
- main plugin-index.php
- api-handler.php for the actuals calls.
- template.php for the output
and a /js folder where I locate the js script file for refreshing the QR code.
I call all of this with a shortcode function on the actual page and part needed on the page.
plugin-index.php file
<?php
/*
Plugin Name: Plugin Name
Description: Integrates QR code generation and status check verification.
Version: 1.0
Author: me.
*/
function ba_bank_enqueue_scripts() {
wp_enqueue_script('ba_bank-ajax', plugin_dir_url(__FILE__) . 'js/bankid-ajax.js', array('jquery'), null, true);
wp_localize_script('bba_bank-ajax', 'bankidAjax', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'ba_bank_enqueue_scripts');
include_once plugin_dir_path(__FILE__) . 'api-handler.php';
function byggauktion_bankid_shortcode() {
$response = get_initial_qr_code_data();
$responseData = json_decode($response, true);
$qrImageUrl = $responseData['apiCallResponse']['Response']['QrImage'] ?? 'No QR code URL available.';
$orderRef = $responseData['OrderRef'] ?? 'No order reference available.';
ob_start();
?>
<div id="qrImageContainer">
<?php if ($qrImageUrl !== 'No QR code URL available.'): ?>
<img id="qrImage" src="<?php echo esc_url($qrImageUrl); ?>" alt="QR Code"><br>
<?php else: ?>
<p>QR code URL not available.</p>
<?php endif; ?>
<div id="updateArea">
<p>Scan the QR code above. Updates will appear here once available.</p>
</div>
</div>
<input type="hidden" id="orderRef" value="<?php echo esc_attr($orderRef); ?>">
<?php
echo ob_get_clean();
}
add_shortcode('ba_bank', 'ba_bank_shortcode');
function ba_bank_handle_ajax() {
check_status_update();
wp_die();
}
add_action('wp_ajax_ba_check_status', 'ba_bank_handle_ajax');
add_action('wp_ajax_nopriv_ba_check_status', 'ba_bank__handle_ajax');
The api-handler.php
<?php
function get_initial_qr_code_data() {
$data = [
'apiUser' => 'aaa',
'password' => 'xxx',
'companyApiGuid' => 'zzz',
'endUserIp' => $_SERVER['REMOTE_ADDR'],
'getQr' => true
];
return make_bank_api_call('https://url/endpoint1', $data);
}
function check_status_update() {
$orderRef = isset($_POST['orderRef']) ? sanitize_text_field($_POST['orderRef']) : '';
$data = [
'apiUser' => 'aaa',
'password' => 'xxx',
'companyApiGuid' => 'zzz',
'orderRef' => $orderRef
];
$response = make_bank_api_call('https://url/endpoint2', $data);
echo $response;
}
function make_bank_api_call($url, $data) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($curl);
curl_close($curl);
return $response ? $response : json_encode(['error' => 'No response from API']);
}
template.php file for the html output
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>QR Code and Status Check</title>
</head>
<body>
<h1>QR Code</h1>
<div id="qrImageContainer">
<?php if (isset($qrImageUrl) && $qrImageUrl !== 'No QR code URL available.') : ?>
<img id="qrImage" src="<?php echo $qrImageUrl; ?>" alt="QR Code">
<?php else : ?>
<p>QR Code URL not available.</p>
<?php endif; ?>
</div>
<div id="logs"></div>
<h2>Log Call Endpoint 1</h2>
<p>Order Reference: <?php echo isset($orderRef) ? $orderRef : 'No order reference available.'; ?></p>
<p>Auth Success: <?php echo $responseData['authResponse']['Success'] ?? 'No data'; ?></p>
<p>Auth Error Message: <?php echo $responseData['authResponse']['ErrorMessage'] ?? 'No error message'; ?></p>
<p>API Call Success: <?php echo $responseData['apiCallResponse']['Success'] ?? 'No data'; ?></p>
<p>Status Message: <?php echo $responseData['apiCallResponse']['StatusMessage'] ?? 'No status message'; ?></p>
<p>Order Reference: <?php echo $orderRef; ?></p>
<div id="messageContainer"></div>
<h2>Log Call Endpoint 2</h2>
<div id="detailedLogs"></div>
<script src="<?php echo plugin_dir_url(__FILE__) . 'js/bankid-ajax.js'; ?>"></script>
</body>
</html>
Finally the bankid-ajax,js
document.addEventListener('DOMContentLoaded', function() {
var qrImage = document.getElementById('qrImage');
var orderRef = document.getElementById('orderRef').value;
var updateArea = document.getElementById('updateArea');
function checkStatus(orderRef) {
fetch(bankidAjax.ajaxurl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=byggauktion_check_status&orderRef=' + encodeURIComponent(orderRef)
})
.then(response => response.json())
.then(data => {
// Dynamically update content
if (data.status === 'complete') {
updateArea.innerHTML = '<p>Verification completed successfully for user ' + data.user.name + '</p>';
} else {
updateArea.innerHTML = '<p>Status: ' + data.status + '</p>';
}
if (data.newQrImage) {
qrImage.src = data.newQrImage + '?refresh=' + new Date().getTime();
}
})
.catch(error => {
console.error('Error:', error);
updateArea.innerHTML = '<p>Error checking status. Please try again.</p>';
});
}
setInterval(() => checkStatus(orderRef), 5000);
});
I am not able to connect to the API on this way and the QR cant be displayed. I have tried to simplify it more. Could try to give me an advice how to streamline my script more for my WordPress use-case?
Thank you
2
Answers
To elaborate on my answer in the comment, I incorporated the JS now int the main file. I am still not really coming to the right solution that the img is refreshing. Any suggestings from you on this function below?
} add_action('wp_enqueue_scripts', 'byggauktion_bankid_enqueue_scripts');
To expand on my comment, you’re missing a couple of key things in your code.
First, lets generate a nonce and pass it across to your JS.
Now, in your JS file you’ll want to call that alongside the
ajaxurl
…Now we have to make sure that your callback function matches the action name you used in your JS and also check your AJAX referer:
Obviously this is untested, but with those added elements you should be able to debug the rest yourself. 🙂 Best of luck.