How to Add QR Codes to WooCommerce Order Confirmation Emails
If your WooCommerce store handles event tickets, order pickups, or in-person check-ins, a QR code in the order confirmation email is the bridge between a digital order and a physical transaction. This post covers two approaches: a dedicated plugin that adds QR codes to all order emails without writing any code, and a custom hook-based snippet for stores that need to control exactly what the code encodes and which emails receive it.
Scan orders, not spreadsheets. Order Barcodes for WooCommerce adds a scannable barcode and QR code to every order — built for check-ins, pickups, and fulfillment.
Why QR Codes in Order Emails Are Actually Useful
Most stores treat the order confirmation email as a receipt and nothing more. A QR code changes that. It turns the email into a scannable credential the customer carries on their phone.
Common scenarios where this pays off:
- Event check-in: Customer shows up, staff scan the QR, order status updates to Complete — no manual lookups, no lost printouts.
- Order pickup at a counter: Scan to confirm the right customer is collecting the right order without asking for an order number.
- Membership and access verification: Pair with WooCommerce Memberships — the QR in the welcome email becomes an instant access card.
- Returns and warranty tracking: Encoding the order view URL means any staff member can pull up the full order history from a single scan.
The code route matters for one reason: what you encode in the QR code depends on your workflow. A URL to the customer’s order page works for most stores, but if you’re building a custom check-in endpoint or need a signed token in the URL, you need control over that.
Method 1: Install a Plugin (Recommended for Most Stores)
Order Barcodes & QR Codes for WooCommerce handles QR generation, email injection, and scanning in a single plugin. No hook wiring needed.
After activating, every order automatically gets a unique QR code. That code appears:
- In the order detail table on the customer’s account page
- In all WooCommerce order emails, below the order table
- On PDF invoices and packing slips (if you use a PDF plugin like WooCommerce PDF Invoices & Packing Slips)
Setup:
- Install and activate the plugin from plugindistrict.com or CodeCanyon.
- Go to WooCommerce → Settings → Order Barcodes.
- Set Barcode Type to QR Code. (The plugin also supports Code 39, Code 128a, Code 128b, Code 128c, and 4 of 5 Interleaved — QR is the right choice for email because it scans reliably from a phone screen without needing a dedicated barcode scanner.)
- Confirm Display in Customer Emails is enabled.
- Place a test order and open the processing email — the QR should appear below the order table.
The plugin also includes a built-in scan form under WooCommerce → Scan Order. Staff open it on any browser, scan the code with a phone or USB scanner, and the order status updates immediately. Nothing to build.
For event ticketing workflows — where you need to validate codes at a door and mark orders as checked-in — this is the fastest path. The scanning infrastructure is already there.
Method 2: Add QR Codes with a WooCommerce Email Hook
If you’d rather not add another plugin, or you need to encode something custom (a tracking URL, a signed endpoint, a plain order ID for your own scanner), use the woocommerce_email_after_order_table action hook.
The hook fires after the order items table in every HTML email. It passes four parameters: $order (the WC_Order object), $sent_to_admin (bool), $plain_text (bool), and $email (the WC_Email object, which exposes $email->id).
Here’s a working snippet. Drop it in a Code Snippets plugin or a child theme’s functions.php:
add_action( 'woocommerce_email_after_order_table', 'pd_order_email_qr_code', 20, 4 );
function pd_order_email_qr_code( $order, $sent_to_admin, $plain_text, $email ) {
// Admin emails and plain-text clients can't render images
if ( $sent_to_admin || $plain_text ) {
return;
}
// Only attach to specific email types
$target_emails = [ 'customer_processing_order', 'customer_completed_order' ];
if ( ! in_array( $email->id, $target_emails, true ) ) {
return;
}
$order_url = $order->get_view_order_url();
$qr_src = 'https://api.qrserver.com/v1/create-qr-code/'
. '?size=150x150&data=' . rawurlencode( $order_url );
printf(
'<p style="text-align:center;margin:24px 0;">
<img src="%s" width="150" height="150" alt="Scan to view order #%s" />
<br><small style="color:#666;">Scan to view your order details</small>
</p>',
esc_url( $qr_src ),
esc_html( $order->get_order_number() )
);
}
One caveat on api.qrserver.com: this calls an external service at email-send time. For low-to-medium volume stores it’s fine. For high-volume (hundreds of orders per day), generate QR images server-side and embed them as inline base64 — the chillerlan/php-qrcode library is the go-to Composer package for this. That removes the external dependency entirely.
What to Encode
The snippet above encodes the customer’s order view URL. Other options depending on your workflow:
| Use case | Value to encode |
|---|---|
| Customer order page | $order->get_view_order_url() |
| Staff lookup by order number | $order->get_order_number() |
| Custom check-in endpoint | home_url( '/check-in/?order=' . $order->get_id() ) |
| Carrier tracking URL | The shipment tracking URL string |
If you’re building a custom scanner, encoding the bare order number is often better than a full URL — your handler does the lookup, and you’re not exposing a customer-facing URL in the QR.
Plain Text Emails and Image Blocking
Two things will cause the QR to not show up, and both are expected behavior:
Plain text emails: WooCommerce sends HTML and plain-text versions of each email. The $plain_text guard in the snippet above handles this. If a customer reports never seeing the QR, check whether their email client is configured for plain-text-only mode — there’s no workaround for that other than telling them to open the email in a browser.
Image blocking: Some corporate email clients block remote images by default (Outlook is the main offender). If your customer base is heavy on corporate buyers, consider embedding the QR as an inline base64 image rather than an external URL. That sidesteps the blocking entirely since the image is part of the email payload. The chillerlan/php-qrcode library mentioned above makes this straightforward — generate the PNG as a data URI and use it as the src.
Plugin vs. Code: Which to Use
| Order Barcodes & QR Codes | Hook snippet | |
|---|---|---|
| Setup time | ~5 minutes | 20–30 min |
| Built-in scan form | Yes | No — build your own |
| PDF / packing slip support | Yes | No |
| Custom encoded data | Via settings | Full control |
| Filter by email type | Yes | Yes ($email->id) |
| Best for | Most stores | Custom workflows |
For stores that need QR codes in emails and a scan form without building anything, the plugin is the right call. If you already have a check-in system and just need a QR embedded in the email pointing to your own endpoint, the hook snippet is cleaner.
For a full overview of how QR codes fit across the entire order lifecycle — product pages, emails, fulfillment, and check-in — see the complete guide to QR codes in WooCommerce.
Ready to add QR codes and a scan form to your store? Order Barcodes & QR Codes for WooCommerce is $39 and covers email injection, PDF support, and six barcode types.
Ready to speed up check-ins and fulfillment? Every order gets a unique code you can scan from any phone camera or USB scanner — no third-party service, no order data leaving your site.
Want help applying this?
Tell us your workflow and we'll point you to the right plugin or next step.