Shop It Docs
Developer Resourcesorder

Invoice Download

On-demand invoice PDF generation and download flow for customer orders

Invoice Download

Overview

The order module supports two invoice download paths:

  1. Authenticated fresh download from order details.
  2. Signed URL download used by email CTA.

Invoices are generated on demand and streamed immediately.

API Endpoints

GET /api/orders/:id/invoice

Legacy authenticated endpoint (still supported for backward compatibility).

  • Auth: Bearer JWT required
  • Owner check: order must belong to authenticated customer
  • Rate limit: 10 requests / minute per client key
  • Response content type: application/pdf

GET /api/orders/:id/invoice-download

Preferred authenticated endpoint for order-page Download Invoice button.

  • Auth: Bearer JWT required
  • Owner check: order must belong to authenticated customer
  • Rate limit: 10 requests / minute per client key
  • Response content type: application/pdf

GET /api/admin/orders/:id/invoice-download

Admin invoice download endpoint for any order.

  • Auth: admin Bearer JWT required
  • Permission: Orders_READ
  • Ownership check: not required (admin scope)
  • Rate limit: admin order-operation limiter
  • Response content type: application/pdf

POST /api/orders/:id/invoice-token

Generates a signed, single-use invoice token for the specified order.

  • Auth: Bearer JWT required
  • Owner check: order must belong to authenticated customer
  • Rate limit: 10 requests / minute per client key
  • Response:
    • token (raw token for URL path)
    • expiresAt (ISO timestamp)
    • downloadUrl (/invoices/{token} or absolute frontend URL)

GET /api/invoices/:token

Public signed URL endpoint used by email CTA.

  • Auth: none
  • Rate limit: 20 requests / minute per client key
  • Behavior:
    • valid + unconsumed token -> streams invoice PDF
    • expired token -> 302 to login with ?redirect=/invoices/{token}
    • consumed token -> 302 to login with ?error=token_consumed
    • invalid token -> 302 to login with ?error=invalid_token

Success Response

  • HTTP 200 OK
  • Content-Disposition: attachment; filename="invoice-{orderNumber}.pdf"

Error Responses

  • 401 Unauthorized
  • 403 Forbidden (order ownership mismatch)
  • 404 Order not found
  • 429 Too many requests
  • 500 Invoice generation failed
  • 400 Invalid token (INVOICE_TOKEN_INVALID)
  • 409 Expired or consumed token (INVOICE_TOKEN_EXPIRED, INVOICE_TOKEN_CONSUMED)

Generated Invoice Content

The generated PDF includes:

  • Invoice number (orderNumber)
  • Invoice date (order.createdAt)
  • Payment status
  • Buyer identity and shipping address
  • Line items with quantity and unit price
  • Subtotal, discount, shipping fee, final total
  • Currency formatting

Order monetary values are stored in paisa and converted for invoice display.

Email Integration

Checkout and buy-now transactional emails include a Download Invoice CTA that points to:

  • {FRONTEND_BASE_URL}/invoices/{token}

Signed token characteristics:

  • stored hashed (SHA-256) in invoice_tokens
  • single-use (consumedAt is set on first successful download)
  • expiry defaults to 7 days and is configurable via INVOICE_SIGNED_URL_TTL_MS

The existing View Order Details CTA remains unchanged.

Operational Notes

  • PDF generation is on-demand, not pre-generated.
  • Temporary PDF files are removed after response generation.
  • INVOICE_PDF_DIR is used when set.
  • If INVOICE_PDF_DIR is unset, default directory is ${UPLOAD_LOCATION}/invoices.
  • If signed URL is expired/consumed, user can still download via order page button using JWT endpoint.