Paying Invoices via API
Process invoice payments programmatically with payment allocations
Invoice payments connect transactions to invoices, automatically reducing the invoice balance and updating its status. The Payload API uses payment allocations to link transactions to invoices, enabling full payments, partial payments, and even split payments across multiple invoices in a single transaction. You can also record external payments made outside the platform for complete invoice tracking.
Invoice payments require an unpaid invoice with a balance due. The payer's payment method will
be charged, and the amount will be allocated to reduce the invoice balance. Successful
payments transition invoices from unpaid to partially_paid or paid status based on the
amount.
Prerequisites
Before paying invoices, ensure you have:
Create invoices
Invoices must exist and be in unpaid or partially_paid status to receive payments.
Set up payment methods
Configure payment methods for the payer account to charge for invoice payments.
When to Pay Invoices via API
Programmatic invoice payments are ideal for automated billing and integration scenarios.
Benefits of API payments
- Automation: Process invoice payments automatically based on business logic
- Batch Processing: Pay multiple invoices in a single transaction
- Partial Payments: Accept installment payments toward large invoices
- Payment Allocation: Split a single payment across multiple invoices
- Custom Workflows: Integrate with internal systems and approval processes
Common use cases
- Subscription Billing: Automatically charge invoices on due dates
- Account Receivables: Process customer payments as they arrive
- Payment Plans: Accept partial payments on installment schedules
- Bulk Processing: Pay multiple outstanding invoices at once
- External Payments: Record check or wire payments in the system
- Integration: Connect to accounting or ERP systems
- Customer Self-Service: Build payment portals and applications
Payment Allocations: Every invoice payment creates a payment allocation that links the transaction to the invoice. Allocations track the amount applied, enable partial payments, and support splitting payments across multiple invoices.
Paying an Invoice in Full
Process a complete payment for an invoice's remaining balance.
This payment transaction includes:
-
type: 'payment'to indicate a payment transaction -
amountmatching the invoice'sbalance_due -
payer.account_ididentifying who is making the payment -
payer.method_idspecifying which payment method to charge -
invoice_allocationsarray linking this payment to the invoice
The payment allocation contains:
-
invoice_idreferencing the invoice being paid -
amountspecifying how much to apply to this invoice
What happens:
- Payment method is charged for the specified amount
- Transaction is created and processed
- Payment allocation links transaction to invoice
- Invoice balance is reduced by the payment amount
- Invoice status updates to
paid(if balance reaches zero)
Check Before Paying: Always retrieve the invoice first to check its current status and
balance_due. This prevents attempting to pay already-paid invoices and ensures you charge
the correct amount.
Understanding Payment Allocations
Payment allocations are the mechanism that connects transactions to invoices.
What are payment allocations?
A payment allocation represents a portion of a transaction's amount being applied to a specific invoice. Each allocation contains:
{
invoice_id: "inv_abc123", // Which invoice receives this payment
amount: 149.00, // How much to apply to this invoice
transaction_id: "txn_xyz", // Which transaction provided the funds (auto-set)
external_payment: false // Whether payment was made outside Payload
}How allocations work
When you create a payment transaction with invoice_allocations:
- Transaction processes - Payment method is charged
- Allocations created - One allocation per invoice in the array
- Invoice updated - Balance is reduced by allocation amount
- Status changes - Invoice moves to
partially_paidorpaid
Allocation rules
- Amount validation: Allocation amount cannot exceed invoice's
balance_due - Multiple allocations: One transaction can have many allocations
- Same payer: All invoices must belong to the same payer account
- Total must match: Sum of allocation amounts must equal transaction amount
- Immutable: Allocations cannot be modified after creation
Viewing allocations
Allocations are automatically included when retrieving invoices:
invoice = pl.Invoice.get("inv_abc123")
# View all payments applied to this invoice
for allocation in invoice.payments:
print("Amount:", allocation.amount)
print("Transaction:", allocation.transaction_id)
print("Date:", allocation.created_at)
print("External?:", allocation.external_payment)Making Partial Payments
Accept installment payments or partial amounts toward an invoice balance.
Partial payment behavior:
- Invoice status becomes
partially_paid(notpaid) -
totals.paidincreases by the payment amount -
totals.balance_duedecreases by the payment amount - Additional payments can be made until balance reaches zero
- Each payment creates a new allocation in the invoice's
paymentsarray
Use cases for partial payments:
- Payment plans and installment billing
- Deposits and progressive payments
- Customer cash flow management
- Milestone-based payments
- Split payments from multiple payment methods
Balance Tracking: After a partial payment, always check invoice.totals.balance_due for
the remaining amount. Don't rely on the original total as multiple partial payments may have
been applied.
Paying Multiple Invoices
Process a single payment transaction that pays several invoices at once.
Multiple invoice allocation rules:
- All invoices must belong to the same payer account
- Transaction
amountmust equal sum of all allocation amounts - Each invoice receives its allocated portion
- Invoices update independently based on their allocations
- One invoice can be paid in full while another receives partial payment
Benefits of batched payments:
- Reduce payment processing fees (single transaction vs multiple)
- Simplify customer experience (one charge vs many)
- Improve reconciliation (one transaction to track)
- Better for customer statement clarity
Common scenarios:
- Paying all outstanding invoices for a customer
- Monthly account settlement
- Bulk invoice processing
- Account balance clearance
Mixed Status Results: After a multi-invoice payment, some invoices may be paid while
others remain partially_paid depending on their balances and allocation amounts. Check each
invoice individually after payment.
Using Default Payment Methods
Charge a customer's default payment method without specifying method_id.
Auto-selecting payment methods
If you don't specify payer.method_id, Payload will attempt to use the payer account's default
payment method:
transaction = pl.Transaction.create(
type="payment",
amount=149.0,
sender={
"account_id": "acct_customer123",
# No method_id specified - uses default
},
invoice_allocations=[{"invoice_id": "inv_abc123", "amount": 149.0}]
)Default payment method behavior
- Has default: Transaction uses the default method automatically
- No default: Transaction will fail with an error
- Method invalid: Transaction fails if default method is expired or invalid
- Autopay: Default method is used for automatic invoice payments
Setting default payment methods
Make a payment method the default for an account:
payment_method = pl.PaymentMethod.get("pm_card_789")
payment_method.update(
account_defaults={
"paying": "payments"
}
)Validation Required: Always ensure the payer has a valid default payment method before
relying on auto-selection. Check the account's payment methods or specify method_id
explicitly for critical payments.
Handling Payment Errors
Implement proper error handling for failed invoice payments.
Common payment failures
invoice = pl.Invoice.get("inv_abc123")
try:
transaction = pl.Transaction.create(
type="payment",
amount=invoice.totals["balance_due"],
sender={
"account_id": invoice.payer["account_id"],
"method_id": "pm_card_789"
},
invoice_allocations=[{"invoice_id": invoice.id, "amount": invoice.totals["balance_due"]}]
)
print("Payment successful:", transaction.id)
except Exception as error:
print("Payment failed:", error)
# Handle payment failures
# - Notify customer of payment failure
# - Request different payment method
# - Suggest partial payment if applicable
# - Log error for investigation
# - Implement retry logic for transient failuresInvoice validation errors
- Invoice already paid: Check
status !== 'paid'before payment - Invalid allocation amount: Cannot exceed
balance_due - Invoice in draft: Cannot pay draft invoices
- Invoice closed: Cannot pay closed invoices
Payment method issues
- Card expired: Update payment method before attempting payment
- Insufficient funds: Suggest partial payment or different card
- Payment declined: Request alternative payment method
- Method not found: Verify
method_idexists for payer
Schema Reference
The following fields are available for invoice payments:
Transaction Payment Fields
typepayment, deposit, withdraw, refund, payoutamountsenderaccountAccountaccount_id ID of Account^acct_[A-Za-z0-9]+$methodPaymentMethodmethod_id ID of PaymentMethod^pm_[A-Za-z0-9]+$Payment Allocation Fields
invoice_id ID of Invoice^inv_[A-Za-z0-9]+$amounttransaction_id ID of Transaction^txn_[A-Za-z0-9]+$external_paymentattrsInvoice Payment Status
When payments are applied, invoices transition through these statuses:
statusdraft, open, unpaid, partially_paid, paid, closed, synctotalsbalance_duepaidsubtotaltaxtotalNext Steps
Enhance your billing workflow with automated payment collection
Automate Payment Collection
Configure autopay for recurring billing with Automatic Payments to charge invoices automatically on their due date, create hosted payment pages for customers with Payment Portal for self-service payment management, and send payment request links with Payment Links for customer-initiated payments.
Manage Invoice Workflow
Track invoice progress with Invoice Statuses to understand the complete invoice lifecycle from draft through paid, automate workflows with payment events using Webhook Events for real-time payment notifications, and monitor payment processing with Transaction Status to track payment completion and failures.
Handle Payment Scenarios
Accept installment payments with Partial Payments for large invoices and payment plans, process multiple payments at once with Bulk Payments for batch payment processing, and record offline payments with External Payments for check and wire transfers.
Related articles
- Creating Invoices - Build invoices with line items
- Transactions API - Process payments via API
- Payment Methods - Configure payment methods
- Webhook Events - Automate payment workflows
- Transactions API Reference - Complete API reference
- Payment Allocations API Reference - Allocation endpoints