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
Create an invoice from the Dashboard
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.
Create a customer via API (if needed)
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.
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);23const 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.
Add invoice items
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).
1// Add line items2await stripe.invoiceItems.create({3 customer: customer.id,4 amount: 50000, // $500.005 currency: 'usd',6 description: 'Website design — homepage and 3 subpages',7});89await stripe.invoiceItems.create({10 customer: customer.id,11 amount: 15000, // $150.0012 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.
Create and send the invoice
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.
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});89// Finalize the invoice (locks the line items)10const finalized = await stripe.invoices.finalizeInvoice(invoice.id);1112// Send the invoice email to the customer13const sent = await stripe.invoices.sendInvoice(invoice.id);1415console.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.
Track invoice payment status
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).
1const invoice = await stripe.invoices.retrieve('in_abc123');2console.log('Status:', invoice.status); // draft, open, paid, void, uncollectible3console.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
1require('dotenv').config();2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);34async function sendOneTimeInvoice({ email, name, items, daysUntilDue = 30, memo }) {5 // 1. Create or find customer6 let customer;7 const existing = await stripe.customers.list({ email, limit: 1 });89 if (existing.data.length > 0) {10 customer = existing.data[0];11 } else {12 customer = await stripe.customers.create({ email, name });13 }1415 // 2. Add invoice items16 for (const item of items) {17 await stripe.invoiceItems.create({18 customer: customer.id,19 amount: item.amount, // in cents20 currency: item.currency || 'usd',21 description: item.description,22 });23 }2425 // 3. Create invoice26 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 });3334 // 4. Finalize and send35 await stripe.invoices.finalizeInvoice(invoice.id);36 const sent = await stripe.invoices.sendInvoice(invoice.id);3738 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}4748// Example usage49sendOneTimeInvoice({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.
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.
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation