Invoices

Receive notifications when invoices are created, updated, paid, failed, or require payment action.

Overview

Invoice webhooks notify your application about the lifecycle of invoices. Use these events to track billing activity, notify customers about payments, handle failed charges, and build automated billing workflows.


Use Cases

  • Notify customers when a new invoice is generated
  • Send payment confirmation emails on successful charges
  • Trigger dunning workflows when payments fail
  • Alert customers when payment action (e.g. 3D Secure) is required
  • Build dashboards to track billing metrics and revenue
  • Send advance notice to customers about upcoming invoices

Events

EventDescription
invoice.createdA new invoice was generated
invoice.updatedAn invoice was updated (e.g. status change, payment applied)
invoice.upcomingAn invoice will be generated soon for an upcoming billing cycle
invoice.payment_succeededPayment was successfully collected for an invoice
invoice.payment_failedPayment collection failed for an invoice
invoice.payment_action_requiredCustomer action is required to complete payment (e.g. 3D Secure authentication)

invoice.created

Triggered When

  • A subscription is created and its first invoice is generated
  • A subscription renews and a new billing cycle invoice is created
  • An invoice is manually created via the API or dashboard

Payload

{
  "type": "invoice.created",
  "id": "evt_HAg8TfEfmhE55hZ3ot6kZ7d2",
  "created": 1676984809,
  "data": {
    "object": {
      "object": "invoice",
      "id": 2947310,
      "address_billing": null,
      "address_shipping": null,
      "amount_due": 3500,
      "amount_paid": 0,
      "amount_remaining": 3500,
      "auto_advance": true,
      "billing": "send_invoice",
      "billing_address": null,
      "billing_reason": "subscription_create",
      "charge_id": null,
      "created": "2023-02-21T13:06:47.000000Z",
      "currency": "cad",
      "customer": {
        "object": "customer",
        "id": 8194391,
        "balance": 0,
        "created": "2023-02-20T13:44:08.000000Z",
        "currency": "cad",
        "default_source": null,
        "delinquent": false,
        "display_name": null,
        "email": "[email protected]",
        "email_confirm": null,
        "email_hardbounce": false,
        "first_name": "John",
        "has_password": 0,
        "language": null,
        "last_login_method": null,
        "last_name": "Doe",
        "metadata": null,
        "object_id": "cus_NOMNc5o5JjBPUi",
        "organization": null,
        "password_last_updated_at": null,
        "phone": null,
        "phone_confirm": null,
        "salutation": null,
        "site_ids": [775],
        "title": null,
        "username": null
      },
      "customer_address": null,
      "customer_shipping": null,
      "days_to_creation": 7,
      "default_tax_rates": null,
      "deleted_at": null,
      "discount_id": null,
      "ending_balance": 0,
      "finalized_at": "2023-02-21T13:06:47.000000Z",
      "hosted_invoice_url": null,
      "invoice_pdf": "https://www.pelcro.com/pdf/invoice/eyJpdiI6Ik...",
      "is_imported": null,
      "lines": {
        "object": "list",
        "data": [
          {
            "object": "line_item",
            "id": 3408896,
            "amount": 3500,
            "created_at": "2023-02-21T13:06:48.000000Z",
            "currency": "cad",
            "deleted_at": null,
            "description": "1 x Monthly Plan (at $35.00 / month)",
            "metadata": null,
            "object_id": null,
            "period": {
              "end": 1677589606,
              "start": 1676984806
            },
            "quantity": 1,
            "subscription": {
              "object": "subscription",
              "id": 2896258,
              "billing": "send_invoice",
              "cancel_at_period_end": 0,
              "canceled_at": null,
              "created": "2023-02-21T13:06:46.000000Z",
              "current_period_start": "2023-02-21T13:06:46.000000Z",
              "current_period_end": "2023-02-28T13:06:46.000000Z",
              "plan": { "..." : "..." }
            },
            "tax_amounts": null,
            "tax_rates": null,
            "updated_at": "2023-02-21T13:06:48.000000Z"
          }
        ]
      },
      "marked_uncollectible_at": null,
      "number": "3D68210F-0006",
      "object_id": null,
      "paid_at": null,
      "payment_link": "https://www.pelcro.com/invoice/payment/eyJpdiI6Ik...",
      "period_end": "2023-02-21T13:06:46.000000Z",
      "period_start": "2023-02-21T13:06:46.000000Z",
      "plan": {
        "id": 374852,
        "nickname": "Monthly Plan",
        "interval": "month"
      },
      "post_payment_credit_notes_amount": 0,
      "pre_payment_credit_notes_amount": 0,
      "product": {
        "id": 4857,
        "name": "Premium Subscription",
        "name_internal": null,
        "description": null,
        "entitlements": null,
        "type": "service"
      },
      "purchase_order": null,
      "site_id": 775,
      "source": null,
      "starting_balance": 0,
      "status": "open",
      "subscription_id": 2896258,
      "subtotal": 3500,
      "tax": null,
      "tax_percent": null,
      "total": 3500,
      "total_tax_amounts": null,
      "updated_at": "2023-02-21T13:06:49.000000Z",
      "voided_at": null
    }
  }
}

