feat: 🎸 openapi contracts for schedules and get customer
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ import {
|
|||||||
AttachParamsV1Schema,
|
AttachParamsV1Schema,
|
||||||
BILLING_PREVIEW_RESPONSE_EXAMPLE,
|
BILLING_PREVIEW_RESPONSE_EXAMPLE,
|
||||||
BillingResponseSchema,
|
BillingResponseSchema,
|
||||||
|
CreateScheduleParamsV0Schema,
|
||||||
|
CreateScheduleResponseSchema,
|
||||||
ExtAttachPreviewResponseSchema,
|
ExtAttachPreviewResponseSchema,
|
||||||
ExtPreviewUpdateSubscriptionResponseSchema,
|
ExtPreviewUpdateSubscriptionResponseSchema,
|
||||||
ExtUpdateSubscriptionV1ParamsSchema,
|
ExtUpdateSubscriptionV1ParamsSchema,
|
||||||
@@ -14,6 +16,7 @@ import {
|
|||||||
import { oc } from "@orpc/contract";
|
import { oc } from "@orpc/contract";
|
||||||
import {
|
import {
|
||||||
billingAttachJsDoc,
|
billingAttachJsDoc,
|
||||||
|
billingCreateScheduleJsDoc,
|
||||||
billingMultiAttachJsDoc,
|
billingMultiAttachJsDoc,
|
||||||
billingPreviewAttachJsDoc,
|
billingPreviewAttachJsDoc,
|
||||||
billingPreviewMultiAttachJsDoc,
|
billingPreviewMultiAttachJsDoc,
|
||||||
@@ -227,6 +230,66 @@ export const billingSetupPaymentContract = oc
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const billingCreateScheduleContract = oc
|
||||||
|
.route({
|
||||||
|
method: "POST",
|
||||||
|
path: "/v1/billing.create_schedule",
|
||||||
|
operationId: "createSchedule",
|
||||||
|
tags: ["billing"],
|
||||||
|
description: billingCreateScheduleJsDoc,
|
||||||
|
spec: (spec) => ({
|
||||||
|
...spec,
|
||||||
|
"x-speakeasy-name-override": "createSchedule",
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.input(
|
||||||
|
CreateScheduleParamsV0Schema.meta({
|
||||||
|
title: "CreateScheduleParams",
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
customer_id: "cus_123",
|
||||||
|
phases: [
|
||||||
|
{
|
||||||
|
starts_at: 1735689600000,
|
||||||
|
plans: [{ plan_id: "trial_plan" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
starts_at: 1736899200000,
|
||||||
|
plans: [{ plan_id: "pro_plan" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
CreateScheduleResponseSchema.meta({
|
||||||
|
title: "CreateScheduleResponse",
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
customer_id: "cus_123",
|
||||||
|
entity_id: null,
|
||||||
|
status: "created",
|
||||||
|
schedule_id: "sch_1234",
|
||||||
|
phases: [
|
||||||
|
{
|
||||||
|
phase_id: "sphs_1111",
|
||||||
|
starts_at: 1735689600000,
|
||||||
|
customer_product_ids: ["cus_prod_1111"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase_id: "sphs_2222",
|
||||||
|
starts_at: 1736899200000,
|
||||||
|
customer_product_ids: ["cus_prod_2222"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invoice: null,
|
||||||
|
payment_url: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
export const billingMultiAttachContract = oc
|
export const billingMultiAttachContract = oc
|
||||||
.route({
|
.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|||||||
@@ -9,10 +9,14 @@ import {
|
|||||||
DeleteCustomerParamsSchema,
|
DeleteCustomerParamsSchema,
|
||||||
DeleteCustomerResponseSchema,
|
DeleteCustomerResponseSchema,
|
||||||
} from "@api/customers/crud/deleteCustomerParams.js";
|
} from "@api/customers/crud/deleteCustomerParams.js";
|
||||||
|
import { GetCustomerParamsV1Schema } from "@api/customers/crud/getCustomerParams.js";
|
||||||
import { ListCustomersV2ParamsSchema } from "@api/customers/crud/listCustomersParamsV2.js";
|
import { ListCustomersV2ParamsSchema } from "@api/customers/crud/listCustomersParamsV2.js";
|
||||||
import { UpdateCustomerParamsV1Schema } from "@api/customers/crud/updateCustomerParams.js";
|
import { UpdateCustomerParamsV1Schema } from "@api/customers/crud/updateCustomerParams.js";
|
||||||
import { oc } from "@orpc/contract";
|
import { oc } from "@orpc/contract";
|
||||||
import { getOrCreateCustomerJsDoc } from "../jsDocs/customerJsDocs";
|
import {
|
||||||
|
getCustomerJsDoc,
|
||||||
|
getOrCreateCustomerJsDoc,
|
||||||
|
} from "../jsDocs/customerJsDocs";
|
||||||
|
|
||||||
export const getOrCreateCustomerContract = oc
|
export const getOrCreateCustomerContract = oc
|
||||||
.route({
|
.route({
|
||||||
@@ -40,6 +44,38 @@ export const getOrCreateCustomerContract = oc
|
|||||||
)
|
)
|
||||||
.output(ApiCustomerV5Schema);
|
.output(ApiCustomerV5Schema);
|
||||||
|
|
||||||
|
export const getCustomerContract = oc
|
||||||
|
.route({
|
||||||
|
method: "POST",
|
||||||
|
path: "/v1/customers.get",
|
||||||
|
operationId: "getCustomer",
|
||||||
|
tags: ["customers"],
|
||||||
|
description: getCustomerJsDoc,
|
||||||
|
spec: (spec) => ({
|
||||||
|
...spec,
|
||||||
|
"x-speakeasy-name-override": "get",
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.input(
|
||||||
|
GetCustomerParamsV1Schema.meta({
|
||||||
|
title: "GetCustomerParams",
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
customer_id: "cus_123",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
customer_id: "cus_123",
|
||||||
|
expand: ["invoices", "entities"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
ApiCustomerV5Schema.meta({
|
||||||
|
examples: [API_CUSTOMER_V5_EXAMPLE],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
export const listCustomersContract = oc
|
export const listCustomersContract = oc
|
||||||
.route({
|
.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|||||||
4
packages/openapi/v2.1/contracts/index.ts
vendored
4
packages/openapi/v2.1/contracts/index.ts
vendored
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "./balancesContract.js";
|
} from "./balancesContract.js";
|
||||||
import {
|
import {
|
||||||
billingAttachContract,
|
billingAttachContract,
|
||||||
|
billingCreateScheduleContract,
|
||||||
billingMultiAttachContract,
|
billingMultiAttachContract,
|
||||||
billingOpenCustomerPortalContract,
|
billingOpenCustomerPortalContract,
|
||||||
billingPreviewAttachContract,
|
billingPreviewAttachContract,
|
||||||
@@ -19,6 +20,7 @@ import {
|
|||||||
} from "./billingContract.js";
|
} from "./billingContract.js";
|
||||||
import {
|
import {
|
||||||
deleteCustomerContract,
|
deleteCustomerContract,
|
||||||
|
getCustomerContract,
|
||||||
getOrCreateCustomerContract,
|
getOrCreateCustomerContract,
|
||||||
listCustomersContract,
|
listCustomersContract,
|
||||||
updateCustomerContract,
|
updateCustomerContract,
|
||||||
@@ -55,6 +57,7 @@ import {
|
|||||||
export const v2_1ContractRouter = oc.router({
|
export const v2_1ContractRouter = oc.router({
|
||||||
// Customers
|
// Customers
|
||||||
getOrCreateCustomer: getOrCreateCustomerContract,
|
getOrCreateCustomer: getOrCreateCustomerContract,
|
||||||
|
getCustomer: getCustomerContract,
|
||||||
listCustomers: listCustomersContract,
|
listCustomers: listCustomersContract,
|
||||||
updateCustomer: updateCustomerContract,
|
updateCustomer: updateCustomerContract,
|
||||||
deleteCustomer: deleteCustomerContract,
|
deleteCustomer: deleteCustomerContract,
|
||||||
@@ -75,6 +78,7 @@ export const v2_1ContractRouter = oc.router({
|
|||||||
|
|
||||||
// Billing
|
// Billing
|
||||||
billingAttach: billingAttachContract,
|
billingAttach: billingAttachContract,
|
||||||
|
billingCreateSchedule: billingCreateScheduleContract,
|
||||||
billingMultiAttach: billingMultiAttachContract,
|
billingMultiAttach: billingMultiAttachContract,
|
||||||
billingPreviewAttach: billingPreviewAttachContract,
|
billingPreviewAttach: billingPreviewAttachContract,
|
||||||
billingPreviewMultiAttach: billingPreviewMultiAttachContract,
|
billingPreviewMultiAttach: billingPreviewMultiAttachContract,
|
||||||
|
|||||||
30
packages/openapi/v2.1/jsDocs/billingJsDocs.ts
vendored
30
packages/openapi/v2.1/jsDocs/billingJsDocs.ts
vendored
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
AttachParamsV1Schema,
|
AttachParamsV1Schema,
|
||||||
|
CreateScheduleParamsV0Schema,
|
||||||
MultiAttachParamsV0Schema,
|
MultiAttachParamsV0Schema,
|
||||||
UpdateSubscriptionV1ParamsSchema,
|
UpdateSubscriptionV1ParamsSchema,
|
||||||
} from "@autumn/shared";
|
} from "@autumn/shared";
|
||||||
@@ -179,6 +180,35 @@ export const billingMultiAttachJsDoc = createJSDocDescription({
|
|||||||
"A billing response with customer ID, invoice details, and payment URL (if checkout required).",
|
"A billing response with customer ID, invoice details, and payment URL (if checkout required).",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const billingCreateScheduleJsDoc = createJSDocDescription({
|
||||||
|
description:
|
||||||
|
"Creates a multi-phase subscription schedule for a customer. The first phase starts immediately and subsequent phases automatically transition at their scheduled start times.",
|
||||||
|
whenToUse:
|
||||||
|
"Use this endpoint to schedule future plan changes (e.g. switch from a trial plan to a paid plan on a specific date) or to define a sequence of plans that should activate over time.",
|
||||||
|
body: CreateScheduleParamsV0Schema,
|
||||||
|
examples: [
|
||||||
|
example({
|
||||||
|
description: "Schedule a transition from a trial plan to a paid plan",
|
||||||
|
values: {
|
||||||
|
customerId: "cus_123",
|
||||||
|
phases: [
|
||||||
|
{
|
||||||
|
startsAt: Date.now(),
|
||||||
|
plans: [{ planId: "trial_plan" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
startsAt: Date.now() + 14 * 24 * 60 * 60 * 1000,
|
||||||
|
plans: [{ planId: "pro_plan" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
methodName: "billing.createSchedule",
|
||||||
|
returns:
|
||||||
|
"A create-schedule response with the schedule ID, persisted phases, and any required payment or checkout URL.",
|
||||||
|
});
|
||||||
|
|
||||||
export const billingPreviewMultiAttachJsDoc = createJSDocDescription({
|
export const billingPreviewMultiAttachJsDoc = createJSDocDescription({
|
||||||
description:
|
description:
|
||||||
"Previews the billing changes that would occur when attaching multiple plans, without actually making any changes.",
|
"Previews the billing changes that would occur when attaching multiple plans, without actually making any changes.",
|
||||||
|
|||||||
29
packages/openapi/v2.1/jsDocs/customerJsDocs.ts
vendored
29
packages/openapi/v2.1/jsDocs/customerJsDocs.ts
vendored
@@ -1,4 +1,7 @@
|
|||||||
import { CreateCustomerParamsV0Schema } from "@autumn/shared";
|
import {
|
||||||
|
CreateCustomerParamsV0Schema,
|
||||||
|
GetCustomerParamsV1Schema,
|
||||||
|
} from "@autumn/shared";
|
||||||
import { createJSDocDescription, example } from "../../utils/jsDocs/index.js";
|
import { createJSDocDescription, example } from "../../utils/jsDocs/index.js";
|
||||||
|
|
||||||
export const getOrCreateCustomerJsDoc = createJSDocDescription({
|
export const getOrCreateCustomerJsDoc = createJSDocDescription({
|
||||||
@@ -19,3 +22,27 @@ export const getOrCreateCustomerJsDoc = createJSDocDescription({
|
|||||||
],
|
],
|
||||||
methodName: "getOrCreate",
|
methodName: "getOrCreate",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const getCustomerJsDoc = createJSDocDescription({
|
||||||
|
description:
|
||||||
|
"Fetches a customer by ID, optionally expanding related data such as invoices or entities.",
|
||||||
|
whenToUse:
|
||||||
|
"Use this when you know the customer exists or assert they exist without creating them.",
|
||||||
|
body: GetCustomerParamsV1Schema,
|
||||||
|
examples: [
|
||||||
|
example({
|
||||||
|
description: "Fetch a customer by external ID",
|
||||||
|
values: {
|
||||||
|
customerId: "cus_123",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
example({
|
||||||
|
description: "Fetch a customer with expanded invoices and entities",
|
||||||
|
values: {
|
||||||
|
customerId: "cus_123",
|
||||||
|
expand: ["invoices", "entities"],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
methodName: "get",
|
||||||
|
});
|
||||||
|
|||||||
2
packages/openapi/v2.1/openapi2.1.ts
vendored
2
packages/openapi/v2.1/openapi2.1.ts
vendored
@@ -16,6 +16,7 @@ import {
|
|||||||
CustomerDataSchema,
|
CustomerDataSchema,
|
||||||
CustomerExpandEnum,
|
CustomerExpandEnum,
|
||||||
CustomerIdSchema,
|
CustomerIdSchema,
|
||||||
|
GetCustomerParamsV1Schema,
|
||||||
LATEST_VERSION,
|
LATEST_VERSION,
|
||||||
PreviewUpdateSubscriptionResponseSchema,
|
PreviewUpdateSubscriptionResponseSchema,
|
||||||
SetupPaymentParamsV1Schema,
|
SetupPaymentParamsV1Schema,
|
||||||
@@ -54,6 +55,7 @@ async function generateOpenApiDocument(): Promise<Record<string, unknown>> {
|
|||||||
// in the OpenAPI output, which removeInternalFields() will then strip
|
// in the OpenAPI output, which removeInternalFields() will then strip
|
||||||
registerInternalSchemas(BaseApiCustomerSchema);
|
registerInternalSchemas(BaseApiCustomerSchema);
|
||||||
registerInternalSchemas(CreateCustomerParamsV1Schema);
|
registerInternalSchemas(CreateCustomerParamsV1Schema);
|
||||||
|
registerInternalSchemas(GetCustomerParamsV1Schema);
|
||||||
registerInternalSchemas(AttachParamsV1Schema);
|
registerInternalSchemas(AttachParamsV1Schema);
|
||||||
registerInternalSchemas(UpdateSubscriptionV1ParamsSchema);
|
registerInternalSchemas(UpdateSubscriptionV1ParamsSchema);
|
||||||
registerInternalSchemas(SetupPaymentParamsV1Schema);
|
registerInternalSchemas(SetupPaymentParamsV1Schema);
|
||||||
|
|||||||
Reference in New Issue
Block a user