Skip to main content
RapidDev - Software Development Agency
stripe-guide

How to send one-time invoices in Stripe

Send one-time invoices in Stripe through the Dashboard (Billing → Invoices → Create invoice) or the API by creating an invoice item, then creating and sending the invoice. The customer receives an email with a payment link. You can set due dates, add line items, attach metadata, and collect payment automatically. All amounts are in cents.

What you'll learn

  • How to create one-time invoices from the Stripe Dashboard
  • How to create and send invoices via the API
  • How to add line items, due dates, and descriptions
  • How to track invoice payment status
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner5 min read15 minutesStripe API v2024-12+, Node.js 18+March 2026RapidDev Engineering Team
TL;DR

Send one-time invoices in Stripe through the Dashboard (Billing → Invoices → Create invoice) or the API by creating an invoice item, then creating and sending the invoice. The customer receives an email with a payment link. You can set due dates, add line items, attach metadata, and collect payment automatically. All amounts are in cents.

Sending One-Time Invoices in Stripe

Stripe invoices aren't just for subscriptions — you can send one-time invoices for project work, consulting fees, custom orders, or any ad-hoc payment. The invoice includes a payment link so your customer can pay online with a card or other payment method. You can create invoices manually through the Dashboard or programmatically via the API for automated billing flows.

Prerequisites

  • A Stripe account in test mode
  • A customer created in Stripe (or their email address)
  • Node.js 18+ for API examples

Step-by-step guide

1

Create an invoice from the Dashboard

Go to Stripe Dashboard → Billing → Invoices → Create invoice. Select an existing customer or enter a new email address. Add line items with descriptions and amounts. Set the due date, memo, and footer. Click 'Review invoice' then 'Send invoice'. The customer receives an email with a payment link.

Expected result: An invoice is created and emailed to the customer with a hosted payment page.

2

Create a customer via API (if needed)

If the customer doesn't exist in Stripe yet, create one first. You need a customer object before you can attach invoice items.

typescript
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2
3const customer = await stripe.customers.create({
4 email: 'client@example.com',
5 name: 'Jane Smith',
6 metadata: { project: 'Website Redesign' },
7});

Expected result: A new customer is created in Stripe with an ID like cus_abc123.

3

Add invoice items

Create one or more invoice items attached to the customer. These will appear as line items on the invoice. Amounts are in cents (2000 = $20.00).

typescript
1// Add line items
2await stripe.invoiceItems.create({
3 customer: customer.id,
4 amount: 50000, // $500.00
5 currency: 'usd',
6 description: 'Website design — homepage and 3 subpages',
7});
8
9await stripe.invoiceItems.create({
10 customer: customer.id,
11 amount: 15000, // $150.00
12 currency: 'usd',
13 description: 'Logo design and branding package',
14});

Expected result: Two invoice items are created and attached to the customer, ready to be bundled into an invoice.

4

Create and send the invoice

Create the invoice object, which automatically includes all pending invoice items for the customer. Set the due date and any optional fields, then send it.

typescript
1const invoice = await stripe.invoices.create({
2 customer: customer.id,
3 collection_method: 'send_invoice',
4 days_until_due: 30,
5 description: 'Website redesign project — Phase 1',
6 footer: 'Thank you for your business!',
7});
8
9// Finalize the invoice (locks the line items)
10const finalized = await stripe.invoices.finalizeInvoice(invoice.id);
11
12// Send the invoice email to the customer
13const sent = await stripe.invoices.sendInvoice(invoice.id);
14
15console.log('Invoice sent:', sent.hosted_invoice_url);

Expected result: The invoice is finalized and emailed to the customer. They receive a payment link where they can pay online.

5

Track invoice payment status

Monitor the invoice status via the Dashboard or API. Invoices go through these statuses: draft → open (sent) → paid (or void/uncollectible).

typescript
1const invoice = await stripe.invoices.retrieve('in_abc123');
2console.log('Status:', invoice.status); // draft, open, paid, void, uncollectible
3console.log('Amount due:', invoice.amount_due / 100);
4console.log('Amount paid:', invoice.amount_paid / 100);

Expected result: You can check whether the invoice has been paid, is still open, or needs follow-up.

Complete working example

