Skip to content
Cipay
Esc
navigateopen⌘Jpreview
On this page

Orders and invoices

Filter orders, retrieve details, and download invoice PDFs in supported frameworks.

Orders record commerce outcomes. Invoice access stays on the server and must be scoped to the authenticated customer.

List and filter orders

// Combine only the filters needed by this merchant view.
const page = await cipay.orders.list({
  customerId,
  status: "paid",
  productId,
  createdFrom: "2026-09-01T00:00:00.000Z",
  createdTo: "2026-10-01T00:00:00.000Z",
  pageSize: 50,
});

console.log({ count: page.items.length, nextCursor: page.nextCursor });

You can also filter by subscriptionId. Reuse nextCursor only with the same filters.

Retrieve one order

// The order ID must come from a trusted customer-scoped lookup.
const order = await cipay.orders.retrieve(orderId);

console.log({
  status: order.status,
  invoiceNumber: order.invoiceNumber,
  totalHalalas: order.totalHalalas,
  currency: order.currency,
});

Download an invoice

downloadInvoice returns { bytes, filename, requestId }. The Web Response version works directly in Next.js, Hono, and Astro; Express writes the same bytes through its response object.

import { cipay } from "@/lib/cipay";

export async function GET(
  _request: Request,
  context: { params: Promise<{ orderId: string }> },
) {
  const { orderId } = await context.params;
  const invoice = await cipay.orders.downloadInvoice(orderId);

  // Keep customer-specific PDFs out of shared browser and CDN caches.
  return new Response(invoice.bytes, {
    headers: invoiceHeaders(invoice.filename),
  });
}
app.get("/api/invoices/:orderId", async (c) => {
  const invoice = await cipay.orders.downloadInvoice(c.req.param("orderId"));

  // Hono accepts a standard Web Response.
  return new Response(invoice.bytes, {
    headers: invoiceHeaders(invoice.filename),
  });
});
import type { APIRoute } from "astro";
import { cipay } from "../../../lib/cipay";

export const GET: APIRoute = async ({ params }) => {
  const invoice = await cipay.orders.downloadInvoice(params.orderId!);

  // Astro endpoints return a standard Web Response.
  return new Response(invoice.bytes, {
    headers: invoiceHeaders(invoice.filename),
  });
};
app.get("/api/invoices/:orderId", async (request, response) => {
  const invoice = await cipay.orders.downloadInvoice(request.params.orderId);

  // Express writes the same private PDF response with Node's Buffer.
  response
    .status(200)
    .set(invoiceHeaders(invoice.filename))
    .send(Buffer.from(invoice.bytes));
});

Use this header helper in each example:

export function invoiceHeaders(filename: string) {
  return {
    "content-type": "application/pdf",
    "content-disposition": `attachment; filename="${filename}"`,
    "cache-control": "private, no-store",
  };
}