invoice.updated

Triggered When

  • An invoice's status changes (e.g. from open to paid)
  • Invoice fields are modified (e.g. amount adjustments, metadata changes)

Payload

{
  "type": "invoice.updated",
  "id": "evt_Kp9xMfEfmhE55hZ3ot6kZ7d3",
  "created": 1676984900,
  "data": {
    "object": {
      "object": "invoice",
      "id": 2947310,
      "amount_due": 3500,
      "amount_paid": 3500,
      "amount_remaining": 0,
      "status": "paid",
      "...": "Same structure as invoice.created"
    },
    "previous_attributes": {
      "amount_paid": 0,
      "amount_remaining": 3500,
      "status": "open"
    }
  }
}

Note: The previous_attributes object contains only the fields that changed, showing their values before the update. Only fields listed in the invoice's publishable attributes are included.


invoice.upcoming

Triggered When

  • A subscription's billing cycle is approaching and an invoice will be generated soon
  • The number of days before the invoice is created is determined by the plan's invoice_upcoming_notification setting or the account-level invoice_upcoming_notification_days setting

Payload

{
  "type": "invoice.upcoming",
  "id": "evt_Rq7xNgGhmjF66iA4pt7lA8e4",
  "created": 1676900000,
  "data": {
    "object": {
      "object": "invoice",
      "id": null,
      "amount_due": 3500,
      "amount_paid": 0,
      "amount_remaining": 3500,
      "currency": "cad",
      "customer": {
        "object": "customer",
        "id": 8194391,
        "...": "Full customer object"
      },
      "days_to_creation": 7,
      "plan": {
        "id": 374852,
        "nickname": "Monthly Plan",
        "interval": "month"
      },
      "product": {
        "id": 4857,
        "name": "Premium Subscription",
        "name_internal": null,
        "description": null,
        "entitlements": null,
        "type": "service"
      },
      "status": null,
      "subscription_id": 2896258,
      "...": "Same structure as invoice.created"
    }
  }
}

Note: The invoice.upcoming event represents a preview of the upcoming invoice. The invoice id may be null since the invoice has not been created yet. The days_to_creation field indicates how many days until the invoice will be generated.


invoice.payment_succeeded

Triggered When

  • Payment is successfully collected for an invoice
  • The invoice status transitions to paid

Payload

{
  "type": "invoice.payment_succeeded",
  "id": "evt_Xt5yPqHinlG77jB5qu8mB9f5",
  "created": 1676985000,
  "data": {
    "object": {
      "object": "invoice",
      "id": 2947310,
      "amount_due": 3500,
      "amount_paid": 3500,
      "amount_remaining": 0,
      "charge": {
        "id": 1234567,
        "offline": false,
        "payment_category": "card",
        "reference": null
      },
      "paid_at": "2023-02-21T13:10:00.000000Z",
      "status": "paid",
      "source": {
        "object": "source",
        "id": 567890,
        "brand": "Visa",
        "country": "US",
        "exp_month": 12,
        "exp_year": 2025,
        "last_four": "4242",
        "type": "card"
      },
      "...": "Same structure as invoice.created"
    },
    "previous_attributes": {
      "amount_paid": 0,
      "amount_remaining": 3500,
      "status": "open"
    }
  }
}

