Skip to content

Commit 4e76602

Browse files
authored
feat: add invoice v3 list endpoint (#4613)
1 parent bb2cf2b commit 4e76602

29 files changed

Lines changed: 1394 additions & 446 deletions

File tree

api/spec/packages/aip-client-javascript/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,10 @@ The full call path, HTTP route, and a short description are listed below.
194194

195195
### Invoices
196196

197-
| Method | HTTP | Description |
198-
| --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
199-
| `client.invoices.get` | `GET /openmeter/billing/invoices/{invoiceId}` | Get a billing invoice by ID. Returns the full invoice resource including line items, status details, totals, and workflow configuration snapshot. |
197+
| Method | HTTP | Description |
198+
| ---------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
199+
| `client.invoices.list` | `GET /openmeter/billing/invoices` | List billing invoices. Returns a page of invoices. Gathering invoices are never included. Use `filter` to narrow by status, customer, dates, or service period start. Use `sort` to control ordering. |
200+
| `client.invoices.get` | `GET /openmeter/billing/invoices/{invoiceId}` | Get a billing invoice by ID. Returns the full invoice resource including line items, status details, totals, and workflow configuration snapshot. |
200201

201202
### Tax
202203

api/spec/packages/aip-client-javascript/src/funcs/invoices.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,29 @@ import { type Result, type RequestOptions } from '../lib/types.js'
33
import { request } from '../lib/request.js'
44
import { encodePath, toURLSearchParams, encodeSort } from '../lib/encodings.js'
55
import type {
6+
ListInvoicesRequest,
7+
ListInvoicesResponse,
68
GetInvoiceRequest,
79
GetInvoiceResponse,
810
} from '../models/operations/invoices.js'
911

12+
export function listInvoices(
13+
client: Client,
14+
req: ListInvoicesRequest = {},
15+
options?: RequestOptions,
16+
): Promise<Result<ListInvoicesResponse>> {
17+
const searchParams = toURLSearchParams({
18+
page: req.page,
19+
sort: encodeSort(req.sort),
20+
filter: req.filter,
21+
})
22+
return request(() =>
23+
http(client)
24+
.get('openmeter/billing/invoices', { ...options, searchParams })
25+
.json<ListInvoicesResponse>(),
26+
)
27+
}
28+
1029
export function getInvoice(
1130
client: Client,
1231
req: GetInvoiceRequest,

api/spec/packages/aip-client-javascript/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ export type {
220220
ProfileAppReferences,
221221
InvoiceWorkflowAppsReferences,
222222
ListEventsParamsFilter,
223+
ListInvoicesParamsFilter,
223224
ResourceFilters,
224225
FieldFilters,
225226
IngestedEvent,
@@ -314,6 +315,7 @@ export type {
314315
SubscriptionAddonPagePaginatedResponse,
315316
PlanPagePaginatedResponse,
316317
InvoiceStandard,
318+
InvoicePagePaginatedResponse,
317319
SortQueryInput,
318320
BaseErrorInput,
319321
WorkflowPaymentSendInvoiceSettingsInput,
@@ -375,4 +377,5 @@ export type {
375377
SubscriptionAddonPagePaginatedResponseInput,
376378
PlanPagePaginatedResponseInput,
377379
InvoiceStandardInput,
380+
InvoicePagePaginatedResponseInput,
378381
} from './models/types.js'

api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
import { z } from 'zod'
22
import * as schemas from '../schemas.js'
3+
import type {
4+
InvoicePagePaginatedResponse,
5+
ListInvoicesParamsFilter,
6+
SortQueryInput,
7+
} from '../types.js'
8+
9+
export interface ListInvoicesQuery {
10+
/** Determines which page of the collection to retrieve. */
11+
page?: { size?: number; number?: number }
12+
/**
13+
* Sort invoices returned in the response. Supported sort attributes:
14+
*
15+
* - `issued_at`
16+
* - `created_at` (default)
17+
* - `service_period_start`
18+
*
19+
* The `asc` suffix is optional as the default sort order is ascending. The `desc`
20+
* suffix is used to specify a descending order.
21+
*/
22+
sort?: SortQueryInput
23+
/**
24+
* Filter invoices returned in the response.
25+
*
26+
* Examples:
27+
*
28+
* - `filter[status][oeq]=draft,issued`
29+
* - `filter[customer_id]=01KPDB8K...`
30+
* - `filter[issued_at][gte]=2024-01-01T00:00:00Z`
31+
*/
32+
filter?: ListInvoicesParamsFilter
33+
}
34+
35+
export type ListInvoicesRequest = ListInvoicesQuery
36+
export type ListInvoicesResponse = InvoicePagePaginatedResponse
337

438
export type GetInvoiceRequest = {
539
invoiceId: string

api/spec/packages/aip-client-javascript/src/models/schemas.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,16 @@ export const listEventsParamsFilter = z
32783278
})
32793279
.describe('Filter options for listing ingested events.')
32803280

3281+
export const listInvoicesParamsFilter = z
3282+
.object({
3283+
status: stringFieldFilterExact.optional(),
3284+
customer_id: ulidFieldFilter.optional(),
3285+
issued_at: dateTimeFieldFilter.optional(),
3286+
service_period_start: dateTimeFieldFilter.optional(),
3287+
created_at: dateTimeFieldFilter.optional(),
3288+
})
3289+
.describe('Filter options for listing invoices.')
3290+
32813291
export const resourceFilters = z
32823292
.object({
32833293
name: stringFieldFilter.optional(),
@@ -5227,6 +5237,13 @@ export const invoice = z
52275237
'An invoice issued to a customer. The `type` field determines the concrete variant: - `standard`: a standard invoice for charges owed.',
52285238
)
52295239

5240+
export const invoicePagePaginatedResponse = z
5241+
.object({
5242+
data: z.array(invoice),
5243+
meta: paginatedMeta,
5244+
})
5245+
.describe('Page paginated response.')
5246+
52305247
export const listMeteringEventsQueryParams = z.object({
52315248
page: cursorPaginationQueryPage.optional(),
52325249
filter: listEventsParamsFilter.optional(),
@@ -5669,6 +5686,27 @@ export const deleteBillingProfilePathParams = z.object({
56695686
id: ulid,
56705687
})
56715688

5689+
export const listInvoicesQueryParams = z.object({
5690+
page: z
5691+
.object({
5692+
size: z.coerce
5693+
.number()
5694+
.int()
5695+
.optional()
5696+
.describe('The number of items to include per page.'),
5697+
number: z.coerce.number().int().optional().describe('The page number.'),
5698+
})
5699+
.optional()
5700+
.describe('Determines which page of the collection to retrieve.'),
5701+
sort: sortQuery.optional(),
5702+
filter: listInvoicesParamsFilter.optional(),
5703+
})
5704+
5705+
export const listInvoicesResponse = z.object({
5706+
data: z.array(invoice),
5707+
meta: paginatedMeta,
5708+
})
5709+
56725710
export const getInvoicePathParams = z.object({
56735711
invoiceId: ulid,
56745712
})

api/spec/packages/aip-client-javascript/src/models/types.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,6 +2823,26 @@ export interface ListEventsParamsFilter {
28232823
| { eq?: string; lt?: string; lte?: string; gt?: string; gte?: string }
28242824
}
28252825

2826+
/** Filter options for listing invoices. */
2827+
export interface ListInvoicesParamsFilter {
2828+
/** Filter by invoice status. */
2829+
status?: string | { eq?: string; oeq?: string[]; neq?: string }
2830+
/** Filter by customer ID. */
2831+
customer_id?: string | { eq?: string; oeq?: string[]; neq?: string }
2832+
/** Filter by the time the invoice was issued. */
2833+
issued_at?:
2834+
| string
2835+
| { eq?: string; lt?: string; lte?: string; gt?: string; gte?: string }
2836+
/** Filter by service period start. */
2837+
service_period_start?:
2838+
| string
2839+
| { eq?: string; lt?: string; lte?: string; gt?: string; gte?: string }
2840+
/** Filter by invoice creation time. */
2841+
created_at?:
2842+
| string
2843+
| { eq?: string; lt?: string; lte?: string; gt?: string; gte?: string }
2844+
}
2845+
28262846
/** Resource filters. */
28272847
export interface ResourceFilters {
28282848
name?:
@@ -5110,6 +5130,12 @@ export interface InvoiceStandard {
51105130
lines?: InvoiceStandardLine[]
51115131
}
51125132

5133+
/** Page paginated response. */
5134+
export interface InvoicePagePaginatedResponse {
5135+
data: InvoiceStandard[]
5136+
meta: PaginatedMeta
5137+
}
5138+
51135139
export interface SortQueryInput {
51145140
/** The attribute to sort by. */
51155141
by: string
@@ -6405,3 +6431,8 @@ export interface InvoiceStandardInput {
64056431
*/
64066432
lines?: InvoiceStandardLineInput[]
64076433
}
6434+
6435+
export interface InvoicePagePaginatedResponseInput {
6436+
data: InvoiceStandardInput[]
6437+
meta: PaginatedMeta
6438+
}

api/spec/packages/aip-client-javascript/src/sdk/invoices.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import { type Client } from '../core.js'
22
import { unwrap, type RequestOptions } from '../lib/types.js'
3-
import { getInvoice } from '../funcs/invoices.js'
3+
import { listInvoices, getInvoice } from '../funcs/invoices.js'
44
import type {
5+
ListInvoicesRequest,
6+
ListInvoicesResponse,
57
GetInvoiceRequest,
68
GetInvoiceResponse,
79
} from '../models/operations/invoices.js'
810

911
export class Invoices {
1012
constructor(private readonly _client: Client) {}
1113

14+
async list(
15+
request?: ListInvoicesRequest,
16+
options?: RequestOptions,
17+
): Promise<ListInvoicesResponse> {
18+
return unwrap(await listInvoices(this._client, request, options))
19+
}
20+
1221
async get(
1322
request: GetInvoiceRequest,
1423
options?: RequestOptions,

api/spec/packages/aip/src/invoices/operations.tsp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,88 @@ using TypeSpec.OpenAPI;
1414

1515
namespace Invoices;
1616

17+
/**
18+
* Filter options for listing invoices.
19+
*/
20+
@friendlyName("ListInvoicesParamsFilter")
21+
model ListInvoicesParamsFilter {
22+
/**
23+
* Filter by invoice status.
24+
*/
25+
#suppress "@openmeter/api-spec-aip/doc-decorator" "filter field"
26+
status?: Common.StringFieldFilterExact;
27+
28+
/**
29+
* Filter by customer ID.
30+
*/
31+
#suppress "@openmeter/api-spec-aip/doc-decorator" "filter field"
32+
customer_id?: Common.ULIDFieldFilter;
33+
34+
/**
35+
* Filter by the time the invoice was issued.
36+
*/
37+
#suppress "@openmeter/api-spec-aip/doc-decorator" "filter field"
38+
issued_at?: Common.DateTimeFieldFilter;
39+
40+
/**
41+
* Filter by service period start.
42+
*/
43+
#suppress "@openmeter/api-spec-aip/doc-decorator" "filter field"
44+
service_period_start?: Common.DateTimeFieldFilter;
45+
46+
/**
47+
* Filter by invoice creation time.
48+
*/
49+
#suppress "@openmeter/api-spec-aip/doc-decorator" "filter field"
50+
created_at?: Common.DateTimeFieldFilter;
51+
}
52+
1753
/**
1854
* Operations for managing billing invoices.
1955
*/
2056
interface InvoicesOperations {
57+
/**
58+
* List billing invoices.
59+
*
60+
* Returns a page of invoices. Gathering invoices are never included. Use `filter`
61+
* to narrow by status, customer, dates, or service period start. Use `sort` to
62+
* control ordering.
63+
*/
64+
@extension(Shared.UnstableExtension, true)
65+
@extension(Shared.InternalExtension, true)
66+
@extension(Shared.PrivateExtension, true)
67+
@get
68+
@operationId("list-invoices")
69+
@summary("List billing invoices")
70+
list(
71+
...Common.PagePaginationQuery,
72+
73+
/**
74+
* Sort invoices returned in the response. Supported sort attributes:
75+
*
76+
* - `issued_at`
77+
* - `created_at` (default)
78+
* - `service_period_start`
79+
*
80+
* The `asc` suffix is optional as the default sort order is ascending. The `desc`
81+
* suffix is used to specify a descending order.
82+
*/
83+
@query(#{ name: "sort" })
84+
sort?: Common.SortQuery,
85+
86+
/**
87+
* Filter invoices returned in the response.
88+
*
89+
* Examples:
90+
*
91+
* - `filter[status][oeq]=draft,issued`
92+
* - `filter[customer_id]=01KPDB8K...`
93+
* - `filter[issued_at][gte]=2024-01-01T00:00:00Z`
94+
*/
95+
@query(#{ style: "deepObject", explode: true })
96+
filter?: ListInvoicesParamsFilter,
97+
): Shared.PagePaginatedResponse<Invoice> | Common.ErrorResponses;
98+
2199
/**
22100
* Get a billing invoice by ID.
23101
*

0 commit comments

Comments
 (0)