Using WooCommerce REST API with our plugins

WooCommerce REST API is useful for creating headless shops and automating processes . Here we will show couple of examples where you can see how our plugins can be managed via Woo REST api like how to retrieve product data and how to create new auction product using WooCommerce REST API v3.

First you will need to go to WooCommerce Settings -> Advanced and enable REST API then create client key and secret, then assign permissions you need for your use case.

Once this is completed go to https://github.com/Automattic/wp-rest-php-lib and download their PHP lib. Extract so you have folder structrue something like https://www.yourwebsite.com\api\WooCommerce and in \api\ create test_api.php file. Their lib is intented to be used with Composer and we advise that but in the example we will not use Composer in order to have as less prerequisites as possible.

Code example for WooCommerce REST API – listing auctions and creating new auction product

Since WooCommerce REST API can retrieve custom product types we will use type parameter to retrieve all auction products available in our Woo product list. Copy paste into your test_api.php file following code:

<?php

include_once(__DIR__ . '/WooCommerce/HttpClient/BasicAuth.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/HttpClient.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/HttpClientException.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/OAuth.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/Options.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/Request.php');
include_once(__DIR__ . '/WooCommerce/HttpClient/Response.php');
include_once(__DIR__ . '/WooCommerce/Client.php');

use Automattic\WooCommerce\Client;

$woocommerce = new Client(
	'https://www.yourwebsite.com',
	'your_client_key',
	'your_client_secret',
	[
	   'wp_api'  => true,
	   'version' => 'wc/v3',           
	]
);
$data = [
    'type' => 'auction' // get all auction products
];
print_r( $woocommerce->get( 'products', $data) );

Examples how to get and create auction products (for WooCommerce Simple Auctions) using WooCommerce API:

$data = [
    'name' => 'New Auction',
    'type' => 'auction',
    'status' => 'draft', // status can be: draft, published, pending

    'meta_data' => array(
        [ 'key' => '_auction_start_price', 'value' => '7.99' ],             // starting bid
        [ 'key' => '_auction_bid_increment', 'value' => '1.5' ],            // min bid increment
        [ 'key' => '_regular_price', 'value' => '2900' ],                   // buy now price
        [ 'key' => '_auction_reserved_price', 'value' => '2000.0' ],       // reserve price
        [ 'key' => '_auction_dates_from', 'value' => '2022-02-11 00:00' ],  // start date
        [ 'key' => '_auction_dates_to', 'value' => '2022-02-27 00:00' ],    // end date
        [ 'key' => '_auction_proxy', 'value' => 'no' ], // proxy auction, yes | no   
        [ 'key' => '_auction_sealed', 'value' => 'no' ], // sealed auction, yes | no        
    ),

    'description' => 'This is sample auction added via WooCommerce API',
    'short_description' => 'Sample api auction.',    
];


print_r( $woocommerce->post( 'products', $data ) );

Examples how to get and create lottery products (for plugin WooCommerce Lottery) using WooCommerce API:

$data = [
    'type' => 'lottery' // get all lottery products
];
print_r( $woocommerce->get( 'products', $data) );
$data = [
    'name' => 'New Lottery',
    'type' => 'lottery',
    'status' => 'draft',    // status can be: draft, published, pending

    'meta_data' => array(       
        
        [ 'key' => '_min_tickets', 'value' => '30' ], // min number of tickets needed
        [ 'key' => '_max_tickets', 'value' => '100' ], // max number of tickets
        [ 'key' => '_max_tickets_per_user', 'value' => '100' ], // max per user (optional)
        [ 'key' => '_lottery_num_winners', 'value' => '1' ], // number of winners        
        [ 'key' => '_lottery_price', 'value' => '20.99' ], // ticket price
        [ 'key' => '_lottery_sale_price', 'value' => '15.99' ], // sale price (optional)
        [ 'key' => '_lottery_dates_from', 'value' => '2022-02-11 00:00' ], // start date
        [ 'key' => '_lottery_dates_to', 'value' => '2022-02-27 00:00' ], // end date        
    ),
    'description' => 'This is sample lottery added via WooCommerce API',
    'short_description' => 'Sample api lottery.',
    
];


print_r( $woocommerce->post( 'products', $data ) );

