Supercommerce API Docs
Vendor API

Bulk Invoices — Vendor

HTTP surface for a vendor to batch-generate invoices for many of their own sub-orders at once, merged into a single downloadable PDF, with async status polling and retry of failed orders.

HTTP surface for a vendor to select many of their own sub-orders and request one merged invoice PDF. A BullMQ worker generates (or reuses the cached) invoice for each selected sub-order, then concatenates every successfully-generated PDF into a single file. A batch finishes ready as soon as at least one sub-order succeeded — it only finishes failed when every one did. Failed sub-orders can be retried without re-selecting the whole batch.

Source: api-modules/invoice/src/controllers/vendor-bulk-invoices.controller.ts.

Scoped to the active vendor (resolveActiveVendorId). A batch id belonging to another vendor returns 404. A requested sub-order that belongs to another vendor is recorded as a failed line item in the batch, not a blanket 404 for the whole request.


Conventions

Authentication

All endpoints require a Better-Auth vendor session. Every read/write is scoped to the caller's vendor id.

Response shape

  • Create / retry / status endpoints return the standard JSON envelope: { data, message, statusCode }.
  • List returns the standard paginated envelope: { data, message, statusCode, metadata: { total, limit, offset, hasMore } }.
  • Download (GET …/:id/download) streams raw application/pdf bytes with Content-Disposition: attachment — no JSON envelope.

Generation flow

POST /vendor/bulk-invoices  { orderVendorIds: [...] }


  bulk_invoice_job created (status: pending) — one item per requested order


  background worker generates each order's invoice, then merges the
  successful PDFs into one file

       ├─ at least one order succeeded  ──►  status: "ready"   (fileName/fileSize set)
       └─ every order failed            ──►  status: "failed"

GET /vendor/bulk-invoices           — poll the batch list (or a single id) for status
GET /vendor/bulk-invoices/:id/download   — download the merged PDF once ready
POST /vendor/bulk-invoices/:id/retry     — re-run only the failed orders in the background

Endpoints

Start a batch

POST /vendor/bulk-invoices

Request body:

{ "orderVendorIds": ["…", "…"] } // 1–200 sub-order ids

An id that doesn't belong to the caller's vendor (but does exist) is recorded as a failed line item, not rejected outright. An id that doesn't exist at all fails the whole request with 400 (the vendor-admin UI only ever sends ids off the caller's own orders list, so this indicates a malformed request).

Response (data field) — a batch row:

{
  "id": "…",
  "status": "pending" | "processing" | "ready" | "failed",
  "orderCount": 20,
  "successCount": 0,
  "failedCount": 0,
  "fileName": null,
  "fileSize": null,
  "retryCount": 0,
  "error": null,
  "createdAt": "…",
  "startedAt": null,
  "completedAt": null,
  "downloadUrl": null // set only when status = ready
}

List my batches

GET /vendor/bulk-invoices

Standard offset/limit pagination (querySchema) plus an optional status filter. Rows are the same shape as the create response, newest first.


Batch status + per-order breakdown

GET /vendor/bulk-invoices/:id

Same row shape as above, plus an items array — one entry per requested sub-order:

{
  "...": "batch row fields",
  "items": [
    {
      "orderVendorId": "…",
      "orderNumber": "ORD-1042" | null,
      "status": "pending" | "success" | "failed",
      "error": "…" | null
    }
  ]
}

Retry failed orders

POST /vendor/bulk-invoices/:id/retry

Allowed only when the batch is ready or failed and has at least one failed item — returns 409 otherwise (including while a batch is still processing). Resets every failed item back to pending and re-runs them in the background; the merged PDF is rebuilt from the full current set of successful invoices (previously-succeeded ones are not re-rendered), so a partially-fixed retry still produces one complete file.

Response: the updated batch row (status: "processing", retryCount incremented).


Download the merged PDF

GET /vendor/bulk-invoices/:id/download

Streams the merged application/pdf once the batch is ready. Returns 404 otherwise (not yet ready, or the batch failed outright).

Filename: bulk-invoices-{id}.pdf (or the batch's stored fileName).

On this page