Note: The previous_attributes object is automatically detected from model changes. It contains the invoice fields that changed during the payment process, with their previous values. The charge and source objects are included when a payment method was used.


invoice.payment_failed

Triggered When

  • An attempt to collect payment for an invoice fails
  • Common causes include insufficient funds, expired cards, or declined transactions

Payload

{
  "type": "invoice.payment_failed",
  "id": "evt_Zu6zRsJjomH88kC6rv9nC0g6",
  "created": 1676985100,
  "data": {
    "object": {
      "object": "invoice",
      "id": 2947310,
      "amount_due": 3500,
      "amount_paid": 0,
      "amount_remaining": 3500,
      "status": "open",
      "...": "Same structure as invoice.created"
    },
    "previous_attributes": {
      "status": "open"
    }
  }
}

Note: The previous_attributes object is automatically detected from model changes. If no publishable fields changed during the failed payment attempt, previous_attributes will be an empty object.


invoice.payment_action_required

Triggered When

  • Payment requires additional customer action to complete (e.g. 3D Secure authentication, bank redirect)
  • The payment gateway returns a requires_action status

Payload

{
  "type": "invoice.payment_action_required",
  "id": "evt_Av7ARtKkpnI99lD7sw0oD1h7",
  "created": 1676985200,
  "data": {
    "object": {
      "object": "invoice",
      "id": 2947310,
      "amount_due": 3500,
      "amount_paid": 0,
      "amount_remaining": 3500,
      "hosted_invoice_url": null,
      "status": "open",
      "...": "Same structure as invoice.created"
    }
  }
}

Note: This event does not include previous_attributes. Use the payment_link to redirect the customer to complete the required payment action.


Payload Fields

All invoice events share the same core payload structure under data.object. Fields are sorted alphabetically with object and id prepended.

Invoice Object

FieldTypeDescription
objectstringAlways "invoice"
idintegerThe invoice ID
address_billingobject | nullDefault billing address (nested Address object)
address_shippingobject | nullShipping address from subscription (nested Address object)
amount_dueintegerAmount in cents that is owed on this invoice
amount_paidintegerAmount in cents that has been paid
amount_remainingintegerAmount in cents remaining to be paid
auto_advancebooleanWhether the invoice will automatically advance to the next status
billingstring | integerCollection method ("charge_automatically" or "send_invoice")
billing_addressobject | nullLegacy billing address (deprecated, use address_billing)
billing_reasonstring | nullReason the invoice was created (e.g. "subscription_create", "subscription_cycle")
chargeobject | nullAssociated charge details (present when a payment was attempted)
charge_idinteger | nullAssociated charge ID
couponobject | nullApplied coupon details (when a discount is applied)
createdstringTimestamp when the invoice was created
currencystringThree-letter ISO currency code (e.g. "usd", "cad")
customerobject | nullCustomer who owns this invoice (nested Customer object)
customer_addressobject | nullCustomer's address at the time of invoicing
customer_shippingobject | nullCustomer's shipping information at the time of invoicing
days_to_creationinteger | nullDays until the invoice will be created (for upcoming invoices)
default_tax_ratesobject | nullDefault tax rates applied to the invoice
deleted_atstring | nullTimestamp when the invoice was deleted (soft delete)
discount_idinteger | nullApplied discount ID
ending_balanceintegerCustomer's ending balance after the invoice is finalized
finalized_atstring | nullTimestamp when the invoice was finalized
hosted_invoice_urlstring | nullURL for an externally-hosted invoice page (null for Pelcro billing engine accounts)
invoice_pdfstringURL to download the invoice PDF
is_importedboolean | nullWhether the invoice was imported from an external system
linesobject | nullInvoice line items (nested list of Line Item objects)
marked_uncollectible_atstring | nullTimestamp when the invoice was marked uncollectible
numberstring | nullUnique invoice number
object_idstring | nullExternal identifier (null for Pelcro billing engine accounts)
orderobject | nullAssociated order details (for e-commerce invoices)
paid_atstring | nullTimestamp when the invoice was paid
payment_linkstringURL for the Pelcro-hosted payment page (only for open/past-due invoices)
period_endstringEnd of the billing period covered by the invoice
period_startstringStart of the billing period covered by the invoice
planobjectAssociated plan details (id, nickname, interval)
post_payment_credit_notes_amountintegerTotal amount of credit notes issued after payment
pre_payment_credit_notes_amountintegerTotal amount of credit notes issued before payment
productobjectAssociated product details (id, name, name_internal, description, entitlements, type)
purchase_orderstring | nullPurchase order number
site_idintegerSite ID where the invoice was created
sourceobject | nullPayment source used (nested Source object)
starting_balanceintegerCustomer's starting balance before the invoice
statusstringInvoice status (see Invoice Statuses below)
subscription_idinteger | nullAssociated subscription ID
subtotalintegerSubtotal in cents before tax and discounts
taxinteger | nullTotal tax amount in cents
tax_percentnumber | nullTax percentage applied
totalintegerTotal amount in cents
total_tax_amountsobject | nullBreakdown of tax amounts by rate
updated_atstringTimestamp when the invoice was last updated
voided_atstring | nullTimestamp when the invoice was voided

