App orders & invoices (trusted apps)
The orders that bill your app's subscriptions and charges – the users' monthly bills – can be read with the app's own token (scope orders:client), e.g. to warn or suspend customers with unpaid orders, or to show a team's invoices.
Endpoints
| Method | Path | |
|---|---|---|
GET | /api/v1/client/orders | list; filters status, user_id, group, per_page (max 100); oldest first |
GET | /api/v1/client/orders/{id} | one order |
GET | /api/v1/client/orders/{id}/invoice | the invoice PDF (application/pdf, with the embedded e-invoice) |
You see only orders that bill subscriptions or charges of your app – no shop orders. Follow one-off orders through their webhooks.
$team->owner->appOrders()->pending(); // unpaid orders of one user, oldest first
app(\Anikeen\Id\AnikeenId::class)->appOrders()->pending(); // of all users
$team->owner->appOrders()->find($orderId); // null if unknown or not this user'sThe order
| Field | |
|---|---|
status | processing (current month, still collecting), pending (closed and not paid), completed, cancelled |
oauth_client_id | the app that bills the order |
| net, VAT and gross totals | what was charged and invoiced |
payment_attempts | how often the payment was tried |
next_payment_attempt_at | the next automatic retry; null = no more automatic retries |
last_payment_error | why the last attempt failed |
due_at | when the order was closed and first charged – count overdue days from here (created_at of a monthly order is the start of its month) |
items | the order's lines, see below |
invoice | null until paid, then {id, number, type, status, service_period_from, service_period_to, created_at, pdf_url} |
Monthly bills are kept per app: your subscriptions are never billed on the same order as another app's, even if both use the same group (or none).
Lines
$order = app(\Anikeen\Id\AnikeenId::class)->appOrders()->find($orderId);
foreach ($order->items as $item) {
$item->subscription_id; // null for lines that bill no subscription
$item->period_start; $item->period_end; // ISO 8601, the end is exclusive; null without a period
$item->net_amount; // units × price, rounded to cents
$item->discount; // {label, percent_off, amount_off} on a discount line, else null
}Each item has id, name, description, type, image_url, units, unit, price, vat_rate, subscription_id, meter, charge_id, monthly_cap, discount, period_start, period_end, net_amount, vat_amount, gross_amount. A line adds up the periods of one subscription at one price, so it can cover several. The net amount actually billed for a subscription is the sum of net_amount of its lines (discount lines are negative). The order's VAT is calculated per rate on the sum, so vat_amount per line is informational.
The invoice PDF
$pdf = app(\Anikeen\Id\AnikeenId::class)->appOrders()->invoicePdf($orderId); // binary| Status | error |
|---|---|
| 404 | order_not_found, invoice_not_found (not paid yet) |
| 409 | invoice_not_ready (the PDF is still being rendered, usually seconds after the payment: try again later) |
| 403 | invoice_includes_other_apps (a legacy order, see below) |
The invoice's status is pending while the PDF is being rendered, completed afterwards.
Legacy orders
Monthly orders from before bills were kept per app (oauth_client_id: null) can also bill other apps' subscriptions. Of such an order your app gets only its own lines (the totals stay the whole order's), invoice.pdf_url is null and the PDF endpoint answers 403 invoice_includes_other_apps.