Examples how to get and create group buy / deal products (for plugin WooCommerce Lottery) using WooCommerce API:

$data = [
    'type' => 'groupbuy' // get all group buy / deal products
];


print_r( $woocommerce->get( 'products', $data) );
$data = [
    'name' => 'New Group Buy',
    'type' => 'groupbuy',
    'status' => 'draft',    // status can be: draft, published, pending
    
    'meta_data' => array(       
        
        [ 'key' => '_groupbuy_min_deals', 'value' => '30' ], // min deals sold needed
        [ 'key' => '_groupbuy_max_deals', 'value' => '100' ], // max deals sold
        [ 'key' => '_groupbuy_max_deals_per_user', 'value' => '100' ], // max per user (optional)
        [ 'key' => '_groupbuy_price', 'value' => '10.99' ], // deal price
        [ 'key' => '_groupbuy_regular_price', 'value' => '21.99' ], // regular price
        [ 'key' => '_groupbuy_dates_from', 'value' => '2022-02-11 00:00' ], // start date
        [ 'key' => '_groupbuy_dates_to', 'value' => '2022-02-27 00:00' ], // end date
        
    ),
    'description' => 'This is sample group buy added via WooCommerce API',
    'short_description' => 'Sample api group buy.',
    
];


print_r( $woocommerce->post( 'products', $data ) );

How can you limit number of produtcs retrieved? You can use per_page attribute in $data like below (search, offset, order, order by etc options are available useful for paging and filtering) – all available parameters are listed here https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-products:

$data = [
    'per_page' => 1,    // api will return only 1 auction product
    'type' => 'auction'
];


print_r( $woocommerce->get( 'products', $data) );

Complete REST API documentation can be found on https://woocommerce.github.io/woocommerce-rest-api-docs/. If you have additional questions on how WooCommerce REST API works with WooCommerce Simple Auctions, WooCommerce Lottery and WooCommerce Group Buy please open ticket here or contact us.

How to Create Entry Lists for WooCommerce Lottery and Pick Number addon?

For entry lists to work you will need WooCommerce Lottery plugin and WooCommerce Lottery / Raffles Pick Ticket Number Mod addon since entry lists make more sense with ticket numbers and feature is implemented in Pick Number addon in version v2.1.0 (Pick Number Mod addon is not mandatory entry lists work with WooCommerce Lottery just without ticket numbers – example screenshot). Make sure you have latest version of WooCommerce Lottery and Pick Number mod addon.

Now you need to create new blank page by going to Pages -> Add New. Just add page title for example “Entry Lists” and click publish.

Next step is to go to WooCommerce Settings then click Lottery tab. Scroll down to WC Lottery Entry Page dropdown and select there “Entry Lists” page which you published moment ago. Save settings and go to “Entry Lists” page to see all active lotteries.

woocommerce lottery entry lists page setup how to

Clicking on specific lottery will lead you to its entry page – see our demo website here.

Change number of products displayed per page

One of the common inqury in our support tickets, unrelated to plugin functionality, was how to change number of products displayed on WooCommerce product archive page.

Most themes come with settings page where you can change number of producs displayed, in fact you can change number of rows and columns per page but there are also themes without that option.

So to do that you need to add code to your child theme’s functions.php file. Avoid adding custom code directly to your parent theme’s functions.php file as this will be wiped entirely when you update the theme.

This solution requires you to have your shop page display (WooCommerce > Product catalog set to “Show products”). Code snippet is below (snippet is from woocommerce.com):

/**
 * Change number of products that are displayed per page (shop page)
 */
add_filter( 'loop_shop_per_page', 'new_loop_shop_per_page', 20 );

function new_loop_shop_per_page( $cols ) {
  // $cols contains the current number of products per page based on the value stored on Options –> Reading
  // Return the number of products you wanna show per page.
  $cols = 9;
  return $cols;
}

Black Friday / Cyber Monday discount and coupon code, current versions update

We have nice promo running this week (until 30th Nov 2021) – all items in our store are 40% off. You can use coupon code blackfriday21 to get the discount once you are on checkout page.

Our current versions for plugins: WooCommerce Lottery v2.1.2, Woo Lottery Pick Number Mod addon v2.1.0, Woo Simple Auctions v2.0.6. If you don’t have those versions we recommend you to update.

