If you’ve ever tried to sync a WooCommerce booking flow with Google Calendar API, you know it’s not plug-and-play. Connecting live availability, real-time slot blocking, and confirmation emails into a single seamless WooCommerce booking Google Calendar integration sounds straightforward — until you’re dealing with OAuth token refresh cycles, timezone mismatches between IST and UTC, and a client who wants WhatsApp confirmations on top of everything else. Here’s how I built it for a real project, and what I’d do differently.

The Problem: Bookings Were Chaos

The client ran a professional services business — consultations booked through their WordPress site. They were using a generic WooCommerce product to collect payments, then manually adding appointments to Google Calendar. Double bookings happened. Clients showed up at the wrong time. The calendar was always a step behind the website.

What they needed was an automated appointment booking WordPress plugin — one that would block the slot the moment payment cleared, fire a calendar invite to both parties, and send a WhatsApp confirmation without a human touching any of it.

What they didn’t need was a ₹30,000/year SaaS subscription for something that should live inside their own site.

My Approach: WooCommerce as the Booking Engine

I kept WooCommerce at the centre rather than replacing it. Here’s why: the client already had WooCommerce running, and their staff knew how to manage orders. Ripping it out would mean retraining people, rebuilding reports, and losing order history. Instead, I extended it.

The architecture looked like this:

  • WooCommerce Variable Products — one variation per service type (30-min, 60-min, 90-min consultations)
  • A custom meta box on the product page to define daily availability windows and max concurrent bookings
  • A date/time picker built with Flatpickr on the frontend, pulling available slots via a custom REST API endpoint
  • On payment completion (woocommerce_payment_complete hook), a PHP class fires the Google Calendar API call
  • MSG91 handles the WhatsApp confirmation after the calendar event is created

Stack

WordPress + WooCommerce, PHP 8.1, Google Calendar API v3, Flatpickr, MSG91 WhatsApp API, custom REST endpoint.

The Interesting Technical Part: OAuth in a WordPress Context

Google Calendar API uses OAuth 2.0. In a typical web app, you’d store tokens in a database and refresh them server-side. In WordPress, there’s a temptation to throw everything into wp_options and call it a day. That’s mostly fine — until the access token expires at 3 AM during a booking and nothing tells you.

The gotcha I ran into: the Google client library for PHP throws an exception when a token refresh fails, but WooCommerce’s payment hook swallows exceptions unless you explicitly catch and log them. I had a booking complete, payment collected, and no calendar event — with no error visible anywhere.

How I fixed it:

  1. Wrapped the entire Calendar API call in a try/catch that logs to a custom WP table (not error_log, which gets rotated)
  2. Added a woocommerce_order_status_changed hook that retries the calendar sync if the order meta shows it failed
  3. Built a tiny WP Admin page that shows pending syncs and lets the client manually trigger them — useful during the initial rollout phase when I was still fine-tuning the OAuth flow

The other tricky bit: IST to UTC conversion. Google Calendar stores everything in UTC. WooCommerce, depending on settings, might be in local time. I enforced UTC storage for all booking meta and converted only on display. One wrong assumption here and every appointment shows up an hour off.

Timezone Handling: A Gotcha Worth Mentioning Separately

India doesn’t observe daylight saving time, which makes IST-to-UTC conversion simpler than most (+5:30, always). But if your client serves customers across multiple timezones — say, UK and US — you need the slot displayed in the customer’s local time, stored in UTC, and sent in the host’s local time in the calendar invite. I handled this with JavaScript’s Intl.DateTimeFormat on the frontend for display, and PHP’s DateTimeZone class on the backend for storage and API calls. Never trust the browser’s timezone assumption; always pass it explicitly.

Results and Lessons

After go-live:

  • Zero double bookings in the first three months
  • Calendar sync success rate above 99% once the retry mechanism was in place
  • Client’s admin time on bookings dropped significantly — no more manual calendar entries

What I’d tell anyone evaluating a similar build: don’t reach for a booking plugin first. Spend 30 minutes mapping your exact data flow — what triggers a booking, what needs to be notified, what needs to roll back if payment fails. Once that’s clear, WooCommerce plus a few well-placed hooks gets you most of the way there without the plugin bloat.

If you need real-time slot blocking with Google Calendar, plan for the OAuth refresh problem from day one. It will bite you if you don’t.