Invoice Payment Requests
Send secure payment links to customers for easy invoice payment collection
Invoice payment requests provide a simple way to collect invoice payments through secure, hosted payment pages. By generating a payment request link for an invoice, you can give customers an easy way to pay without building custom checkout UI. Share links via email, SMS, or any communication channel—customers complete payment on a Payload-hosted page and the invoice is automatically updated when payment is received.
Payment requests automatically inherit the invoice amount, payer, and biller information. When
payment is completed, the invoice status is automatically updated to paid or
partially_paid and a payment allocation is created linking the transaction to the invoice.
Prerequisites
Before creating invoice payment requests, ensure you have:
Create invoices
Invoices must exist in unpaid or partially_paid status to accept payment requests.
Understand payment processing
Learn how payments are processed via the API.
When to Use Payment Requests
Use invoice payment requests when you want to provide customers with a simple, secure way to pay invoices without building custom checkout UI.
Benefits of payment requests
- No Custom Checkout: Skip building payment forms—use Payload-hosted pages
- PCI Compliance: Secure payment collection handled automatically
- Multiple Delivery Options: Send via email, SMS, or share URLs directly
- Mobile Optimized: Payment pages work seamlessly on all devices
- Payment Method Flexibility: Support cards, bank accounts, and digital wallets
- One-Click Sharing: Generate and share payment links instantly
Common use cases
- Invoice Payments: Send payment links when invoices are issued
- Payment Reminders: Share links in reminder emails for overdue invoices
- Customer Support: Generate payment links during support calls
- Partial Payments: Send links for installment or partial invoice payments
- Manual Billing: Create ad-hoc payment links for custom billing scenarios
- Account Receivables: Streamline collection workflow with shareable links
Link Expiration: Payment request links expire after 60 days and can only be used once successfully. After expiration or completion, generate a new link if needed.
Creating Payment Requests
Create payment links for existing invoices or generate invoices and payment links together.
Reference an existing invoice by ID to create a payment link.
When to use:
- Invoice already exists in your system
- Sending payment requests after invoice generation
- Creating payment links for existing balances
Benefits:
- Simplest approach for existing invoices
- No need to specify amount or payer details
- Automatically uses current invoice balance
Create a payment link with an inline invoice in a single API call.
When to use:
- Creating invoice and payment link together
- Immediate payment link generation needed
- Streamlined checkout flow
Benefits:
- Single API call creates both invoice and link
- Invoice automatically linked to payment link
- Faster workflow for new invoices
Create an invoice with an inline payment link and custom fields.
When to use:
- Creating invoice and payment link together
- Collecting additional information at checkout
- Customizing the payment experience
Benefits:
- Single API call creates invoice and link
- Custom fields for additional data collection
- Payer information derived from invoice
- Payment link automatically associated
Payment link details:
- Links expire after 60 days or when payment is completed
- Amount is set to the invoice's current
balance_due - Payer and biller information inherited from invoice
- Payment automatically allocated to the invoice
- Invoice status updates automatically on payment completion
Current Balance: Payment requests always use the invoice's current balance_due at the
time the link is created. If the invoice receives other payments before the customer uses the
link, you may need to generate a new link for the updated balance.
Sending Payment Requests via Email
Automatically send payment request links to customers via email.
Email delivery behavior:
- Email is automatically sent to the payer from the invoice (payer info is derived)
- Payload sends a professional email with the payment link
- Email includes invoice details and payment instructions
- Link status changes to
sentafter email delivery - Customer receives a "Click here to pay" button in the email
- To prevent automatic email sending, set
email_customer: false
Email content includes:
- Subject line with invoice reference
- Payment amount and due date
- Business/merchant information
- Secure payment link button
- Invoice details and line items
Tracking email delivery:
# Check if email was delivered
payment_link = pl.PaymentLink.get("pay_xyz789")
print("Link status:", payment_link.status)Email Validation: Ensure email addresses are valid before sending. Invalid or bounced
emails will result in status bounced and customers won't receive the payment link. Always
verify email addresses before sending payment requests.
Sending Payment Requests via SMS
Send payment request links directly to customers' mobile phones via SMS.
SMS delivery
Include customer phone number to trigger SMS sending:
payment_link = pl.PaymentLink.create(
type="one_time",
invoice_id="inv_abc123",
description="Invoice #1234 Payment"
)
print("Short URL:", payment_link.url)SMS delivery behavior:
- Include
notificationsarray withphoneto trigger SMS - Phone number must be in E.164 format (e.g., +15555551234)
- Message includes shortened payment link
- Customer receives text with tap-to-pay link
- Optimized for mobile device payment experience
SMS message format:
[Business Name]: You have an invoice for $149.00.
Pay securely here: https://pay.link/xyz123Phone Format: Phone numbers must be in E.164 international format starting with a plus sign and country code. US numbers: +1XXXXXXXXXX, UK numbers: +44XXXXXXXXXX. Invalid formats will cause SMS delivery to fail.
Customizing Checkout Options
Configure which payment methods and features are available during checkout.
Checkout configuration options:
Payment Methods
Control which payment types customers can use:
checkout_options: {
card_payments: true, // Enable credit/debit cards
bank_account_payments: true, // Enable bank transfer bank accounts
enable_mobile_wallets: true, // Enable Apple Pay / Google Pay
enable_plaid: true // Enable Plaid bank linking
}Payment method availability:
-
card_payments- Credit and debit card processing -
bank_account_payments- bank transfer direct debit from bank accounts -
enable_mobile_wallets- Apple Pay, Google Pay for supported devices -
enable_plaid- Instant bank verification via Plaid integration
Field Options
Configure customer information collection:
field_options: {
payer_fields: "required", // Require customer name/email/phone
// Options: "required", "optional", "disabled"
}Payer field options:
-
required- Customer must provide name, email, and phone -
optional- Fields shown but not required -
disabled- Fields hidden (use for known customers)
Additional Settings
checkout_options: {
billing_address: true, // Collect billing address
auto_billing_toggle: true, // Show autopay enrollment checkbox
payment_method_preview: true, // Show payment method review step
show_disclosure: true // Display payment terms
}Additional checkout features:
-
billing_address- Require full billing address for AVS verification -
auto_billing_toggle- Let customers opt into automatic payments -
payment_method_preview- Show confirmation step before payment -
show_disclosure- Display legal terms and processing disclosures
Conversion Optimization: Enable mobile wallets and Plaid to improve conversion rates. Customers can complete payment faster using saved payment methods or instant bank linking, reducing friction in the payment process.
Collecting Custom Information
Add custom fields to collect additional information during payment.
Custom Field Configuration
field_options: {
custom_fields: [
{
section: "Order Information",
fields: [
{
name: "purchase_order",
title: "PO Number",
type: "text",
optional: false,
placeholder: "Enter your PO number"
},
{
name: "department",
title: "Department",
type: "text",
optional: true
}
]
},
{
section: "Delivery Instructions",
fields: [
{
name: "delivery_notes",
title: "Special Instructions",
type: "textarea",
optional: true,
placeholder: "Any special delivery instructions..."
}
]
}
];
}Custom field types:
-
text- Single-line text input -
textarea- Multi-line text area -
email- Email address with validation -
phone- Phone number input -
date- Date picker -
checkbox- Boolean checkbox -
select- Dropdown menu
Field properties:
-
name- Field identifier (used in transaction attrs) -
title- Label displayed to customer -
type- Field input type -
optional- Whether field is required (default: false) -
placeholder- Hint text shown in empty field -
value- Pre-filled default value -
readonly- Display-only field (cannot be edited)
Accessing Custom Field Data
After payment is completed, custom field values are stored in the transaction attrs:
transaction = pl.Transaction.get("txn_abc123")
print("Custom field values:", transaction.attrs)
# {
# "purchase_order": "PO-2024-001",
# "department": "Accounting",
# "delivery_notes": "Deliver to back entrance"
# }Field Storage: Custom field values are stored in the transaction's attrs object. Use
consistent field names across payment requests to enable reporting and data analysis. All
custom fields are stored as strings regardless of input type.
Handling Payment Completion
Process and verify payments after customers complete payment requests.
Webhook Notifications
Configure webhooks to receive reliable payment notifications:
# Webhook handler for payment completion
from flask import Flask, request
app = Flask(__name__)
@app.route("/webhooks/payload", methods=["POST"])
def handle_webhook():
event = request.json
if event["trigger"] == "processed" and event["triggered_on"]["type"] == "payment":
transaction_id = event["triggered_on"]["id"]
transaction = pl.Transaction.get(transaction_id)
if transaction.invoice_allocations and len(transaction.invoice_allocations) > 0:
invoice_id = transaction.invoice_allocations[0]["invoice_id"]
invoice = pl.Invoice.get(invoice_id)
print("Invoice payment received!")
print("Transaction:", transaction.id)
print("Invoice:", invoice.id)
print("Invoice status:", invoice.status)
print("Remaining balance:", invoice.totals["balance_due"])
return "OK", 200Webhook setup:
- Create a webhook with
trigger: 'processed' - Set
reference_object: 'transaction' - Point to your webhook handler URL
- Process payment events in real-time
Webhook Best Practices: Always verify webhook authenticity, use idempotency keys to prevent duplicate processing, and return 200 status quickly to avoid retries. See the Webhook Guide for detailed setup instructions.
Managing Payment Request Links
Update, cancel, or resend payment request links.
Resend Payment Requests
# Resend an existing payment link via email
def resend_payment_request(link_id, email):
link = pl.PaymentLink.get(link_id)
if link.status == "completed":
print("Payment already completed")
return
if link.status == "expired":
print("Link expired - create a new one")
new_link = pl.PaymentLink.create(
type="one_time",
invoice_id=link.invoice_id
)
print("New payment link sent:", new_link.url)
return
pl.Notification.create(
payment_link_id=link.id,
email=email
)
print("Payment reminder email sent to:", email)Cancel Payment Links
# Delete a payment link to prevent use
link = pl.PaymentLink.get("pay_xyz789")
link.delete()
print("Payment link canceled and cannot be used")
# Or update to inactive status
deactivated = pl.PaymentLink.get("pay_xyz789")
deactivated.update(
status="inactive"
)
print("Payment link deactivated")When to cancel links:
- Invoice was paid through another method
- Customer requested cancellation
- Invoice was voided or canceled
- Link was sent to wrong email address
- Creating a replacement link with different settings
Handle Expired Links
# Find expired payment links
expired_links = pl.PaymentLink.filter_by(
q='status == "expired" && invoice_id != null'
).all()
print(f"Found {len(expired_links)} expired payment links")
# Create new links for unpaid invoices
for link in expired_links:
invoice = pl.Invoice.get(link.invoice_id)
if invoice.status in ("unpaid", "partially_paid"):
new_link = pl.PaymentLink.create(
type="one_time",
invoice_id=invoice.id
)
print(f"New link created for invoice {invoice.id}:", new_link.url)Link Security: Never reuse or share the same payment link with multiple customers. Each payment request should have a unique link. If you need to send a payment link to multiple people, create separate links for each recipient.
Schema Reference
Fields relevant to invoice payment requests:
Payment Link Configuration
typeone_time, reusableinvoice_id ID of Invoice^inv_[A-Za-z0-9]+$descriptionpayeraccountAccountaccount_id ID of Account^acct_[A-Za-z0-9]+$urlstatusactive, sent, received, opened, bounced, completed, inactive, expired"Undocumented"Checkout Options
checkout_optionsauto_billing_togglebank_account_paymentsbilling_addresscard_paymentsdefault_payment_optioncard, bank_accountenable_mobile_walletsenable_plaidkeep_active_togglepayment_method_previewshow_disclosurefield_optionsamount_fieldeditable, staticcustom_fieldspayer_fieldsrequired, optional, disabledInvoice Association
statusdraft, open, unpaid, partially_paid, paid, closed, synctotalsbalance_duepaidsubtotaltaxtotalpaymentsPaymentAllocationNext Steps
Enhance invoice payment collection with automated workflows
Optimize Payment Collection
Enable autopay for recurring invoices with Automatic Payments to automatically charge customers on due dates, process invoice payments programmatically with Payment API for automated billing workflows, and provide customer self-service payment management with Payment Portal for hosted payment experiences.
Manage Invoice Workflows
Generate invoices with line items using Creating Invoices for professional billing, track the invoice lifecycle with Invoice Statuses from draft through paid status, and automate recurring invoice creation with Billing Schedules for subscription-based billing.
Monitor Payment Events
Receive real-time notifications for payment completion with Webhook Events to automate post-payment workflows, track payment processing status with Transaction Status to monitor payment completion and failures, and explore general payment link features with Payment Links Overview for advanced payment collection.
Related articles
- Payment Links Overview - Complete payment link documentation
- Payment Request Links - General payment request guide
- Creating Invoices - Build invoices for customers
- Payment API - Programmatic invoice payments
- Webhook Events - Automate payment workflows
- Payment Links API Reference - Complete API documentation