Why we use and suggest real cronjobs for our plugins (and WordPress)?

wordpress_cronjobs_real_cronjob

In this article we’ll explain benefits of using real UNIX cronjobs instead of interal WordPress cron. The default WordPress cron functionality checks on each page load for scheduled tasks that are due to run. This means wp-cron is not a true UNIX cron and actually runs more or less often based how much access to site you have (traffic).

First of all, a couple words about why do we have a need for cronjobs in our plugins like Simple Auctions, Lotteries and Group Buy. Custom product types (auctions, lotteries and deals) in these plugins have start and end timestamp and we need to have reliable way to fullfill start and end timestamps for auctions, lotteries and group buy / deals on time and to send email notifications in specified intervals (for example twice daily).

We cannot use WordPress cronjobs because they are not reliable and depend on visitor accessing your website. That means if your WordPress has say 3 visitors a day it will run internal WP cron 3 times that day (and we will be able to close auction only 3 times a day and not on end datetime set in auction). So if there is no site activity for say 3 days, the cron will not be triggered for 3 days but next time you have visit on your website.

Another problem – if there are a lot of pending tasks to be run by WP internal cron, user will have to wait for those to be executed and then website will load for user meaning bad user experience due to slow loading times (which are caused by WP internal cronjob running and executing pending tasks). Real server cronjobs do not depend on website activity and are run in fixed defined intervals as set in cronjob config.

It’s better to have maintenance tasks running in background by cron than by your visitors – one more reason to use either real cronjobs or external service like EasyCron. EasyCron has nice tutorial how to setup cronjobs for Simple Auctions (also useful for Lotteries and Group Buy plugin).

If your hosting company (hosting provider) does not support one minute cronjobs we suggest that you move your website to better (serious) hosting company (or use service like EasyCron).

One performance suggestion for your WordPress site – since you are allready setting up cronjobs, you could also setup main WP cron to be run by real cronjob (or EasyCron) so your visitors don’t load WP cron at all. You need to edit wp-config.php file and add this line:

define('DISABLE_WP_CRON', true);

Then set this cron (use either wget or curl – whatever your hosting supports, just don’t use both at same time!):


/usr/bin/wget -q -O https://domain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

OR 

/usr/local/bin/curl --silent https://domain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Where you need to replace domain.com with your actual domain to your WordPress site and make sure to have right path to wget or curl (safest way to find out those is to contact your hosting provider).

With these in place you will have reliable way to do WordPress maintenance cron tasks and your visitors will have better user experience because your WordPress will load a bit faster since users will not run WP cron on every website access.

Using Post Expirator plugin for ending soon lotteries, auctions and group buy deals

post expirator plugin for wordpress

Ever wanted to have category called ending soon or starting today which are automatically populated based on auction, lottery, deal end / start date? One client did it with a free plugin so he does not need to use widgets or shortcodes for that purpose. Plugin called Post Expirator does the trick – among other things it can change (custom) product category on selected date.

Along with main features to modify, remove or completely delete content when the expiry date arrives plugin allows also some useful actions with posts / pages / products:

  • Change the status to “Draft”
  • Delete the post
  • Send the post to the Trash
  • Change the status to “Private”
  • Enable the “Stick to the top of the blog” option
  • Disable the “Stick to the top of the blog” option
  • Remove all existing categories, and add new categories
  • Keep all existing categories, and add new categories
  • Keep all existing categories, except for those specified in this change

For our example we will use “Remove all existing categories, and add new categories” action. First define product categories – something like on screenshot below (and ofcourse categorize auctions with Auctions product category):

You can use “do not mix” settings for auctions, lotteries and group buy / deals. Now in Settings -> Post Expirator we need to enable it for product post type (and disable it on for example posts and pages if you don’t need it there).

Post Expirator plugin comes with handy bulk edit option and can be bulk set but problem is that expiration category must be set for each auction manually, one by one. This can be done during auction post publishing when you enter all auction details so we don’t see this as huge problem.

After time set in above screenshot auction is categoriezed under Auctions -> Ending Soon category.