send-invoice.js
1require('dotenv').config();
2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
3
4async function sendOneTimeInvoice({ email, name, items, daysUntilDue = 30, memo }) {
5 // 1. Create or find customer
6 let customer;
7 const existing = await stripe.customers.list({ email, limit: 1 });
8
9 if (existing.data.length > 0) {
10 customer = existing.data[0];
11 } else {
12 customer = await stripe.customers.create({ email, name });
13 }
14
15 // 2. Add invoice items
16 for (const item of items) {
17 await stripe.invoiceItems.create({
18 customer: customer.id,
19 amount: item.amount, // in cents
20 currency: item.currency || 'usd',
21 description: item.description,
22 });
23 }
24
25 // 3. Create invoice
26 const invoice = await stripe.invoices.create({
27 customer: customer.id,
28 collection_method: 'send_invoice',
29 days_until_due: daysUntilDue,
30 description: memo || '',
31 footer: 'Thank you for your business!',
32 });
33
34 // 4. Finalize and send
35 await stripe.invoices.finalizeInvoice(invoice.id);
36 const sent = await stripe.invoices.sendInvoice(invoice.id);
37
38 return {
39 id: sent.id,
40 number: sent.number,
41 amount_due: sent.amount_due,
42 hosted_url: sent.hosted_invoice_url,
43 pdf_url: sent.invoice_pdf,
44 status: sent.status,
45 };
46}
47
48// Example usage
49sendOneTimeInvoice({
50 email: 'client@example.com',
51 name: 'Jane Smith',
52 items: [
53 { amount: 50000, description: 'Website design — homepage + 3 pages' },
54 { amount: 15000, description: 'Logo design package' },
55 ],
56 daysUntilDue: 30,
57 memo: 'Website redesign project — Phase 1',
58}).then(result => {
59 console.log('Invoice sent:', result);
60}).catch(console.error);

Common mistakes when sending one-time invoices in Stripe

Why it's a problem: Forgetting to finalize the invoice before sending

How to avoid: Call stripe.invoices.finalizeInvoice(id) before sendInvoice(). Sending a draft invoice will throw an error.

Why it's a problem: Using amounts in dollars instead of cents

How to avoid: All Stripe amounts are in the smallest currency unit. For USD, pass 5000 for $50.00. For JPY, pass the full amount (no conversion needed).

Why it's a problem: Using collection_method: 'charge_automatically' when you want the customer to pay manually

How to avoid: Use 'send_invoice' for invoices where the customer pays via the hosted link. 'charge_automatically' immediately charges the card on file.

Why it's a problem: Creating invoice items without a customer

How to avoid: Invoice items must be attached to a customer. Create the customer first, then create invoice items with the customer ID.

Best practices

  • Use descriptive line item descriptions so customers know exactly what they're paying for
  • Set a reasonable due date — 15 or 30 days is standard for most businesses
  • Include a professional memo and footer on your invoices
  • Use metadata to track internal references like project IDs or PO numbers
  • Monitor invoice.payment_succeeded webhooks to trigger fulfillment automatically
  • Send reminders for unpaid invoices using Stripe's built-in reminder settings
  • Test the full invoice flow in test mode using the 4242424242424242 card

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Write a Node.js function that creates a one-time Stripe invoice for a customer. Accept email, name, line items with amounts and descriptions, and due date. Create the customer if they don't exist, add invoice items, create the invoice with send_invoice collection method, finalize it, and send it. Return the invoice URL and PDF link.

Stripe Prompt

Build a Stripe one-time invoice sender in Node.js. Create or find a customer by email, add multiple line items, create an invoice with a configurable due date, finalize and send it, and return the hosted URL and PDF URL.

Frequently asked questions

Can I send a Stripe invoice without a subscription?

Yes. One-time invoices work independently of subscriptions. Create invoice items for the customer, then create and send the invoice. The customer pays via a hosted payment page.

How does the customer pay a one-time invoice?

The customer receives an email with a link to a Stripe-hosted payment page. They can pay with a credit card, debit card, or other enabled payment methods. No Stripe account is needed.

Can I auto-charge a customer's card instead of sending an invoice?

Yes. Set collection_method to 'charge_automatically' instead of 'send_invoice'. This charges the customer's default payment method immediately when the invoice is finalized.

How do I add tax to a one-time invoice?

Use Stripe Tax or add tax rates manually. When creating invoice items, you can attach a tax_rates array. Or enable Stripe Tax in Dashboard → Settings → Tax to calculate automatically.

Can I edit an invoice after sending it?

No. Once finalized and sent, invoices are immutable. You can void the invoice and create a new one, or issue a credit note for partial adjustments.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.