Customer invoice access
Factulit can host a read-only invoice portal for an order. Your server authenticates the local customer and calls Factulit; the browser only receives a random URL that expires after 30 minutes. Never expose an API key in JavaScript, HTML, a redirect or an iframe.
Recommended flow
- On an order-history page, send up to 50 external order identifiers to
POST /api/v1/order/invoice-availabilityfrom your server. Render “View invoices” only foravailableitems. - When the customer clicks, send them to a protected local controller. Re-check that the signed-in customer owns that order using the CMS's native authorization.
- The controller calls
POST /api/v1/order/invoice-accesswithpresentation: linkand redirects toviewer_url. - If the URL has expired, repeat step 3. Do not store it as a permanent order field.
// Server-side example after the CMS has authorized access to $order.
$response = $http->post('/api/v1/order/invoice-access', [
'headers' => ['X-API-KEY' => getenv('FACTULIT_API_KEY')],
'json' => ['order_id' => (string) $order->externalId(), 'presentation' => 'link'],
]);
if ($response->getStatusCode() === 200) {
$data = json_decode($response->getBody(), true)['data'];
if ($data['state'] === 'available') {
redirect($data['viewer_url']);
}
}Unknown orders return 404; disabled customer access returns 403; invalid input or an unregistered iframe origin returns 422. Respect 429, 503 and Retry-After. A known order without deliverable invoices returns 200 with state: not_available.
Iframe integrations
Use presentation: embed and send the exact HTTPS origin of the page that will contain the iframe. The origin must already belong to the connection or its reported multi-store inventory; wildcards and arbitrary origins are rejected.
<!-- viewerUrl came from your backend; it is never minted in browser code. -->
<iframe src="<?= htmlspecialchars($viewerUrl) ?>" title="Invoices" loading="lazy"></iframe>The standard link portal cannot be framed. Tokens are opaque capabilities: do not log their full URL, forward them to analytics, or share them between customers. Guest orders may only use a CMS-native order-key/session flow that already proves ownership; otherwise keep the invoice email link.
The connection owner can disable this feature under Connection → Customer invoice access in Factulit. Disabling it immediately invalidates live capabilities.