Benefits of this approach is that when you custom style product archive page same style will be applied to all products even custom ones like auctions, lotteries and group buy / deals.

Customizing loop for widgets and shortcodes is not that easy while customizing product categories is more easy and can be done for example with Elementor. You can also completely unpublish finished auctions, lotteries, group buy / deals, or move them to their special product category called for example Past Competitions.

Post Expirator plugin is well maintained, has solid user base (more than 100k installations) and top rating.

Debugging in WordPress (WP debug tips)

One of the most important things when developing is a way to locate source of the problem fast and with as much details as possible – which file and more specifially line of code caused the trouble.

WordPress has solid debug logger which can be complement with 3rd party plugins like Query Monitor and Debug Bar. First step is to edit wp-config.php file and set following constants:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', true );
define( 'WP_DEBUG_LOG', true );

These lines will enable debug mode which will both displaying errors in frontend and log them in file located at /wp-content/debug.log – make sure to set define( ‘WP_DEBUG_DISPLAY’, false); if you are doing debugging on live production website (site is accessible online) so errors are not displayed to eventual visitors but only logged to a log file.

If WP_DEBUG has been enabled it is possible that this file is huge in size and best would be to delete it and let WordPress start logging from beginnig so you don’t end up inspecting debug.log with 500MB of debug info.

To limit what is logged into debug.log (for example you don’t want to log notices or warnings there are a lot of those entries and they are not particularly useful) you will need to use small mu plugin, create folder wp-content/mu-plugins/ and in that folder create for example file no-warnings-in-debuglog.php with content:

<?php


// no more notices and warnings in debug.log!
error_reporting ( E_ALL &  ~( E_NOTICE | E_WARNING) );

Fatal error will causing a white screen of death, and without WP_DEBUG enabled you will see only white screen without any error messages. Debug.log file can be viewed using your favorite text / code editor or from WordPress backend using plugin like Log Viewer.

But true power of WordPress debug logger comes with error_log() php function which you can use in your code in order to log something in wp-content/debug.log file in your custom code (you added for example in functions.php), plugin or theme template or gather and log other info you need (for example who accessed a page or viewed a product – example on pastebin).

With below statement you can even log a line in particular file in which error_log() function was invoked:

