@peable.to/contracts 6.1.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/cjs/resources/billingEngine/index.js +4 -1
  2. package/dist/cjs/resources/billingEngine/quotes.js +342 -0
  3. package/dist/cjs/resources/connect/reporting.js +250 -2
  4. package/dist/cjs/resources/events/events.js +4 -0
  5. package/dist/cjs/vocabulary/errors.js +4 -0
  6. package/dist/cjs/vocabulary/events.js +4 -0
  7. package/dist/cjs/vocabulary/index.js +1 -0
  8. package/dist/cjs/vocabulary/invoices.js +3 -0
  9. package/dist/cjs/vocabulary/quotes.js +31 -0
  10. package/dist/cjs/vocabulary/reporting.js +28 -1
  11. package/dist/esm/resources/billingEngine/index.js +4 -1
  12. package/dist/esm/resources/billingEngine/quotes.js +339 -0
  13. package/dist/esm/resources/connect/reporting.js +251 -3
  14. package/dist/esm/resources/events/events.js +4 -0
  15. package/dist/esm/vocabulary/errors.js +4 -0
  16. package/dist/esm/vocabulary/events.js +4 -0
  17. package/dist/esm/vocabulary/index.js +1 -0
  18. package/dist/esm/vocabulary/invoices.js +3 -0
  19. package/dist/esm/vocabulary/quotes.js +28 -0
  20. package/dist/esm/vocabulary/reporting.js +27 -0
  21. package/dist/types/resources/billingEngine/index.d.ts +839 -1
  22. package/dist/types/resources/billingEngine/invoices.d.ts +12 -0
  23. package/dist/types/resources/billingEngine/quotes.d.ts +1032 -0
  24. package/dist/types/resources/connect/index.d.ts +671 -0
  25. package/dist/types/resources/connect/reporting.d.ts +894 -0
  26. package/dist/types/resources/events/events.d.ts +16 -0
  27. package/dist/types/resources/events/index.d.ts +54 -2
  28. package/dist/types/resources/events/webhookDeliveries.d.ts +12 -0
  29. package/dist/types/resources/events/webhookEndpoints.d.ts +52 -4
  30. package/dist/types/resources/payments/disputes.d.ts +10 -10
  31. package/dist/types/resources/payments/index.d.ts +6 -6
  32. package/dist/types/vocabulary/errors.d.ts +4 -0
  33. package/dist/types/vocabulary/events.d.ts +4 -0
  34. package/dist/types/vocabulary/index.d.ts +1 -0
  35. package/dist/types/vocabulary/invoices.d.ts +1 -1
  36. package/dist/types/vocabulary/quotes.d.ts +27 -0
  37. package/dist/types/vocabulary/reporting.d.ts +23 -0
  38. package/package.json +1 -1
