Adding custom data to an order


Since: v1.041

Let's say you want to attach a piece of custom data to a users order. The custom data is something unrelated to Shopify, but important to track like a membership level, group ID, or some kind of custom field in WordPress. This can be broken down into four steps, each of which we'll cover below. First let's quickly look at how the information will flow.


Shopify will soon begin requiring sites to have a valid HTTPS certificate to use their webhooks functionality. Therefore your WordPress site must be HTTPS enabled for this guide to work. Learn more.

Starting in the top left box labeled “Front-end”, we begin by capturing any custom data that we want to eventually attached to the order. This can come from anywhere. In our example we’ll assume it comes from a JavaScript event like a button click.

Once captured, we then make an AJAX to the server containing the data. Afterwards we then take this data and store it in the current PHP $_SESSION variable.

At this point we wait until the checkout event fires. Once it does, we grab the custom data from the $_SESSION that we saved earlier and attach it to the order. Once the order is successfully paid we can then take this custom data and save it into our database in any way we want.

Step 1. Capture custom data and send it to the server

Here we'll attach a JavaScript handler to the add to cart event which will then allow us to send any custom data to the server. Your scenario will probably be unique so you don't have to rely on the event fired by the add to cart click.
/* Step 1. Add an AJAX POST request to the add to cart click event. Resolves through the then() method once the data has been saved. You'll need to write some jQuery to fill in the "dynamicValues" object according to your own markup */ jQuery('.wps-add-to-cart').on('click', function(e) { jQuery.ajax({ method: 'POST', // url needs to point to the admin-ajax.php file within your WordPress setup. url: 'http://wpstest.test/wp/wp-admin/admin-ajax.php', dataType: 'json', data: { action: 'save_dynamic_values_to_session', dynamicValues: { // Dynamically grab this data according to your unique setup dynamicValue1: 'Hello!', dynamicValue2: 'Greetings!' } } }).then(function(data) { console.log('Data has been saved'); }); });

Step 2. Receive custom data and save it to the Session

The code in the example below will receive our AJAX request containing the custom data. Then we'll save it to the $_SESSION for later use.
/* Step 2. Save any dynamic values to the users Session This gets called from the JS via the 'save_dynamic_values_to_session' AJAX action. */ function save_dynamic_values_to_session() { // Gain access to the global $_SESSION variable if (session_status() == PHP_SESSION_NONE) { session_start(); } // Clearing any existing values set to our Session variable first unset($_SESSION['dynamic_values']); // Checking to see if the data was passed to the server correctly if (isset($_POST['dynamicValues']) && $_POST['dynamicValues']) { // Set our session variable to the data coming from the client $_SESSION['dynamic_values'] = $_POST['dynamicValues']; } else { wp_send_json_error('No dynamic values found'); } wp_send_json_success(); } add_action( 'wp_ajax_save_dynamic_values_to_session', 'save_dynamic_values_to_session'); add_action( 'wp_ajax_nopriv_save_dynamic_values_to_session', 'save_dynamic_values_to_session');

Step 3. Attach custom data to the order

Here we hook into the wps_cart_checkout_attrs filter and return our custom data from the session. This return value will be what gets added as "Additional details" within the order itself.

It should also be noted that this will execute once the user clicks the checkout button.
/* Step 3. Saves any dynamic session variables to the Shopify order. Fires once the user clicks the checkout button. */ function namespace_cart_checkout_attrs() { // Gain access to the global $_SESSION variable if (session_status() == PHP_SESSION_NONE) { session_start(); } // Check to make sure our unique Session variable exists first if ( isset($_SESSION['dynamic_values']) && $_SESSION['dynamic_values'] ) { return $_SESSION['dynamic_values']; } } add_filter('wps_cart_checkout_attrs', 'namespace_cart_checkout_attrs');

Step 4. Capture the order containing our custom data

Finally, we listen for the order paid event through the wps_webhook_checkouts_order_paid action. At this point we'll have access to the $order parameter which will contain all the information about the customer and order. More information about this can be found here. Scroll down to the "Order" webhook.
/* Step 4. Once the order is successfully paid for ... */ function namespace_checkouts_order_paid($order) { // Check to make sure note attributes exists and has a value if (isset($order->note_attributes) && $order->note_attributes) { $dynamicValues = $order->note_attributes; } else { $dynamicValues = 'No dynamic values found!'; } // Check to make sure first name exists and has a value if (isset($order->customer->first_name) && $order->customer->first_name) { $customerFirstName = $order->customer->first_name; // Andrew } else { $customerFirstName = ''; } // Check to make sure last name exists and has a value if (isset($order->customer->last_name) && $order->customer->last_name) { $customerLastName = $order->customer->last_name; // Robbins } else { $customerLastName = ''; } // Check to make sure email exists and has a value if (isset($order->customer->email) && $order->customer->email) { $customerEmail = $order->customer->email; // } else { return; // Return immediately if email isn't set } // Create a new WordPres user based on the customer information if ( !username_exists($customerEmail) && !email_exists($customerEmail) ) { // Generates a random password 20 characters long and with special characters $password = wp_generate_password(20, true); // Creates the actual user using the email as the username $userID = wp_create_user($customerEmail, $password, $customerEmail); // Update the new user with the appropriate data from order wp_update_user(array( 'ID' => $userID, 'nickname' => $customerFirstName . ' ' . $customerLastName, 'first_name' => $customerFirstName, 'last_name' => $customerLastName, 'description' => maybe_serialize($dynamicValues) )); // Sets the user role $user = new WP_User($userID); $user->set_role('contributor'); // Sends the user an email with their new password wp_mail($customerEmail, 'Welcome!', 'Your password is: ' . $password); } else { // User already exists, don't do anything } } add_action('wps_webhook_checkouts_order_paid', 'namespace_checkouts_order_paid');