Kemp.rest / Examples / Code / Syncs Points Data

KEMP.REST / EXAMPLES / CODE

Syncs Points Data

Written by Kevin Kemp in PHP. JSON REST between WooCommerce and a proprietary back office .NET points system.

View the code

The shop ran on WooCommerce. Customer profiles and the loyalty balance lived in a separate back office built in .NET. After login, and again after a purchase, the store needed the same person, address, and points balance the back office already had. This plugin keeps the two sides aligned.

Type of code

A small WordPress plugin. It does not render a screen. It registers hooks and calls two HTTP APIs.

Technology

PHP, WordPress hooks, WooCommerce (WC_Customer, order queries, thank-you and login hooks), WooRewards points, Advanced Custom Fields for the access token, and the WordPress HTTP API. The back office is a JSON REST API using a bearer token. Point changes go out as a PUT to the local WooRewards route. The WooCommerce REST credentials in the source are shown as XXXX.

What it does

Problem it solved

Loyalty points and the customer record no longer drifted between the .NET back office and the WooCommerce shop. Login refreshed the profile. Checkout pushed a points adjustment when the back office balance and the store balance did not match.

Code

Back to summary · syncs_data.php

<?php
/**
 * Plugin Name:  Syncs Points Data
 */
define('BACKOFFICE_API_BASE_URL','https://api.example.com');
define('WOOREWARDS_API_BASE_URL', home_url('/wp-json/woorewards/v1'));
define('WR_WC_CK','XXXX');
define('WR_WC_CS','XXXX');

function backoffice_update_user_details($user_id, $backoffice_user_data){

    $user_data = wp_update_user(
        array(
            'ID' => $user_id,
            'user_email' => $backoffice_user_data['email'],
            'first_name' => $backoffice_user_data['firstname'],
            'last_name' => $backoffice_user_data['lastname'],
            //'nickname' => 'new_nickname',
            'display_name' => $backoffice_user_data['name'],
        )
    );
    if (!is_wp_error($user_data)) {

        $customer = new WC_Customer($user_id);

        $customer->set_shipping_first_name($backoffice_user_data['firstname']);
        $customer->set_shipping_last_name($backoffice_user_data['lastname']);
        $customer->set_shipping_address_1($backoffice_user_data['shippingAddress']['address1']);
        $customer->set_shipping_address_2($backoffice_user_data['shippingAddress']['address2']);
        $customer->set_shipping_city($backoffice_user_data['shippingAddress']['city']);
        $customer->set_shipping_state($backoffice_user_data['shippingAddress']['state']);
        $customer->set_shipping_postcode($backoffice_user_data['shippingAddress']['postalCode']);

        $customer->set_billing_first_name($backoffice_user_data['firstname']);
        $customer->set_billing_last_name($backoffice_user_data['lastname']);
        $customer->set_billing_address_1($backoffice_user_data['billingAddress']['address1']);
        $customer->set_billing_address_2($backoffice_user_data['billingAddress']['address2']);
        $customer->set_billing_city($backoffice_user_data['billingAddress']['city']);
        $customer->set_billing_state($backoffice_user_data['billingAddress']['state']);
        $customer->set_billing_postcode($backoffice_user_data['billingAddress']['postalCode']);
        $customer->set_billing_phone($backoffice_user_data['phone']);

        $customer->save();

        update_user_meta($user_id, 'memberId', $backoffice_user_data['memberId']);

    }
}


