1 | |
2 |
|
3 | |
4 | * List Customers |
5 | * List customers, newest first, optionally filtered by exact email (case-sensitive). `created_gte`/`created_lte` take ISO 8601 date-times. Returns one page (`limit` 1-100, default 10); pass the last object's id as `starting_after` for the next page while `has_more` is true. |
6 | */ |
7 | export async function main( |
8 | auth: RT.Stripe, |
9 | email: string | undefined, |
10 | created_gte: string | undefined, |
11 | created_lte: string | undefined, |
12 | limit: number | undefined, |
13 | starting_after: string | undefined, |
14 | ending_before: string | undefined |
15 | ) { |
16 | const url = new URL(`https://api.stripe.com/v1/customers`) |
17 | url.search = toForm({ |
18 | email, |
19 | created: { gte: ts(created_gte), lte: ts(created_lte) }, |
20 | limit, |
21 | starting_after, |
22 | ending_before, |
23 | }).toString() |
24 |
|
25 | const response = await fetch(url, { |
26 | headers: { |
27 | Authorization: `Bearer ${auth.token}`, |
28 | Accept: "application/json", |
29 | "Stripe-Version": "2025-03-31.basil", |
30 | }, |
31 | }) |
32 |
|
33 | if (!response.ok) { |
34 | throw new Error(`${response.status} ${await response.text()}`) |
35 | } |
36 |
|
37 | return await response.json() |
38 | } |
39 |
|
40 | |
41 | function toForm( |
42 | params: { [key: string]: any }, |
43 | prefix = "", |
44 | out = new URLSearchParams() |
45 | ) { |
46 | for (const [key, value] of Object.entries(params)) { |
47 | if (value == null || value === "") continue |
48 | const name = prefix ? `${prefix}[${key}]` : key |
49 | if (typeof value === "object") toForm(value, name, out) |
50 | else out.append(name, String(value)) |
51 | } |
52 | return out |
53 | } |
54 |
|
55 | const ts = (iso: string | undefined) => |
56 | iso ? Math.floor(new Date(iso).getTime() / 1000) : undefined |
57 |
|