git:20260804.99838a7 to git:20260817.2671d27
1 added, 1 removed. Audit A to A.
---
name: "Alternative Payments Invoicing"
description: >
Alternative Payments invoices and hosted payment requests: invoice status
and line-item fields, hosted payment links and signed PDF links,
archiving, and payment-request creation and retrieval. Hosted links let
the customer choose to pay; the integration never moves money on the
customer's behalf.
when_to_use: >-
When creating, listing, retrieving, or archiving Alternative Payments invoices, or generating
hosted payment links and payment requests. Use when: alternative payments invoice, create
invoice, list invoices, archive invoice, payment link, payment request, hosted payment link,
invoice pdf, line items, or alternativepayments invoice.
---
# Alternative Payments Invoicing
## Overview
Invoices are the billing records in Alternative Payments. Each invoice belongs to
a customer, carries one or more line items, and has a due date. Once an invoice
exists you can fetch a **hosted payment link** (a URL the customer visits to pay)
and a **PDF link** (a signed download of the invoice document).
Separately, **payment requests** are standalone hosted payment links that are not
tied to a stored invoice — useful for ad-hoc charges and follow-ups.
The key posture: hosted payment links and payment requests let the **customer**
choose to pay. Generating a link does **not** charge a card or move money — it
simply produces a URL. This integration never executes a direct charge. See
[Alternative Payments API Patterns](../api-patterns/SKILL.md) for why
`POST /payments` (direct charge) is excluded by design.
## Anti-triggers
- **The invoice as an accounting document** — these invoices are collection
artefacts with no GL coding, tax treatment, or aging; use `xero-invoices` or
- `quickbooks-online-invoices`.
+ `qbo-invoices`.
- **Whether the invoice was paid and where the money settled** — use
`alternative-payments-payments`.
- **Charging a card or bank account directly** — no such tool exists here by
design; a hosted link is the only collection mechanism, and the reasoning is
in `alternative-payments-api-patterns`.
## Core Concepts
### Invoice Status
| Status | Description | Payable |
|--------|-------------|---------|
| `open` | Issued and awaiting payment | Yes |
| `paid` | Fully paid | No |
| `overdue` | Past `due_date` and still unpaid | Yes |
| `archived` | Removed from default lists (destructive) | No |
Archiving uses `DELETE /invoices/{id}` and is destructive — confirm before running.
### Hosted Links vs. Direct Charges
| Mechanism | What it does | Money movement |
|-----------|--------------|----------------|
| Payment link (`GET /invoices/{id}/payment-link`) | URL for an existing invoice | Customer pays — not the integration |
| Payment request (`POST /payments/request`) | Standalone hosted link | Customer pays — not the integration |
| Direct charge (`POST /payments`) | Charges a card/bank | **Not exposed** |
## Field Reference
### Invoice Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string | System | Auto-generated unique identifier |
| `customer_id` | string | Yes | Customer the invoice belongs to |
| `currency` | string | Yes | ISO currency code (e.g. `USD`) |
| `due_date` | string | Yes | Payment due date (`YYYY-MM-DD`) |
| `line_items` | array | Yes | One or more line items (see below) |
| `reference` | string | No | Reference text (PO number, billing period) |
| `status` | string | Read-only | `open`, `paid`, `overdue`, `archived` |
| `amount_due` | number | Read-only | Remaining unpaid amount |
| `created_at` | datetime | Read-only | Creation timestamp |
### Line Item Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `description` | string | Yes | Line item description |
| `quantity` | number | Yes | Quantity |
| `unit_amount` | number | Yes | Price per unit |
### Payment Request Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `amount` | number | Yes | Amount to request |
| `currency` | string | Yes | ISO currency code (e.g. `USD`) |
| `redirect_url` | string | Yes | Where to send the customer after paying |
| `reference_id` | string | No | Your reference for reconciliation |
## API Patterns
All requests carry a bearer token (`Authorization: Bearer <token>`). See
[Alternative Payments API Patterns](../api-patterns/SKILL.md) for the OAuth2 token
flow, the 5 req/sec rate limit, and cursor pagination.
### List Invoices
```bash
curl -s "https://public-api.alternativepayments.io/invoices?limit=100" \
-H "Authorization: Bearer ${TOKEN}"
```
Responses are cursor-paginated — items in `data[]`, with `next_cursor` / `has_more`.
Pass `after=<cursor>` for the next page.
### Get a Single Invoice
```bash
curl -s "https://public-api.alternativepayments.io/invoices/${INVOICE_ID}" \
-H "Authorization: Bearer ${TOKEN}"
```
### Create an Invoice
Required: `customer_id`, `currency`, `due_date`, and a non-empty `line_items[]`.
```bash
curl -s -X POST "https://public-api.alternativepayments.io/invoices" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "'${CUSTOMER_ID}'",
"currency": "USD",
"due_date": "2026-07-05",
"reference": "June 2026 Managed Services",
"line_items": [
{
"description": "Monthly Managed Services - Acme Corp (25 endpoints)",
"quantity": 1,
"unit_amount": 2500.00
},
{
"description": "Microsoft 365 Business Premium (25 users)",
"quantity": 25,
"unit_amount": 22.00
}
]
}'
```
### Get a Hosted Payment Link
Returns a URL the customer visits to pay the invoice. No charge occurs until the
customer completes payment.
```bash
curl -s "https://public-api.alternativepayments.io/invoices/${INVOICE_ID}/payment-link" \
-H "Authorization: Bearer ${TOKEN}"
```
### Get a Signed PDF Link
```bash
curl -s "https://public-api.alternativepayments.io/invoices/${INVOICE_ID}/pdf-link" \
-H "Authorization: Bearer ${TOKEN}"
```
### Archive an Invoice (Destructive — Confirm First)
`DELETE /invoices/{id}` archives the invoice. **Confirm with the operator before
running it.**
```bash
curl -s -X DELETE "https://public-api.alternativepayments.io/invoices/${INVOICE_ID}" \
-H "Authorization: Bearer ${TOKEN}"
```
A `204 No Content` indicates success.
### Create a Hosted Payment Request
A standalone hosted link, not tied to a stored invoice. Required: `amount`,
`currency`, `redirect_url`. The response includes a hosted URL — the customer
chooses to pay; the integration does not charge them.
```bash
curl -s -X POST "https://public-api.alternativepayments.io/payments/request" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"amount": 2500.00,
"currency": "USD",
"redirect_url": "https://portal.example-msp.com/thanks",
"reference_id": "MS-2026-06-ACME"
}'
```
### Get a Payment Request
```bash
curl -s "https://public-api.alternativepayments.io/payments/request/${REQUEST_ID}" \
-H "Authorization: Bearer ${TOKEN}"
```
### JavaScript Example
```javascript
async function createInvoiceWithLink(token, invoice) {
const base = 'https://public-api.alternativepayments.io';
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const createRes = await fetch(`${base}/invoices`, {
method: 'POST', headers, body: JSON.stringify(invoice)
});
const createText = await createRes.text();
if (!createRes.ok) throw new Error(`Create invoice failed (${createRes.status}): ${createText}`);
const created = JSON.parse(createText);
// Fetch a hosted link the customer can use to pay — no charge happens here.
const linkRes = await fetch(`${base}/invoices/${created.id}/payment-link`, {
headers: { 'Authorization': `Bearer ${token}` }
});
const link = JSON.parse(await linkRes.text());
return { invoice: created, paymentLink: link };
}
```
## Common Workflows
### Monthly MSP Billing Cycle
1. **Create invoices** for each managed services customer with their line items
2. **Generate hosted payment links** and email them to the customer's users
3. **Track payment** via read-only transactions (see [Payments & Payouts](../payments/SKILL.md))
4. **Follow up** on `overdue` invoices with a fresh payment link
### Ad-hoc Charge Follow-up
When chasing an outstanding balance that isn't a formal invoice, create a
payment request with the amount, currency, and a `redirect_url`, then send the
hosted link. The customer pays at their discretion.
## Error Handling
| Code | Meaning | Action |
|------|---------|--------|
| 201 | Invoice / payment request created | Process response |
| 204 | Archived | Treat as success |
| 400 / 422 | Validation error | Inspect the `errors` array; fix the request |
| 401 | Unauthorized | Refresh token, retry once |
| 404 | Invoice / request not found | Verify the id |
| 429 | Rate limited | Back off (`Retry-After`), retry |
Common validation causes: empty `line_items[]`, missing `due_date`, an unknown
`customer_id`, or a missing `redirect_url` on a payment request.
## Best Practices
1. **Always include line items** — `line_items[]` must be non-empty.
2. **Use clear references** — include the billing period and service in `reference`.
3. **Send hosted links, not charges** — let the customer pay via the payment link.
4. **Set a `reference_id` on payment requests** — makes reconciliation clean.
5. **Confirm before archiving** — `DELETE` is destructive.
## Endpoint Reference
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/invoices` | GET | List invoices (cursor-paginated) |
| `/invoices` | POST | Create an invoice with line items |
| `/invoices/{id}` | GET | Get a single invoice |
| `/invoices/{id}` | DELETE | Archive an invoice (destructive) |
| `/invoices/{id}/payment-link` | GET | Hosted payment link for the invoice |
| `/invoices/{id}/pdf-link` | GET | Signed PDF download link |
| `/payments/request` | POST | Create a hosted payment request |
| `/payments/request/{id}` | GET | Get a payment request |
## Related Skills
- [Alternative Payments API Patterns](../api-patterns/SKILL.md) - Auth, pagination, rate limits
- [Alternative Payments Customers](../customers/SKILL.md) - Customers and their users
- [Alternative Payments Payments & Payouts](../payments/SKILL.md) - Read-only transactions and payouts