On this page
WordPress & WooCommerce Setup#
This guide connects a WooCommerce store so your chatbot can answer “where is my order?”. Signed-in shoppers see their own orders straight away; guests are asked for their order number and billing email. It takes about 20 minutes and needs access to your WordPress files (by SFTP, your host’s file manager, or a code-snippets plugin).
Background: Identify signed-in visitors explains how the identity token works, and Guests & data never to send lists what must stay out of it.
1. Connect WooCommerce in Gydr#
In the Console, open Plugins → WooCommerce Storefront. A short setup walks you through it. Enter your store URL (for example https://shop.example.com) and press Test connection — Gydr checks your store answers before you continue. On the next step you can keep the recommended product-search settings. Then attach the plugin to your widget’s Skill; the chatbot can now search your products. The prerequisites are on the Plugins & MCP page.
2. Create a read-only REST key#
- In WordPress, go to WooCommerce → Settings → Advanced → REST API → Add key.
- Description:
Gydr. User: a Shop Manager or Administrator. Permissions: Read. - Copy the consumer key and consumer secret, paste both into the Order & delivery status step of the setup, and press Check key. Once it says the key is accepted, continue — this switches on order and delivery answers.
- Already connected your store? Open the plugin’s Orders tab instead, paste the key, press Check key, and switch on Answer order & delivery questions.
Read is all Gydr needs — it can never change or cancel an order. What Check key can report:
- Result
- Accepted
- What to do
- Nothing — carry on.
- Result
- Rejected key
- What to do
- The key or secret is wrong or was revoked. Create a new key and paste both halves again.
- Result
- Key lacks read permission
- What to do
- Edit the key in WooCommerce and set Permissions to Read (or pick a user who can read orders).
- Result
- Host strips the Authorization header
- What to do
- Your web server removes the header before WordPress sees it. Add
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1to your.htaccess, or ask your host to pass theAuthorizationheader through.
- Result
- REST API unreachable
- What to do
- Gydr can’t reach
/wp-json/. Check permalinks are not “Plain” and that no security plugin, firewall or Cloudflare rule blocks it.
| Result | What to do |
|---|---|
| Accepted | Nothing — carry on. |
| Rejected key | The key or secret is wrong or was revoked. Create a new key and paste both halves again. |
| Key lacks read permission | Edit the key in WooCommerce and set Permissions to Read (or pick a user who can read orders). |
| Host strips the Authorization header | Your web server removes the header before WordPress sees it. Add SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 to your .htaccess, or ask your host to pass the Authorization header through. |
| REST API unreachable | Gydr can’t reach /wp-json/. Check permalinks are not “Plain” and that no security plugin, firewall or Cloudflare rule blocks it. |
3. Create an identity key in Gydr#
In the Console, go to Settings → Identity verification → Create key. Gydr shows the WordPress lines for step 4 — with your account id, key id and secret filled in — only once. Copy them now. A lost secret can’t be shown again; you would create a new key.
Then check that WooCommerce customer ID is mapped to Subject (sub) — in the setup’s Recognise signed-in shoppers step, or later on the plugin’s Identity tab. It is pre-selected; leave it. This step is optional: without it, shoppers still get their order status by entering the order number and email.
4. Add the secret to wp-config.php#
Paste the three lines into wp-config.php in your WordPress root folder:
// wp-config.php — above the line "That's all, stop editing!"
define( 'GYDR_ACCOUNT_ID', 'your-gydr-account-id' );
define( 'GYDR_IDENTITY_KID', 'idk_xxxx' );
define( 'GYDR_IDENTITY_SECRET', 'your-identity-secret' );wp-config.php — never in your theme, a page, or a plugin setting stored in the database. Theme files get shared and database settings end up in backups and exports.5. Add the token plugin#
Create the file wp-content/mu-plugins/gydr-identity.php (create the mu-plugins folder if it doesn’t exist) with the code below. “Must-use” plugins load automatically and can’t be switched off by accident. A code-snippets plugin works too — paste everything after the first line.
<?php
/**
* Plugin Name: Gydr identity verification
* Signs a short-lived identity token for the signed-in WordPress user.
*/
defined( 'ABSPATH' ) || exit;
function gydr_b64url( string $data ): string {
return rtrim( strtr( base64_encode( $data ), '+/', '-_' ), '=' );
}
function gydr_identity_token( WP_User $user ): string {
$now = time();
$header = array( 'alg' => 'HS256', 'typ' => 'JWT', 'kid' => GYDR_IDENTITY_KID );
$payload = array(
'sub' => (string) $user->ID, // = the WooCommerce customer id
'aud' => GYDR_ACCOUNT_ID,
'iat' => $now,
'exp' => $now + HOUR_IN_SECONDS,
'name' => $user->display_name,
'email' => $user->user_email,
'email_verified' => false, // WordPress does not verify emails
);
$signing = gydr_b64url( wp_json_encode( $header ) ) . '.' . gydr_b64url( wp_json_encode( $payload ) );
$sig = gydr_b64url( hash_hmac( 'sha256', $signing, GYDR_IDENTITY_SECRET, true ) );
return $signing . '.' . $sig;
}
// admin-ajax is never page-cached; the token must never be baked into cached HTML.
add_action( 'wp_ajax_gydr_identity_token', function () {
nocache_headers();
wp_send_json( array( 'token' => gydr_identity_token( wp_get_current_user() ) ) );
} );
add_action( 'wp_ajax_nopriv_gydr_identity_token', function () {
nocache_headers();
wp_send_json( array( 'token' => null ) ); // guests stay anonymous
} );6. Point the widget at the endpoint#
Add one attribute to the Gydr script tag already on your site:
<script
src="https://cdn.gydr.ai/widget.js"
data-api-key="pk_live_YOUR_KEY"
data-identity-endpoint="/wp-admin/admin-ajax.php?action=gydr_identity_token"
async
></script>7. Test it#
- Sign in to your store as a customer who has an order. Open
/wp-admin/admin-ajax.php?action=gydr_identity_tokenin the same browser — you should see{"token":"eyJ…"}. Signed out, you should see{"token":null}. - Copy the token and paste it into the tester in Console → Settings → Identity verification. It should be accepted; if not, the troubleshooting table explains each reason.
- Still signed in, ask the chatbot “where is my order?”. It should list your recent orders without asking anything.
- Sign out and ask again. The conversation starts fresh, and the chatbot asks for an order number and billing email.
Why it is set up this way#
- Choice
- An endpoint, not a token printed into the page
- Reason
- Page caches such as LiteSpeed Cache, WP Rocket and Cloudflare APO store whole pages. A token printed into the HTML would be served to the next visitor — with the first customer's orders. admin-ajax.php is never page-cached.
- Choice
sub= the WordPress user id- Reason
- A WooCommerce customer id IS the WordPress user id, so the plugin can find the shopper's orders directly.
- Choice
email_verified: false- Reason
- WordPress doesn't confirm that users own their email address, so Gydr must not match orders by it.
- Choice
- Guests use the form
- Reason
- A guest checkout has no account (customer id 0), so a guest proves an order is theirs with the order number and billing email instead.
| Choice | Reason |
|---|---|
| An endpoint, not a token printed into the page | Page caches such as LiteSpeed Cache, WP Rocket and Cloudflare APO store whole pages. A token printed into the HTML would be served to the next visitor — with the first customer's orders. admin-ajax.php is never page-cached. |
sub = the WordPress user id | A WooCommerce customer id IS the WordPress user id, so the plugin can find the shopper's orders directly. |
email_verified: false | WordPress doesn't confirm that users own their email address, so Gydr must not match orders by it. |
| Guests use the form | A guest checkout has no account (customer id 0), so a guest proves an order is theirs with the order number and billing email instead. |
What shoppers see#
- Signed in: their 5 most recent orders, with tracking for the newest, without being asked anything. Asking about a specific order they own shows it. Another customer’s order number gets “no order with that number” — it never reveals that the order exists.
- Guests: a short form asks for the order number and billing email. A wrong pair and a missing order get the same answer, and attempts are limited per email and per visitor.
- Tracking comes from WooCommerce Shipment Tracking, Advanced Shipment Tracking (AST), or WooCommerce order fulfilments.
On WhatsApp, Messenger, Instagram and Telegram
The full plugin reference is in WooCommerce Storefront → Order Status & Delivery Tracking.