error_log( __LINE__ . ' i'm here!');

Since logging is unformatted you will need to use print_r or var_export to log variables like arrays and objects:

error_log( print_r( $log, true ) ); // useful for arrays
error_log( var_export( $object, true ) ); // any variable type, objects


SCRIPT_DEBUG is a related constant that will force WordPress to use the dev versions of core CSS and JavaScript files rather than the minified versions that are normally loaded. This is useful when you are testing modifications to any built-in .js or .css files. Default is false.

define( 'SCRIPT_DEBUG', true );

If you are trying to debug what is going on with your MySQL / MariaDB, you can add the following line to your wp-config.php file.

define( 'SAVEQUERIES', true );


This saves the database queries to an array which is then written to the debug.log.

There is also a way to rename debug.log file or move it to non default folder. For that you can use this in your wp-config.php:

define( 'WP_DEBUG_LOG', false ); // disable default log function
ini_set( 'log_errors', 1 ); // tell PHP to start logging to a file
ini_set( 'error_log', dirname(__FILE__)  . '/debug-folder/my_debug_1.log' );

Last line means that my_debug_1.log will be created in /path/to/your/wordpress/debug-folder/ my_debug_1.log – you can also use constant ABSPATH which is a WordPress defined constant specifying the root path of your installation.

In some cases you might want to write information to the log, even if it’s not technically an error but you need output something during development phase (useful to debug ajax requests for example). PHP has a function called error_log, that will print information to the error log for you (and saved to /wp-content/debug.log file). By default it does not print and format properly so here is wrapper for error_log, that uses print_r() to format arrays and objects properly before logging them:

if ( ! function_exists('write_log')) {
   function write_log ( $log )  {
      if ( is_array( $log ) || is_object( $log ) ) {
         error_log( print_r( $log, true ) );
      } else {
         error_log( $log );
      }
   }
}

WordPress debug.log just captures PHP errors – JavaScript errors are output to the browsers console log which is available in DevTools (or Firebug ) by pressing F12 in Chrome and clicking on Console tab. Complete WordPress reference page for debugging is here and documentation for error_log() PHP function is here.

Note: once everything is sorted and work done is ready for production – turn off all logs. Writing debug info to a file will have a performance hit on the server meaning you get slower load times for your website (along with huge security issue if WP_DEBUG_DISPLAY is not turned off!), especially these SAVEQUERIES and SCRIPT_DEBUG logs, so use them with caution if you have to debug on a production server.

WooCommerce Simple Auctions with SMS notifications

wsa sms notifications

Initial setup and requirements for WooCommerce Simple Auctions with SMS notifications

In this tutorial we will explain how you can enable true SMS notifications for (your auction website powered by Simple Auctions): new bid, auction finished, auction won, outbid note, reminder to pay and reserve failed notifications.

Developer also has specific integrations for many different plugins like WooCommerce, Contact Form 7, Event Espresso, Easy Digital Downloads, ClassiPress, AdForest, JobManager, Bulk SMS, WC Bookings etc. You can get access to all addons here.

To implement SMS notifications feature for WSA you will need two additional plugins WP SMS for WordPress (free) and WP SMS For WooCommerce Simple Auctions ($29). Next requirement is Twilio account to enable using their API for send SMS messages. In case you encounter any issue with setup you can always reach us via support ticket system and we will help you with setup.

wp sms twillio plugins for sms notifications

Once plugins are installed we can start with setting up Twillio account and API. On url https://www.twilio.com/console/projects/summary you will need to create new account / project and will get Account SID. Project will have also Auth Token and Twilio phone number (found under TRIAL NUMBER label) that is needed for WP SMS for WordPress to access API. See screenshot below:

twillio project setting for use with wp sms for wordpress plugin

Now we need to enter those values in WP SMS for WordPress settings, see screenshot below:

wp sms for wordpress settings

Now that all is set, we need to take care of key parameters phone number and message content – where to send SMS notification and what is actual content of message to be sent. To send SMS to a client you will need them to enter a mobile phone number able to receive SMS messages. WP SMS for WordPress allows shipping or billing phone number fields to be used but also allows creation of special custom meta user field that adds “Mobile Phone” input form to user profile.

It is up to site owner to define what user meta field will be used for SMS notifications phone number, all 3 ways are equal and there is no preferred option. For example if your clients did not make any purchases yet, they might not have entered billing or shipping phone number.

Also some clients might have billing and shipping phone number but they don’t want to receive SMS messages. In that case the best solution would be to enable “Add Mobile Number Field to User Profiles” and tell users to add their number there if they want SMS notifications.

WooCommerce Simple Auctions SMS Triggers / Notifications

Below is screenshot of available triggers / notifications and placeholder tags which are replaced with actual values like %auction_title% which becomes real title of auction in SMS message.

All notifications can be send to admin and customer (bidder), except for outbid note and reminder to pay notification that can be sent only to bidder who was outbidded or who has outstanding payment to make for won auction.

Admin does not have to add phone number to profile, you need to add number to input called “Receiver Number”. So you can receive different notifications on different phones (if needed). Along admin and customer, notifications for new bid, auction finished and auction won can be sent to user (vendor / post author). This is useful if you use multivendor plugin or you have users who add auctions and you want them to get notification.

Simple Auctions with SMS notifications settings explanation

Things to remember to check when you enable Simple Auctions with SMS notifications for production websites

Performance. For busy sites with a lot of bids performance penalty must be considered. If you have a lot of bids and you enable bid notification you need to expect that a lot of API calls will be made. Make sure you have adequate hosting meaning you will need proper (non cheap) dedicated server or cloud hosting with good connecitvity to Twillio. Make sure for production webistes logging is disabled. Drop us email if you need hosting suggestion.

Costs and Budget. High number of SMS notifications will cost more. For start enable only most important SMS notifications to keep SMS sending costs low and inside your budget. If you deplete your credit at Twillio, site will stop sending SMS notifications and some important ones could be missed.

Debugging and Logs. WP SMS for WordPress has nice detailed logging, activate it during testing phase then disable once everything is ready for better performance (you can monitor delivery at Twillio side). Do not forget about WP_DEBUG and WP_DEBUG_LOG settings in wp-config.php file!