Skip to main content
The PayPal Invoicing API lets you create, send, and manage professional invoices directly from your applications. By integrating this REST-based API, you can automate your billing workflows, provide a seamless payment experience for your customers, and maintain detailed transaction records. This guide walks you through integrating PayPal’s Invoicing capabilities, enabling you to:
  • Create customized invoices with flexible payment terms
  • Automatically send invoices to customers
  • Support partial payments and tips
  • Track payment status in real-time
  • Reduce manual billing processes

Prerequisites

Complete the steps in Get started with PayPal REST APIs to obtain:
  • Your personal and business sandbox accounts.
  • Your access token.
  • Your sandbox business email for the Invoicer API object address.
This integration uses the Invoicing REST API.
You can test calls to the Invoicing API with the Get an access token tool or you can use Postman to explore.
See the following steps to create, review, and send your invoice using the Invoicing API.

1. Create a draft invoice

Copy and modify the following sample code to draft an invoice. This sample request creates an invoice with the following details:
  • Sender: David Larusso. Includes address, email, and phone number.
  • Recipient: Stephanie Meyers. Includes address, email, and phone number.
  • Items: One $50 yoga mat and one $10 t-shirt.
  • Minimum partial payment: $20.
  • Tip option: Enabled.
  • Packing charge: $10. Includes sales tax.
  • Shipping charge: $10. Includes sales tax.
  • Discount: 5%.

Sample request

curl -v -X POST 'https://api-m.sandbox.paypal.com/v2/invoicing/invoices' \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Bearer ACCESS-TOKEN' \
 -d '{
          "detail": {
            "invoice_number": "123",
            "reference": "deal-ref",
            "invoice_date": "2028-11-22",
            "currency_code": "USD",
            "note": "Thank you for your business.",
            "term": "No refunds after 30 days.",
            "memo": "This is a long contract",
            "payment_term": {
              "term_type": "DUE_ON_DATE_SPECIFIED",
              "due_date": "2028-11-22"
            }
          },
          "invoicer": {
            "name": {
              "given_name": "David",
              "surname": "Larusso"
            },
            "address": {
              "address_line_1": "1234 First Street",
              "address_line_2": "337673 Hillside Court",
              "admin_area_2": "Anytown",
              "admin_area_1": "CA",
              "postal_code": "98765",
              "country_code": "US"
            },
            "email_address": "merchant@example.com",
            "phones": [
              {
                "country_code": "001",
                "national_number": "4085551234",
                "phone_type": "MOBILE"
              }
            ],
            "website": "https://example.com",
            "tax_id": "XX-XXXXXXX",
            "logo_url": "https://example.com/logo.PNG",
            "additional_notes": "example note"
          },
          "primary_recipients": [
            {
              "billing_info": {
                "name": {
                  "given_name": "Stephanie",
                  "surname": "Meyers"
                },
                "address": {
                  "address_line_1": "1234 Main Street",
                  "admin_area_2": "Anytown",
                  "admin_area_1": "CA",
                  "postal_code": "98765",
                  "country_code": "US"
                },
                "email_address": "payer@example.com",
                "phones": [
                  {
                    "country_code": "001",
                    "national_number": "4884551234",
                    "phone_type": "HOME"
                  }
                ],
                "additional_info_value": "add-info"
              },
              "shipping_info": {
                "name": {
                  "given_name": "Stephanie",
                  "surname": "Meyers"
                },
                "address": {
                  "address_line_1": "1234 Main Street",
                  "admin_area_2": "Anytown",
                  "admin_area_1": "CA",
                  "postal_code": "98765",
                  "country_code": "US"
                }
              }
            }
          ],
          "items": [
            {
              "name": "Yoga mat",
              "description": "Elastic mat to practice yoga.",
              "quantity": "1",
              "unit_amount": {
                "currency_code": "USD",
                "value": "50.00"
              },
              "tax": {
                "name": "Sales Tax",
                "percent": "7.25"
              },
              "discount": {
                "percent": "5"
              },
              "unit_of_measure": "QUANTITY"
            },
            {
              "name": "Yoga t-shirt",
              "quantity": "1",
              "unit_amount": {
                "currency_code": "USD",
                "value": "10.00"
              },
              "tax": {
                "name": "Sales Tax",
                "percent": "7.25"
              },
              "discount": {
                "amount": {
                  "currency_code": "USD",
                  "value": "5.00"
                }
              },
              "unit_of_measure": "QUANTITY"
            }
          ],
          "configuration": {
            "partial_payment": {
              "allow_partial_payment": true,
              "minimum_amount_due": {
                "currency_code": "USD",
                "value": "20.00"
              }
            },
            "allow_tip": true,
            "tax_calculated_after_discount": true,
            "tax_inclusive": false,
            "template_id": ""
          },
          "amount": {
            "breakdown": {
              "custom": {
                "label": "Packing Charges",
                "amount": {
                  "currency_code": "USD",
                  "value": "10.00"
                }
              },
              "shipping": {
                "amount": {
                  "currency_code": "USD",
                  "value": "10.00"
                },
                "tax": {
                  "name": "Sales Tax",
                  "percent": "7.25"
                }
              },
              "discount": {
                "invoice_discount": {
                  "percent": "5"
                }
              }
            }
          }
        }'

Sample response

    {
          "rel": "self",
          "href": "https://api-m.sandbox.paypal.com/v2/invoicing/invoices/INVOICE-ID",
          "method": "GET"
      }

Modify the code

Update the following values:
  • Replace ACCESS-TOKEN with your access token.
  • Update merchant@example.com in invoicer: email_address to your sandbox business account email. Ensure it matches the sandbox account linked to your access token. Use your live PayPal business email in production.
  • Replace payer@example.com in primary_recipients: email_address with a sandbox personal account email.
  • Change invoice_date and due_date to a current or future date in YYYY-MM-DD format. If you specify a term_type, ensure the due date falls within the term.
  • Optionally, customize other invoice parameters to fit your needs.
A successful request returns:
  • An invoice in your sandbox business account with a Draft status. You can verify this by logging into your sandbox account.
  • An HTTP status code 201 Created.
  • A JSON response containing the invoice ID. In the sample response, the ID is INV2-W44B-KRGF-JM6R-26VU.
Use this ID to perform other REST API actions like editing, deleting, or sending payment reminders.

2. Send the invoice

Copy and modify the following sample code to send the invoice.

Sample request

curl -v -X POST 'https://api-m.sandbox.paypal.com/v2/invoicing/invoices/INVOICE-ID/send' \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Bearer ACCESS-TOKEN' \
 -d '{
        "send_to_invoicer": true
      }'

Sample response

{
          "rel": "self",
          "href": "https://api-m.sandbox.paypal.com/v2/invoicing/invoices/INVOICE-ID",
          "method": "GET"
      }

Modify the code

Update the following values:
  • Replace ACCESS-TOKEN with your access token.
  • Replace INVOICE-ID with the invoice ID returned when you created the invoice.
A successful request returns:
  • HTTP status code 200 OK.
  • A JSON response with invoice details.
The invoice status changes to Unpaid (Sent) in your sandbox business account, and PayPal sends the invoice by email if you enable email notifications in the send request body. PayPal tracks payments that users make with the Pay Now button. For offline payments, such as checks or wire transfers, record the payment manually in your account.
I