Why Automate Customer Receipts?
Xero has rock-solid invoicing, but it doesn't email a receipt to the customer when an invoice is paid. Most businesses either skip the receipt, remember to send one manually, or paste payment details into an email and hope it looks professional. Over a year, that's thousands of missed touchpoints with paying customers.
Xero Receipt Rocket is a small, purpose-built app that closes that gap. It listens for Xero's "invoice paid" webhook, pulls the invoice data, renders a branded PDF receipt, and emails it to the customer — automatically, every time, within seconds of the payment being recorded.
Every paid invoice in Xero — whether marked via the Xero UI, reconciled from a bank feed, or paid via Stripe/GoCardless — triggers an automatic receipt email with a PDF attachment. No human involvement, no duplicates, no missed receipts.
How It Works (The Flow)
Xero Receipt Rocket sits between Xero's webhook and your email server. Here's what happens from the moment a payment is reconciled:
You reconcile the bank feed, apply a payment, or a Stripe charge posts — Xero's invoice status flips to PAID.
Xero pushes a signed webhook to Receipt Rocket's /webhook.php endpoint with the invoice's unique ID.
The app validates the HMAC-SHA256 signature, then fetches the full invoice from Xero's API — contact, email, line items, amount, tax, payment date.
A SQLite-backed duplicate check makes sure the same invoice never gets a second receipt, even if Xero re-fires the webhook.
Your HTML template is merged with the invoice data using Dompdf — logo, business details, line items, total paid, payment method.
PHPMailer delivers the receipt email to the customer's address on file, with the PDF attached and a download link for future reference.
Prerequisites
Before you start, make sure you have:
- A Xero organisation where you can access Advanced Settings → Connected Apps
- Access to developer.xero.com/myapps (free, separate from your Xero login)
- SMTP credentials for outgoing email — Gmail with an app password works well, or any transactional provider (SendGrid, Postmark, Mailgun)
- A server or hosting account where Receipt Rocket will run — PHP 8.0+ with Composer; cPanel works fine
- A publicly-reachable HTTPS URL (Xero will not deliver webhooks over HTTP)
Xero refuses to send webhooks to plain HTTP endpoints. If you're testing locally, use ngrok to tunnel a public HTTPS URL to your machine. On production, make sure your hosting has a valid SSL certificate.
Step-by-Step Setup
Deploy Receipt Rocket to your server
Upload the Receipt Rocket project folder to your hosting, then install dependencies:
# from the project root composer install # create the storage directories mkdir -p storage/logs storage/receipts database chmod -R 775 storage database
Point your web server's document root at the public/ folder. The app is self-contained — SQLite database, log files, and generated receipts all live inside the project folder, no external dependencies beyond PHP and SMTP.
Create a Xero developer app
Go to developer.xero.com/myapps and create a new app. Set the Redirect URI to:
https://your-domain.com/callback.php
Copy the Client ID and Client Secret — you'll drop these into the app's .env file in the next step.
Configure .env
Copy .env.example to .env and fill in your credentials. The three sections that matter:
# Xero XERO_CLIENT_ID=your-client-id XERO_CLIENT_SECRET=your-client-secret XERO_REDIRECT_URI=https://your-domain.com/callback.php XERO_WEBHOOK_KEY=set-this-after-step-5 # SMTP SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=you@yourcompany.com SMTP_PASS=your-app-password SMTP_FROM_NAME=Your Business Name # Business details (shown on the receipt) BUSINESS_NAME=Your Business Sdn Bhd BUSINESS_ADDRESS=123 Main St, Kuala Lumpur BUSINESS_EMAIL=info@yourcompany.com BUSINESS_PHONE=+60 3 0000 0000 BUSINESS_WEBSITE=https://yourcompany.com
Connect the app to Xero (OAuth)
Open your Receipt Rocket dashboard at https://your-domain.com/ and click Connect Xero. You'll be redirected to Xero to authorise the app — choose the organisation you want to send receipts from, accept the permissions, and Xero sends you back to the dashboard.
From this point on, Receipt Rocket has a refresh token and can read invoices on your behalf. You never need to log in again.
Register the webhook in Xero
Back in your Xero developer app, open Webhooks and set the delivery URL:
https://your-domain.com/webhook.php
Subscribe to the Invoices event type. Xero generates a webhook signing key — copy it into your .env as XERO_WEBHOOK_KEY, then click Send intent to receive. Receipt Rocket must respond with HTTP 200 within a few seconds for Xero to activate the webhook.
The Client ID/Secret authorise the app to read Xero data. The webhook signing key is used to verify that incoming webhook requests actually came from Xero and haven't been tampered with. Both must be set correctly for the pipeline to work.
Customise the receipt template
Two files control how your receipts look and read:
- templates/pdf/receipt.html — the PDF receipt itself (logo, layout, line items)
- templates/email/receipt.html — the covering email body
Both use simple {{VARIABLE}} placeholders that are replaced at send time — {{CUSTOMER_NAME}}, {{RECEIPT_NUMBER}}, {{AMOUNT_PAID}}, {{PAYMENT_DATE}}, and so on. Preview changes from the dashboard's Template Preview page before going live.
Test the full flow
The safest way to test is Xero's Demo Company — it's a sandbox org inside Xero with fake contacts and invoices. Connect Receipt Rocket to the Demo Company, then:
- Open any invoice in Xero and set the contact's email to your own address
- Mark the invoice as paid (or apply a payment)
- Watch the Receipt Rocket dashboard — you should see a new row in the Sent Receipts list within seconds
- Check your inbox for the branded PDF receipt
If something doesn't arrive, check storage/logs/app-YYYY-MM-DD.log — it logs every webhook received and every decision the app makes.
What Happens Once You Go Live
Flip your Receipt Rocket connection from the Demo Company to your production organisation, and the automation runs continuously — no cron, no scheduled tasks. Xero pushes webhooks in real time, so receipts land in customer inboxes within seconds of payment reconciliation.
Every Paid Invoice
Customer gets a branded PDF receipt email automatically — no matter how the invoice was paid
No Duplicates
The duplicate guard stops the same receipt being sent twice, even if Xero re-delivers a webhook
Audit Trail
Every sent receipt is saved to the dashboard and to storage/receipts/ for re-download
Fully Branded
Your logo, colours, address, and wording — not a generic Xero template
Token Auto-Refresh
OAuth refresh tokens rotate automatically — you don't reconnect every 30 days
Daily Log Files
Every decision and every send is logged so you can troubleshoot or audit later
Common Issues & Fixes
| Problem | Fix |
|---|---|
| Webhook not received | Confirm the webhook URL in Xero matches your APP_URL, and that the site is reachable over public HTTPS. |
| Signature mismatch (HTTP 401) | Check that XERO_WEBHOOK_KEY in .env matches the key in the Xero app dashboard exactly — no trailing spaces. |
| Token expired / disconnected | Click Reconnect Xero from the dashboard. Going forward the refresh token rotates automatically every 30 minutes. |
| Email not sending | For Gmail, use an App Password (not your login password) and confirm 2FA is enabled. For other providers, verify SMTP host/port/TLS are correct. |
| PDF is blank or missing fields | Check that all BUSINESS_* variables are set in .env — missing values break template rendering. |
| SQLite permission error | Run chmod -R 775 storage database on the server so the web user can write the database file and receipts. |
| Can't see what happened | Open storage/logs/app-YYYY-MM-DD.log — every webhook, every skip, every send is recorded with timestamps. |
Frequently Asked Questions
Does this work with multi-currency invoices? ▾
What if the customer doesn't have an email address in Xero? ▾
Can I send receipts only for certain invoices? ▾
Does it work with Stripe, GoCardless, or other payment gateways? ▾
Can I re-send a receipt that was already sent? ▾
How do I change the receipt's look and wording? ▾
Do I need to be a developer to run this? ▾
Xero Receipt Rocket is built and maintained by FusionETA — Malaysia's Xero Gold Partner. We can deploy, configure, and brand the app for your business in under a week. Get in touch to discuss.