How to Send Receipt & Invoice Emails
Send transactional receipt and invoice emails after a payment — HTML you own, delivery via Notify.
Receipt and invoice emails are transactional: a user paid, your backend knows the amount and line items, and you need that record in their inbox. Build the HTML (or plain text) in your app; Notify sends it.
Prerequisites
- Payment provider webhook or server-side confirmation (e.g. Stripe
checkout.session.completed) - API key from Credentials
- Verified domain for production
fromaddresses
Flow
- Confirm payment in your backend (never trust the client alone)
- Load order details (amount, currency, items, customer email)
- Render a receipt as HTML or text
POST https://notify.cx/api/email/send- Optionally store the Notify message id next to the order for support
Example send
async function sendReceiptEmail(order: {
email: string;
id: string;
totalFormatted: string;
itemsHtml: string;
}) {
const response = await fetch('https://notify.cx/api/email/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.NOTIFY_API_KEY!
},
body: JSON.stringify({
to: order.email,
subject: `Receipt for order ${order.id}`,
from: 'billing@your-verified-domain.com',
message: `
<h1>Thanks for your purchase</h1>
<p>Order <strong>${order.id}</strong></p>
<p>Total: <strong>${order.totalFormatted}</strong></p>
${order.itemsHtml}
<p>Questions? Reply to this email.</p>
`
})
});
if (!response.ok) {
throw new Error(await response.text());
}
return response.json();
}
Invoices vs receipts
| | Receipt | Invoice |
| --- | --- | --- |
| When | After successful payment | Often before/with payment terms |
| Content | What was paid | What is owed / was billed |
| Notify role | Same — deliver message | Same |
If you generate PDF invoices, attach them in your own stack or link to a signed download URL in the HTML. Notify’s send body is message (HTML or text); keep attachments in your app if you need them.
Idempotency
Payment webhooks can fire more than once. Gate the send on “receipt not yet sent” for that order.id so customers do not get duplicates.
Observe
- Dashboard logs for delivery
- Webhooks for bounce/complaint on Pro/Scale
- Correlate failures with the order id you put in the subject or body