function update_user_info_and_points($user_id,$sync_point_after_login = false){
    $access_token = get_field('access_token','option');
    $user_info = get_userdata($user_id);
    $email_user = $user_info->user_email;
    // 1. Fetch data from back office API
    $api_url = BACKOFFICE_API_BASE_URL.'/V2/Customer/?EmailOrMemberId='.$email_user;
    $api_response = wp_remote_get($api_url, array(
        'headers' => array('Authorization' => 'Bearer ' . $access_token)
    ));

    if (is_wp_error($api_response)) {
        return;
    }

    $body = wp_remote_retrieve_body($api_response);
    $backoffice_data = json_decode($body, true);

    if (!$backoffice_data) {
        return;
    }
    $backoffice_email = $backoffice_data['email'];
    $backoffice_last_order_ref_num = $backoffice_data['lastOrderRefNum'];
    if($sync_point_after_login){
        backoffice_update_user_details($user_id, $backoffice_data);
        update_user_meta( $user_id, 'lws_wre_points_rewards',$backoffice_data['pointsBalance']);
    }

    // 2. Compare with WooCommerce data
    $backoffice_last_order_date = new DateTime($backoffice_data['dateOfLastOrder']);
    //    $backoffice_last_order_date = $backoffice_last_order_date->format('Y-m-d H:i:s');
    $backoffice_last_order_date = $backoffice_last_order_date->format('Y-m-d');
    $woo_last_order = backoffice_get_customer_last_order_info($backoffice_email);


    if(!$woo_last_order)  return;
    $woo_last_order_id = $woo_last_order['id'];
    //    $woo_last_order_date = $order_data['date_created']->date('Y-m-d H:i:s');
    $woo_last_order_date = $woo_last_order['date_created']->date('Y-m-d');

    if ($woo_last_order_date) {
        $backoffice_date = strtotime($backoffice_last_order_date);
        $woo_date = strtotime($woo_last_order_date);

        $office_points_balance = $backoffice_data['pointsBalance'];
        $woo_rewards_point_balance = get_user_meta( $user_id, 'lws_wre_points_rewards',true);
        $is_point_different = $office_points_balance !== $woo_rewards_point_balance;

        if(($backoffice_date === $woo_date && $backoffice_last_order_ref_num === $woo_last_order_id && $is_point_different) || ($backoffice_date > $woo_date && $is_point_different)){
            $points_to_add_or_subtract = $office_points_balance - $woo_rewards_point_balance;
            $reason = sanitize_text_field('Points_Activity');

            $api_url = WOOREWARDS_API_BASE_URL."/points/$backoffice_email/do_not_remove_this/$points_to_add_or_subtract/$reason?consumer_key=".WR_WC_CK."&consumer_secret=".WR_WC_CS;
            $args = array('method'    => 'PUT');
            $response = wp_remote_request( $api_url, $args );
            if ( is_wp_error( $response ) ) {
                echo $response->get_error_message();
            } else {
                if($backoffice_last_order_ref_num){
                    update_post_meta($woo_last_order_id, '_last_ref_num', $backoffice_last_order_ref_num);
                }
            }
        }
    }
 }

function backoffice_get_customer_last_order_info($customer_email) {
    $user_id = email_exists($customer_email);

    if ($user_id) {
        $customer = new WC_Customer($user_id);
        // Get customer orders
        $customer_orders = wc_get_orders(array(
            'customer_id' => $user_id,
            'limit'       => 1,
            'orderby'     => 'date',
            'order'       => 'DESC',
        ));

        if ($customer_orders) {
            $last_order = reset($customer_orders);

            if ($last_order) {
                $order_status = $last_order->get_status();

                if (in_array($order_status, array('processing', 'completed'))) {
                    return $last_order->get_data();
                }
            }
        }
    }

    return false;
}

add_action('woocommerce_thankyou', 'backoffice_function_after_place_order', 20, 1);
function backoffice_function_after_place_order($order_id) {
    if (is_user_logged_in()) {
        $user_id = get_current_user_id();
        update_user_info_and_points($user_id);
    }
}


add_action("init" , "backoffice_update_user_info_and_points",100);
function backoffice_update_user_info_and_points(){
    if($_POST && isset($_POST['refresh_points'])){
        if (is_user_logged_in()) {
            $user_id = get_current_user_id();
            update_user_info_and_points($user_id,true);
        }
    }
}


// function update points when login from form my account
add_filter('woocommerce_login_redirect', 'update_user_meta_after_woocommerce_login', 10, 2);

function update_user_meta_after_woocommerce_login($redirect, $user) {
    // Get the user ID
    $user_id = $user->ID;

    if ( is_wp_error( $response ) ) {

    }
    update_user_info_and_points($user_id,true);

    return $redirect;
}

// function update points when login from form wp-login
add_action('wp_login', 'update_user_meta_after_login', 10, 2);

function update_user_meta_after_login($user_login, $user) {

    $user_id = $user->ID;
    if ( is_wp_error( $response ) ) {

    }
    update_user_info_and_points($user_id,true);

    return $redirect;

}