I posted this code before it has been passed on to me, but this time I have a different question. We are using an integration with a company called GiveX who has given me very little documentation. The company that hired me had to sign a nda, so I don't think I can reveal much of the documentation they have revealed to us. I will try and make it as clear as possible what I am trying to achieve. I will place all my code below my questions with titles of the file naming in Wordpress.
- How do I console log for example the
$result
of thegi_check_balance()
function in theintegrate.php
file? what I want to know is what giveX is sending back to us. Now this is even if this function is sending apost
request to giveX I can't even tell. And where am I supposed to be to see this consoled? on the order complete page? or in some logs somewhere? - What does
add_action( 'wp_ajax_gi_check_balance', 'gi_check_balance' );
this line do? I see that in the Wordpress docsadd_action
is a hook that fires at a certain point and the first value should be astring
and the second a function, I see that to be true however what is the point of creating this hook, I don't see the first value the string referenced anywhere else, so how is it triggered? or when is that function run or does just giving it astring
name and a function allow that function to run? - Again there are two functions
gi_check_balance()
andgi_secure_register()
how do I know when these are fired? how do these functions connect to thecheck-balance.js
file and thesecure-register.js
file (now my understanding of thegi_secure_register()
function is that it is only for testing purposes, the only difference I know is the code that is sent in the post request labeled as themethod
one is904
and one is994
and they are supposed to do different things but reading through giveX documentation I can't really tell the difference. - Now I am aware that there is a webhook as well, and it seems to run based on a custom topic in woocommerce that is defined inside the
integrate.php
file. This web hook also seems to make a post request to giveX url, now I can't for the life of me understand why would we be firing a post request 3 times, one in theintegrate.php
plugin file itself, one in thewebhook.php
file and another in either one of thejs
files. I know it will be hard for someone to determine this for me, but if I could know what scenarios in a woocommerce completed order these post requests will be fired? it will help me understand why there are three different ones. - This section of the email that is being sent by the webhook
<b>Card Number:</b> ' . $response->result[3] . '<br /> <b>PIN:</b> ' . $response_reference[1] . '<br /> <b>Card Amount:</b> ' . $response->result[4] . '<br /> <b>Reference Number:</b> ' . $response_reference[0] . '</p>'
currently returns empty variables in the email. I want to figure out why giveX is not sending back data? I'd like to be able to console log this result somewhere I can see any errors coming back from giveX. - So Basically, I would like some help breaking down when certain functions are being fired based off of events in woocommerce/wordpress. Also I want to know which
post
requests are actually being fired, because I would think we only have to send one request to giveX to order these gift card purchase.
Ok Here is the code (thanks so much ahead of time :)
plugins/givex/integrate.php
// Get grouped product ID from child product ID
function get_parent_grouped_id( $children_id ){
global $wpdb;
$results = $wpdb->get_col("SELECT post_id FROM {$wpdb->prefix}postmeta
WHERE meta_key = '_children' AND meta_value LIKE '%$children_id%'");
// Will only return one product Id or false if there is zero or many
return sizeof($results) == 1 ? reset($results) : false;
}
/**
* add_new_topic_hooks will add a new webhook topic hook.
* @param array $topic_hooks Esxisting topic hooks.
*/
function add_new_topic_hooks( $topic_hooks ) {
// Array that has the topic as resource.event with arrays of actions that call that topic.
$new_hooks = array(
'order.gift_card' => array(
'order_gift_card_filter',
),
);
return array_merge( $topic_hooks, $new_hooks );
}
add_filter( 'woocommerce_webhook_topic_hooks', 'add_new_topic_hooks' );
/**
* add_new_topic_events will add new events for topic resources.
* @param array $topic_events Existing valid events for resources.
*/
function add_new_topic_events( $topic_events ) {
// New events to be used for resources.
$new_events = array(
'gift_card',
);
return array_merge( $topic_events, $new_events );
}
add_filter( 'woocommerce_valid_webhook_events', 'add_new_topic_events' );
/**
* add_new_webhook_topics adds the new webhook to the dropdown list on the Webhook page.
* @param array $topics Array of topics with the i18n proper name.
*/
function add_new_webhook_topics( $topics ) {
// New topic array to add to the list, must match hooks being created.
$new_topics = array(
'order.gift_card' => __( 'Order Gift Card', 'woocommerce' ),
);
return array_merge( $topics, $new_topics );
}
add_filter( 'woocommerce_webhook_topics', 'add_new_webhook_topics' );
/**
* my_order_item_check will check an order when it is created through the checkout form,
* if it has product ID 1030 as one of the items, it will fire off the action `order_gift_card_filter`
*
* @param int $order_id The ID of the order that was just created.
* @param array $posted_data Array of all of the data that was posted through checkout form.
* @param object $order The order object.
* @return null
*/
function my_order_item_check( $order_id, $posted_data, $order ) {
$order = wc_get_order( $order_id );
$order_status = $order->status;
$items = $order->get_items();
foreach ( $items as $item ) {
if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
if ( 1457 === $item->get_product_id() ) {
$item_data = $item->get_data();
$item_meta_data_group = $item_data['meta_data'];
$gift_card_data = array();
foreach ( $item_meta_data_group as $item_meta_data ) {
$gift_card_data[$item_meta_data->key] = $item_meta_data->value;
}
do_action( 'order_gift_card_filter', $order_id, $posted_data, $order );
}
}
}
}
//The two below actions are what the order.created webhook is tied into, it is up to you to use these if you wish.
//add_action( 'woocommerce_payment_complete', 'my_order_item_check', 10, 4 );
add_action( 'woocommerce_checkout_order_processed', 'my_order_item_check', 10, 3 );
//add_action( 'woocommerce_process_shop_order_meta', 'my_order_item_check', 10, 2 );
add_action( 'wp_enqueue_scripts', 'add_ajax_script' );
function add_ajax_script() {
wp_enqueue_script( 'check-balance', plugins_url( '/check-balance.js', __FILE__ ), array('jquery'), '1.0', true );
wp_enqueue_script( 'secure-register', plugins_url( '/secure-register.js', __FILE__ ), array('jquery'), '1.0', true );
wp_localize_script( 'check-balance', 'gi_check_balance', array( 'ajax_url' => admin_url('admin-ajax.php') ) );
wp_localize_script( 'secure-register', 'gi_secure_register', array( 'ajax_url' => admin_url('admin-ajax.php') ) );
}
add_action( 'wp_ajax_nopriv_gi_check_balance', 'gi_check_balance' );
add_action( 'wp_ajax_gi_check_balance', 'gi_check_balance' );
function gi_check_balance() {
$gx_url_1 = 'https://givexurl-1.com';
$gx_url_2 = 'https://givexurl-2.com';
$gx_port_1 = port;
$gx_port_2 = port;
$gx_post_url_1 = $gx_url_1 . ':' . $gx_port_1;
$gx_post_url_2 = $gx_url_2 . ':' . $gx_port_2;
$gx_user = 'user';
$gx_password = 'pass';
$gx_card_number = $_POST['gx_card_number'];
$data = array(
'method' => '994',
'params' => [
'en',
'rc1',
//null,
$gx_user,
$gx_password,
$gx_card_number,
$gx_card_pin,
null
],
'id' => 'test'
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode( $data )
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $gx_post_url_1, false, $context );
if ( $result == false ) {
$result = file_get_contents( $gx_post_url_2, false, $context );
}
$response = json_decode( $result );
echo $result;
//echo json_encode($result) ;
//var_dump( $response );
//echo $response;
die();
}
// function only for dev testing purposes
//add_action( 'wp_ajax_gi_secure_register', 'gi_secure_register' );
function gi_secure_register() {
$gx_url_1 = 'https://givexurl-1.com';
$gx_url_2 = 'https://givexurl-2.com';
$gx_port_1 = port;
$gx_port_2 = port;
$gx_post_url_1 = $gx_url_1 . ':' . $gx_port_1;
$gx_post_url_2 = $gx_url_2 . ':' . $gx_port_2;
$gx_user = 'user';
$gx_password = 'pass';
$gx_register_amount = $_POST['gx_register_amount'];
$data = array(
'method' => '904',
'params' => [
'en',
'rc2',
//null,
$gx_user,
$gx_password,
$gx_register_amount,
null,
null,
null
],
'id' => 'test'
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode( $data )
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $gx_post_url_1, false, $context );
if ( $result == false ) {
$result = file_get_contents( $gx_post_url_2, false, $context );
}
$response = json_decode( $result );
echo json_encode($result);
die();
}
plugins/givex/webhook.php
<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$passed = false;
$request_body = file_get_contents('php://input');
$secret = 'P&_(e>P _I?%/aOW?wv0H.U149+Eyv8bh~qXd<6XrIY8+K0oo]';
$sig = base64_encode(hash_hmac('sha256', $request_body, $secret, true));
if( !function_exists('apache_request_headers') ) {
function apache_request_headers() {
$headers = array();
foreach($_SERVER as $key => $value) {
if (substr($key, 0, 5) <> 'HTTP_') {
continue;
}
$header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
$headers[$header] = $value;
}
return $headers;
}
}
$header = apache_request_headers();
foreach ( $header as $headers => $value ) {
if( $headers == 'X-Wc-Webhook-Signature' ) {
if ( $value == $sig ) {
$passed = true;
}
}
}
if( $passed !== true ) {
header("Location: https://our-url.com");
} else {
$gx_url_1 = 'https://givexurl-1.com';
$gx_url_2 = 'https://givexurl-2.com';
$gx_port_1 = port;
$gx_port_2 = port;
$gx_post_url_1 = $gx_url_1 . ':' . $gx_port_1;
$gx_post_url_2 = $gx_url_2 . ':' . $gx_port_2;
$gx_user = 'user';
$gx_password = 'pass';
$data = json_decode(file_get_contents('php://input'), true);
foreach( $data['line_items'] as $item ) {
if( $item['product_id'] == 1457 ) {
$item_meta_data_group = $item['meta_data'];
$gift_card_data = array();
foreach( $item_meta_data_group as $item_meta_data ) {
$gift_card_data[$item_meta_data['key']] = $item_meta_data['value'];
}
$data_modified = array(
'method' => '904',
'params' => [
'en',
null,
$gx_user,
$gx_password,
str_replace(array(',', '$', ' '), '', $gift_card_data['gift-card-amount']),
null,
null,
null
],
'id' => 'test'
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode( $data_modified )
)
);
$context = stream_context_create( $options );
//$result = file_get_contents( $gx_post_url, false, $context );
$result = file_get_contents( $gx_post_url_1, false, $context );
if ( $result == false ) {
$result = file_get_contents( $gx_post_url_2, false, $context );
}
$response = json_decode( $result );
$response_reference = explode(':', $response->result[2]);
echo $result;
$to = $gift_card_data['recipient_email'];
$subject_decoded = 'You received a gift card ';
$subject = '=?UTF-8?B?' . base64_encode( $subject_decoded ) . '?=';
$subject1 = 'test';
$message = '<table border="0" cellspacing="0" cellpadding="0" width="100%" style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="padding: 40px 40px 20px; background-color: #f9f9f9;" align="center"><table border="0" cellspacing="0" cellpadding="0" width="600" style="border-collapse: collapse;"><tbody>';
$message .= '<tr><td align="center" valign="bottom" style="padding: 0 0 20px;">';
$message .= '</td></tr>';
$message .= '<tr><td align="center" style="padding: 10px 40px 20px; background-color: #ffffff; color: #676767; font-family: Helvetica, Arial, sans-serif;">';
$message .= '<h2 style="font-family: Garamond, serif; font-size: 28px; font-weight: 600; color: #444444;">' . (!empty($gift_card_data['recipient_name']) ? $gift_card_data['recipient_name'] : 'Whoa') . ', you’ve got ' . $gift_card_data['gift-card-amount'] . ' to spend at!</h2>';
$message .= '<p style="color: #676767;">' . (!empty($gift_card_data['sender']) ? $gift_card_data['sender'] : 'Someone') . ' sent you a gift card' . (!empty($gift_card_data['message']) ? ' with the following message:' : '.') . '</p>';
if( !empty($gift_card_data['message']) ) {
$message .= '<p style="color: #676767;"><i><br />' . nl2br($gift_card_data['message']) . '<br /><br /></i></p>';
}
//$message .= '<img src="https://www.barcodesinc.com/generator/image.php?code=' . $response->result[3] . '&style=68&type=C39&width=300&height=50&xres=1&font=4" alt="" />';
// barcode generator website: https://www.barcodesinc.com/generator/index.php
$message .= '<p style="color: 676767; font-size: 1.25em;"><b>Card Number:</b> ' . $response->result[3] . '<br /> <b>PIN:</b> ' . $response_reference[1] . '<br /> <b>Card Amount:</b> ' . $response->result[4] . '<br /> <b>Reference Number:</b> ' . $response_reference[0] . '</p>';
$message .= '</td></tr>';
$message .= '<tr><td align="center" style="padding: 20px 0 0;">';
$message .= '<p style="color: #676767;"><b>We look forward to you dining with us!</b></p>';
$message .= '</td></tr>';
$message .= '</tbody></table></td></tr></tbody></table>';
$headers = "From: Gift Cards <test.com>\r\n";
$headers .= "Reply-To: noreply@test.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
mail($to, $subject, $message, $headers);
}
} // end foreach
} // end if else '$passed !== true'
plugins/givex/check-balance.js
jQuery(document).ready(function($) {
// checks card balance
$('.gi-check-balance').submit(function() {
var gx_card_number = $(this).find('[name=card-number]').val()
var gx_card_pin = $(this).find('[name=card-pin]').val()
$.ajax({
url: gi_check_balance.ajax_url,
type: 'post',
data: {
action: 'gi_check_balance',
gx_card_number: gx_card_number,
gx_card_pin: gx_card_pin
},
dataType: 'json',
success: function(response) {
console.log(response)
$('.gi-check-balance-result').text(response['result'][2])
//$('.gi-check-balance-result').text(JSON.stringify(response))
$('.gi-check-balance-result').show()
}
})
return false
})
})
plugins/givex/secure-register.js
jQuery(document).ready(function($) {
// registers gift card
$('.gi-secure-register').submit(function() {
var gx_register_amount = $(this).find('[name=register-amount]').val()
$.ajax({
url: gi_secure_register.ajax_url,
type: 'post',
data: {
action: 'gi_secure_register',
gx_register_amount: gx_register_amount
},
dataType: 'json',
success: function(response) {
//$('.gi-secure-register-result').html('Reference Number: ' + response['result'][2] + '<br>' + 'Card Number: ' + response['result'][3] + '<br>' + 'Card Amount: ' + response['result'][4])
$('.gi-secure-register-result').text(response)
$('.gi-secure-register-result').show();
console.log(response);
}
})
return false
})
})
UPDATE
First Noticed error. It looks like since I am on localhost I am getting rejected from the https connection? Now I know very little about ssl, how would I get that working locally. Do I need something further from the url I am sending the request too?
[22-Nov-2019 02:59:00 UTC] PHP Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in /Users/anderskitson/Local Sites/river-cafe/app/public/wp-content/plugins/givex-integrate/webhook.dev.php on line 94
The error above is solved here https://stackoverflow.com/a/58924492/2949184 and solves the main issues I have been having.