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 from addresses

Flow

  1. Confirm payment in your backend (never trust the client alone)
  2. Load order details (amount, currency, items, customer email)
  3. Render a receipt as HTML or text
  4. POST https://notify.cx/api/email/send
  5. 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

Where to next?