@@ -123,6 +123,10 @@ exports.WEBHOOK_EVENT_OBJECTS = {
123
123
  'billing_portal.configuration.created': 'billing_portal.configuration',
124
124
  'billing_portal.configuration.updated': 'billing_portal.configuration',
125
125
  'billing_portal.session.created': 'billing_portal.session',
126
+ 'quote.created': 'quote',
127
+ 'quote.finalized': 'quote',
128
+ 'quote.accepted': 'quote',
129
+ 'quote.canceled': 'quote',
126
130
  'tax.assessment.created': 'tax.assessment',
127
131
  'tax.review_item.created': 'tax.review_item',
128
132
  'tax.review_item.updated': 'tax.review_item',
@@ -29,6 +29,7 @@ __exportStar(require("./lists"), exports);
29
29
  __exportStar(require("./money"), exports);
30
30
  __exportStar(require("./tax"), exports);
31
31
  __exportStar(require("./subscriptions"), exports);
32
+ __exportStar(require("./quotes"), exports);
32
33
  __exportStar(require("./reporting"), exports);
33
34
  __exportStar(require("./payments"), exports);
34
35
  __exportStar(require("./version"), exports);
@@ -13,6 +13,9 @@ exports.INVOICE_BILLING_REASONS = [
13
13
  'subscription_update',
14
14
  'subscription_cancel',
15
15
  'upcoming',
16
+ // A one-time quote's invoice (Stripe's name); a recurring quote's first
17
+ // invoice is its subscription's `subscription_create`.
18
+ 'quote_accept',
16
19
  ];
17
20
  /**
18
21
  * `automatic_tax.status` — Peable Tax (ADR 0011) is computed before an invoice
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // Quotes (`qt_…`, ADR 0018 §5) — the closed value sets their schemas are built
3
+ // from. Zod-free: `@peable.to/shared-types` re-exports them at runtime.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.QUOTE_LIMITS = exports.QUOTE_STATUSES = void 0;
6
+ /**
7
+ * Where a quote stands — Stripe's four.
8
+ *
9
+ * - `draft` — being written; the only status a quote can be edited in.
10
+ * - `open` — finalized: numbered, priced and taxed, waiting for the
11
+ * customer's answer until `expires_at`.
12
+ * - `accepted` — terminal: the native billing engine made its invoice (one-time
13
+ * lines) or its subscription and first invoice (recurring lines).
14
+ * - `canceled` — terminal: cancelled by the merchant, or expired while open.
15
+ */
16
+ exports.QUOTE_STATUSES = ['draft', 'open', 'accepted', 'canceled'];
17
+ /** Bounds a quote is checked against. */
18
+ exports.QUOTE_LIMITS = {
19
+ /** Lines on one quote — a subscription's item limit. */
20
+ lineItemsMax: 20,
21
+ quantityMax: 1000000,
22
+ /** `header` and `footer`; `description` is 1500 like an invoice's. */
23
+ headerMax: 50,
24
+ footerMax: 500,
25
+ descriptionMax: 1500,
26
+ /** A quote expires 30 days after it is created unless `expires_at` says otherwise (Stripe's default). */
27
+ defaultExpiryDays: 30,
28
+ /** `expires_at` at most this far ahead. */
29
+ expiryMaxDays: 365,
30
+ trialPeriodDaysMax: 730,
31
+ };
@@ -3,7 +3,7 @@
3
3
  // run's lifecycle, and the methods and status classes a request log is
4
4
  // filtered by. Zod-free, like every vocabulary module.
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.REQUEST_LOG_RETENTION_DAYS = exports.REQUEST_LOG_STATUS_CLASSES = exports.REQUEST_LOG_METHODS = exports.REPORT_RUN_STATUSES = exports.REPORT_TYPE_IDS = void 0;
6
+ exports.REPORT_SCHEDULE_MAX_RECIPIENTS = exports.REPORT_SCHEDULE_LOCALES = exports.REPORT_SCHEDULE_WEEKDAYS = exports.REPORT_SCHEDULE_INTERVALS = exports.REPORT_SCHEDULE_STATUSES = exports.REQUEST_LOG_RETENTION_DAYS = exports.REQUEST_LOG_STATUS_CLASSES = exports.REQUEST_LOG_METHODS = exports.REPORT_RUN_STATUSES = exports.REPORT_TYPE_IDS = void 0;
7
7
  /**
8
8
  * Every report Peable produces, by Stripe's versioned id: the trailing `.1` is
9
9
  * the column layout's version, so a layout can change under a new id without
@@ -25,3 +25,30 @@ exports.REQUEST_LOG_METHODS = ['GET', 'POST', 'DELETE', 'PATCH', 'PUT'];
25
25
  exports.REQUEST_LOG_STATUS_CLASSES = ['2xx', '3xx', '4xx', '5xx'];
26
26
  /** How long a request log is kept (and served). */
27
27
  exports.REQUEST_LOG_RETENTION_DAYS = 30;
28
+ /**
29
+ * A report schedule's lifecycle: `active` fires at each occurrence, `paused`
30
+ * fires nothing until resumed (resuming never backfills), `canceled` is
31
+ * terminal.
32
+ */
33
+ exports.REPORT_SCHEDULE_STATUSES = ['active', 'paused', 'canceled'];
34
+ /**
35
+ * How often a schedule fires — Stripe's payout-schedule spelling: every day,
36
+ * once a week on `weekly_anchor`, once a month on `monthly_anchor`. Each
37
+ * occurrence is local midnight in the schedule's timezone, and its run covers
38
+ * the time since the previous occurrence.
39
+ */
40
+ exports.REPORT_SCHEDULE_INTERVALS = ['daily', 'weekly', 'monthly'];
41
+ /** A weekly schedule's day, Monday first (ISO 8601). */
42
+ exports.REPORT_SCHEDULE_WEEKDAYS = [
43
+ 'monday',
44
+ 'tuesday',
45
+ 'wednesday',
46
+ 'thursday',
47
+ 'friday',
48
+ 'saturday',
49
+ 'sunday',
50
+ ];
51
+ /** The languages a schedule's emails are written in — Orbit's own. */
52
+ exports.REPORT_SCHEDULE_LOCALES = ['en', 'es'];
53
+ /** How many addresses one schedule may email. */
54
+ exports.REPORT_SCHEDULE_MAX_RECIPIENTS = 10;
@@ -6,6 +6,7 @@ import { customerBalanceTransactionRoutes } from './customerBalanceTransactions.
6
6
  import { invoiceItemRoutes } from './invoiceItems.js';
7
7
  import { invoiceRoutes } from './invoices.js';
8
8
  import { publicBillingRoutes } from './public.js';
9
+ import { quoteRoutes } from './quotes.js';
9
10
  import { subscriptionRoutes } from './subscriptions.js';
10
11
  export * from './billingPortal.js';
11
12
  export * from './creditNotes.js';
@@ -13,13 +14,15 @@ export * from './customerBalanceTransactions.js';
13
14
  export * from './invoiceItems.js';
14
15
  export * from './invoices.js';
15
16
  export * from './public.js';
17
+ export * from './quotes.js';
16
18
  export * from './subscriptions.js';
17
- /** Orbit's native billing engine (ADR 0018): subscriptions, invoices, credit notes, the balance ledger and the customer portal. */
19
+ /** Orbit's native billing engine (ADR 0018): subscriptions, invoices, credit notes, quotes, the balance ledger and the customer portal. */
18
20
  export const billingEngineRoutes = [
19
21
  ...subscriptionRoutes,
20
22
  ...invoiceRoutes,
21
23
  ...invoiceItemRoutes,
22
24
  ...creditNoteRoutes,
25
+ ...quoteRoutes,
23
26
  ...customerBalanceTransactionRoutes,
24
27
  ...billingPortalRoutes,
25
28
  ...publicBillingRoutes,
@@ -0,0 +1,339 @@
1
+ import { z } from 'zod';
2
+ import { listOf } from '../../common/envelopes.js';
3
+ import { defineObject, expandable } from '../../common/objects.js';
4
+ import { expandOnlyQuery, expandParam, idParam, listQuery, metadataCreateParam, metadataUpdateParam, unixSecondsParam, } from '../../common/params.js';
5
+ import { amount, currency, livemode, metadata, unixSeconds } from '../../common/primitives.js';
6
+ import { defineRoute } from '../../route.js';
7
+ import { AUTOMATIC_TAX_STATUSES } from '../../vocabulary/invoices.js';
8
+ import { QUOTE_LIMITS, QUOTE_STATUSES } from '../../vocabulary/quotes.js';
9
+ import { COLLECTION_METHODS } from '../../vocabulary/subscriptions.js';
10
+ import { checkoutLineItemSchema } from '../checkout/shared.js';
11
+ import { automaticTaxParam, daysUntilDueParam, discountsParam, shortText } from './params.js';
12
+ import { discountSchema } from './subscriptions.js';
13
+ /**
14
+ * Quotes (`qt_…`) — Stripe's Quotes on Orbit's native billing engine (ADR 0018
15
+ * §5). A quote prices catalog Prices for one customer: a `draft` is edited,
16
+ * `finalize` numbers it and fixes its discount and Peable Tax (failing closed,
17
+ * never zero), and `accept` turns it into native billing objects — an invoice
18
+ * for one-time lines, a subscription with its first invoice for recurring ones
19
+ * (one-time lines then ride on that first invoice). Its lines are Stripe's
20
+ * `item`, the same object a Checkout Session's lines are.
21
+ */
22
+ const totalDetailsSchema = z
23
+ .object({
24
+ amount_discount: amount,
25
+ amount_shipping: amount.describe('Always `0`: a quote ships nothing.'),
26
+ amount_tax: amount
27
+ .nullable()
28
+ .describe('Every tax, inclusive and exclusive; `null` on a draft whose tax is not known yet.'),
29
+ })
30
+ .strict();
31
+ export const quoteSchema = defineObject('quote', 'Quote', z
32
+ .object({
33
+ id: z.string(),
34
+ object: z.literal('quote'),
35
+ livemode,
36
+ number: z
37
+ .string()
38
+ .nullable()
39
+ .describe('`null` while a draft; `QT-PREFIX-0001` once finalized — per merchant.'),
40
+ status: z.enum(QUOTE_STATUSES),
41
+ customer: expandable('customer', '`cus_…`, or the Customer with `expand[]=customer`.'),
42
+ currency,
43
+ collection_method: z.enum(COLLECTION_METHODS),
44
+ invoice_settings: z
45
+ .object({
46
+ days_until_due: z
47
+ .number()
48
+ .int()
49
+ .nullable()
50
+ .describe("`send_invoice` only; the billing settings' default when `null`."),
51
+ })
52
+ .strict(),
53
+ subscription_data: z
54
+ .object({
55
+ description: z.string().nullable(),
56
+ trial_period_days: z.number().int().nullable(),
57
+ metadata,
58
+ })
59
+ .strict()
60
+ .describe('What the subscription an accepted quote with recurring lines starts with.'),
61
+ discount: discountSchema.nullable(),
62
+ automatic_tax: z
63
+ .object({
64
+ enabled: z.boolean(),
65
+ status: z.enum(AUTOMATIC_TAX_STATUSES).nullable(),
66
+ tax_calculation: z
67
+ .string()
68
+ .nullable()
69
+ .describe('The Peable Tax calculation (`taxcalc_…`) the quote finalized with.'),
70
+ })
71
+ .strict(),
72
+ amount_subtotal: amount.describe('Every line before discount and tax (one period of a recurring line).'),
73
+ amount_total: amount.describe('`amount_subtotal - amount_discount + exclusive tax`.'),
74
+ total_details: totalDetailsSchema,
75
+ expires_at: unixSeconds.describe('An open quote is cancelled at this instant.'),
76
+ header: z.string().nullable(),
77
+ description: z.string().nullable(),
78
+ footer: z.string().nullable(),
79
+ invoice: expandable('invoice', "The invoice accepting made (`in_…`, expandable): the one-time invoice, or the subscription's first.").nullable(),
80
+ subscription: expandable('subscription', 'The subscription accepting made (`sub_…`, expandable); `null` without recurring lines.').nullable(),
81
+ status_transitions: z
82
+ .object({
83
+ finalized_at: unixSeconds.nullable(),
84
+ accepted_at: unixSeconds.nullable(),
85
+ canceled_at: unixSeconds.nullable(),
86
+ })
87
+ .strict(),
88
+ test_clock: z.string().nullable(),
89
+ metadata,
90
+ created: unixSeconds,
91
+ })
92
+ .strict(), {
93
+ examples: [
94
+ {
95
+ id: 'qt_0193b8f2c1a87d3e9f4a',
96
+ object: 'quote',
97
+ livemode: false,
98
+ number: 'QT-ACME-0001',
99
+ status: 'open',
100
+ customer: 'cus_0193b8f2c1a87d3e9f4a',
101
+ currency: 'EUR',
102
+ collection_method: 'send_invoice',
103
+ invoice_settings: { days_until_due: 30 },
104
+ subscription_data: { description: null, trial_period_days: null, metadata: {} },
105
+ discount: null,
106
+ automatic_tax: { enabled: false, status: null, tax_calculation: null },
107
+ amount_subtotal: '120000',
108
+ amount_total: '120000',
109
+ total_details: { amount_discount: '0', amount_shipping: '0', amount_tax: '0' },
110
+ expires_at: 1796342400,
111
+ header: 'Annual support',
112
+ description: null,
113
+ footer: null,
114
+ invoice: null,
115
+ subscription: null,
116
+ status_transitions: { finalized_at: 1793750400, accepted_at: null, canceled_at: null },
117
+ test_clock: null,
118
+ metadata: {},
119
+ created: 1793750400,
120
+ },
121
+ ],
122
+ });
123
+ // ---- Requests ------------------------------------------------------------------------
124
+ const quoteLineItemParams = z
125
+ .object({
126
+ price: idParam.describe('An active, licensed catalog Price (`price_…`), one-time or recurring.'),
127
+ quantity: z
128
+ .number()
129
+ .int()
130
+ .min(1)
131
+ .max(QUOTE_LIMITS.quantityMax)
132
+ .optional()
133
+ .describe('Default 1.'),
134
+ })
135
+ .strict();
136
+ const lineItemsParam = z
137
+ .array(quoteLineItemParams)
138
+ .min(1)
139
+ .max(QUOTE_LIMITS.lineItemsMax)
140
+ .describe('Each price once, in one currency; every recurring price on one interval. Replaces every line on an update.');
141
+ const invoiceSettingsParam = z.object({ days_until_due: daysUntilDueParam.optional() }).strict();
142
+ const subscriptionDataParam = z
143
+ .object({
144
+ description: shortText(500).optional(),
145
+ trial_period_days: z.number().int().min(1).max(QUOTE_LIMITS.trialPeriodDaysMax).optional(),
146
+ metadata: metadataCreateParam.optional(),
147
+ })
148
+ .strict();
149
+ export const createQuoteParams = z
150
+ .object({
151
+ customer: idParam,
152
+ line_items: lineItemsParam,
153
+ collection_method: z
154
+ .enum(COLLECTION_METHODS)
155
+ .optional()
156
+ .describe('Default `charge_automatically`; a FairCoin (`FAIR`) quote is always `send_invoice`.'),
157
+ invoice_settings: invoiceSettingsParam.optional(),
158
+ subscription_data: subscriptionDataParam.optional(),
159
+ discounts: discountsParam.optional().describe('At most one: a coupon or a promotion code.'),
160
+ automatic_tax: automaticTaxParam.optional(),
161
+ expires_at: unixSecondsParam
162
+ .optional()
163
+ .describe("Default: 30 days from now (the customer's test clock time when it has one)."),
164
+ header: shortText(QUOTE_LIMITS.headerMax).optional(),
165
+ description: shortText(QUOTE_LIMITS.descriptionMax).optional(),
166
+ footer: shortText(QUOTE_LIMITS.footerMax).optional(),
167
+ metadata: metadataCreateParam.optional(),
168
+ expand: expandParam.optional(),
169
+ })
170
+ .strict();
171
+ /** Drafts only, except `metadata`. A field sent as `""` is cleared. */
172
+ export const updateQuoteParams = z
173
+ .object({
174
+ line_items: lineItemsParam.optional(),
175
+ collection_method: z.enum(COLLECTION_METHODS).optional(),
176
+ invoice_settings: invoiceSettingsParam.optional(),
177
+ subscription_data: subscriptionDataParam.optional(),
178
+ discounts: z.union([discountsParam, z.literal('')]).optional(),
179
+ automatic_tax: automaticTaxParam.optional(),
180
+ expires_at: unixSecondsParam.optional(),
181
+ header: z.union([shortText(QUOTE_LIMITS.headerMax), z.literal('')]).optional(),
182
+ description: z.union([shortText(QUOTE_LIMITS.descriptionMax), z.literal('')]).optional(),
183
+ footer: z.union([shortText(QUOTE_LIMITS.footerMax), z.literal('')]).optional(),
184
+ metadata: metadataUpdateParam.optional(),
185
+ expand: expandParam.optional(),
186
+ })
187
+ .strict();
188
+ export const finalizeQuoteParams = z
189
+ .object({
190
+ expires_at: unixSecondsParam.optional().describe('A new expiry, set as it finalizes.'),
191
+ expand: expandParam.optional(),
192
+ })
193
+ .strict();
194
+ /** The body of `accept` and `cancel`: nothing but `expand[]`. */
195
+ export const quoteActionParams = z.object({ expand: expandParam.optional() }).strict();
196
+ export const listQuotesQuery = listQuery({
197
+ customer: idParam.optional(),
198
+ status: z.enum(QUOTE_STATUSES).optional(),
199
+ });
200
+ /** A quote's lines, in their order; `created` does not apply to them. */
201
+ export const listQuoteLineItemsQuery = listQuery({});
202
+ // ---- Routes --------------------------------------------------------------------------
203
+ const quoteId = { id: 'The quote (`qt_…`).' };
204
+ export const quoteRoutes = [
205
+ defineRoute({
206
+ operationId: 'createQuote',
207
+ method: 'post',
208
+ path: '/v1/quotes',
209
+ tag: 'Quotes',
210
+ summary: 'Create a quote',
211
+ description: "A draft for one customer, priced from catalog Prices with the catalog's own pricing. Its tax is computed when it finalizes.",
212
+ auth: 'service',
213
+ scope: 'payments:write',
214
+ idempotent: true,
215
+ body: createQuoteParams,
216
+ response: quoteSchema,
217
+ sdk: 'quotes.create',
218
+ expandable: 'quote',
219
+ }),
220
+ defineRoute({
221
+ operationId: 'listQuotes',
222
+ method: 'get',
223
+ path: '/v1/quotes',
224
+ tag: 'Quotes',
225
+ summary: 'List quotes',
226
+ auth: 'service',
227
+ scope: 'payments:read',
228
+ query: listQuotesQuery,
229
+ response: listOf(quoteSchema),
230
+ sdk: 'quotes.list',
231
+ expandable: 'quote',
232
+ }),
233
+ defineRoute({
234
+ operationId: 'retrieveQuote',
235
+ method: 'get',
236
+ path: '/v1/quotes/{id}',
237
+ tag: 'Quotes',
238
+ summary: 'Retrieve a quote',
239
+ auth: 'service',
240
+ scope: 'payments:read',
241
+ params: quoteId,
242
+ query: expandOnlyQuery,
243
+ response: quoteSchema,
244
+ sdk: 'quotes.retrieve',
245
+ expandable: 'quote',
246
+ }),
247
+ defineRoute({
248
+ operationId: 'updateQuote',
249
+ method: 'post',
250
+ path: '/v1/quotes/{id}',
251
+ tag: 'Quotes',
252
+ summary: 'Update a quote',
253
+ description: 'Drafts only, except `metadata`. `line_items` replaces every line; a field sent as `""` is cleared; `metadata` is a patch.',
254
+ auth: 'service',
255
+ scope: 'payments:write',
256
+ idempotent: true,
257
+ params: quoteId,
258
+ body: updateQuoteParams,
259
+ response: quoteSchema,
260
+ sdk: 'quotes.update',
261
+ expandable: 'quote',
262
+ }),
263
+ defineRoute({
264
+ operationId: 'finalizeQuote',
265
+ method: 'post',
266
+ path: '/v1/quotes/{id}/finalize',
267
+ tag: 'Quotes',
268
+ summary: 'Finalize a draft quote',
269
+ description: 'It gets its number, its discount and its Peable Tax. Tax fails closed: a quote whose tax cannot be computed stays a draft (`automatic_tax.status` says why).',
270
+ auth: 'service',
271
+ scope: 'payments:write',
272
+ idempotent: true,
273
+ params: quoteId,
274
+ body: finalizeQuoteParams,
275
+ response: quoteSchema,
276
+ sdk: 'quotes.finalizeQuote',
277
+ expandable: 'quote',
278
+ }),
279
+ defineRoute({
280
+ operationId: 'acceptQuote',
281
+ method: 'post',
282
+ path: '/v1/quotes/{id}/accept',
283
+ tag: 'Quotes',
284
+ summary: 'Accept an open quote',
285
+ description: 'The customer said yes. One-time lines become an invoice; recurring lines a subscription whose first invoice also carries the one-time lines. The invoice is finalized (tax before finalize) and collected as the engine collects any other: charged when `charge_automatically` and the customer has a card, otherwise paid on its hosted page — where FairCoin is always offered.',
286
+ auth: 'service',
287
+ scope: 'payments:write',
288
+ idempotent: true,
289
+ params: quoteId,
290
+ body: quoteActionParams,
291
+ response: quoteSchema,
292
+ sdk: 'quotes.accept',
293
+ expandable: 'quote',
294
+ }),
295
+ defineRoute({
296
+ operationId: 'cancelQuote',
297
+ method: 'post',
298
+ path: '/v1/quotes/{id}/cancel',
299
+ tag: 'Quotes',
300
+ summary: 'Cancel a quote',
301
+ description: 'A draft or an open quote; an accepted one cannot be cancelled.',
302
+ auth: 'service',
303
+ scope: 'payments:write',
304
+ idempotent: true,
305
+ params: quoteId,
306
+ body: quoteActionParams,
307
+ response: quoteSchema,
308
+ sdk: 'quotes.cancel',
309
+ expandable: 'quote',
310
+ }),
311
+ defineRoute({
312
+ operationId: 'listQuoteLineItems',
313
+ method: 'get',
314
+ path: '/v1/quotes/{id}/line_items',
315
+ tag: 'Quotes',
316
+ summary: "List a quote's line items",
317
+ description: "In their order (at most twenty); the cursor is a line's own `li_…`.",
318
+ auth: 'service',
319
+ scope: 'payments:read',
320
+ params: quoteId,
321
+ query: listQuoteLineItemsQuery,
322
+ response: listOf(checkoutLineItemSchema),
323
+ sdk: 'quotes.listLineItems',
324
+ expandable: 'item',
325
+ }),
326
+ defineRoute({
327
+ operationId: 'retrieveQuotePdf',
328
+ method: 'get',
329
+ path: '/v1/quotes/{id}/pdf',
330
+ tag: 'Quotes',
331
+ summary: "Download a quote's PDF",
332
+ description: 'A draft renders marked as a draft, without a number.',
333
+ auth: 'service',
334
+ scope: 'payments:read',
335
+ params: quoteId,
336
+ response: { kind: 'binary', contentType: 'application/pdf' },
337
+ sdk: 'quotes.pdf',
338
+ }),
339
+ ];