Guides · Convert WooCommerce webhook to PDF invoice
Convert a WooCommerce Webhook to a PDF Invoice
Searching for convert WooCommerce webhook to PDF invoice usually means you already have order.completed firing — and you need a printable invoice without standing up a separate PDF microservice.
This guide wires WooCommerce → WordPress → DocuHook so each paid order becomes PDF-ready HTML in one function call.
Architecture
- WooCommerce emits
order.completed(or you hookwoocommerce_order_status_completed). - Your theme/plugin builds a small JSON payload from the order.
- DocuHook merges that JSON into your invoice HTML template.
- You email, store, or stream the result as a PDF (browser print / html2pdf / your mailer attachment pipeline).
1. Install the DocuHook WordPress plugin
- Download docuhook.zip
- WP Admin → Plugins → Add New → Upload Plugin
- Activate → Settings → DocuHook
- API URL
https://docuhook.com+ API key from your account
Helper available in PHP: docuhook_render( $data, $html, $args ).
2. Invoice HTML template
Store this as an option, theme file, or constant. Tokens match nested JSON paths:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: system-ui, sans-serif; margin: 36px; color: #111; }
h1 { font-size: 22px; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { text-align: left; padding: 8px 0; border-bottom: 1px solid #ddd; font-size: 14px; }
</style>
</head>
<body>
<h1>Invoice {{order.number}}</h1>
<p>{{billing.name}} · {{billing.email}}</p>
<p>Date: {{order.date}} · Total: {{order.currency}} {{order.total}}</p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Total</th></tr></thead>
<tbody>
<tr>
<td>{{line_items.0.name}}</td>
<td>{{line_items.0.quantity}}</td>
<td>{{order.currency}} {{line_items.0.total}}</td>
</tr>
</tbody>
</table>
</body>
</html>For multi-line orders, either generate rows in PHP before merge, or map the first N lines into line_items.0, line_items.1, …
3. Hook order completion
Drop this in a small custom plugin or your theme’s functions.php (prefer a plugin):
add_action( 'woocommerce_order_status_completed', 'my_docuhook_invoice_on_complete', 20, 1 );
function my_docuhook_invoice_on_complete( $order_id ) {
if ( ! function_exists( 'docuhook_render' ) || ! function_exists( 'wc_get_order' ) ) {
return;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
$items = [];
foreach ( $order->get_items() as $item ) {
$items[] = [
'name' => $item->get_name(),
'quantity' => $item->get_quantity(),
'total' => $item->get_total(),
];
}
$data = [
'order' => [
'number' => $order->get_order_number(),
'date' => $order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d' ) : '',
'total' => $order->get_total(),
'currency' => $order->get_currency(),
],
'billing' => [
'name' => trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ),
'email' => $order->get_billing_email(),
],
'line_items' => $items,
];
$html = file_get_contents( WP_CONTENT_DIR . '/uploads/invoice-template.html' );
if ( $html === false ) {
return;
}
$result = docuhook_render( $data, $html, [
'mode' => 'async', // webhook-friendly: returns 202 job
'filename' => 'invoice-' . $order->get_order_number() . '.pdf',
] );
if ( ! empty( $result['job_id'] ) ) {
update_post_meta( $order_id, '_docuhook_job_id', $result['job_id'] );
}
}Use mode => sync when you need the HTML in the same request (interactive admin actions). Prefer async for storefront webhooks so WooCommerce is not held open.
4. Optional: pure webhook URL
Point a WooCommerce webhook at DocuHook’s hook endpoint if you already wrap the payload:
POST https://docuhook.com/api/v1/hooks/render
Authorization: Bearer dh_...
Content-Type: application/json
{
"mode": "async",
"data": { "...order fields..." },
"html": "<h1>Invoice {{order.number}}</h1>",
"filename": "invoice.pdf"
}Returns 202 with job_id, status_url, and result_url.
Checklist
- API key saved under Settings → DocuHook
- Template file readable by PHP
- Test with a completed order in staging
- Poll
docuhook_job_result( $job_id )if you need the HTML later (email, download link)
The 3-line fix
Once the plugin is configured, converting a WooCommerce order payload into a PDF-ready invoice is:
$result = docuhook_render( $order_data, $invoice_html, [ 'filename' => 'invoice.pdf' ] );
// ~200ms sync merge — or pass mode => 'async' for webhook bursts
$html = $result['html'] ?? null;Get started: download the plugin · register for an API key.