---
title: Create and send an invoice
subtitle: Build an example Invoicing integration.
route: /invoicing/integration/quickstart
---
# Create and send an invoice
Build an example Invoicing integration.
# Create and send an invoice
Build a full, working invoicing integration using Stripe Invoicing. Learn how to look up a customer, get a price from an object that represents a database, and create and send an invoice.
```
# Create and send an invoice
Create and send a Stripe-hosted invoice in minutes.
## Running the sample
1. Build the server
~~~
npm install
~~~
2. Run the server
~~~
npm start
~~~
1. Run the server
~~~
go run server.go
~~~
1. Build the server
~~~
pip3 install -r requirements.txt
~~~
2. Run the server
~~~
export FLASK_APP=server.py
python3 -m flask run --port=4242
~~~
1. Build the server
~~~
bundle install
~~~
2. Run the server
~~~
ruby server.rb -o 0.0.0.0
~~~
1. Build the server
~~~
composer install
~~~
2. Run the server
~~~
php -S 127.0.0.1:4242 --docroot=public
~~~
1. Build the server
~~~
dotnet build
~~~
2. Run the server
~~~
dotnet run
~~~
1. Build the server
~~~
mvn package
~~~
2. Run the server
~~~
java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
~~~
## Testing the webhook
Use the Stripe CLI to test your webhook locally. Download [the CLI](https://github.com/stripe/stripe-cli) and log in with your Stripe account. Alternatively, use a service like ngrok to make your local endpoint publicly accessible.
Set up event forwarding with the CLI to send all Stripe events in your *sandbox* to your local webhook endpoint.
~~~
stripe listen --forward-to localhost:4242/webhook.php
~~~
~~~
stripe listen --forward-to localhost:4242/webhook
~~~
Use the CLI to simulate specific events that test your webhook application logic by sending a POST request to your webhook endpoint with a mocked Stripe event object.
~~~
stripe trigger payment_intent.succeeded
~~~
```
### Install the Stripe Node library
Install the library:
```
npm install --save stripe
```
Initialize the Stripe library with your key:
### Install the Stripe Ruby library
Install the gem:
```
gem install stripe
```
Initialize the Stripe library with your key:
### Install the Stripe Java library
Add the following dependency to your POM and replace {VERSION} with the version number you want to use.
```
com.stripestripe-java{VERSION}
```
Initialize the Stripe library with your key:
### Install the Stripe Python package
Install the package via pip:
```
pip3 install stripe
```
Initialize the Stripe library with your key:
### Install the Stripe PHP library
Install the library:
```
composer require stripe/stripe-php
```
Initialize the Stripe library with your key:
### Set up your server
Make sure to initialize with Go Modules:
```
go get -u github.com/stripe/stripe-go/v82
```
Initialize the Stripe library with your key:
### Install the Stripe.net library
Install the library:
```
dotnet add package Stripe.net
```
Initialize the Stripe library with your key:
### Install the Stripe libraries
Install the libraries:
```
npm install --save stripe @stripe/stripe-js next
```
Initialize the Stripe library with your key:
### Manage Products, Prices, and Customers
First, create a price for your product in the [Dashboard](https://docs.stripe.com/invoicing/products-prices.md) or through the [API](https://docs.stripe.com/api/prices/create.md). After you create a price and associate it with a product, store its ID in your database.
Next, look up a [Customer](https://docs.stripe.com/api/customers.md) in your database by [email](https://docs.stripe.com/api/customers/object.md?lang=dotnet#customer_object-email). If that customer doesn’t exist, create the `Customer` and store their ID for future purchases. The next step, for example, uses the [id](https://docs.stripe.com/api/customers/object.md#customer_object-id) of [Customer object](https://docs.stripe.com/api/customers/object.md) to create an invoice.
The `Customer` object represents the customer purchasing your product. It’s required for creating an invoice.
### Create an Empty Invoice
Set the [collection_method](https://docs.stripe.com/api/invoices/object.md#invoice_object-collection_method) attribute to `send_invoice`. For Stripe to mark an invoice as past due, you must add the [days_until_due](https://docs.stripe.com/api/invoices/create.md#create_invoice-days_until_due) parameter. When you send an invoice, Stripe emails the invoice to the customer with payment instructions.
The other available collection method is `charge_automatically`. When charging automatically, Stripe attempts to immediately pay the invoice using the default source that’s attached to the customer. Here, we use `send_invoice` to prevent an immediate, undesired customer charge.
### Create an Invoice Item
Create an invoice item by passing in the customer `id`, product `price`, and invoice ID `invoice`.
The maximum number of invoice items is 250.
If invoice items are created before an invoice is created, set the [pending_invoice_items_behavior](https://docs.stripe.com/api/invoices/create.md#create_invoice-pending_invoice_items_behavior) to `include` when creating the invoice so that all pending invoice items are automatically added to the invoice. In this case, only add invoice items to a single customer at a time to avoid adding them to the wrong customer.
Creating an invoice adds up to 250 pending invoice items with the remainder to be added on the next invoice. To see your customer’s pending invoice items, see the **Customer details** page or set the [pending](https://docs.stripe.com/api/invoiceitems/list.md#list_invoiceitems-pending) attribute to `true` when you use the API to list all of the invoice items.
Send the invoice to the email address associated with the customer. As soon as you send an invoice, Stripe finalizes it. Many jurisdictions consider finalized invoices a legal document making certain fields unalterable. If you send invoices that have already been paid, there’s no reference to the payment in the email.
With any finalized invoice, you can either download and send a [PDF](https://docs.stripe.com/api/invoices/object.md#invoice_object-invoice_pdf) or [link](https://docs.stripe.com/api/invoices/object.md#invoice_object-hosted_invoice_url) to the associated [Hosted Invoice Page](https://docs.stripe.com/invoicing/hosted-invoice-page.md).
## Congratulations!
You’ve created and sent your first invoice. Take your integration further and learn how to quickly automate tax collection through the API.
### Automate tax collection
Calculate and collect the right amount of tax on your Stripe transactions. Learn more about [Stripe Tax](https://docs.stripe.com/tax.md), and how to [activate it](https://dashboard.stripe.com/tax) in the Dashboard before you integrate it.
### Add the automatic tax parameter
Set the `automatic_tax` parameter to `enabled: true`.
```javascript
const stripe = require('stripe')('<>');
// You probably have a database to keep track of preexisting customers.
// But to keep things simple, we'll use an Object to store Stripe object IDs in this example.
const CUSTOMERS = [{stripeId: "cus_123456789", email: "jenny.rosen@example.com"}];
// Prices on Stripe model the pricing scheme of your business.
// Create Prices in the Dashboard or with the API before accepting payments
// and store the IDs in your database.
const PRICES = {basic: "price_123456789", professional: "price_987654321"};
const sendInvoice = async function (email) {
// Look up a customer in your database
let customer = CUSTOMERS.find(c => c.email === email);
let customerId;
if (!customer) {
// Create a new Customer
customer = await stripe.customers.create({
email,
description: 'Customer to invoice',
});
// Store the Customer ID in your database to use for future purchases
CUSTOMERS.push({stripeId: customer.id, email: email});
customerId = customer.id;
} else {
// Read the Customer ID from your database
customerId = customer.stripeId;
}
// Create an Invoice
const invoice = await stripe.invoices.create({
customer: customerId,
collection_method: 'send_invoice',
days_until_due: 30,
automatic_tax: {enabled: true},
});
// Create an Invoice Item with the Price, and Customer you want to charge
const invoiceItem = await stripe.invoiceItems.create({
customer: customerId,
price: PRICES.basic,
invoice: invoice.id
});
// Send the Invoice
await stripe.invoices.sendInvoice(invoice.id);
};
```
```json
{
"name": "stripe-sample",
"version": "1.0.0",
"description": "A sample Stripe implementation",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "stripe-samples",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"stripe": "^18.0.0"
}
}
{
"name": "stripe-sample",
"version": "0.1.0",
"dependencies": {
"@stripe/react-stripe-js": "^1.0.0",
"@stripe/stripe-js": "^1.0.0",
"express": "^4.17.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "^3.4.0",
"stripe": "^18.0.0"
},
"devDependencies": {
"concurrently": "4.1.2"
},
"homepage": "http://localhost:3000/checkout",
"proxy": "http://localhost:4242",
"scripts": {
"start-client": "react-scripts start",
"start-server": "node server.js",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"start": "concurrently \"yarn start-client\" \"yarn start-server\""
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
```
```javascript
const stripe = require('stripe')('<>');
// Replace this endpoint secret with your endpoint's unique secret
// If you are testing with the CLI, find the secret by running 'stripe listen'
// If you are using an endpoint defined with the API or dashboard, look in your webhook settings
// at https://dashboard.stripe.com/webhooks
const endpointSecret = 'whsec_...';
const express = require('express');
const app = express();
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
let event = request.body;
// Only verify the event if you have an endpoint secret defined.
// Otherwise use the basic event deserialized with JSON.parse
if (endpointSecret) {
// Get the signature sent by Stripe
const signature = request.headers['stripe-signature'];
try {
event = stripe.webhooks.constructEvent(
request.body,
signature,
endpointSecret
);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`, err.message);
return response.sendStatus(400);
}
}
// Handle the event
switch (event.type) {
default:
// Unexpected event type
console.log(`Unhandled event type ${event.type}.`);
}
// Return a 200 response to acknowledge receipt of the event
response.send();
});
app.listen(4242, () => console.log('Running on port 4242'));
```
```ruby
require 'stripe'
Stripe.api_key = '<>'
# You probably have a database to keep track of preexisting customers.
# But to keep things simple, we'll use an Object to store Stripe object IDs in this example.
$CUSTOMERS = [{ stripeId: 'cus_123456789', email: 'jenny.rosen@example.com' }]
# Prices on Stripe model the pricing scheme of your business.
# Create Prices in the Dashboard or with the API before accepting payments
# and store the IDs in your database.
$PRICES = { basic: 'price_123456', professional: 'price_456789' }
def send_invoice(email)
# Look up a customer in your database
customer = $CUSTOMERS.find { |customer_obj| customer_obj[:email] == email }
customer_id = nil
if !customer
# Create a new Customer
customer = Stripe::Customer.create({
email: email,
description: 'Customer to invoice'
})
# Store the Customer ID in your database to use for future purchases
$CUSTOMERS << { stripeId: customer.id, email: email }
customer_id = customer.id
else
# Read the Customer ID from your database
customer_id = customer[:stripeId]
end
# Create an Invoice
invoice = Stripe::Invoice.create({
customer: customer_id,
collection_method: 'send_invoice',
days_until_due: 30,
automatic_tax: {
enabled: true
},
})
# Create an Invoice Item
invoice_item = Stripe::InvoiceItem.create({
customer: customer_id,
price: $PRICES[:basic],
invoice: invoice.id
})
# Send the Invoice
Stripe::Invoice.send_invoice(invoice[:id])
end
```
```
source 'https://rubygems.org/'
gem 'sinatra'
gem 'stripe'
```
```ruby
require 'sinatra'
require 'json'
require 'stripe'
Stripe.api_key = '<>'
# Replace this endpoint secret with your endpoint's unique secret
# If you are testing with the CLI, find the secret by running 'stripe listen'
# If you are using an endpoint defined with the API or dashboard, look in your webhook settings
# at https://dashboard.stripe.com/webhooks
endpoint_secret = 'whsec_...';
set :port, 4242
post '/webhook' do
payload = request.body.read
event = nil
begin
event = Stripe::Event.construct_from(
JSON.parse(payload, symbolize_names: true)
)
rescue JSON::ParserError => e
# Invalid payload
puts "⚠️ Webhook error while parsing basic request. #{e.message}"
status 400
return
end
# Check if webhook signing is configured.
if endpoint_secret
# Retrieve the event by verifying the signature using the raw body and secret.
signature = request.env['HTTP_STRIPE_SIGNATURE'];
begin
event = Stripe::Webhook.construct_event(
payload, signature, endpoint_secret
)
rescue Stripe::SignatureVerificationError => e
puts "⚠️ Webhook signature verification failed. #{e.message}"
status 400
end
end
# Handle the event
case event.type
else
puts "Unhandled event type: #{event.type}"
end
# Return a 200 response to acknowledge receipt of the event
status 200
end
```
```python
\#! /usr/bin/env python3.6
# Python 3.6 or newer required.
import stripe
stripe.api_key = '<>'
# You probably have a database to keep track of preexisting customers
# But to keep things simple, we'll use an Object to store Stripe object IDs in this example.
CUSTOMERS = [{"stripe_id": "cus_123456789", "email": "jenny.rosen@example.com"}]
# Prices in Stripe model the pricing scheme of your business.
# Create Prices in the Dashboard or with the API before accepting payments
# and store the IDs in your database.
PRICES = {"basic": "price_123456789", "professional": "price_987654321"}
def send_invoice(email):
# Look up a customer in your database
customers = [c for c in CUSTOMERS if c["email"] == email]
if customers:
customer_id=customers[0]["stripe_id"]
else:
# Create a new Customer
customer = stripe.Customer.create(
email=email, # Use your email address for testing purposes
description="Customer to invoice",
)
# Store the customer ID in your database for future purchases
CUSTOMERS.append({"stripe_id": customer.id, "email": email})
# Read the Customer ID from your database
customer_id = customer.id
# Create an Invoice
invoice = stripe.Invoice.create(
customer=customer_id,
collection_method='send_invoice',
days_until_due=30,
automatic_tax={ 'enabled': True },
)
# Create an Invoice Item with the Price and Customer you want to charge
stripe.InvoiceItem.create(
customer=customer_id,
price=PRICES["basic"],
invoice=invoice.id
)
# Send the Invoice
stripe.Invoice.send_invoice(invoice.id)
return
```
```
certifi==2021.5.30
chardet==4.0.0
Click==8.0.1
Flask==2.0.1
idna==3.2
itsdangerous==2.0.1
Jinja2==3.0.1
MarkupSafe==2.0.1
requests==2.26.0
stripe==12.0.0
toml==0.10.2
Werkzeug==2.0.1
```
```python
\#! /usr/bin/env python3.6
# Python 3.6 or newer required.
import json
import os
import stripe
stripe.api_key = '<>'
# Replace this endpoint secret with your endpoint's unique secret
# If you are testing with the CLI, find the secret by running 'stripe listen'
# If you are using an endpoint defined with the API or dashboard, look in your webhook settings
# at https://dashboard.stripe.com/webhooks
endpoint_secret = 'whsec_...'
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
event = None
payload = request.data
try:
event = json.loads(payload)
except json.decoder.JSONDecodeError as e:
print('⚠️ Webhook error while parsing basic request.' + str(e))
return jsonify(success=False)
if endpoint_secret:
# Only verify the event if there is an endpoint secret defined
# Otherwise use the basic event deserialized with json
sig_header = request.headers.get('stripe-signature')
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except stripe.error.SignatureVerificationError as e:
print('⚠️ Webhook signature verification failed.' + str(e))
return jsonify(success=False)
# Handle the event
else:
# Unexpected event type
print('Unhandled event type {}'.format(event['type']))
return jsonify(success=True)
```
```php
'cus_123456789',
'email' => 'jenny.rosen@example.com'
],
];
// Prices on Stripe model the pricing scheme of your business.
// Create Prices in the Dashboard or with the API before accepting payments
// and store the IDs in your database.
$PRICES = [
'basic' => 'price_123456789',
'professional' => 'price_987654321',
];
function sendInvoice($email) {
// Look up a customer in your database
global $CUSTOMERS;
global $PRICES;
$customerId = null;
$customers = array_filter($CUSTOMERS, function ($customer) use ($email) {
return $customer['email'] === $email;
});
if (!$customers) {
// Create a new Customer
$customer = \Stripe\Customer::create([
'email' => $email,
'description' => 'Customer to invoice',
]);
// Store the Customer ID in your database to use for future purchases
$CUSTOMERS[] = [
'stripeId' => $customer->id,
'email' => $email
];
$customerId = $customer->id;
}
else {
// Read the Customer ID from your database
$customerId = $customers[0]['stripeId'];
}
// Create an Invoice
$invoice = \Stripe\Invoice::create([
'customer' => $customerId,
'collection_method' => 'send_invoice',
'days_until_due' => 30,
'automatic_tax' => [
'enabled' => true,
],
]);
// Create an Invoice Item with the Price, and Customer you want to charge
$invoiceItem = \Stripe\InvoiceItem::create([
'customer' => $customerId,
'price' => $PRICES['basic'],
'invoice' => $invoice->id
]);
// Send the Invoice
$invoice->sendInvoice();
}
```
```php
>';
```
```json
{
"require": {
"stripe/stripe-php": "^17.0"
}
}
```
```php
type) {
// Unexpected event type
error_log('Received unknown event type');
}
http_response_code(200);
```
```csharp
using Stripe;
using System;
namespace InvoicingSample
{
// You probably have a database to keep track of preexisting customers.
// But to keep things simple, we'll use an Object to store Stripe object IDs in this example.
public class MyCustomer
{
public string StripeId { get; set; }
public string Email { get; set; }
}
class Program
{
// You probably have a database to keep track of preexisting customers.
// But to keep things simple, we'll use an Object to store Stripe object IDs in this example.
private static List Customers { get; set; } = new List();
// Prices on Stripe model the pricing scheme of your business.
// Create Prices in the Dashboard or with the API before accepting payments
// and store the IDs in your database.
private static Dictionary Prices { get; set; } = new Dictionary();
public static void Main(string[] args)
{
StripeConfiguration.ApiKey = "<>";
// Add a Customer
Customers.Add(new MyCustomer()
{
StripeId = "cus_123456789",
Email = "jenny.rosen@example.com"
});
Prices.Add("basic", "price_123456");
Prices.Add("professional", "price_456789");
}
public static void sendInvoice(String email)
{
// Look up a customer in your database
var customer = Customers.Find(customer => customer.Email == email);
String customerId;
if(customer == null) {
// Create a new Customer
var customerOptions = new CustomerCreateOptions
{
Email = email,
Description = "Customer to invoice",
};
var customerService = new CustomerService();
var stripeCustomer = customerService.Create(customerOptions);
customerId = stripeCustomer.Id;
// Store the Customer ID in your database to use for future purchases
Customers.Add(new MyCustomer()
{
StripeId = stripeCustomer.Id,
Email = stripeCustomer.Email,
});
} else {
// Read the Customer ID from your database
customerId = customer.StripeId;
}
// Create an Invoice
var invoiceOptions = new InvoiceCreateOptions
{
Customer = customerId,
CollectionMethod = "send_invoice",
DaysUntilDue = 30,
AutomaticTax = new InvoiceAutomaticTaxOptions
{
Enabled = true,
},
};
var invoiceService = new InvoiceService();
var invoice = invoiceService.Create(invoiceOptions);
// Create an Invoice Item with the Price, and Customer you want to charge
var invoiceItemOptions = new InvoiceItemCreateOptions
{
Customer = customerId,
Price = Prices["basic"],
Invoice = invoice.Id
};
var invoiceItemService = new InvoiceItemService();
invoiceItemService.Create(invoiceItemOptions);
// Send the Invoice
invoiceService.SendInvoice(invoice.Id);
}
}
}
```
```
net8.0StripeExampleMajor
```
```csharp
using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using Stripe;
namespace StripeExample
{
public class Program
{
public static void Main(string[] args)
{
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://0.0.0.0:4242")
.UseWebRoot("public")
.UseStartup()
.Build()
.Run();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
StripeConfiguration.ApiKey = "<>";
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
}
[Route("webhook")]
[ApiController]
public class WebhookController : Controller
{
[HttpPost]
public async Task Index()
{
var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
const string endpointSecret = "whsec_...";
try
{
var stripeEvent = EventUtility.ParseEvent(json);
var signatureHeader = Request.Headers["Stripe-Signature"];
stripeEvent = EventUtility.ConstructEvent(json,
signatureHeader, endpointSecret);
switch (stripeEvent.Type)
{
// If on SDK version < 46, use class Events instead of EventTypes
default:
Console.WriteLine("Unhandled event type: {0}", stripeEvent.Type);
break;
}
return Ok();
}
catch (StripeException e)
{
Console.WriteLine("Error: {0}", e.Message);
return BadRequest();
}
catch (Exception e)
{
return StatusCode(500);
}
}
}
}
```
```go
package main
import (
"github.com/stripe/stripe-go/v82"
"github.com/stripe/stripe-go/v82/customer"
"github.com/stripe/stripe-go/v82/invoice"
"github.com/stripe/stripe-go/v82/invoiceitem"
)
type MyCustomer struct {
StripeId string
Email string
}
type MyPrice struct {
StripeId string
Tier string
}
func sendInvoice(email string) {
stripe.Key = "<>"
// You probably have a database to keep track of preexisting customers.
// But to keep things simple, we'll hardcode a list of fake customers.
customers := []MyCustomer{
{
StripeId: "cus_123456789",
Email: "jenny.rosen@example.com",
},
}
// Prices on Stripe model the pricing scheme of your business.
// Create Prices in the Dashboard or with the API before accepting payments
// and store the IDs in your database.
prices := []MyPrice{
{
Tier: "basic",
StripeId: "price_123456789",
},
{
Tier: "professional",
StripeId: "price_987654321",
},
}
customerID := ""
// Look up a customer in your database
for _, x := range customers {
if x.Email == email {
customerID = x.StripeId
break
}
}
if customerID == "" {
params := &stripe.CustomerParams{
Email: stripe.String("jenny.rosen@example.com"),
Description: stripe.String("Customer to invoice"),
}
cus, _ := customer.New(params)
newCus := MyCustomer{
Email: email,
StripeId: cus.ID,
}
customers = append(customers, newCus)
customerID = cus.ID
}
// Look up the Price ID from your database
var priceID string
for _, y := range prices {
if y.Tier == "basic" {
priceID = y.StripeId
break
}
}
// Create an Invoice
inParams := &stripe.InvoiceParams{
Customer: stripe.String(customerID),
CollectionMethod: stripe.String("send_invoice"),
DaysUntilDue: stripe.Int64(30),
AutomaticTax: &stripe.CheckoutSessionAutomaticTaxParams{Enabled: stripe.Bool(true)},
}
in, _ := invoice.New(inParams)
// Create an Invoice Item with the Price, and Customer you want to charge
iiParams := &stripe.InvoiceItemParams{
Customer: stripe.String(customerID),
Price: stripe.String(priceID),
Invoice: stripe.String(in.ID)
}
invoiceitem.New(iiParams)
// Send the Invoice
params := &stripe.InvoiceSendInvoiceParams{}
invoice.SendInvoice(in.ID, params)
}
func main() {
// Call sendInvoice somewhere in your codebase to send an email to a customer
}
```
```
module stripe.com/docs/payments
go 1.13
require github.com/stripe/stripe-go/v82 v82.0.0
```
```go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"github.com/stripe/stripe-go/v82"
"github.com/stripe/stripe-go/v82/webhook"
)
func main() {
stripe.Key = "<>"
http.HandleFunc("/webhook", handleWebhook)
addr := "localhost:4242"
log.Printf("Listening on %s", addr)
log.Fatal(http.ListenAndServe(addr, nil))
}
func handleWebhook(w http.ResponseWriter, req *http.Request) {
const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable)
return
}
event := stripe.Event{}
if err := json.Unmarshal(payload, &event); err != nil {
fmt.Fprintf(os.Stderr, "⚠️ Webhook error while parsing basic request. %v\n", err.Error())
w.WriteHeader(http.StatusBadRequest)
return
}
// Replace this endpoint secret with your endpoint's unique secret
// If you are testing with the CLI, find the secret by running 'stripe listen'
// If you are using an endpoint defined with the API or dashboard, look in your webhook settings
// at https://dashboard.stripe.com/webhooks
endpointSecret := "whsec_..."
signatureHeader := req.Header.Get("Stripe-Signature")
event, err = webhook.ConstructEvent(payload, signatureHeader, endpointSecret)
if err != nil {
fmt.Fprintf(os.Stderr, "⚠️ Webhook signature verification failed. %v\n", err)
w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
return
}
// Unmarshal the event data into an appropriate struct depending on its Type
switch event.Type {
w.WriteHeader(http.StatusOK)
}
```
```java
package com.stripe.sample;
import java.util.ArrayList;
import static spark.Spark.post;
import static spark.Spark.port;
import com.google.gson.JsonSyntaxException;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.StripeObject;
import com.stripe.model.Customer;
import com.stripe.model.Price;
import com.stripe.model.Invoice;
import com.stripe.model.InvoiceItem;
import com.stripe.param.CustomerCreateParams;
import com.stripe.param.InvoiceItemCreateParams;
import com.stripe.param.InvoiceSendInvoiceParams;
import com.stripe.param.InvoiceCreateParams;
public class Server {
public static class MyCustomer {
private String stripeId;
private String email;
public MyCustomer(String stripeId, String email) {
this.stripeId = stripeId;
this.email = email;
}
public String getStripeId() {
return this.stripeId;
}
public String getEmail() {
return this.email;
}
}
public static class MyPrice {
private String stripeId;
private String tier;
public MyPrice(String stripeId, String tier) {
this.stripeId = stripeId;
this.tier = tier;
}
public String getStripeId() {
return this.stripeId;
}
public String getTier() {
return this.tier;
}
}
// You probably have a database to keep track of preexisting customers.
// But to keep things simple, we'll use an fake dataset to store Stripe object IDs in this example.
public static ArrayList customers = new ArrayList();
// Prices on Stripe model the pricing scheme of your business.
// Create Prices in the Dashboard or with the API before accepting payments
// and store the IDs in your database.
public static ArrayList prices = new ArrayList();
public static void main(String[] args) {
Stripe.apiKey = "<>";
// Simulate data in the DB
customers.add(new MyCustomer("cus_123456789", "jenny.rosen@example.com"));
prices.add(new MyPrice("price_123456", "basic"));
prices.add(new MyPrice("price_789123", "professional"));
}
static void sendInvoice(String email) {
Customer stripeCustomer;
// Look up a customer in your database
String customerId = null;
for (MyCustomer c : customers) {
if (c.getEmail().equals(email)) {
customerId = c.getStripeId();
}
}
// Create a new Customer
if(customerId == null) {
CustomerCreateParams params =
CustomerCreateParams
.builder()
.setEmail(email)
.setDescription("Customer to invoice")
.build();
try {
// Store the Customer ID in your database to use for future purchases
stripeCustomer = Customer.create(params);
customers.add(new MyCustomer(stripeCustomer.getId(), email));
customerId = stripeCustomer.getId();
} catch(StripeException e) {
System.out.println(e.getMessage());
}
}
try {
// Create an Invoice
InvoiceCreateParams invoiceParams =
InvoiceCreateParams
.builder()
.setCustomer(customerId)
.setCollectionMethod(InvoiceCreateParams.CollectionMethod.SEND_INVOICE)
.setDaysUntilDue(30L)
.setAutomaticTax(
InvoiceCreateParams.AutomaticTax.builder().setEnabled(true).build()
)
.build();
Invoice invoice = Invoice.create(invoiceParams);
// Look up the Price ID from your database
String priceId = null;
for (MyPrice p : prices) {
if (p.getTier().equals("basic")) {
priceId = p.getStripeId();
}
}
// Create an Invoice Item with the Price and Customer you want to charge
InvoiceItemCreateParams invoiceItemParams =
InvoiceItemCreateParams.builder()
.setCustomer(customerId)
.setPrice(priceId)
.setInvoice(invoice.getId())
.build();
try {
InvoiceItem.create(invoiceItemParams);
} catch(StripeException e) {
System.out.println(e.getMessage());
}
// Send an Invoice
InvoiceSendInvoiceParams params = InvoiceSendInvoiceParams.builder().build();
invoice.sendInvoice(params);
} catch(StripeException e) {
System.out.println(e.getMessage());
}
}
}
```
```xml
4.0.0com.stripe.samplestripe-payment1.0.0-SNAPSHOTorg.slf4jslf4j-simple2.0.3com.sparkjavaspark-core2.9.4com.google.code.gsongson2.9.1org.projectlomboklombok1.18.20providedcom.stripestripe-java29.0.0sampleorg.apache.maven.pluginsmaven-compiler-plugin3.10.11.81.8maven-assembly-pluginpackagesinglejar-with-dependenciesServer
```
```java
package com.stripe.sample;
import static spark.Spark.post;
import static spark.Spark.port;
import com.google.gson.JsonSyntaxException;
import com.stripe.Stripe;
import com.stripe.model.StripeObject;
import com.stripe.net.ApiResource;
import com.stripe.net.Webhook;
import com.stripe.model.Event;
import com.stripe.model.EventDataObjectDeserializer;
import com.stripe.exception.SignatureVerificationException;
import com.stripe.model.PaymentIntent;
import com.stripe.model.PaymentMethod;
public class Server {
public static void main(String[] args) {
port(4242);
Stripe.apiKey = "<>";
// Replace this endpoint secret with your endpoint's unique secret
// If you are testing with the CLI, find the secret by running 'stripe listen'
// If you are using an endpoint defined with the API or dashboard, look in your webhook settings
// at https://dashboard.stripe.com/webhooks
String endpointSecret = "whsec_...";
post("/webhook", (request, response) -> {
String payload = request.body();
Event event = null;
try {
event = ApiResource.GSON.fromJson(payload, Event.class);
} catch (JsonSyntaxException e) {
// Invalid payload
System.out.println("⚠️ Webhook error while parsing basic request.");
response.status(400);
return "";
}
String sigHeader = request.headers("Stripe-Signature");
if(endpointSecret != null && sigHeader != null) {
// Only verify the event if you have an endpoint secret defined.
// Otherwise use the basic event deserialized with GSON.
try {
event = Webhook.constructEvent(
payload, sigHeader, endpointSecret
);
} catch (SignatureVerificationException e) {
// Invalid signature
System.out.println("⚠️ Webhook error while validating signature.");
response.status(400);
return "";
}
}
// Deserialize the nested object inside the event
EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
StripeObject stripeObject = null;
if (dataObjectDeserializer.getObject().isPresent()) {
stripeObject = dataObjectDeserializer.getObject().get();
} else {
// Deserialization failed, probably due to an API version mismatch.
// Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
// instructions on how to handle this case, or return an error here.
}
// Handle the event
switch (event.getType()) {
default:
System.out.println("Unhandled event type: " + event.getType());
break;
}
response.status(200);
return "";
});
}
}
```
## See Also
#### [Use incoming webhooks to get real-time updates](https://docs.stripe.com/webhooks.md)
Listen for events on your Stripe account so your integration can automatically trigger reactions.
#### [Customize invoices](https://docs.stripe.com/invoicing/customize.md)
You can use the [Invoice template](https://dashboard.stripe.com/account/billing/invoice) to customize the content of an invoice. You can also set a customer preferred language and include public information in your [account details](https://dashboard.stripe.com/settings/account/?support_details=true).
#### [Invoicing API](https://docs.stripe.com/api/invoices.md)
Learn more about the Invoicing API.
#### [Stripe CLI](https://docs.stripe.com/stripe-cli.md)
The Stripe CLI has several commands that can help you test your Stripe application beyond invoicing.