Line Item Object

Each line item in the lines.data array contains:

FieldTypeDescription
objectstringAlways "line_item"
idintegerLine item ID
amountintegerAmount in cents for this line item
created_atstringTimestamp when the line item was created
currencystringThree-letter ISO currency code
descriptionstring | nullDescription of the line item
metadataobject | nullAdditional metadata
object_idstring | nullExternal identifier (null for Pelcro billing engine accounts)
periodobjectBilling period (start and end as unix timestamps)
quantityintegerQuantity of items
subscriptionobject | nullNested subscription object
tax_amountsobject | nullTax amounts for this line item
tax_ratesobject | nullTax rates applied to this line item

Charge Object

When a payment was attempted, the charge object includes:

FieldTypeDescription
idintegerCharge ID
offlinebooleanWhether this was an offline payment
payment_categorystringPayment method category (e.g. "card", "bank")
referencestring | nullExternal payment reference

Invoice Statuses

StatusDescription
draftInvoice is a draft and not yet finalized
openInvoice is finalized and awaiting payment
paidInvoice has been paid in full
uncollectibleInvoice has been marked as uncollectible
voidInvoice has been voided

Events with Previous Attributes

The following events include a previous_attributes object showing changed field values before the update:

EventHow Previous Attributes Are Determined
invoice.updatedPassed explicitly from the domain event — contains the previous values of changed publishable fields
invoice.payment_succeededAuto-detected from model changes via getChanges() — filtered to publishable fields only
invoice.payment_failedAuto-detected from model changes via getChanges() — filtered to publishable fields only

Events without previous_attributes: invoice.created, invoice.upcoming, invoice.payment_action_required.


Invoice Lifecycle

The typical lifecycle of an invoice follows one of these sequences:

Successful payment (charge automatically):

  1. invoice.created - Invoice generated
  2. invoice.payment_succeeded - Payment collected
  3. invoice.updated - Status changed to paid

Successful payment (send invoice):

  1. invoice.upcoming - Advance notice of upcoming invoice
  2. invoice.created - Invoice generated and sent
  3. invoice.payment_succeeded - Customer pays the invoice
  4. invoice.updated - Status changed to paid

Failed payment:

  1. invoice.created - Invoice generated
  2. invoice.payment_failed - Payment attempt failed
  3. invoice.updated - Status may change (e.g. to uncollectible)

Payment requiring action (3D Secure):

  1. invoice.created - Invoice generated
  2. invoice.payment_action_required - Customer must complete authentication
  3. invoice.payment_succeeded - Payment completed after authentication
  4. invoice.updated - Status changed to paid