SnapPDFSnapPDF
integration · dev · live

SnapPDF + Stripe

Post-payment webhook → auto-generate and compress invoices.

Every SaaS team that charges customers on Stripe hits the same wall: Stripe's default PDF invoices are functional but bland. The SnapPDF + Stripe integration listens for payment events, pulls Stripe's invoice, merges your branded cover + terms, applies watermarks or PAID stamps, compresses for email delivery, and fires the customer email. It replaces 200 lines of glue code with one Stripe webhook handler template we ship out of the box.

What you can build

  • Listen to `invoice.paid`, `invoice.finalized`, `charge.refunded`, `checkout.session.completed`.
  • Merge Stripe's auto-generated invoice with your cover page, terms, and receipt PDFs.
  • Stamp PAID / REFUNDED / OVERDUE based on event type.
  • Compress to <1MB for Gmail-safe attachment delivery.
  • Emit a SnapPDF webhook on completion so downstream services (Resend, SES, HubSpot) can finalize.

Setup

  1. 01
    Configure Stripe webhook
    Stripe dashboard → Developers → Webhooks → Add endpoint. URL: `https://api.snappdf.dev/api/v1/webhooks/stripe` (or your own handler).
  2. 02
    Select events
    Pick `invoice.paid`, `invoice.finalized`, `charge.refunded`, `checkout.session.completed`. Fewer events = less quota burn.
  3. 03
    Copy the webhook signing secret
    Stripe shows the `whsec_…` signing secret. Paste it into SnapPDF dashboard → Integrations → Stripe.
  4. 04
    Configure the flow
    SnapPDF dashboard → Stripe flow editor. Pick: merge with cover? apply watermark? compress? email via Resend?
  5. 05
    Link your Stripe account (optional)
    Use Stripe Connect to let SnapPDF read invoice PDFs directly — avoids needing you to provide a URL.
  6. 06
    Test with Stripe CLI
    `stripe trigger invoice.paid` against your endpoint. Verify the final PDF lands in the test customer's inbox.

Code example

Raw Stripe webhook handler wiring — what the integration does under the hood.

import Stripe from 'stripe';
import { SnapPDF } from '@snappdf/sdk';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const snap = new SnapPDF({ apiKey: process.env.SNAPPDF_KEY! });

export async function POST(req: Request) {
  const sig = req.headers.get('stripe-signature')!;
  const event = stripe.webhooks.constructEvent(
    await req.text(),
    sig,
    process.env.STRIPE_WEBHOOK_SECRET!,
  );

  if (event.type !== 'invoice.paid') return new Response('ok');
  const inv = event.data.object as Stripe.Invoice;

  const { pdf: merged } = await snap.pdf.merge({
    files: [inv.invoice_pdf!, 'https://cdn.acme.com/legal/terms.pdf'],
  });
  const { pdf: stamped } = await snap.pdf.watermark({
    file: merged, kind: 'text', text: 'PAID',
    position: 'diagonal', opacity: 0.18, color: '#0f766e',
  });
  const { pdf: small } = await snap.pdf.compress({ file: stamped, level: 'high' });

  await resend.emails.send({
    to: inv.customer_email!,
    from: 'billing@acme.com',
    subject: `Invoice ${inv.number} — Paid`,
    attachments: [{ filename: `${inv.number}.pdf`, content: small }],
  });

  return new Response('ok');
}

Known limits

  • · Stripe webhook delivery has a 30s timeout — long OCR must be routed to async.
  • · Stripe Connect flows must set `Stripe-Account` header on each API call; our integration handles this automatically.

Pricing notes

Stripe integration free on every plan; invoice-volume ops are billed normally. High-volume shops usually sit on Business ($299/mo).

Available from the Free plan.

FAQ

Does this replace Stripe Invoices entirely?

No — we build on top of Stripe's canonical invoice PDF. You still get Stripe's tax calc, line-item logic, and legal-name formatting; we just layer your brand and policies on top.

What about refunds?

Configure a separate flow for `charge.refunded` — typically stamp REFUNDED and re-send the receipt.

Stripe Tax / VAT compliance?

Stripe's PDF is the legal record. We preserve it as-is and wrap additional pages around it. The stamped version remains legally equivalent in most jurisdictions; consult your counsel.

How does this interact with Stripe Connect?

Connected accounts can have their own SnapPDF flows. We scope the flow to the Stripe account ID.

Multi-currency?

All ops are currency-agnostic — we operate on the PDF bytes Stripe gives us.

Start freeRead the quickstart

Related integrations