WooCommerce Integration
Wallet coupons, loyalty cards, and memberships for a WooCommerce store. Passes are redeemed at checkout as coupon codes, every paid order is reported to Pass Studio with one hook, and partners who sent the customer are paid on real sales. No plugin to install: WooCommerce runs on your WordPress, so the integration is a short snippet and an API key.
How it fits together
- The pass barcode is a WooCommerce coupon code. Each pass carries a unique code; the same string exists as a coupon in WooCommerce.
- The customer saves the pass from a share link, a QR code, an email, or a partner's tracking link — Pass Studio stamps where they came from.
- At checkout the code is applied as a coupon. WooCommerce prices the order; nothing about checkout changes.
- When the order is paid, one hook calls Pass Studio. The pass is redeemed in the wallet, the order's value is recorded, the
pass.redeemedwebhook fires, and any partner postback goes out with the amount.
Step 1 — Get matching codes into WooCommerce
Two ways. Pick one per pass.
A. WooCommerce owns the codes
Create the coupon codes in WooCommerce first (one per customer, Usage limit per coupon = 1, or a bulk-coupon plugin for hundreds), then issue each pass with that code as its barcode: POST /api/v1/passes/{passId}/issue with barcodeValue set to the coupon code — one call per customer, or up to 500 at a time with the batch endpoint or a CSV import. Best when your team already manages coupons in WooCommerce.
B. Pass Studio owns the codes
Let Pass Studio mint a unique code per pass (share links, enrollment forms, and partner links all do this on their own) and create the matching coupon when the pass is issued, from the pass.issued webhook through the WooCommerce REST API. Best when customers self-serve the pass and you never want to pre-create anything.
// Pass Studio pass.issued webhook → create the matching WooCommerce coupon.
// Runs on your server (or a Zap / Make scenario). WooCommerce REST API with a
// read/write key from WooCommerce → Settings → Advanced → REST API.
POST https://your-store.example/wp-json/wc/v3/coupons
Authorization: Basic base64(consumer_key:consumer_secret)
Content-Type: application/json
{
"code": "<data.barcodeContent from the webhook>",
"discount_type": "percent",
"amount": "15",
"individual_use": true,
"usage_limit": 1,
"usage_limit_per_user": 1
}Either way the coupon's discount is configured in WooCommerce and the pass just shows it; a field update changes what the card says without touching the coupon.
Step 2 — Redeem on paid orders (the hook)
Add this to your theme's functions.php or a code-snippets plugin, and define PASSSTUDIO_API_KEY in wp-config.php with a key from Settings → API Keys (a key restricted to the passes you sell with is enough).
<?php
// Pass Studio — redeem wallet passes used as coupons on paid WooCommerce orders.
// Put your API key in wp-config.php: define( 'PASSSTUDIO_API_KEY', 'ps_live_...' );
add_action( 'woocommerce_payment_complete', 'passstudio_redeem_order_passes' );
add_action( 'woocommerce_order_status_completed', 'passstudio_redeem_order_passes' );
function passstudio_redeem_order_passes( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order || ! defined( 'PASSSTUDIO_API_KEY' ) ) {
return;
}
foreach ( $order->get_coupon_codes() as $code ) {
$response = wp_remote_post( 'https://www.passstudio.online/api/v1/redeem', array(
'timeout' => 15,
'headers' => array(
'Authorization' => 'Bearer ' . PASSSTUDIO_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'code' => $code,
'orderId' => (string) $order->get_id(), // idempotency key — the hook may run twice
'amount' => (float) $order->get_total(),
'currency' => $order->get_currency(),
'source' => 'woocommerce',
'occurredAt' => gmdate( 'c', $order->get_date_paid() ? $order->get_date_paid()->getTimestamp() : time() ),
) ),
) );
if ( is_wp_error( $response ) ) {
error_log( 'Pass Studio redeem failed for order ' . $order_id . ': ' . $response->get_error_message() );
continue;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
// Codes that are not Pass Studio passes (your ordinary coupons) come back
// { valid: false, reason: "not_found" } — nothing to do. A pass that was
// already spent answers reason "already_redeemed": the coupon should have
// been refused at checkout, so note it for review.
if ( isset( $body['valid'] ) && ! $body['valid'] && 'not_found' !== ( $body['reason'] ?? '' ) ) {
$order->add_order_note( 'Pass Studio: coupon ' . $code . ' — ' . ( $body['reason'] ?? 'not redeemable' ) );
}
}
}- Two hooks, one call.
woocommerce_payment_completefires for online payments;woocommerce_order_status_completedcovers manual and offline ones. Both may run for one order — that is fine, becauseorderIdmakes the call idempotent: the second run returns the first result withalreadyProcessed: true, and no second redemption, charge, or postback happens. - Ordinary coupons are ignored. A coupon code that is not a Pass Studio pass answers
valid: false, reason: not_found; the snippet skips it. - Refunds. Pass Studio does not reverse a redemption on refund; a refunded single-use pass stays spent. If you want to hand the customer a fresh pass, issue one.
- Billing. One redemption credit per order on every plan, no register window; a zero balance never blocks the redemption (the response says
billing.charged: false).
The full field list and every response is in the redeem reference.
Step 3 (optional) — Pay partners on sales
Give each publisher, affiliate, or venue a tracking link. A customer who saves the pass through it is attributed to that partner for the pass's lifetime, and the hook above fires the partner's signed postback with {orderId}, {amount}, and {currency}. The partner report in Settings shows saves, redemptions, and revenue by day.
Step 4 (optional) — Loyalty points on WooCommerce orders
For a points program, also send the paid order to POST /api/v1/orders/process with the customer's email, the order id as externalOrderId, and source: "woocommerce". Points accrue, rewards unlock, and the card updates in the wallet. Put the order amount on that call or on the redeem call, not both, so the partner report counts each sale once.
No code — WooCommerce in Zapier
Everything except the checkout redemption can be done without touching PHP. Pass Studio's Zapier app pairs with Zapier's WooCommerce app:
- WooCommerce New Order → Issue Pass by Email — every paying customer gets a wallet coupon or loyalty card in their inbox; idempotent, so a repeat customer keeps one card.
- WooCommerce New Customer → Issue Pass by Email — a membership card on sign-up.
- WooCommerce Order Paid → Process Order — loyalty points on every order, rewards unlocked, card updated.
- WooCommerce Order Paid → Award or Adjust Points — a fixed bonus per order instead of spend-based accrual.
Redeeming a pass code used as a coupon is the one step that needs the hook above — or a Webhooks by Zapier step that posts the same redeem call. Both paths bill the same and fire the same events.
Getting passes to customers
- After purchase: from the same hook, call issue with the customer's email and
sendEmail: true— the wallet link arrives in their inbox; or print the pass's share QR on the packing slip. - On your site: put the share link or its QR on a landing page, the thank-you page, or a WooCommerce email template. Tagged links carry
utm_*so you can see which placement works. - Through partners: tracking links, as above.
FAQ
Does Pass Studio have a WooCommerce plugin?
Not a plugin from the WordPress directory — a recipe, and a no-code path. WooCommerce runs on your own WordPress, so a fifteen-line snippet in your theme or a code-snippets plugin calls the Pass Studio API when an order is paid; or connect WooCommerce to Pass Studio in Zapier and issue passes, award points, and process orders with no code at all. There is nothing to install from us, nothing to keep updated, and your API key never leaves your server.
How does the pass code reach the WooCommerce order?
The pass barcode is a WooCommerce coupon code. Either create the coupon codes in WooCommerce and issue each pass with that code as its barcodeValue, or let Pass Studio mint the codes and create the matching coupon through the WooCommerce REST API from the pass.issued webhook. At checkout the customer types or scans the code as a normal coupon; the paid order carries it.
What does a redemption cost?
One redemption credit per order, on every plan — the same credit a counter scan costs. Idle passes cost nothing. A retried hook for the same order is free: the call is idempotent per order id.
Can partners or affiliates be paid on WooCommerce sales?
Yes. When the customer saved the pass through a partner's tracking link, the redeem call fires that partner's signed postback with the order id, amount, and currency, and the partner report shows the revenue by day.
Do I also get loyalty points on WooCommerce orders?
Send the same paid order to POST /api/v1/orders/process with the customer's email; the loyalty engine awards points, unlocks rewards, and updates the card. Put the amount on one of the two calls, not both, so the partner report does not count the sale twice.
What if the same order fires the hook twice?
Nothing happens the second time. Redeem with an orderId is idempotent per source and order id: the replay returns the original response with alreadyProcessed: true — no second redemption, charge, or postback.
Related
- API and Integration Guide — issue, redeem, orders, webhooks.
- Partner attribution and postbacks
- WordPress event tickets — FooEvents, Tickera, and other ticketing plugins on the same store.
- Shopify — the native app, if your store is on Shopify.