diff --git a/.agents/skills/api/rules/aip-126-enums.md b/.agents/skills/api/rules/aip-126-enums.md index 9a711872c3..21e7e4fc69 100644 --- a/.agents/skills/api/rules/aip-126-enums.md +++ b/.agents/skills/api/rules/aip-126-enums.md @@ -3,5 +3,5 @@ Reference: https://kong-aip.netlify.app/aip/126/ - All enum wire values must be `snake_case` (enforced as an error by the `casing-aip-errors` linter rule). -- Every enum must define an `unknown` member as the zero/default value. +- Prefer defining an `unknown` member as the zero/default value. This is a recommendation, not a requirement — most domains (charges, subscriptions, currencies) omit it, so do not flag its absence as a violation. - Prefer enums over booleans for two-state fields — this allows a third state to be added later without a breaking change. diff --git a/api/spec/packages/aip-client-javascript/README.md b/api/spec/packages/aip-client-javascript/README.md index 8603d912cd..d9dcf45b12 100644 --- a/api/spec/packages/aip-client-javascript/README.md +++ b/api/spec/packages/aip-client-javascript/README.md @@ -24,6 +24,7 @@ TypeSpec definitions and ships fully-typed request and response models. - [Subscriptions](#subscriptions) - [Apps](#apps) - [Billing](#billing) + - [Invoices](#invoices) - [Tax](#tax) - [Currencies](#currencies) - [Features](#features) @@ -190,6 +191,12 @@ The full call path, HTTP route, and a short description are listed below. | `client.billing.updateProfile` | `PUT /openmeter/profiles/{id}` | Update a billing profile. | | `client.billing.deleteProfile` | `DELETE /openmeter/profiles/{id}` | Delete a billing profile. Only such billing profiles can be deleted that are: - not the default profile - not pinned to any customer using customer overrides - only have finalized invoices | +### Invoices + +| Method | HTTP | Description | +| --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `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. | + ### Tax | Method | HTTP | Description | diff --git a/api/spec/packages/aip-client-javascript/src/funcs/index.ts b/api/spec/packages/aip-client-javascript/src/funcs/index.ts index 5fba13a2ca..fb1f6ed3e8 100644 --- a/api/spec/packages/aip-client-javascript/src/funcs/index.ts +++ b/api/spec/packages/aip-client-javascript/src/funcs/index.ts @@ -5,6 +5,7 @@ export * from './entitlements.js' export * from './subscriptions.js' export * from './apps.js' export * from './billing.js' +export * from './invoices.js' export * from './tax.js' export * from './currencies.js' export * from './features.js' diff --git a/api/spec/packages/aip-client-javascript/src/funcs/invoices.ts b/api/spec/packages/aip-client-javascript/src/funcs/invoices.ts new file mode 100644 index 0000000000..88e4f13b7e --- /dev/null +++ b/api/spec/packages/aip-client-javascript/src/funcs/invoices.ts @@ -0,0 +1,21 @@ +import { type Client, http } from '../core.js' +import { type Result, type RequestOptions } from '../lib/types.js' +import { request } from '../lib/request.js' +import { encodePath, toURLSearchParams, encodeSort } from '../lib/encodings.js' +import type { + GetInvoiceRequest, + GetInvoiceResponse, +} from '../models/operations/invoices.js' + +export function getInvoice( + client: Client, + req: GetInvoiceRequest, + options?: RequestOptions, +): Promise> { + const path = encodePath('openmeter/billing/invoices/{invoiceId}', { + invoiceId: req.invoiceId, + }) + return request(() => + http(client).get(path, options).json(), + ) +} diff --git a/api/spec/packages/aip-client-javascript/src/index.ts b/api/spec/packages/aip-client-javascript/src/index.ts index d8a05931a8..ea535f596f 100644 --- a/api/spec/packages/aip-client-javascript/src/index.ts +++ b/api/spec/packages/aip-client-javascript/src/index.ts @@ -6,6 +6,7 @@ export { Entitlements } from './sdk/entitlements.js' export { Subscriptions } from './sdk/subscriptions.js' export { Apps } from './sdk/apps.js' export { Billing } from './sdk/billing.js' +export { Invoices } from './sdk/invoices.js' export { Tax } from './sdk/tax.js' export { Currencies } from './sdk/currencies.js' export { Features } from './sdk/features.js' @@ -38,6 +39,7 @@ export type * from './models/operations/entitlements.js' export type * from './models/operations/subscriptions.js' export type * from './models/operations/apps.js' export type * from './models/operations/billing.js' +export type * from './models/operations/invoices.js' export type * from './models/operations/tax.js' export type * from './models/operations/currencies.js' export type * from './models/operations/features.js' @@ -62,11 +64,15 @@ export type { CreateLabels, TaxConfigStripe, TaxConfigExternalInvoicing, - FlatFeeDiscounts, + ChargeFlatFeeDiscounts, PriceFree, WorkflowCollectionAlignmentSubscription, WorkflowPaymentChargeAutomaticallySettings, WorkflowPaymentSendInvoiceSettings, + InvoiceExternalReferences, + InvoiceAvailableActionDetails, + InvoiceWorkflowInvoicingSettings, + InvoiceLineExternalReferences, LlmCostProvider, LlmCostModel, RateCardStaticEntitlement, @@ -91,6 +97,7 @@ export type { PriceUnit, RateCardDiscounts, Totals, + InvoiceLineCreditsApplied, FeatureManualUnitCost, FeatureLlmUnitCostPricing, LlmCostModelPricing, @@ -109,6 +116,7 @@ export type { SubscriptionReference, AddonReference, AppReference, + ChargeReference, CurrencyFiat, FeatureReference, Event, @@ -149,7 +157,6 @@ export type { QueryFilterStringMapItem, CustomerKeyReference, CustomerUsageAttribution, - BillingAddress, Address, AppStripeCreateCheckoutSessionCustomerUpdate, AppStripeCreateCheckoutSessionConsentCollectionPaymentMethodReuseAgreement, @@ -173,6 +180,11 @@ export type { TaxCodeAppMapping, PartyTaxIdentity, WorkflowInvoicingSettings, + InvoiceValidationIssue, + InvoiceAvailableActions, + InvoiceLineAmountDiscount, + InvoiceLineUsageDiscount, + InvoiceLineBaseDiscount, ListCurrenciesParamsFilter, CurrencyCustom, CreateCurrencyCustomRequest, @@ -206,6 +218,7 @@ export type { PlanAddon, CreatePlanAddonRequest, ProfileAppReferences, + InvoiceWorkflowAppsReferences, ListEventsParamsFilter, ResourceFilters, FieldFilters, @@ -220,6 +233,7 @@ export type { Customer, UpsertCustomerRequest, PartyAddresses, + InvoiceCustomer, AppStripeCreateCheckoutSessionConsentCollection, ListCustomerEntitlementAccessResponseData, WorkflowCollectionAlignmentAnchored, @@ -233,6 +247,9 @@ export type { CreateTaxCodeRequest, TaxCode, UpsertTaxCodeRequest, + InvoiceWorkflow, + InvoiceStatusDetails, + InvoiceLineDiscounts, InvoiceUsageQuantityDetail, GovernanceFeatureAccess, CustomerData, @@ -244,7 +261,7 @@ export type { PricePagePaginatedResponse, CreateCreditGrantRequest, CreditGrant, - CreateFlatFeeChargeRequest, + CreateChargeFlatFeeRequest, WorkflowTaxSettings, SubscriptionAddonPagePaginatedResponse, PlanAddonPagePaginatedResponse, @@ -253,8 +270,11 @@ export type { MeterQueryRequest, CustomerPagePaginatedResponse, Party, + Supplier, AppStripeCreateCheckoutSessionRequestOptions, TaxCodePagePaginatedResponse, + InvoiceWorkflowSettings, + InvoiceDetailedLine, CurrencyPagePaginatedResponse, GovernanceQueryResult, Feature, @@ -262,17 +282,20 @@ export type { UpdateFeatureRequest, CreditGrantPagePaginatedResponse, BadRequest, + InvoiceBase, CustomerStripeCreateCheckoutSessionRequest, WorkflowCollectionSettings, AppPagePaginatedResponse, ProfileApps, GovernanceQueryResponse, - FlatFeeCharge, - UsageBasedCharge, - CreateUsageBasedChargeRequest, + ChargeFlatFee, + ChargeUsageBased, + CreateChargeUsageBasedRequest, + InvoiceLineRateCard, RateCard, FeaturePagePaginatedResponse, Workflow, + InvoiceStandardLine, PlanPhase, Addon, CreateAddonRequest, @@ -286,10 +309,12 @@ export type { UpsertPlanRequest, AddonPagePaginatedResponse, ProfilePagePaginatedResponse, + InvoiceStandard, PlanPagePaginatedResponse, SortQueryInput, BaseErrorInput, WorkflowPaymentSendInvoiceSettingsInput, + InvoiceWorkflowInvoicingSettingsInput, EventInput, UnauthorizedInput, ForbiddenInput, @@ -313,6 +338,7 @@ export type { GovernanceQueryRequestInput, IngestedEventInput, SubscriptionCancelInput, + InvoiceWorkflowInput, InvoiceUsageQuantityDetailInput, CreateCreditGrantRequestInput, CreditGrantInput, @@ -320,12 +346,15 @@ export type { IngestedEventPaginatedResponseInput, MeterQueryRequestInput, AppStripeCreateCheckoutSessionRequestOptionsInput, + InvoiceWorkflowSettingsInput, + InvoiceDetailedLineInput, CreditGrantPagePaginatedResponseInput, BadRequestInput, CustomerStripeCreateCheckoutSessionRequestInput, WorkflowCollectionSettingsInput, RateCardInput, WorkflowInput, + InvoiceStandardLineInput, PlanPhaseInput, AddonInput, CreateAddonRequestInput, @@ -338,5 +367,6 @@ export type { UpsertPlanRequestInput, AddonPagePaginatedResponseInput, ProfilePagePaginatedResponseInput, + InvoiceStandardInput, PlanPagePaginatedResponseInput, } from './models/types.js' diff --git a/api/spec/packages/aip-client-javascript/src/models/operations/customers.ts b/api/spec/packages/aip-client-javascript/src/models/operations/customers.ts index 6639e02010..ddc08dd08e 100644 --- a/api/spec/packages/aip-client-javascript/src/models/operations/customers.ts +++ b/api/spec/packages/aip-client-javascript/src/models/operations/customers.ts @@ -5,11 +5,11 @@ import type { AppStripeCreateCheckoutSessionResult, AppStripeCreateCustomerPortalSessionResult, ChargePagePaginatedResponse, + CreateChargeFlatFeeRequest, + CreateChargeUsageBasedRequest, CreateCreditAdjustmentRequest as CreateCreditAdjustmentRequestBody, CreateCreditGrantRequestInput, CreateCustomerRequest as CreateCustomerRequestBody, - CreateFlatFeeChargeRequest, - CreateUsageBasedChargeRequest, CreditAdjustment, CreditBalances, CreditGrant, @@ -172,7 +172,7 @@ export type ListCustomerChargesResponse = ChargePagePaginatedResponse export type CreateCustomerChargesRequest = { customerId: string - body: CreateFlatFeeChargeRequest | CreateUsageBasedChargeRequest + body: CreateChargeFlatFeeRequest | CreateChargeUsageBasedRequest } export type CreateCustomerChargesResponse = z.output< typeof schemas.createCustomerChargesResponse diff --git a/api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts b/api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts new file mode 100644 index 0000000000..0bcb2662c5 --- /dev/null +++ b/api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts @@ -0,0 +1,7 @@ +import { z } from 'zod' +import * as schemas from '../schemas.js' + +export type GetInvoiceRequest = { + invoiceId: string +} +export type GetInvoiceResponse = z.output diff --git a/api/spec/packages/aip-client-javascript/src/models/schemas.ts b/api/spec/packages/aip-client-javascript/src/models/schemas.ts index 532f636365..90a3dd4a99 100644 --- a/api/spec/packages/aip-client-javascript/src/models/schemas.ts +++ b/api/spec/packages/aip-client-javascript/src/models/schemas.ts @@ -584,11 +584,11 @@ export const chargesExpand = z "Expands for customer charges. Values: - `real_time_usage`: The charge's real-time usage.", ) -export const resourceManagedBy = z - .enum(['manual', 'system', 'subscription']) +export const lifecycleController = z + .enum(['system', 'manual']) .describe( - 'Identifies which system manages a resource. Values: - `manual`: The resource is managed manually (overridden by our API users). - `system`: The resource is managed by the system. - `subscription`: The resource is managed by the subscription.', + 'Identifies whether a resource lifecycle is controlled by OpenMeter or manually overridden by the API user. Values: - `system`: The resource lifecycle is controlled by OpenMeter. - `manual`: The resource lifecycle was manually overridden by the API user.', ) export const chargeStatus = z @@ -630,7 +630,7 @@ export const pricePaymentTerm = z .union([z.literal('in_advance'), z.literal('in_arrears')]) .describe('The payment term of a flat price.') -export const flatFeeDiscounts = z +export const chargeFlatFeeDiscounts = z .object({ percentage: z .number() @@ -728,6 +728,112 @@ export const workflowPaymentSendInvoiceSettings = z 'Payment settings for a billing workflow when the collection method is send invoice.', ) +export const invoiceNumber = z + .string() + .min(1) + .max(256) + + .describe( + 'InvoiceNumber is a unique identifier for the invoice, generated by the invoicing app. The uniqueness depends on a lot of factors: - app setting (unique per app or unique per customer) - multiple app scenarios (multiple apps generating invoices with the same prefix)', + ) + +export const invoiceValidationIssueSeverity = z + .enum(['critical', 'warning']) + .describe('Severity level of an invoice validation issue.') + +export const invoiceExternalReferences = z + .object({ + invoicing_id: z + .string() + .optional() + + .describe( + 'The ID assigned by the external invoicing app (e.g. Stripe invoice ID).', + ), + payment_id: z + .string() + .optional() + + .describe( + 'The ID assigned by the external payment app (e.g. Stripe payment intent ID).', + ), + }) + + .describe( + 'External identifiers assigned to an invoice by third-party systems.', + ) + +export const invoiceStandardStatus = z + .enum([ + 'draft', + 'issuing', + 'issued', + 'payment_processing', + 'overdue', + 'paid', + 'uncollectible', + 'voided', + ]) + .describe('Lifecycle status of a standard invoice.') + +export const invoiceAvailableActionDetails = z + .object({ + resulting_state: z + .string() + + .describe( + 'The extended status the invoice will transition to after performing this action.', + ), + }) + + .describe( + 'Details about an available invoice action including the resulting state.', + ) + +export const invoiceWorkflowInvoicingSettings = z + .object({ + auto_advance: z + .boolean() + .optional() + .default(true) + + .describe( + 'Whether to automatically issue the invoice after the draft_period has passed.', + ), + draft_period: z + .string() + .optional() + .default('P0D') + + .describe( + 'The period for the invoice to be kept in draft status for manual reviews.', + ), + }) + + .describe( + 'Invoice-level invoicing settings. A subset of BillingWorkflowInvoicingSettings limited to fields that are meaningful per-invoice. progressive_billing is omitted as it is a gather-time / profile-level decision.', + ) + +export const invoiceDiscountReason = z + .enum(['maximum_spend', 'ratecard_percentage', 'ratecard_usage']) + .describe('The reason a discount was applied to an invoice line.') + +export const invoiceLineExternalReferences = z + .object({ + invoicing_id: z + .string() + .optional() + .describe('The ID assigned by the external invoicing app.'), + }) + + .describe( + 'External identifiers for an invoice line item assigned by third-party systems.', + ) + +export const invoiceDetailedLineCostCategory = z + .enum(['regular', 'commitment']) + .describe('Cost category of a detailed invoice line item.') + export const currencyType = z .enum(['fiat', 'custom']) @@ -1097,13 +1203,19 @@ export const chargeType = z 'Type of a charge. Values: - `flat_fee`: A fixed-amount charge. - `usage_based`: A usage-priced charge.', ) -export const invoiceNumber = z - .string() - .min(1) - .max(256) +export const invoiceType = z + .enum(['standard']) + .describe('The type of a billing invoice.') + +export const invoiceLineType = z + .enum(['standard_line']) + .describe('Line item type discriminator.') + +export const priceType = z + .enum(['free', 'flat', 'unit', 'graduated', 'volume']) .describe( - 'InvoiceNumber is a unique identifier for the invoice, generated by the invoicing app. The uniqueness depends on a lot of factors: - app setting (unique per app or unique per customer) - multiple app scenarios (multiple apps generating invoices with the same prefix)', + "The type of the price. - `free`: No charge, the rate card is included at no cost. - `flat`: A fixed amount charged once per billing period, regardless of usage. - `unit`: A fixed rate charged per billing unit consumed. - `graduated`: Tiered pricing where each tier's rate applies only to usage within that tier. - `volume`: Tiered pricing where the rate for the highest tier reached applies to all units in the period.", ) export const collectionAlignment = z @@ -1120,13 +1232,6 @@ export const collectionMethod = z 'Collection method specifies how the invoice should be collected (automatic or manual).', ) -export const priceType = z - .enum(['free', 'flat', 'unit', 'graduated', 'volume']) - - .describe( - "The type of the price. - `free`: No charge, the rate card is included at no cost. - `flat`: A fixed amount charged once per billing period, regardless of usage. - `unit`: A fixed rate charged per billing unit consumed. - `graduated`: Tiered pricing where each tier's rate applies only to usage within that tier. - `volume`: Tiered pricing where the rate for the highest tier reached applies to all units in the period.", - ) - export const featureUnitCostType = z .enum(['llm', 'manual']) .describe('The type of unit cost.') @@ -1271,6 +1376,19 @@ export const totals = z 'Totals contains the summaries of all calculations for a billing resource.', ) +export const invoiceLineCreditsApplied = z + .object({ + amount: numeric, + description: z + .string() + .optional() + + .describe( + 'Optional human-readable description of the credit allocation.', + ), + }) + .describe('A credit allocation applied to an invoice line item.') + export const featureManualUnitCost = z .object({ type: z @@ -1461,6 +1579,12 @@ export const appReference = z }) .describe('App reference.') +export const chargeReference = z + .object({ + id: ulid, + }) + .describe('Reference to a charge associated with an invoice line.') + export const currencyFiat = z .object({ id: ulid, @@ -2154,18 +2278,6 @@ export const customerUsageAttribution = z 'Mapping to attribute metered usage to the customer. One customer can have zero or more subjects, but one subject can only belong to one customer.', ) -export const billingAddress = z - .object({ - country: countryCode.optional(), - postal_code: z.string().optional().describe('Postal code.'), - state: z.string().optional().describe('State or province.'), - city: z.string().optional().describe('City.'), - line1: z.string().optional().describe('First line of the address.'), - line2: z.string().optional().describe('Second line of the address.'), - phone_number: z.string().optional().describe('Phone number.'), - }) - .describe('Address') - export const address = z .object({ country: countryCode.optional(), @@ -2532,6 +2644,79 @@ export const workflowPaymentSettings = z ]) .describe('Payment settings for a billing workflow.') +export const invoiceValidationIssue = z + .object({ + code: z.string().describe('Machine-readable error code.'), + message: z.string().describe('Human-readable description of the error.'), + attributes: z + .record(z.string(), z.unknown()) + .optional() + .describe('Additional structured context.'), + severity: invoiceValidationIssueSeverity, + field: z + .string() + .optional() + + .describe( + 'JSON path to the field that caused this validation issue, if applicable. For example: `lines/0/rate_card/price`.', + ), + }) + + .describe( + 'A validation issue found during invoice processing. Converges on the same structure used by plan and subscription validation errors: a machine-readable `code`, a human-readable `message`, optional structured `attributes`, plus a `severity` and optional `field` path.', + ) + +export const invoiceAvailableActions = z + .object({ + advance: invoiceAvailableActionDetails.optional(), + approve: invoiceAvailableActionDetails.optional(), + delete: invoiceAvailableActionDetails.optional(), + retry: invoiceAvailableActionDetails.optional(), + snapshot_quantities: invoiceAvailableActionDetails.optional(), + }) + + .describe( + 'The set of state-transition actions available for an invoice in its current status. A field is present only when that action is permitted from the current state.', + ) + +export const invoiceLineAmountDiscount = z + .object({ + id: ulid, + reason: invoiceDiscountReason, + description: z + .string() + .optional() + .describe('Optional human-readable description of the discount.'), + external_references: invoiceLineExternalReferences.optional(), + amount: numeric, + }) + .describe('A monetary amount discount applied to an invoice line item.') + +export const invoiceLineUsageDiscount = z + .object({ + id: ulid, + reason: invoiceDiscountReason, + description: z + .string() + .optional() + .describe('Optional human-readable description of the discount.'), + external_references: invoiceLineExternalReferences.optional(), + quantity: numeric, + }) + .describe('A usage quantity discount applied to an invoice line item.') + +export const invoiceLineBaseDiscount = z + .object({ + id: ulid, + reason: invoiceDiscountReason, + description: z + .string() + .optional() + .describe('Optional human-readable description of the discount.'), + external_references: invoiceLineExternalReferences.optional(), + }) + .describe('Base fields shared by all invoice line item discounts.') + export const listCurrenciesParamsFilter = z .object({ type: currencyType.optional(), @@ -3092,6 +3277,17 @@ export const profileAppReferences = z }) .describe('References to the applications used by a billing profile.') +export const invoiceWorkflowAppsReferences = z + .object({ + tax: appReference, + invoicing: appReference, + payment: appReference, + }) + + .describe( + 'BillingInvoiceWorkflowAppsReferences represents the references (id) to the apps used by a billing profile', + ) + export const listEventsParamsFilter = z .object({ id: stringFieldFilter.optional(), @@ -3231,7 +3427,7 @@ export const createCustomerRequest = z .optional() .describe('The primary email address of the customer.'), currency: currencyCode.optional(), - billing_address: billingAddress.optional(), + billing_address: address.optional(), }) .describe('Customer create request.') @@ -3262,7 +3458,7 @@ export const customer = z .optional() .describe('The primary email address of the customer.'), currency: currencyCode.optional(), - billing_address: billingAddress.optional(), + billing_address: address.optional(), }) .describe( @@ -3291,7 +3487,7 @@ export const upsertCustomerRequest = z .optional() .describe('The primary email address of the customer.'), currency: currencyCode.optional(), - billing_address: billingAddress.optional(), + billing_address: address.optional(), }) .describe('Customer upsert request.') @@ -3301,6 +3497,23 @@ export const partyAddresses = z }) .describe('A collection of addresses for the party.') +export const invoiceCustomer = z + .object({ + id: ulid, + name: z + .string() + .min(1) + .max(256) + .describe('Display name of the resource. Between 1 and 256 characters.'), + usage_attribution: customerUsageAttribution.optional(), + billing_address: address.optional(), + key: externalResourceKey.optional(), + }) + + .describe( + "Snapshot of the customer's information at the time the invoice was issued.", + ) + export const appStripeCreateCheckoutSessionConsentCollection = z .object({ payment_method_reuse_agreement: @@ -3577,6 +3790,51 @@ export const upsertTaxCodeRequest = z }) .describe('TaxCode upsert request.') +export const invoiceWorkflow = z + .object({ + invoicing: invoiceWorkflowInvoicingSettings.optional(), + payment: workflowPaymentSettings.optional(), + }) + + .describe( + 'Invoice-level snapshot of the workflow configuration. Contains only the settings that are meaningful for an already-created invoice: invoicing behaviour and payment settings. Collection alignment and tax policy are gather-time / profile-wide concerns and are not included.', + ) + +export const invoiceStatusDetails = z + .object({ + immutable: z + .boolean() + + .describe( + 'Whether the invoice is immutable (i.e. cannot be modified or deleted).', + ), + failed: z.boolean().describe('Whether the invoice is in a failed state.'), + extended_status: z + .string() + + .describe( + 'Fine-grained internal status string providing additional workflow detail beyond the top-level status enum.', + ), + available_actions: invoiceAvailableActions, + }) + .describe('Detailed status information for a standard invoice.') + +export const invoiceLineDiscounts = z + .object({ + amount: z + .array(invoiceLineAmountDiscount) + .optional() + + .describe( + 'Monetary amount discounts (e.g. from maximum spend commitments).', + ), + usage: z + .array(invoiceLineUsageDiscount) + .optional() + .describe('Usage quantity discounts (e.g. free tier usage allowances).'), + }) + .describe('Discounts applied to an invoice line item.') + export const currency = z .discriminatedUnion('type', [currencyFiat, currencyCustom]) .describe('Fiat or custom currency.') @@ -3769,7 +4027,7 @@ export const creditGrant = z 'A credit grant allocates credits to a customer. Credits are drawn down against charges according to the settlement mode configured on the rate card.', ) -export const createFlatFeeChargeRequest = z +export const createChargeFlatFeeRequest = z .object({ name: z .string() @@ -3796,7 +4054,7 @@ export const createFlatFeeChargeRequest = z settlement_mode: settlementMode, tax_config: taxConfig.optional(), payment_term: pricePaymentTerm, - discounts: flatFeeDiscounts.optional(), + discounts: chargeFlatFeeDiscounts.optional(), feature_key: z .string() .optional() @@ -3898,6 +4156,21 @@ export const party = z }) .describe('Party represents a person or business entity.') +export const supplier = z + .object({ + id: z.string().optional().describe('Unique identifier for the party.'), + name: z + .string() + .optional() + .describe('Legal name or representation of the party.'), + tax_id: partyTaxIdentity.optional(), + addresses: partyAddresses.optional(), + }) + + .describe( + "Snapshot of the supplier's information at the time the invoice was issued. Structurally a read-only subset of `BillingParty` (the type configured on the billing profile), so the snapshot stays aligned with the source. `key` is omitted because it is not part of the snapshotted supplier data.", + ) + export const appStripeCreateCheckoutSessionRequestOptions = z .object({ billing_address_collection: @@ -3998,6 +4271,54 @@ export const taxCodePagePaginatedResponse = z }) .describe('Page paginated response.') +export const invoiceWorkflowSettings = z + .object({ + apps: invoiceWorkflowAppsReferences.optional(), + source_billing_profile: profileReference, + workflow: invoiceWorkflow, + }) + + .describe( + 'Snapshot of the billing workflow configuration captured at invoice creation.', + ) + +export const invoiceDetailedLine = z + .object({ + id: ulid, + name: z + .string() + .min(1) + .max(256) + .describe('Display name of the resource. Between 1 and 256 characters.'), + description: z + .string() + .max(1024) + .optional() + + .describe( + 'Optional description of the resource. Maximum 1024 characters.', + ), + labels: labels.optional(), + created_at: dateTime, + updated_at: dateTime, + deleted_at: dateTime.optional(), + service_period: closedPeriod, + totals: totals, + category: invoiceDetailedLineCostCategory.default('regular'), + discounts: invoiceLineDiscounts.optional(), + credits_applied: z + .array(invoiceLineCreditsApplied) + .optional() + .describe('Credit applied to this detailed line.'), + external_references: invoiceLineExternalReferences.optional(), + quantity: numeric, + unit_price: numeric, + }) + + .describe( + 'A detailed (child) sub-line belonging to a parent invoice line. Detailed lines represent the individual flat-fee components that make up a usage-based parent line after quantity snapshotting.', + ) + export const currencyPagePaginatedResponse = z .object({ data: z.array(currency), @@ -4120,6 +4441,41 @@ export const badRequest = z ) .describe('Bad Request.') +export const invoiceBase = z + .object({ + id: ulid, + description: z + .string() + .max(1024) + .optional() + + .describe( + 'Optional description of the resource. Maximum 1024 characters.', + ), + labels: labels.optional(), + created_at: dateTime, + updated_at: dateTime, + deleted_at: dateTime.optional(), + number: invoiceNumber, + currency: currencyCode, + supplier: supplier, + customer: invoiceCustomer, + totals: totals, + service_period: closedPeriod, + validation_issues: z + .array(invoiceValidationIssue) + .optional() + + .describe( + 'Validation issues found during invoice processing. Present only when there are one or more validation findings. An empty list is omitted.', + ), + external_references: invoiceExternalReferences.optional(), + }) + + .describe( + 'Base fields shared by all invoice types. Spread this model into each concrete invoice variant.', + ) + export const customerStripeCreateCheckoutSessionRequest = z .object({ stripe_options: appStripeCreateCheckoutSessionRequestOptions, @@ -4175,7 +4531,7 @@ export const governanceQueryResponse = z }) .describe('Response of the governance query.') -export const flatFeeCharge = z +export const chargeFlatFee = z .object({ id: ulid, name: z @@ -4197,7 +4553,7 @@ export const flatFeeCharge = z deleted_at: dateTime.optional(), type: z.literal('flat_fee').describe('The type of the charge.'), customer: billingCustomerReference, - managed_by: resourceManagedBy, + lifecycle_controller: lifecycleController, subscription: subscriptionReference.optional(), currency: currencyCode, status: chargeStatus, @@ -4213,7 +4569,7 @@ export const flatFeeCharge = z settlement_mode: settlementMode, tax_config: taxConfig.optional(), payment_term: pricePaymentTerm, - discounts: flatFeeDiscounts.optional(), + discounts: chargeFlatFeeDiscounts.optional(), feature_key: z .string() .optional() @@ -4225,7 +4581,7 @@ export const flatFeeCharge = z }) .describe('A flat fee charge for a customer.') -export const usageBasedCharge = z +export const chargeUsageBased = z .object({ id: ulid, name: z @@ -4247,7 +4603,7 @@ export const usageBasedCharge = z deleted_at: dateTime.optional(), type: z.literal('usage_based').describe('The type of the charge.'), customer: billingCustomerReference, - managed_by: resourceManagedBy, + lifecycle_controller: lifecycleController, subscription: subscriptionReference.optional(), currency: currencyCode, status: chargeStatus, @@ -4269,7 +4625,7 @@ export const usageBasedCharge = z }) .describe('A usage-based charge for a customer.') -export const createUsageBasedChargeRequest = z +export const createChargeUsageBasedRequest = z .object({ name: z .string() @@ -4303,6 +4659,15 @@ export const createUsageBasedChargeRequest = z }) .describe('Usage-based charge create request.') +export const invoiceLineRateCard = z + .object({ + price: price, + tax_config: rateCardTaxConfig.optional(), + feature_key: resourceKey.optional(), + discounts: rateCardDiscounts.optional(), + }) + .describe('Rate card configuration snapshot for a usage-based invoice line.') + export const rateCard = z .object({ name: z @@ -4352,16 +4717,63 @@ export const workflow = z .describe('Billing workflow settings.') export const charge = z - .discriminatedUnion('type', [flatFeeCharge, usageBasedCharge]) + .discriminatedUnion('type', [chargeFlatFee, chargeUsageBased]) .describe('Customer charge.') export const createChargeRequest = z .discriminatedUnion('type', [ - createFlatFeeChargeRequest, - createUsageBasedChargeRequest, + createChargeFlatFeeRequest, + createChargeUsageBasedRequest, ]) .describe('Customer charge.') +export const invoiceStandardLine = z + .object({ + id: ulid, + name: z + .string() + .min(1) + .max(256) + .describe('Display name of the resource. Between 1 and 256 characters.'), + description: z + .string() + .max(1024) + .optional() + + .describe( + 'Optional description of the resource. Maximum 1024 characters.', + ), + labels: labels.optional(), + created_at: dateTime, + updated_at: dateTime, + deleted_at: dateTime.optional(), + type: z + .literal('standard_line') + .describe('The type of charge this line item represents.'), + lifecycle_controller: lifecycleController, + service_period: closedPeriod, + totals: totals, + discounts: invoiceLineDiscounts.optional(), + credits_applied: z + .array(invoiceLineCreditsApplied) + .optional() + .describe('Credit applied to this line item.'), + external_references: invoiceLineExternalReferences.optional(), + subscription: subscriptionReference.optional(), + rate_card: invoiceLineRateCard, + detailed_lines: z + .array(invoiceDetailedLine) + + .describe( + 'Detailed sub-lines that this line has been broken down into. Present when line has individual details.', + ), + charge: chargeReference.optional(), + }) + + .describe( + 'A top-level line item on an invoice. Each line represents a single charge, typically associated with a rate card from a subscription. Detailed (child) lines are nested under `detailed_lines` when present.', + ) + export const planPhase = z .object({ name: z @@ -4559,6 +4971,13 @@ export const chargePagePaginatedResponse = z }) .describe('Page paginated response.') +export const invoiceLine = z + .discriminatedUnion('type', [invoiceStandardLine]) + + .describe( + 'A top-level line item on an invoice. Each line represents a single charge, typically associated with a rate card from a subscription. Detailed (child) lines are nested under `detailed_lines` when present.', + ) + export const plan = z .object({ id: ulid, @@ -4696,6 +5115,57 @@ export const profilePagePaginatedResponse = z }) .describe('Page paginated response.') +export const invoiceStandard = z + .object({ + id: ulid, + description: z + .string() + .max(1024) + .optional() + + .describe( + 'Optional description of the resource. Maximum 1024 characters.', + ), + labels: labels.optional(), + created_at: dateTime, + updated_at: dateTime, + deleted_at: dateTime.optional(), + number: invoiceNumber, + currency: currencyCode, + supplier: supplier, + customer: invoiceCustomer, + totals: totals, + service_period: closedPeriod, + validation_issues: z + .array(invoiceValidationIssue) + .optional() + + .describe( + 'Validation issues found during invoice processing. Present only when there are one or more validation findings. An empty list is omitted.', + ), + external_references: invoiceExternalReferences.optional(), + type: z + .literal('standard') + .describe('Discriminator field identifying this as a standard invoice.'), + status: invoiceStandardStatus, + status_details: invoiceStatusDetails, + issued_at: dateTime.optional(), + draft_until: dateTime.optional(), + quantity_snapshotted_at: dateTime.optional(), + collection_at: dateTime.optional(), + due_at: dateTime.optional(), + sent_to_customer_at: dateTime.optional(), + workflow: invoiceWorkflowSettings, + lines: z + .array(invoiceLine) + .optional() + + .describe( + 'Line items on this invoice. Always returned on single-resource GET; omitted on list endpoints unless explicitly expanded.', + ), + }) + .describe('A standard invoice for charges owed by the customer.') + export const planPagePaginatedResponse = z .object({ data: z.array(plan), @@ -4703,6 +5173,13 @@ export const planPagePaginatedResponse = z }) .describe('Page paginated response.') +export const invoice = z + .discriminatedUnion('type', [invoiceStandard]) + + .describe( + 'An invoice issued to a customer. The `type` field determines the concrete variant: - `standard`: a standard invoice for charges owed.', + ) + export const listMeteringEventsQueryParams = z.object({ page: cursorPaginationQueryPage.optional(), filter: listEventsParamsFilter.optional(), @@ -5137,6 +5614,12 @@ export const deleteBillingProfilePathParams = z.object({ id: ulid, }) +export const getInvoicePathParams = z.object({ + invoiceId: ulid, +}) + +export const getInvoiceResponse = invoice + export const createTaxCodeBody = createTaxCodeRequest export const createTaxCodeResponse = taxCode diff --git a/api/spec/packages/aip-client-javascript/src/models/types.ts b/api/spec/packages/aip-client-javascript/src/models/types.ts index e8423e8ba0..0b9e487edf 100644 --- a/api/spec/packages/aip-client-javascript/src/models/types.ts +++ b/api/spec/packages/aip-client-javascript/src/models/types.ts @@ -126,7 +126,7 @@ export interface TaxConfigExternalInvoicing { } /** Discounts applicable to flat fee charges. This is the same as `ProductCatalog.Discounts` but without the `usage` field, which is not applicable to flat fee charges. */ -export interface FlatFeeDiscounts { +export interface ChargeFlatFeeDiscounts { /** Percentage discount applied to the price (0–100). */ percentage?: number } @@ -157,6 +157,34 @@ export interface WorkflowPaymentSendInvoiceSettings { due_after: string } +/** External identifiers assigned to an invoice by third-party systems. */ +export interface InvoiceExternalReferences { + /** The ID assigned by the external invoicing app (e.g. Stripe invoice ID). */ + invoicing_id?: string + /** The ID assigned by the external payment app (e.g. Stripe payment intent ID). */ + payment_id?: string +} + +/** Details about an available invoice action including the resulting state. */ +export interface InvoiceAvailableActionDetails { + /** The extended status the invoice will transition to after performing this action. */ + resulting_state: string +} + +/** Invoice-level invoicing settings. A subset of BillingWorkflowInvoicingSettings limited to fields that are meaningful per-invoice. progressive_billing is omitted as it is a gather-time / profile-level decision. */ +export interface InvoiceWorkflowInvoicingSettings { + /** Whether to automatically issue the invoice after the draft_period has passed. */ + auto_advance: boolean + /** The period for the invoice to be kept in draft status for manual reviews. */ + draft_period: string +} + +/** External identifiers for an invoice line item assigned by third-party systems. */ +export interface InvoiceLineExternalReferences { + /** The ID assigned by the external invoicing app. */ + invoicing_id?: string +} + /** LLM Provider */ export interface LlmCostProvider { /** Identifier of the provider, e.g., "openai", "anthropic". */ @@ -373,6 +401,14 @@ export interface Totals { total: string } +/** A credit allocation applied to an invoice line item. */ +export interface InvoiceLineCreditsApplied { + /** The monetary amount credited. */ + amount: string + /** Optional human-readable description of the credit allocation. */ + description?: string +} + /** A fixed per-unit cost amount. */ export interface FeatureManualUnitCost { /** The type discriminator for manual unit cost. */ @@ -623,6 +659,12 @@ export interface AppReference { id: string } +/** Reference to a charge associated with an invoice line. */ +export interface ChargeReference { + /** Unique identifier for the charge. */ + id: string +} + /** Currency describes a currency supported by the billing system. */ export interface CurrencyFiat { id: string @@ -1071,24 +1113,6 @@ export interface CustomerUsageAttribution { subject_keys: string[] } -/** Address */ -export interface BillingAddress { - /** Country code in [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) alpha-2 format. */ - country?: string - /** Postal code. */ - postal_code?: string - /** State or province. */ - state?: string - /** City. */ - city?: string - /** First line of the address. */ - line1?: string - /** Second line of the address. */ - line2?: string - /** Phone number. */ - phone_number?: string -} - /** Address */ export interface Address { /** Country code in [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) alpha-2 format. */ @@ -1383,6 +1407,74 @@ export interface WorkflowInvoicingSettings { subscription_end_proration_mode: 'bill_full_period' | 'bill_actual_period' } +/** A validation issue found during invoice processing. Converges on the same structure used by plan and subscription validation errors: a machine-readable `code`, a human-readable `message`, optional structured `attributes`, plus a `severity` and optional `field` path. */ +export interface InvoiceValidationIssue { + /** Machine-readable error code. */ + code: string + /** Human-readable description of the error. */ + message: string + /** Additional structured context. */ + attributes?: Record + /** Severity of the validation issue. */ + severity: 'critical' | 'warning' + /** JSON path to the field that caused this validation issue, if applicable. For example: `lines/0/rate_card/price`. */ + field?: string +} + +/** The set of state-transition actions available for an invoice in its current status. A field is present only when that action is permitted from the current state. */ +export interface InvoiceAvailableActions { + /** Advance the invoice to the next workflow step. */ + advance?: InvoiceAvailableActionDetails + /** Approve the invoice for issuance. */ + approve?: InvoiceAvailableActionDetails + /** Delete the invoice. */ + delete?: InvoiceAvailableActionDetails + /** Retry a failed workflow step. */ + retry?: InvoiceAvailableActionDetails + /** Snapshot the current usage quantities. */ + snapshot_quantities?: InvoiceAvailableActionDetails +} + +/** A monetary amount discount applied to an invoice line item. */ +export interface InvoiceLineAmountDiscount { + /** Unique identifier for the discount. */ + id: string + /** The reason this discount was applied. */ + reason: 'maximum_spend' | 'ratecard_percentage' | 'ratecard_usage' + /** Optional human-readable description of the discount. */ + description?: string + /** External identifiers for this discount. */ + external_references?: InvoiceLineExternalReferences + /** The monetary amount deducted. */ + amount: string +} + +/** A usage quantity discount applied to an invoice line item. */ +export interface InvoiceLineUsageDiscount { + /** Unique identifier for the discount. */ + id: string + /** The reason this discount was applied. */ + reason: 'maximum_spend' | 'ratecard_percentage' | 'ratecard_usage' + /** Optional human-readable description of the discount. */ + description?: string + /** External identifiers for this discount. */ + external_references?: InvoiceLineExternalReferences + /** The usage quantity deducted (in billing units). */ + quantity: string +} + +/** Base fields shared by all invoice line item discounts. */ +export interface InvoiceLineBaseDiscount { + /** Unique identifier for the discount. */ + id: string + /** The reason this discount was applied. */ + reason: 'maximum_spend' | 'ratecard_percentage' | 'ratecard_usage' + /** Optional human-readable description of the discount. */ + description?: string + /** External identifiers for this discount. */ + external_references?: InvoiceLineExternalReferences +} + /** Filter options for listing currencies. */ export interface ListCurrenciesParamsFilter { type?: 'fiat' | 'custom' @@ -1944,6 +2036,16 @@ export interface ProfileAppReferences { payment: AppReference } +/** BillingInvoiceWorkflowAppsReferences represents the references (id) to the apps used by a billing profile */ +export interface InvoiceWorkflowAppsReferences { + /** The tax app used for this workflow */ + tax: AppReference + /** The invoicing app used for this workflow */ + invoicing: AppReference + /** The payment app used for this workflow */ + payment: AppReference +} + /** Filter options for listing ingested events. */ export interface ListEventsParamsFilter { /** Filter events by ID. */ @@ -2162,7 +2264,7 @@ export interface CreateCustomerRequest { /** Currency of the customer. Used for billing, tax and invoicing. */ currency?: string /** The billing address of the customer. Used for tax and invoicing. */ - billing_address?: BillingAddress + billing_address?: Address } /** Customers can be individuals or organizations that can subscribe to plans and have access to features. */ @@ -2187,7 +2289,7 @@ export interface Customer { /** Currency of the customer. Used for billing, tax and invoicing. */ currency?: string /** The billing address of the customer. Used for tax and invoicing. */ - billing_address?: BillingAddress + billing_address?: Address } /** Customer upsert request. */ @@ -2204,7 +2306,7 @@ export interface UpsertCustomerRequest { /** Currency of the customer. Used for billing, tax and invoicing. */ currency?: string /** The billing address of the customer. Used for tax and invoicing. */ - billing_address?: BillingAddress + billing_address?: Address } /** A collection of addresses for the party. */ @@ -2213,6 +2315,19 @@ export interface PartyAddresses { billing_address: Address } +/** Snapshot of the customer's information at the time the invoice was issued. */ +export interface InvoiceCustomer { + id: string + /** Display name of the resource. Between 1 and 256 characters. */ + name: string + /** Mapping to attribute metered usage to the customer by the event subject. */ + usage_attribution?: CustomerUsageAttribution + /** The billing address of the customer. Used for tax and invoicing. */ + billing_address?: Address + /** Optional external resource key for the customer. Omitted when the customer was created without a key. Unlike on the customer resource itself, the key is optional here because the invoice snapshot may predate or omit it. */ + key?: string +} + /** Checkout Session consent collection configuration. */ export interface AppStripeCreateCheckoutSessionConsentCollection { /** Controls the visibility of payment method reuse agreement. */ @@ -2392,6 +2507,36 @@ export interface UpsertTaxCodeRequest { app_mappings: TaxCodeAppMapping[] } +/** Invoice-level snapshot of the workflow configuration. Contains only the settings that are meaningful for an already-created invoice: invoicing behaviour and payment settings. Collection alignment and tax policy are gather-time / profile-wide concerns and are not included. */ +export interface InvoiceWorkflow { + /** Invoicing settings for this invoice. */ + invoicing?: InvoiceWorkflowInvoicingSettings + /** Payment settings for this invoice. */ + payment?: + | WorkflowPaymentChargeAutomaticallySettings + | WorkflowPaymentSendInvoiceSettings +} + +/** Detailed status information for a standard invoice. */ +export interface InvoiceStatusDetails { + /** Whether the invoice is immutable (i.e. cannot be modified or deleted). */ + immutable: boolean + /** Whether the invoice is in a failed state. */ + failed: boolean + /** Fine-grained internal status string providing additional workflow detail beyond the top-level status enum. */ + extended_status: string + /** The set of state-transition actions currently available for this invoice. */ + available_actions: InvoiceAvailableActions +} + +/** Discounts applied to an invoice line item. */ +export interface InvoiceLineDiscounts { + /** Monetary amount discounts (e.g. from maximum spend commitments). */ + amount?: InvoiceLineAmountDiscount[] + /** Usage quantity discounts (e.g. free tier usage allowances). */ + usage?: InvoiceLineUsageDiscount[] +} + /** Usage quantity details on an invoice line item when UnitConfig is in effect. Provides the full audit trail from raw meter output to the invoiced amount. */ export interface InvoiceUsageQuantityDetail { /** The raw quantity as reported by the meter (native units). */ @@ -2530,7 +2675,7 @@ export interface CreditGrant { } /** Flat fee charge create request. */ -export interface CreateFlatFeeChargeRequest { +export interface CreateChargeFlatFeeRequest { /** Display name of the resource. Between 1 and 256 characters. */ name: string /** Optional description of the resource. Maximum 1024 characters. */ @@ -2553,7 +2698,7 @@ export interface CreateFlatFeeChargeRequest { /** Payment term of the flat fee charge. */ payment_term: 'in_advance' | 'in_arrears' /** The discounts applied to the charge. */ - discounts?: FlatFeeDiscounts + discounts?: ChargeFlatFeeDiscounts /** The feature associated with the charge, when applicable. */ feature_key?: string /** The proration configuration of the charge. */ @@ -2639,6 +2784,18 @@ export interface Party { addresses?: PartyAddresses } +/** Snapshot of the supplier's information at the time the invoice was issued. Structurally a read-only subset of `BillingParty` (the type configured on the billing profile), so the snapshot stays aligned with the source. `key` is omitted because it is not part of the snapshotted supplier data. */ +export interface Supplier { + /** Unique identifier for the party. */ + id?: string + /** Legal name or representation of the party. */ + name?: string + /** The entity's legal identification used for tax purposes. They may have other numbers, but we're only interested in those valid for tax purposes. */ + tax_id?: PartyTaxIdentity + /** Address for where information should be sent if needed. */ + addresses?: PartyAddresses +} + /** Configuration options for creating a Stripe Checkout Session. Based on Stripe's [Checkout Session API parameters](https://docs.stripe.com/api/checkout/sessions/create). */ export interface AppStripeCreateCheckoutSessionRequestOptions { /** Whether to collect the customer's billing address. Defaults to auto, which only collects the address when necessary for tax calculation. */ @@ -2681,6 +2838,48 @@ export interface TaxCodePagePaginatedResponse { meta: PaginatedMeta } +/** Snapshot of the billing workflow configuration captured at invoice creation. */ +export interface InvoiceWorkflowSettings { + /** The apps that will be used to orchestrate the invoice's workflow. */ + apps?: InvoiceWorkflowAppsReferences + /** The billing profile that was the source of this workflow snapshot. */ + source_billing_profile: ProfileReference + /** The workflow configuration that was active when the invoice was created. Only the fields that are meaningful at the per-invoice level are included: invoicing behaviour (auto-advance, draft period) and payment settings (collection method, due date). Profile-wide settings such as collection alignment, progressive billing, and tax policy are omitted. */ + workflow: InvoiceWorkflow +} + +/** A detailed (child) sub-line belonging to a parent invoice line. Detailed lines represent the individual flat-fee components that make up a usage-based parent line after quantity snapshotting. */ +export interface InvoiceDetailedLine { + id: string + /** Display name of the resource. Between 1 and 256 characters. */ + name: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** The service period covered by this detailed line. */ + service_period: ClosedPeriod + /** Aggregated financial totals for the detailed line. */ + totals: Totals + /** The cost category of this detailed line. */ + category: 'regular' | 'commitment' + /** Discounts applied to this detailed line. */ + discounts?: InvoiceLineDiscounts + /** Credit applied to this detailed line. */ + credits_applied?: InvoiceLineCreditsApplied[] + /** External identifiers for this detailed line. */ + external_references?: InvoiceLineExternalReferences + /** The quantity of the detailed line. */ + quantity: string + /** The unit price of the detailed line. */ + unit_price: string +} + /** Page paginated response. */ export interface CurrencyPagePaginatedResponse { data: (CurrencyFiat | CurrencyCustom)[] @@ -2758,6 +2957,36 @@ export interface BadRequest extends BaseError { )[] } +/** Base fields shared by all invoice types. Spread this model into each concrete invoice variant. */ +export interface InvoiceBase { + id: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** Human-readable invoice number generated by the invoicing app. */ + number: string + /** Three-letter ISO 4217 currency code for the invoice. */ + currency: string + /** Snapshot of the supplier's contact information at the time the invoice was issued. */ + supplier: Supplier + /** Snapshot of the customer's information at the time the invoice was issued. */ + customer: InvoiceCustomer + /** Aggregated financial totals for the invoice. */ + totals: Totals + /** The service period covered by this invoice. For flat fee the service period can be empty which means `from` will be equals to `to`. In other cases those fields will be filled with the actual service period. */ + service_period: ClosedPeriod + /** Validation issues found during invoice processing. Present only when there are one or more validation findings. An empty list is omitted. */ + validation_issues?: InvoiceValidationIssue[] + /** External identifiers assigned to this invoice by third-party systems. */ + external_references?: InvoiceExternalReferences +} + /** Request to create a Stripe Checkout Session for the customer. Checkout Sessions are used to collect payment method information from customers in a secure, Stripe-hosted interface. This integration uses setup mode to collect payment methods that can be charged later for subscription billing. */ export interface CustomerStripeCreateCheckoutSessionRequest { /** Options for configuring the Stripe Checkout Session. These options are passed directly to Stripe's [checkout session creation API](https://docs.stripe.com/api/checkout/sessions/create). */ @@ -2801,7 +3030,7 @@ export interface GovernanceQueryResponse { } /** A flat fee charge for a customer. */ -export interface FlatFeeCharge { +export interface ChargeFlatFee { id: string /** Display name of the resource. Between 1 and 256 characters. */ name: string @@ -2818,8 +3047,8 @@ export interface FlatFeeCharge { type: 'flat_fee' /** The customer owning the charge. */ customer: BillingCustomerReference - /** The charge is managed by the following entity. */ - managed_by: 'manual' | 'system' | 'subscription' + /** Indicates whether the charge lifecycle is controlled by OpenMeter or manually overridden by the API user. */ + lifecycle_controller: 'system' | 'manual' /** The subscription that originated the charge, when the charge was created from a subscription item. */ subscription?: SubscriptionReference /** The currency of the charge. */ @@ -2845,7 +3074,7 @@ export interface FlatFeeCharge { /** Payment term of the flat fee charge. */ payment_term: 'in_advance' | 'in_arrears' /** The discounts applied to the charge. */ - discounts?: FlatFeeDiscounts + discounts?: ChargeFlatFeeDiscounts /** The feature associated with the charge, when applicable. */ feature_key?: string /** The proration configuration of the charge. */ @@ -2859,7 +3088,7 @@ export interface FlatFeeCharge { } /** A usage-based charge for a customer. */ -export interface UsageBasedCharge { +export interface ChargeUsageBased { id: string /** Display name of the resource. Between 1 and 256 characters. */ name: string @@ -2876,8 +3105,8 @@ export interface UsageBasedCharge { type: 'usage_based' /** The customer owning the charge. */ customer: BillingCustomerReference - /** The charge is managed by the following entity. */ - managed_by: 'manual' | 'system' | 'subscription' + /** Indicates whether the charge lifecycle is controlled by OpenMeter or manually overridden by the API user. */ + lifecycle_controller: 'system' | 'manual' /** The subscription that originated the charge, when the charge was created from a subscription item. */ subscription?: SubscriptionReference /** The currency of the charge. */ @@ -2911,7 +3140,7 @@ export interface UsageBasedCharge { } /** Usage-based charge create request. */ -export interface CreateUsageBasedChargeRequest { +export interface CreateChargeUsageBasedRequest { /** Display name of the resource. Between 1 and 256 characters. */ name: string /** Optional description of the resource. Maximum 1024 characters. */ @@ -2943,6 +3172,18 @@ export interface CreateUsageBasedChargeRequest { billing_period?: ClosedPeriod } +/** Rate card configuration snapshot for a usage-based invoice line. */ +export interface InvoiceLineRateCard { + /** The price definition used to calculate charges for this line. */ + price: PriceFree | PriceFlat | PriceUnit | PriceGraduated | PriceVolume + /** Tax configuration snapshot for this line. */ + tax_config?: RateCardTaxConfig + /** The feature key associated with this line's rate card. */ + feature_key?: string + /** Discount configuration from the rate card. */ + discounts?: RateCardDiscounts +} + /** A rate card defines the pricing and entitlement of a feature or service. */ export interface RateCard { /** Display name of the resource. Between 1 and 256 characters. */ @@ -2994,6 +3235,44 @@ export interface Workflow { tax?: WorkflowTaxSettings } +/** A top-level line item on an invoice. Each line represents a single charge, typically associated with a rate card from a subscription. Detailed (child) lines are nested under `detailed_lines` when present. */ +export interface InvoiceStandardLine { + id: string + /** Display name of the resource. Between 1 and 256 characters. */ + name: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** The type of charge this line item represents. */ + type: 'standard_line' + /** Indicates whether this line item's lifecycle is controlled by OpenMeter or manually overridden by the API user. */ + lifecycle_controller: 'system' | 'manual' + /** The service period covered by this invoice, spanning the earliest line start to the latest line end across all of its lines. For an invoice with no lines the period is empty, which means `from` will be equal to `to`. */ + service_period: ClosedPeriod + /** Aggregated financial totals for the line item. */ + totals: Totals + /** Discounts applied to this line item. */ + discounts?: InvoiceLineDiscounts + /** Credit applied to this line item. */ + credits_applied?: InvoiceLineCreditsApplied[] + /** External identifiers for this line item assigned by third-party systems. */ + external_references?: InvoiceLineExternalReferences + /** Reference to the subscription item that generated this line. */ + subscription?: SubscriptionReference + /** The rate card configuration snapshot used to price this line item. */ + rate_card: InvoiceLineRateCard + /** Detailed sub-lines that this line has been broken down into. Present when line has individual details. */ + detailed_lines: InvoiceDetailedLine[] + /** Reference to the charge associated with this line item. */ + charge?: ChargeReference +} + /** The plan phase or pricing ramp allows changing a plan's rate cards over time as a subscription progresses. */ export interface PlanPhase { /** Display name of the resource. Between 1 and 256 characters. */ @@ -3130,7 +3409,7 @@ export interface UpsertBillingProfileRequest { /** Page paginated response. */ export interface ChargePagePaginatedResponse { - data: (FlatFeeCharge | UsageBasedCharge)[] + data: (ChargeFlatFee | ChargeUsageBased)[] meta: PaginatedMeta } @@ -3216,6 +3495,66 @@ export interface ProfilePagePaginatedResponse { meta: PaginatedMeta } +/** A standard invoice for charges owed by the customer. */ +export interface InvoiceStandard { + id: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** Human-readable invoice number generated by the invoicing app. */ + number: string + /** Three-letter ISO 4217 currency code for the invoice. */ + currency: string + /** Snapshot of the supplier's contact information at the time the invoice was issued. */ + supplier: Supplier + /** Snapshot of the customer's information at the time the invoice was issued. */ + customer: InvoiceCustomer + /** Aggregated financial totals for the invoice. */ + totals: Totals + /** The service period covered by this invoice. For flat fee the service period can be empty which means `from` will be equals to `to`. In other cases those fields will be filled with the actual service period. */ + service_period: ClosedPeriod + /** Validation issues found during invoice processing. Present only when there are one or more validation findings. An empty list is omitted. */ + validation_issues?: InvoiceValidationIssue[] + /** External identifiers assigned to this invoice by third-party systems. */ + external_references?: InvoiceExternalReferences + /** Discriminator field identifying this as a standard invoice. */ + type: 'standard' + /** Current lifecycle status of the invoice. */ + status: + | 'draft' + | 'issuing' + | 'issued' + | 'payment_processing' + | 'overdue' + | 'paid' + | 'uncollectible' + | 'voided' + /** Detailed status information including available actions and workflow state. */ + status_details: InvoiceStatusDetails + /** Timestamp when the invoice was issued to the customer. */ + issued_at?: string + /** Timestamp until which the invoice remains in draft state. The invoice advances automatically once this time is reached. */ + draft_until?: string + /** Timestamp when usage quantities were last snapshotted for this invoice. */ + quantity_snapshotted_at?: string + /** Timestamp when collection was initiated for this invoice. */ + collection_at?: string + /** Timestamp when payment is due. */ + due_at?: string + /** Timestamp when the invoice was sent to the customer. */ + sent_to_customer_at?: string + /** Workflow configuration snapshot captured at invoice creation time. */ + workflow: InvoiceWorkflowSettings + /** Line items on this invoice. Always returned on single-resource GET; omitted on list endpoints unless explicitly expanded. */ + lines?: InvoiceStandardLine[] +} + /** Page paginated response. */ export interface PlanPagePaginatedResponse { data: Plan[] @@ -3250,6 +3589,13 @@ export interface WorkflowPaymentSendInvoiceSettingsInput { due_after?: string } +export interface InvoiceWorkflowInvoicingSettingsInput { + /** Whether to automatically issue the invoice after the draft_period has passed. */ + auto_advance?: boolean + /** The period for the invoice to be kept in draft status for manual reviews. */ + draft_period?: string +} + export interface EventInput { /** Identifies the event. */ id: string @@ -3393,6 +3739,15 @@ export interface SubscriptionCancelInput { timing?: 'immediate' | 'next_billing_cycle' | string } +export interface InvoiceWorkflowInput { + /** Invoicing settings for this invoice. */ + invoicing?: InvoiceWorkflowInvoicingSettingsInput + /** Payment settings for this invoice. */ + payment?: + | WorkflowPaymentChargeAutomaticallySettings + | WorkflowPaymentSendInvoiceSettingsInput +} + export interface InvoiceUsageQuantityDetailInput { /** The raw quantity as reported by the meter (native units). */ raw_quantity: string @@ -3531,6 +3886,46 @@ export interface AppStripeCreateCheckoutSessionRequestOptionsInput { tax_id_collection?: AppStripeCreateCheckoutSessionTaxIdCollectionInput } +export interface InvoiceWorkflowSettingsInput { + /** The apps that will be used to orchestrate the invoice's workflow. */ + apps?: InvoiceWorkflowAppsReferences + /** The billing profile that was the source of this workflow snapshot. */ + source_billing_profile: ProfileReference + /** The workflow configuration that was active when the invoice was created. Only the fields that are meaningful at the per-invoice level are included: invoicing behaviour (auto-advance, draft period) and payment settings (collection method, due date). Profile-wide settings such as collection alignment, progressive billing, and tax policy are omitted. */ + workflow: InvoiceWorkflowInput +} + +export interface InvoiceDetailedLineInput { + id: string + /** Display name of the resource. Between 1 and 256 characters. */ + name: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** The service period covered by this detailed line. */ + service_period: ClosedPeriod + /** Aggregated financial totals for the detailed line. */ + totals: Totals + /** The cost category of this detailed line. */ + category?: 'regular' | 'commitment' + /** Discounts applied to this detailed line. */ + discounts?: InvoiceLineDiscounts + /** Credit applied to this detailed line. */ + credits_applied?: InvoiceLineCreditsApplied[] + /** External identifiers for this detailed line. */ + external_references?: InvoiceLineExternalReferences + /** The quantity of the detailed line. */ + quantity: string + /** The unit price of the detailed line. */ + unit_price: string +} + export interface CreditGrantPagePaginatedResponseInput { data: CreditGrantInput[] meta: PaginatedMeta @@ -3604,6 +3999,43 @@ export interface WorkflowInput { tax?: WorkflowTaxSettingsInput } +export interface InvoiceStandardLineInput { + id: string + /** Display name of the resource. Between 1 and 256 characters. */ + name: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** The type of charge this line item represents. */ + type: 'standard_line' + /** Indicates whether this line item's lifecycle is controlled by OpenMeter or manually overridden by the API user. */ + lifecycle_controller: 'system' | 'manual' + /** The service period covered by this invoice, spanning the earliest line start to the latest line end across all of its lines. For an invoice with no lines the period is empty, which means `from` will be equal to `to`. */ + service_period: ClosedPeriod + /** Aggregated financial totals for the line item. */ + totals: Totals + /** Discounts applied to this line item. */ + discounts?: InvoiceLineDiscounts + /** Credit applied to this line item. */ + credits_applied?: InvoiceLineCreditsApplied[] + /** External identifiers for this line item assigned by third-party systems. */ + external_references?: InvoiceLineExternalReferences + /** Reference to the subscription item that generated this line. */ + subscription?: SubscriptionReference + /** The rate card configuration snapshot used to price this line item. */ + rate_card: InvoiceLineRateCard + /** Detailed sub-lines that this line has been broken down into. Present when line has individual details. */ + detailed_lines: InvoiceDetailedLineInput[] + /** Reference to the charge associated with this line item. */ + charge?: ChargeReference +} + export interface PlanPhaseInput { /** Display name of the resource. Between 1 and 256 characters. */ name: string @@ -3808,6 +4240,65 @@ export interface ProfilePagePaginatedResponseInput { meta: PaginatedMeta } +export interface InvoiceStandardInput { + id: string + /** Optional description of the resource. Maximum 1024 characters. */ + description?: string + labels?: Labels + /** An ISO-8601 timestamp representation of entity creation date. */ + created_at: string + /** An ISO-8601 timestamp representation of entity last update date. */ + updated_at: string + /** An ISO-8601 timestamp representation of entity deletion date. */ + deleted_at?: string + /** Human-readable invoice number generated by the invoicing app. */ + number: string + /** Three-letter ISO 4217 currency code for the invoice. */ + currency: string + /** Snapshot of the supplier's contact information at the time the invoice was issued. */ + supplier: Supplier + /** Snapshot of the customer's information at the time the invoice was issued. */ + customer: InvoiceCustomer + /** Aggregated financial totals for the invoice. */ + totals: Totals + /** The service period covered by this invoice. For flat fee the service period can be empty which means `from` will be equals to `to`. In other cases those fields will be filled with the actual service period. */ + service_period: ClosedPeriod + /** Validation issues found during invoice processing. Present only when there are one or more validation findings. An empty list is omitted. */ + validation_issues?: InvoiceValidationIssue[] + /** External identifiers assigned to this invoice by third-party systems. */ + external_references?: InvoiceExternalReferences + /** Discriminator field identifying this as a standard invoice. */ + type: 'standard' + /** Current lifecycle status of the invoice. */ + status: + | 'draft' + | 'issuing' + | 'issued' + | 'payment_processing' + | 'overdue' + | 'paid' + | 'uncollectible' + | 'voided' + /** Detailed status information including available actions and workflow state. */ + status_details: InvoiceStatusDetails + /** Timestamp when the invoice was issued to the customer. */ + issued_at?: string + /** Timestamp until which the invoice remains in draft state. The invoice advances automatically once this time is reached. */ + draft_until?: string + /** Timestamp when usage quantities were last snapshotted for this invoice. */ + quantity_snapshotted_at?: string + /** Timestamp when collection was initiated for this invoice. */ + collection_at?: string + /** Timestamp when payment is due. */ + due_at?: string + /** Timestamp when the invoice was sent to the customer. */ + sent_to_customer_at?: string + /** Workflow configuration snapshot captured at invoice creation time. */ + workflow: InvoiceWorkflowSettingsInput + /** Line items on this invoice. Always returned on single-resource GET; omitted on list endpoints unless explicitly expanded. */ + lines?: InvoiceStandardLineInput[] +} + export interface PlanPagePaginatedResponseInput { data: PlanInput[] meta: PaginatedMeta diff --git a/api/spec/packages/aip-client-javascript/src/sdk/invoices.ts b/api/spec/packages/aip-client-javascript/src/sdk/invoices.ts new file mode 100644 index 0000000000..fb03589110 --- /dev/null +++ b/api/spec/packages/aip-client-javascript/src/sdk/invoices.ts @@ -0,0 +1,18 @@ +import { type Client } from '../core.js' +import { unwrap, type RequestOptions } from '../lib/types.js' +import { getInvoice } from '../funcs/invoices.js' +import type { + GetInvoiceRequest, + GetInvoiceResponse, +} from '../models/operations/invoices.js' + +export class Invoices { + constructor(private readonly _client: Client) {} + + async get( + request: GetInvoiceRequest, + options?: RequestOptions, + ): Promise { + return unwrap(await getInvoice(this._client, request, options)) + } +} diff --git a/api/spec/packages/aip-client-javascript/src/sdk/sdk.ts b/api/spec/packages/aip-client-javascript/src/sdk/sdk.ts index 43fba66553..7df7721a0f 100644 --- a/api/spec/packages/aip-client-javascript/src/sdk/sdk.ts +++ b/api/spec/packages/aip-client-javascript/src/sdk/sdk.ts @@ -6,6 +6,7 @@ import { Entitlements } from './entitlements.js' import { Subscriptions } from './subscriptions.js' import { Apps } from './apps.js' import { Billing } from './billing.js' +import { Invoices } from './invoices.js' import { Tax } from './tax.js' import { Currencies } from './currencies.js' import { Features } from './features.js' @@ -52,6 +53,11 @@ export class OpenMeter extends Client { return (this._billing ??= new Billing(this)) } + private _invoices?: Invoices + get invoices(): Invoices { + return (this._invoices ??= new Invoices(this)) + } + private _tax?: Tax get tax(): Tax { return (this._tax ??= new Tax(this)) diff --git a/api/spec/packages/aip/src/customers/charges/charges.tsp b/api/spec/packages/aip/src/customers/charges/charges.tsp index 3443d6da0a..806a6c66db 100644 --- a/api/spec/packages/aip/src/customers/charges/charges.tsp +++ b/api/spec/packages/aip/src/customers/charges/charges.tsp @@ -45,9 +45,9 @@ enum ChargeStatus { * This is the same as `ProductCatalog.Discounts` but without the `usage` field, * which is not applicable to flat fee charges. */ -@friendlyName("BillingFlatFeeDiscounts") +@friendlyName("BillingChargeFlatFeeDiscounts") @summary("Flat fee charge discounts") -model FlatFeeDiscounts { +model ChargeFlatFeeDiscounts { ...OmitProperties; } @@ -75,11 +75,12 @@ model ChargeBase { customer: CustomerReference; /** - * The charge is managed by the following entity. + * Indicates whether the charge lifecycle is controlled by OpenMeter or manually + * overridden by the API user. */ @visibility(Lifecycle.Read) - @summary("Managed by") - managed_by: Shared.ResourceManagedBy; + @summary("Lifecycle controller") + lifecycle_controller: Shared.LifecycleController; /** * The subscription that originated the charge, when the charge was created from a @@ -165,9 +166,9 @@ model ChargeBase { * A flat fee charge for a customer. */ #suppress "@openmeter/api-spec-aip/repeated-prefix-grouping" "" -@friendlyName("BillingFlatFeeCharge") +@friendlyName("BillingChargeFlatFee") @summary("Flat fee charge") -model FlatFeeCharge { +model ChargeFlatFee { ...ChargeBase; /** @@ -182,7 +183,7 @@ model FlatFeeCharge { */ @visibility(Lifecycle.Read, Lifecycle.Create) @summary("Discounts") - discounts?: FlatFeeDiscounts; + discounts?: ChargeFlatFeeDiscounts; /** * The feature associated with the charge, when applicable. @@ -248,9 +249,9 @@ model ChargeTotals { /** * A usage-based charge for a customer. */ -@friendlyName("BillingUsageBasedCharge") +@friendlyName("BillingChargeUsageBased") @summary("Usage-based charge") -model UsageBasedCharge { +model ChargeUsageBased { ...ChargeBase; /** @@ -294,12 +295,12 @@ union Charge { /** * A flat fee charge. */ - flat_fee: FlatFeeCharge, + flat_fee: ChargeFlatFee, /** * A usage-based charge. */ - usage_based: UsageBasedCharge, + usage_based: ChargeUsageBased, } /** @@ -325,12 +326,12 @@ union CreateCharge { /** * A flat fee charge. */ - flat_fee: CreateFlatFeeCharge, + flat_fee: CreateChargeFlatFee, /** * A usage-based charge. */ - usage_based: CreateUsageBasedCharge, + usage_based: CreateChargeUsageBased, } /** @@ -338,9 +339,9 @@ union CreateCharge { */ @doc("Flat fee charge create request.") @withVisibility(Lifecycle.Create) -@friendlyName("CreateFlatFeeChargeRequest") -model CreateFlatFeeCharge { - ...OmitProperties; +@friendlyName("CreateChargeFlatFeeRequest") +model CreateChargeFlatFee { + ...OmitProperties; /** * The full, unprorated service period of the charge. @@ -362,9 +363,9 @@ model CreateFlatFeeCharge { */ @doc("Usage-based charge create request.") @withVisibility(Lifecycle.Create) -@friendlyName("CreateUsageBasedChargeRequest") -model CreateUsageBasedCharge { - ...OmitProperties; +@friendlyName("CreateChargeUsageBasedRequest") +model CreateChargeUsageBased { + ...OmitProperties; /** * The full, unprorated service period of the charge. @@ -380,3 +381,16 @@ model CreateUsageBasedCharge { @summary("Billing period") billing_period?: Shared.ClosedPeriod; } + +/** + * Reference to a charge associated with an invoice line. + */ +@friendlyName("BillingChargeReference") +model ChargeReference { + /** + * Unique identifier for the charge. + */ + @visibility(Lifecycle.Read) + @summary("ID") + id: Shared.ULID; +} diff --git a/api/spec/packages/aip/src/customers/customer.tsp b/api/spec/packages/aip/src/customers/customer.tsp index 0aa6c2e5ea..1b98366f0f 100644 --- a/api/spec/packages/aip/src/customers/customer.tsp +++ b/api/spec/packages/aip/src/customers/customer.tsp @@ -41,63 +41,7 @@ model Customer { */ @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) @summary("Billing Address") - billing_address?: Address; -} - -/** - * Address - */ -@friendlyName("BillingAddress") -model Address { - /** - * Country code in [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) - * alpha-2 format. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("Country") - country?: Shared.CountryCode; - - /** - * Postal code. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("Postal Code") - postal_code?: string; - - /** - * State or province. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("State") - state?: string; - - /** - * City. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("City") - city?: string; - - /** - * First line of the address. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("Line 1") - line1?: string; - - /** - * Second line of the address. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("Line 2") - line2?: string; - - /** - * Phone number. - */ - @visibility(Lifecycle.Create, Lifecycle.Read, Lifecycle.Update) - @summary("Phone Number") - phone_number?: string; + billing_address?: Shared.Address; } /** diff --git a/api/spec/packages/aip/src/invoices/index.tsp b/api/spec/packages/aip/src/invoices/index.tsp index 69b8dcb5fe..0804a8fbaa 100644 --- a/api/spec/packages/aip/src/invoices/index.tsp +++ b/api/spec/packages/aip/src/invoices/index.tsp @@ -1,2 +1,3 @@ import "./invoice.tsp"; import "./party.tsp"; +import "./operations.tsp"; diff --git a/api/spec/packages/aip/src/invoices/invoice.tsp b/api/spec/packages/aip/src/invoices/invoice.tsp index 3364bcc8f4..35a656b723 100644 --- a/api/spec/packages/aip/src/invoices/invoice.tsp +++ b/api/spec/packages/aip/src/invoices/invoice.tsp @@ -1,4 +1,11 @@ import "../shared/index.tsp"; +import "../customers/index.tsp"; +import "../productcatalog/price.tsp"; +import "../productcatalog/ratecard.tsp"; +import "../billing/profile.tsp"; +import "../billing/totals.tsp"; +import "../billing/tax.tsp"; +import "../subscriptions/index.tsp"; namespace Invoices; @@ -17,3 +24,964 @@ namespace Invoices; @maxLength(256) @friendlyName("BillingInvoiceNumber") scalar InvoiceNumber extends string; + +/** + * An invoice issued to a customer. + * + * The `type` field determines the concrete variant: + * + * - `standard`: a standard invoice for charges owed. + */ +@friendlyName("BillingInvoice") +@discriminated(#{ discriminatorPropertyName: "type", envelope: "none" }) +union Invoice { + @summary("Standard invoice") + standard: InvoiceStandard, + + // @summary("Credit note invoice") + // credit_note: BillingCreditNoteInvoice, +} + +/** + * The type of a billing invoice. + */ +@friendlyName("BillingInvoiceType") +enum InvoiceType { + /** + * A standard invoice for charges owed by the customer. + */ + Standard: "standard", + + // /** + // * A credit note reducing the amount owed on a previous invoice. + // */ + // CreditNote: "credit_note", +} + +/** + * Base fields shared by all invoice types. + * + * Spread this model into each concrete invoice variant. + */ +@friendlyName("BillingInvoiceBase") +model InvoiceBase { + ...OmitProperties; + + /** + * Human-readable invoice number generated by the invoicing app. + */ + @visibility(Lifecycle.Read) + @summary("Number") + number: InvoiceNumber; + + /** + * Three-letter ISO 4217 currency code for the invoice. + */ + @visibility(Lifecycle.Read) + @summary("Currency") + currency: Shared.CurrencyCode; + + /** + * Snapshot of the supplier's contact information at the time the invoice was + * issued. + */ + @visibility(Lifecycle.Read) + @summary("Supplier") + supplier: Supplier; + + /** + * Snapshot of the customer's information at the time the invoice was issued. + */ + @visibility(Lifecycle.Read) + @summary("Customer") + customer: InvoiceCustomer; + + /** + * Aggregated financial totals for the invoice. + */ + @visibility(Lifecycle.Read) + @summary("Totals") + totals: Billing.BillingTotals; + + /** + * The service period covered by this invoice. + * + * For flat fee the service period can be empty which means `from` will be equals + * to `to`. In other cases those fields will be filled with the actual service + * period. + */ + @visibility(Lifecycle.Read) + @summary("Service period") + service_period: Shared.ClosedPeriod; + + /** + * Validation issues found during invoice processing. + * + * Present only when there are one or more validation findings. An empty list is + * omitted. + */ + @visibility(Lifecycle.Read) + @summary("Validation issues") + validation_issues?: InvoiceValidationIssue[]; + + /** + * External identifiers assigned to this invoice by third-party systems. + */ + @visibility(Lifecycle.Read) + @summary("External references") + external_references?: InvoiceExternalReferences; +} + +/** + * A top-level line item on an invoice. + * + * Each line represents a single charge, typically associated with a rate card from + * a subscription. Detailed (child) lines are nested under `detailed_lines` when + * present. + */ +@friendlyName("BillingInvoiceLine") +@discriminated(#{ discriminatorPropertyName: "type", envelope: "none" }) +union InvoiceLine { + @summary("Standard invoice line") + standard_line: InvoiceStandardLine, + + // @summary("Credit note invoice") + // credit_note: BillingCreditNoteInvoice, +} + +/** + * A standard invoice for charges owed by the customer. + */ +@friendlyName("BillingInvoiceStandard") +model InvoiceStandard { + ...InvoiceBase; + + /** + * Discriminator field identifying this as a standard invoice. + */ + @visibility(Lifecycle.Read) + @summary("Type") + type: InvoiceType.Standard; + + /** + * Current lifecycle status of the invoice. + */ + @visibility(Lifecycle.Read) + @summary("Status") + status: InvoiceStandardStatus; + + /** + * Detailed status information including available actions and workflow state. + */ + @visibility(Lifecycle.Read) + @summary("Status details") + status_details: InvoiceStatusDetails; + + /** + * Timestamp when the invoice was issued to the customer. + */ + @visibility(Lifecycle.Read) + @summary("Issued at") + issued_at?: Shared.DateTime; + + /** + * Timestamp until which the invoice remains in draft state. + * + * The invoice advances automatically once this time is reached. + */ + @visibility(Lifecycle.Read) + @summary("Draft until") + draft_until?: Shared.DateTime; + + /** + * Timestamp when usage quantities were last snapshotted for this invoice. + */ + @visibility(Lifecycle.Read) + @summary("Quantity snapshotted at") + quantity_snapshotted_at?: Shared.DateTime; + + /** + * Timestamp when collection was initiated for this invoice. + */ + @visibility(Lifecycle.Read) + @summary("Collection at") + collection_at?: Shared.DateTime; + + /** + * Timestamp when payment is due. + */ + @visibility(Lifecycle.Read) + @summary("Due at") + due_at?: Shared.DateTime; + + /** + * Timestamp when the invoice was sent to the customer. + */ + @visibility(Lifecycle.Read) + @summary("Sent to customer at") + sent_to_customer_at?: Shared.DateTime; + + /** + * Workflow configuration snapshot captured at invoice creation time. + */ + @visibility(Lifecycle.Read) + @summary("Workflow") + workflow: InvoiceWorkflowSettings; + + /** + * Line items on this invoice. + * + * Always returned on single-resource GET; omitted on list endpoints unless + * explicitly expanded. + */ + @visibility(Lifecycle.Read) + @summary("Lines") + lines?: InvoiceLine[]; +} + +/** + * Lifecycle status of a standard invoice. + */ +@friendlyName("BillingInvoiceStandardStatus") +enum InvoiceStandardStatus { + /** + * The invoice is in draft and can still be modified. + */ + Draft: "draft", + + /** + * The invoice is being issued (e.g. submitted to an invoicing app). + */ + Issuing: "issuing", + + /** + * The invoice has been issued and is awaiting payment. + */ + Issued: "issued", + + /** + * Payment processing is in progress. + */ + PaymentProcessing: "payment_processing", + + /** + * Payment is past due. + */ + Overdue: "overdue", + + /** + * The invoice has been paid in full. + */ + Paid: "paid", + + /** + * The invoice has been marked uncollectible. + */ + Uncollectible: "uncollectible", + + /** + * The invoice has been voided. + */ + Voided: "voided", +} + +// /** +// * A credit note invoice. +// * +// * @placeholder Credit note domain support is not yet implemented. This model is a +// * forward-compatibility placeholder and will be expanded in a future release. +// */ +// @friendlyName("BillingInvoiceCreditNote") +// model InvoiceCreditNote { +// ...InvoiceBase; + +// /** +// * Discriminator field identifying this as a credit note invoice. +// */ +// @visibility(Lifecycle.Read) +// @summary("Type") +// type: InvoiceType.CreditNote; + +// /** +// * Current lifecycle status of the credit note. +// */ +// @visibility(Lifecycle.Read) +// @summary("Status") +// status: InvoiceStatusCreditNote; +// } + +// /** +// * Lifecycle status of a credit note invoice. +// */ +// @friendlyName("BillingInvoiceStatusCreditNote") +// enum InvoiceStatusCreditNote { +// /** +// * The credit note is in draft state. +// */ +// Draft: "draft", + +// /** +// * The credit note has been issued. +// */ +// Issued: "issued", +// } + +/** + * Snapshot of the customer's information at the time the invoice was issued. + */ +@friendlyName("BillingInvoiceCustomer") +@withVisibility(Lifecycle.Read) +model InvoiceCustomer { + ...PickProperties< + Customers.Customer, + "id" | "name" | "usage_attribution" | "billing_address" + >; + + /** + * Optional external resource key for the customer. + * + * Omitted when the customer was created without a key. Unlike on the customer + * resource itself, the key is optional here because the invoice snapshot may + * predate or omit it. + */ + key?: Shared.ExternalResourceKey; +} + +/** + * Snapshot of the supplier's information at the time the invoice was issued. + * + * Structurally a read-only subset of `BillingParty` (the type configured on the + * billing profile), so the snapshot stays aligned with the source. `key` is + * omitted because it is not part of the snapshotted supplier data. + */ +@friendlyName("BillingSupplier") +@withVisibility(Lifecycle.Read) +model Supplier { + ...OmitProperties; +} + +/** + * Snapshot of the billing workflow configuration captured at invoice creation. + */ +@friendlyName("BillingInvoiceWorkflowSettings") +model InvoiceWorkflowSettings { + /** + * The apps that will be used to orchestrate the invoice's workflow. + */ + @visibility(Lifecycle.Read) + @summary("Application that generated the invoice") + apps?: InvoiceWorkflowAppsReferences; + + /** + * The billing profile that was the source of this workflow snapshot. + */ + @visibility(Lifecycle.Read) + @summary("Source billing profile") + source_billing_profile: Billing.BillingProfileReference; + + /** + * The workflow configuration that was active when the invoice was created. + * + * Only the fields that are meaningful at the per-invoice level are included: + * invoicing behaviour (auto-advance, draft period) and payment settings + * (collection method, due date). Profile-wide settings such as collection + * alignment, progressive billing, and tax policy are omitted. + */ + @visibility(Lifecycle.Read) + @summary("Workflow config") + workflow: BillingInvoiceWorkflow; +} + +/** + * BillingInvoiceWorkflowAppsReferences represents the references (id) to the apps + * used by a billing profile + */ +@friendlyName("BillingInvoiceWorkflowAppsReferences") +model InvoiceWorkflowAppsReferences { + /** + * The tax app used for this workflow + */ + @visibility(Lifecycle.Read) + tax: Apps.AppReference; + + /** + * The invoicing app used for this workflow + */ + @visibility(Lifecycle.Read) + invoicing: Apps.AppReference; + + /** + * The payment app used for this workflow + */ + @visibility(Lifecycle.Read) + payment: Apps.AppReference; +} + +/** + * Invoice-level snapshot of the workflow configuration. + * + * Contains only the settings that are meaningful for an already-created invoice: + * invoicing behaviour and payment settings. Collection alignment and tax policy + * are gather-time / profile-wide concerns and are not included. + */ +@friendlyName("BillingInvoiceWorkflow") +model BillingInvoiceWorkflow { + /** + * Invoicing settings for this invoice. + */ + @visibility(Lifecycle.Read) + @summary("Invoicing settings") + invoicing?: BillingInvoiceWorkflowInvoicingSettings; + + /** + * Payment settings for this invoice. + */ + @visibility(Lifecycle.Read) + @summary("Payment settings") + payment?: Billing.BillingWorkflowPaymentSettings; +} + +/** + * Invoice-level invoicing settings. + * + * A subset of BillingWorkflowInvoicingSettings limited to fields that are + * meaningful per-invoice. progressive_billing is omitted as it is a gather-time / + * profile-level decision. + */ +@friendlyName("BillingInvoiceWorkflowInvoicingSettings") +model BillingInvoiceWorkflowInvoicingSettings { + /** + * Whether to automatically issue the invoice after the draft_period has passed. + */ + @visibility(Lifecycle.Read) + auto_advance?: boolean = true; + + /** + * The period for the invoice to be kept in draft status for manual reviews. + */ + @encode(DurationKnownEncoding.ISO8601) + @example("P1D") + @visibility(Lifecycle.Read) + draft_period?: string = "P0D"; +} + +/** + * Detailed status information for a standard invoice. + */ +@friendlyName("BillingInvoiceStatusDetails") +model InvoiceStatusDetails { + /** + * Whether the invoice is immutable (i.e. cannot be modified or deleted). + */ + @visibility(Lifecycle.Read) + @summary("Immutable") + immutable: boolean; + + /** + * Whether the invoice is in a failed state. + */ + @visibility(Lifecycle.Read) + @summary("Failed") + failed: boolean; + + /** + * Fine-grained internal status string providing additional workflow detail beyond + * the top-level status enum. + */ + @visibility(Lifecycle.Read) + @summary("Extended status") + extended_status: string; + + /** + * The set of state-transition actions currently available for this invoice. + */ + @visibility(Lifecycle.Read) + @summary("Available actions") + available_actions: InvoiceAvailableActions; +} + +/** + * The set of state-transition actions available for an invoice in its current + * status. + * + * A field is present only when that action is permitted from the current state. + */ +@friendlyName("BillingInvoiceAvailableActions") +model InvoiceAvailableActions { + /** + * Advance the invoice to the next workflow step. + */ + @visibility(Lifecycle.Read) + @summary("Advance") + advance?: InvoiceAvailableActionDetails; + + /** + * Approve the invoice for issuance. + */ + @visibility(Lifecycle.Read) + @summary("Approve") + approve?: InvoiceAvailableActionDetails; + + /** + * Delete the invoice. + */ + @visibility(Lifecycle.Read) + @summary("Delete") + delete?: InvoiceAvailableActionDetails; + + /** + * Retry a failed workflow step. + */ + @visibility(Lifecycle.Read) + @summary("Retry") + retry?: InvoiceAvailableActionDetails; + + /** + * Snapshot the current usage quantities. + */ + @visibility(Lifecycle.Read) + @summary("Snapshot quantities") + snapshot_quantities?: InvoiceAvailableActionDetails; +} + +/** + * Details about an available invoice action including the resulting state. + */ +@friendlyName("BillingInvoiceAvailableActionDetails") +model InvoiceAvailableActionDetails { + /** + * The extended status the invoice will transition to after performing this action. + */ + @visibility(Lifecycle.Read) + @summary("Resulting state") + resulting_state: string; +} + +/** + * External identifiers assigned to an invoice by third-party systems. + */ +@friendlyName("BillingInvoiceExternalReferences") +model InvoiceExternalReferences { + /** + * The ID assigned by the external invoicing app (e.g. Stripe invoice ID). + */ + @visibility(Lifecycle.Read) + @summary("Invoicing ID") + invoicing_id?: string; + + /** + * The ID assigned by the external payment app (e.g. Stripe payment intent ID). + */ + @visibility(Lifecycle.Read) + @summary("Payment ID") + payment_id?: string; +} + +/** + * Severity level of an invoice validation issue. + */ +@friendlyName("BillingInvoiceValidationIssueSeverity") +enum InvoiceValidationIssueSeverity { + /** + * A critical issue that prevents the invoice from being finalized. + */ + Critical: "critical", + + /** + * A warning that does not block finalization but should be reviewed. + */ + Warning: "warning", +} + +/** + * A validation issue found during invoice processing. + * + * Converges on the same structure used by plan and subscription validation errors: + * a machine-readable `code`, a human-readable `message`, optional structured + * `attributes`, plus a `severity` and optional `field` path. + */ +@friendlyName("BillingInvoiceValidationIssue") +model InvoiceValidationIssue is Shared.BaseError { + /** + * Severity of the validation issue. + */ + @visibility(Lifecycle.Read) + @summary("Severity") + severity: InvoiceValidationIssueSeverity; + + /** + * JSON path to the field that caused this validation issue, if applicable. + * + * For example: `lines/0/rate_card/price`. + */ + @visibility(Lifecycle.Read) + @summary("Field path") + field?: string; +} + +/** + * Line item type discriminator. + */ +@friendlyName("BillingInvoiceLineType") +enum InvoiceLineType { + /** + * A standard line item representing a single charge. + */ + StandardLine: "standard_line", + + /** + * A line item representing a credit purchase. + */ + // CreditPurchase: "credit_purchase"; +} + +/** + * A top-level line item on an invoice. + * + * Each line represents a single charge, typically associated with a rate card from + * a subscription. Detailed (child) lines are nested under `detailed_lines` when + * present. + */ +@friendlyName("BillingInvoiceStandardLine") +model InvoiceStandardLine { + ...Shared.Resource; + + /** + * The type of charge this line item represents. + */ + @visibility(Lifecycle.Read) + @summary("Type") + type: InvoiceLineType.StandardLine; + + /** + * Indicates whether this line item's lifecycle is controlled by OpenMeter or + * manually overridden by the API user. + */ + @visibility(Lifecycle.Read) + @summary("Lifecycle controller") + lifecycle_controller: Shared.LifecycleController; + + /** + * The service period covered by this invoice, spanning the earliest line start to + * the latest line end across all of its lines. + * + * For an invoice with no lines the period is empty, which means `from` will be + * equal to `to`. + */ + @visibility(Lifecycle.Read) + @summary("Service period") + service_period: Shared.ClosedPeriod; + + /** + * Aggregated financial totals for the line item. + */ + @visibility(Lifecycle.Read) + @summary("Totals") + totals: Billing.BillingTotals; + + /** + * Discounts applied to this line item. + */ + @visibility(Lifecycle.Read) + @summary("Discounts") + discounts?: InvoiceLineDiscounts; + + /** + * Credit applied to this line item. + */ + @visibility(Lifecycle.Read) + @summary("Credit applied") + credits_applied?: InvoiceLineCreditsApplied[]; + + /** + * External identifiers for this line item assigned by third-party systems. + */ + @visibility(Lifecycle.Read) + @summary("External references") + external_references?: InvoiceLineExternalReferences; + + /** + * Reference to the subscription item that generated this line. + */ + @visibility(Lifecycle.Read) + @summary("Subscription reference") + subscription?: Subscriptions.SubscriptionReference; + + /** + * The rate card configuration snapshot used to price this line item. + */ + @visibility(Lifecycle.Read) + @summary("Rate card") + rate_card: InvoiceLineRateCard; + + /** + * Detailed sub-lines that this line has been broken down into. + * + * Present when line has individual details. + */ + @visibility(Lifecycle.Read) + @summary("Detailed lines") + detailed_lines: InvoiceDetailedLine[]; + + /** + * Reference to the charge associated with this line item. + */ + @visibility(Lifecycle.Read) + @summary("Charge") + charge?: Customers.ChargeReference; +} + +/** + * Rate card configuration snapshot for a usage-based invoice line. + */ +@friendlyName("BillingInvoiceLineRateCard") +model InvoiceLineRateCard { + /** + * The price definition used to calculate charges for this line. + */ + @visibility(Lifecycle.Read) + @summary("Price") + price: ProductCatalog.Price; + + /** + * Tax configuration snapshot for this line. + */ + @visibility(Lifecycle.Read) + @summary("Tax config") + tax_config?: ProductCatalog.RateCardTaxConfig; + + /** + * The feature key associated with this line's rate card. + */ + @visibility(Lifecycle.Read) + @summary("Feature key") + feature_key?: Shared.ResourceKey; + + /** + * Discount configuration from the rate card. + */ + @visibility(Lifecycle.Read) + @summary("Discounts") + discounts?: ProductCatalog.Discounts; +} + +/** + * Discounts applied to an invoice line item. + */ +@friendlyName("BillingInvoiceLineDiscounts") +model InvoiceLineDiscounts { + /** + * Monetary amount discounts (e.g. from maximum spend commitments). + */ + @visibility(Lifecycle.Read) + @summary("Amount discounts") + amount?: InvoiceLineAmountDiscount[]; + + /** + * Usage quantity discounts (e.g. free tier usage allowances). + */ + @visibility(Lifecycle.Read) + @summary("Usage discounts") + usage?: InvoiceLineUsageDiscount[]; +} + +/** + * The reason a discount was applied to an invoice line. + */ +@friendlyName("BillingInvoiceDiscountReason") +enum InvoiceDiscountReason { + /** + * Discount applied because a maximum spend commitment was reached. + */ + MaximumSpend: "maximum_spend", + + /** + * Discount applied from a rate card percentage discount rule. + */ + RatecardPercentage: "ratecard_percentage", + + /** + * Discount applied from a rate card usage discount rule. + */ + RatecardUsage: "ratecard_usage", +} + +/** + * Base fields shared by all invoice line item discounts. + */ +@friendlyName("BillingInvoiceLineBaseDiscount") +model InvoiceLineBaseDiscount { + /** + * Unique identifier for the discount. + */ + @visibility(Lifecycle.Read) + @summary("ID") + id: Shared.ULID; + + /** + * The reason this discount was applied. + */ + @visibility(Lifecycle.Read) + @summary("Reason") + reason: InvoiceDiscountReason; + + /** + * Optional human-readable description of the discount. + */ + @visibility(Lifecycle.Read) + @summary("Description") + description?: string; + + /** + * External identifiers for this discount. + */ + @visibility(Lifecycle.Read) + @summary("External references") + external_references?: InvoiceLineExternalReferences; +} + +/** + * A monetary amount discount applied to an invoice line item. + */ +@friendlyName("BillingInvoiceLineAmountDiscount") +model InvoiceLineAmountDiscount { + ...InvoiceLineBaseDiscount; + + /** + * The monetary amount deducted. + */ + @visibility(Lifecycle.Read) + @summary("Amount") + amount: Shared.Numeric; +} + +/** + * A usage quantity discount applied to an invoice line item. + */ +@friendlyName("BillingInvoiceLineUsageDiscount") +model InvoiceLineUsageDiscount { + ...InvoiceLineBaseDiscount; + + /** + * The usage quantity deducted (in billing units). + */ + @visibility(Lifecycle.Read) + @summary("Quantity") + quantity: Shared.Numeric; +} + +/** + * A credit allocation applied to an invoice line item. + */ +@friendlyName("BillingInvoiceLineCreditsApplied") +model InvoiceLineCreditsApplied { + /** + * The monetary amount credited. + */ + @visibility(Lifecycle.Read) + @summary("Amount") + amount: Shared.Numeric; + + /** + * Optional human-readable description of the credit allocation. + */ + @visibility(Lifecycle.Read) + @summary("Description") + description?: string; +} + +/** + * External identifiers for an invoice line item assigned by third-party systems. + */ +@friendlyName("BillingInvoiceLineExternalReferences") +model InvoiceLineExternalReferences { + /** + * The ID assigned by the external invoicing app. + */ + @visibility(Lifecycle.Read) + @summary("Invoicing ID") + invoicing_id?: string; +} + +/** + * Cost category of a detailed invoice line item. + */ +@friendlyName("BillingInvoiceDetailedLineCostCategory") +enum InvoiceDetailedLineCostCategory { + /** + * A regular charge. + */ + Regular: "regular", + + /** + * A commitment charge (e.g. minimum spend). + */ + Commitment: "commitment", +} + +/** + * A detailed (child) sub-line belonging to a parent invoice line. + * + * Detailed lines represent the individual flat-fee components that make up a + * usage-based parent line after quantity snapshotting. + */ +@friendlyName("BillingInvoiceDetailedLine") +model InvoiceDetailedLine { + ...Shared.Resource; + + /** + * The service period covered by this detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Service period") + service_period: Shared.ClosedPeriod; + + /** + * Aggregated financial totals for the detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Totals") + totals: Billing.BillingTotals; + + /** + * The cost category of this detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Category") + category: InvoiceDetailedLineCostCategory = InvoiceDetailedLineCostCategory.Regular; + + /** + * Discounts applied to this detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Discounts") + discounts?: InvoiceLineDiscounts; + + /** + * Credit applied to this detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Credit applied") + credits_applied?: InvoiceLineCreditsApplied[]; + + /** + * External identifiers for this detailed line. + */ + @visibility(Lifecycle.Read) + @summary("External references") + external_references?: InvoiceLineExternalReferences; + + /** + * The quantity of the detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Quantity") + quantity: Shared.Numeric; + + /** + * The unit price of the detailed line. + */ + @visibility(Lifecycle.Read) + @summary("Unit Price") + unit_price: Shared.Numeric; +} diff --git a/api/spec/packages/aip/src/invoices/operations.tsp b/api/spec/packages/aip/src/invoices/operations.tsp new file mode 100644 index 0000000000..5669d1ddfe --- /dev/null +++ b/api/spec/packages/aip/src/invoices/operations.tsp @@ -0,0 +1,34 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@typespec/openapi"; +import "@typespec/openapi3"; +import "../common/error.tsp"; +import "../common/pagination.tsp"; +import "../common/parameters.tsp"; +import "../shared/index.tsp"; +import "../billing/profile.tsp"; +import "./invoice.tsp"; + +using TypeSpec.Http; +using TypeSpec.OpenAPI; + +namespace Invoices; + +/** + * Operations for managing billing invoices. + */ +interface InvoicesOperations { + /** + * Get a billing invoice by ID. + * + * Returns the full invoice resource including line items, status details, totals, + * and workflow configuration snapshot. + */ + @get + @operationId("get-invoice") + @summary("Get a billing invoice") + get(@path invoiceId: Shared.ULID): + | Shared.GetResponse + | Common.NotFound + | Common.ErrorResponses; +} diff --git a/api/spec/packages/aip/src/konnect.tsp b/api/spec/packages/aip/src/konnect.tsp index ac0321c29d..e6a79fdc4d 100644 --- a/api/spec/packages/aip/src/konnect.tsp +++ b/api/spec/packages/aip/src/konnect.tsp @@ -14,6 +14,7 @@ import "./billing/index.tsp"; import "./tax/index.tsp"; import "./defaults/index.tsp"; import "./governance/index.tsp"; +import "./invoices/index.tsp"; using TypeSpec.Http; using TypeSpec.OpenAPI; @@ -145,6 +146,10 @@ interface AppsEndpoints extends Apps.AppsOperations {} @tag(Shared.BillingTag) interface BillingProfilesEndpoints extends Billing.BillingProfilesOperations {} +@route("/openmeter/billing/invoices") +@tag(Shared.BillingTag) +interface BillingInvoicesEndpoints extends Invoices.InvoicesOperations {} + @route("/openmeter/tax-codes") @tag(Shared.TaxTag) interface TaxCodesEndpoints extends Tax.TaxCodesOperations {} diff --git a/api/spec/packages/aip/src/openmeter.tsp b/api/spec/packages/aip/src/openmeter.tsp index 830c855a95..d37a5d2b5c 100644 --- a/api/spec/packages/aip/src/openmeter.tsp +++ b/api/spec/packages/aip/src/openmeter.tsp @@ -15,6 +15,7 @@ import "./llmcost/index.tsp"; import "./productcatalog/index.tsp"; import "./defaults/index.tsp"; import "./governance/index.tsp"; +import "./invoices/index.tsp"; using TypeSpec.Http; using TypeSpec.OpenAPI; @@ -150,6 +151,10 @@ interface AppsEndpoints extends Apps.AppsOperations {} @tag(Shared.BillingTag) interface BillingProfilesEndpoints extends Billing.BillingProfilesOperations {} +@route("/openmeter/billing/invoices") +@tag(Shared.BillingTag) +interface BillingInvoicesEndpoints extends Invoices.InvoicesOperations {} + @route("/openmeter/tax-codes") @tag(Shared.TaxTag) interface TaxCodesEndpoints extends Tax.TaxCodesOperations {} diff --git a/api/spec/packages/aip/src/shared/enums.tsp b/api/spec/packages/aip/src/shared/enums.tsp index 794c759158..54050b434c 100644 --- a/api/spec/packages/aip/src/shared/enums.tsp +++ b/api/spec/packages/aip/src/shared/enums.tsp @@ -1,18 +1,17 @@ namespace Shared; /** - * Identifies which system manages a resource. + * Identifies whether a resource lifecycle is controlled by OpenMeter or manually + * overridden by the API user. * * Values: * - * - `manual`: The resource is managed manually (overridden by our API users). - * - `system`: The resource is managed by the system. - * - `subscription`: The resource is managed by the subscription. + * - `system`: The resource lifecycle is controlled by OpenMeter. + * - `manual`: The resource lifecycle was manually overridden by the API user. */ -@friendlyName("ResourceManagedBy") -@summary("Resource managed by") -enum ResourceManagedBy { - Manual: "manual", +@friendlyName("BillingLifecycleController") +@summary("Lifecycle controller") +enum LifecycleController { System: "system", - Subscription: "subscription", + Manual: "manual", } diff --git a/api/v3/api.gen.go b/api/v3/api.gen.go index 4cd4a73818..b383dd48b0 100644 --- a/api/v3/api.gen.go +++ b/api/v3/api.gen.go @@ -308,6 +308,21 @@ func (e BillingAppType) Valid() bool { } } +// Defines values for BillingChargeFlatFeeType. +const ( + BillingChargeFlatFeeTypeFlatFee BillingChargeFlatFeeType = "flat_fee" +) + +// Valid indicates whether the value is a known member of the BillingChargeFlatFeeType enum. +func (e BillingChargeFlatFeeType) Valid() bool { + switch e { + case BillingChargeFlatFeeTypeFlatFee: + return true + default: + return false + } +} + // Defines values for BillingChargeStatus. const ( BillingChargeStatusActive BillingChargeStatus = "active" @@ -332,6 +347,21 @@ func (e BillingChargeStatus) Valid() bool { } } +// Defines values for BillingChargeUsageBasedType. +const ( + BillingChargeUsageBasedTypeUsageBased BillingChargeUsageBasedType = "usage_based" +) + +// Valid indicates whether the value is a known member of the BillingChargeUsageBasedType enum. +func (e BillingChargeUsageBasedType) Valid() bool { + switch e { + case BillingChargeUsageBasedTypeUsageBased: + return true + default: + return false + } +} + // Defines values for BillingChargesExpand. const ( BillingChargesExpandRealTimeUsage BillingChargesExpand = "real_time_usage" @@ -581,15 +611,141 @@ func (e BillingFeatureManualUnitCostType) Valid() bool { } } -// Defines values for BillingFlatFeeChargeType. +// Defines values for BillingInvoiceDetailedLineCostCategory. +const ( + BillingInvoiceDetailedLineCostCategoryCommitment BillingInvoiceDetailedLineCostCategory = "commitment" + BillingInvoiceDetailedLineCostCategoryRegular BillingInvoiceDetailedLineCostCategory = "regular" +) + +// Valid indicates whether the value is a known member of the BillingInvoiceDetailedLineCostCategory enum. +func (e BillingInvoiceDetailedLineCostCategory) Valid() bool { + switch e { + case BillingInvoiceDetailedLineCostCategoryCommitment: + return true + case BillingInvoiceDetailedLineCostCategoryRegular: + return true + default: + return false + } +} + +// Defines values for BillingInvoiceDiscountReason. +const ( + BillingInvoiceDiscountReasonMaximumSpend BillingInvoiceDiscountReason = "maximum_spend" + BillingInvoiceDiscountReasonRatecardPercentage BillingInvoiceDiscountReason = "ratecard_percentage" + BillingInvoiceDiscountReasonRatecardUsage BillingInvoiceDiscountReason = "ratecard_usage" +) + +// Valid indicates whether the value is a known member of the BillingInvoiceDiscountReason enum. +func (e BillingInvoiceDiscountReason) Valid() bool { + switch e { + case BillingInvoiceDiscountReasonMaximumSpend: + return true + case BillingInvoiceDiscountReasonRatecardPercentage: + return true + case BillingInvoiceDiscountReasonRatecardUsage: + return true + default: + return false + } +} + +// Defines values for BillingInvoiceStandardType. +const ( + BillingInvoiceStandardTypeStandard BillingInvoiceStandardType = "standard" +) + +// Valid indicates whether the value is a known member of the BillingInvoiceStandardType enum. +func (e BillingInvoiceStandardType) Valid() bool { + switch e { + case BillingInvoiceStandardTypeStandard: + return true + default: + return false + } +} + +// Defines values for BillingInvoiceStandardLineType. +const ( + BillingInvoiceStandardLineTypeStandardLine BillingInvoiceStandardLineType = "standard_line" +) + +// Valid indicates whether the value is a known member of the BillingInvoiceStandardLineType enum. +func (e BillingInvoiceStandardLineType) Valid() bool { + switch e { + case BillingInvoiceStandardLineTypeStandardLine: + return true + default: + return false + } +} + +// Defines values for BillingInvoiceStandardStatus. +const ( + BillingInvoiceStandardStatusDraft BillingInvoiceStandardStatus = "draft" + BillingInvoiceStandardStatusIssued BillingInvoiceStandardStatus = "issued" + BillingInvoiceStandardStatusIssuing BillingInvoiceStandardStatus = "issuing" + BillingInvoiceStandardStatusOverdue BillingInvoiceStandardStatus = "overdue" + BillingInvoiceStandardStatusPaid BillingInvoiceStandardStatus = "paid" + BillingInvoiceStandardStatusPaymentProcessing BillingInvoiceStandardStatus = "payment_processing" + BillingInvoiceStandardStatusUncollectible BillingInvoiceStandardStatus = "uncollectible" + BillingInvoiceStandardStatusVoided BillingInvoiceStandardStatus = "voided" +) + +// Valid indicates whether the value is a known member of the BillingInvoiceStandardStatus enum. +func (e BillingInvoiceStandardStatus) Valid() bool { + switch e { + case BillingInvoiceStandardStatusDraft: + return true + case BillingInvoiceStandardStatusIssued: + return true + case BillingInvoiceStandardStatusIssuing: + return true + case BillingInvoiceStandardStatusOverdue: + return true + case BillingInvoiceStandardStatusPaid: + return true + case BillingInvoiceStandardStatusPaymentProcessing: + return true + case BillingInvoiceStandardStatusUncollectible: + return true + case BillingInvoiceStandardStatusVoided: + return true + default: + return false + } +} + +// Defines values for BillingInvoiceValidationIssueSeverity. const ( - BillingFlatFeeChargeTypeFlatFee BillingFlatFeeChargeType = "flat_fee" + BillingInvoiceValidationIssueSeverityCritical BillingInvoiceValidationIssueSeverity = "critical" + BillingInvoiceValidationIssueSeverityWarning BillingInvoiceValidationIssueSeverity = "warning" ) -// Valid indicates whether the value is a known member of the BillingFlatFeeChargeType enum. -func (e BillingFlatFeeChargeType) Valid() bool { +// Valid indicates whether the value is a known member of the BillingInvoiceValidationIssueSeverity enum. +func (e BillingInvoiceValidationIssueSeverity) Valid() bool { switch e { - case BillingFlatFeeChargeTypeFlatFee: + case BillingInvoiceValidationIssueSeverityCritical: + return true + case BillingInvoiceValidationIssueSeverityWarning: + return true + default: + return false + } +} + +// Defines values for BillingLifecycleController. +const ( + BillingLifecycleControllerManual BillingLifecycleController = "manual" + BillingLifecycleControllerSystem BillingLifecycleController = "system" +) + +// Valid indicates whether the value is a known member of the BillingLifecycleController enum. +func (e BillingLifecycleController) Valid() bool { + switch e { + case BillingLifecycleControllerManual: + return true + case BillingLifecycleControllerSystem: return true default: return false @@ -896,21 +1052,6 @@ func (e BillingUnitConfigRoundingMode) Valid() bool { } } -// Defines values for BillingUsageBasedChargeType. -const ( - BillingUsageBasedChargeTypeUsageBased BillingUsageBasedChargeType = "usage_based" -) - -// Valid indicates whether the value is a known member of the BillingUsageBasedChargeType enum. -func (e BillingUsageBasedChargeType) Valid() bool { - switch e { - case BillingUsageBasedChargeTypeUsageBased: - return true - default: - return false - } -} - // Defines values for BillingWorkflowCollectionAlignmentAnchoredType. const ( BillingWorkflowCollectionAlignmentAnchoredTypeAnchored BillingWorkflowCollectionAlignmentAnchoredType = "anchored" @@ -989,30 +1130,30 @@ func (e BillingWorkflowPaymentSendInvoiceSettingsCollectionMethod) Valid() bool } } -// Defines values for CreateFlatFeeChargeRequestType. +// Defines values for CreateChargeFlatFeeRequestType. const ( - CreateFlatFeeChargeRequestTypeFlatFee CreateFlatFeeChargeRequestType = "flat_fee" + CreateChargeFlatFeeRequestTypeFlatFee CreateChargeFlatFeeRequestType = "flat_fee" ) -// Valid indicates whether the value is a known member of the CreateFlatFeeChargeRequestType enum. -func (e CreateFlatFeeChargeRequestType) Valid() bool { +// Valid indicates whether the value is a known member of the CreateChargeFlatFeeRequestType enum. +func (e CreateChargeFlatFeeRequestType) Valid() bool { switch e { - case CreateFlatFeeChargeRequestTypeFlatFee: + case CreateChargeFlatFeeRequestTypeFlatFee: return true default: return false } } -// Defines values for CreateUsageBasedChargeRequestType. +// Defines values for CreateChargeUsageBasedRequestType. const ( - CreateUsageBasedChargeRequestTypeUsageBased CreateUsageBasedChargeRequestType = "usage_based" + CreateChargeUsageBasedRequestTypeUsageBased CreateChargeUsageBasedRequestType = "usage_based" ) -// Valid indicates whether the value is a known member of the CreateUsageBasedChargeRequestType enum. -func (e CreateUsageBasedChargeRequestType) Valid() bool { +// Valid indicates whether the value is a known member of the CreateChargeUsageBasedRequestType enum. +func (e CreateChargeUsageBasedRequestType) Valid() bool { switch e { - case CreateUsageBasedChargeRequestTypeUsageBased: + case CreateChargeUsageBasedRequestTypeUsageBased: return true default: return false @@ -1316,27 +1457,6 @@ func (e MeteringEventDatacontenttype) Valid() bool { } } -// Defines values for ResourceManagedBy. -const ( - ResourceManagedByManual ResourceManagedBy = "manual" - ResourceManagedBySubscription ResourceManagedBy = "subscription" - ResourceManagedBySystem ResourceManagedBy = "system" -) - -// Valid indicates whether the value is a known member of the ResourceManagedBy enum. -func (e ResourceManagedBy) Valid() bool { - switch e { - case ResourceManagedByManual: - return true - case ResourceManagedBySubscription: - return true - case ResourceManagedBySystem: - return true - default: - return false - } -} - // Addon Add-on allows extending subscriptions with compatible plans with additional // ratecards. type Addon struct { @@ -1524,31 +1644,6 @@ type BaseError struct { Type *string `json:"type,omitempty"` } -// BillingAddress Address -type BillingAddress struct { - // City City. - City *string `json:"city,omitempty"` - - // Country Country code in [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) - // alpha-2 format. - Country *CountryCode `json:"country,omitempty"` - - // Line1 First line of the address. - Line1 *string `json:"line1,omitempty"` - - // Line2 Second line of the address. - Line2 *string `json:"line2,omitempty"` - - // PhoneNumber Phone number. - PhoneNumber *string `json:"phone_number,omitempty"` - - // PostalCode Postal code. - PostalCode *string `json:"postal_code,omitempty"` - - // State State or province. - State *string `json:"state,omitempty"` -} - // BillingApp Installed application. type BillingApp struct { union json.RawMessage @@ -2110,114 +2205,311 @@ type BillingCharge struct { union json.RawMessage } -// BillingChargeStatus Lifecycle status of a charge. -// -// Values: -// -// - `created`: The charge has been created but is not active yet. -// - `active`: The charge is active. -// - `final`: The charge is fully finalized and no further changes are expected. -// - `deleted`: The charge has been deleted. -type BillingChargeStatus string - -// BillingChargeTotals The totals of a change. -// -// RealTime is only expanded when the `real_time_usage` expand is used. -type BillingChargeTotals struct { - // Booked The amount of the charge already booked to the internal accounting system. - Booked BillingTotals `json:"booked"` +// BillingChargeFlatFee A flat fee charge for a customer. +type BillingChargeFlatFee struct { + // AdvanceAfter The earliest time when the charge should be advanced again by background + // processing. + AdvanceAfter *DateTime `json:"advance_after,omitempty"` - // Realtime The realtime amount of the charge. - // - // Requires the `realtime_usage` expand. - Realtime *BillingTotals `json:"realtime,omitempty"` -} + // AmountAfterProration The amount after proration of the charge. + AmountAfterProration CurrencyAmount `json:"amount_after_proration"` -// BillingChargesExpand Expands for customer charges. -// -// Values: -// -// - `real_time_usage`: The charge's real-time usage. -type BillingChargesExpand string + // BillingPeriod The billing period the charge belongs to. + BillingPeriod ClosedPeriod `json:"billing_period"` -// BillingCostBasis Describes currency basis supported by billing system. -type BillingCostBasis struct { // CreatedAt An ISO-8601 timestamp representation of entity creation date. CreatedAt DateTime `json:"created_at"` - // EffectiveFrom An ISO-8601 timestamp representation of the date from which the cost basis is - // effective. If not provided, it will be effective immediately and will be set to - // `now` by the system. - EffectiveFrom *DateTime `json:"effective_from,omitempty"` + // Currency The currency of the charge. + Currency CurrencyCode `json:"currency"` - // FiatCode The fiat currency code for the cost basis. - FiatCode CurrencyCode `json:"fiat_code"` - Id ULID `json:"id"` + // Customer The customer owning the charge. + Customer BillingCustomerReference `json:"customer"` - // Rate The cost rate for the currency. - Rate Numeric `json:"rate"` -} + // DeletedAt An ISO-8601 timestamp representation of entity deletion date. + DeletedAt *DateTime `json:"deleted_at,omitempty"` -// BillingCreditAdjustment A credit adjustment can be used to make manual adjustments to a customer's -// credit balance. -// -// Supported use-cases: -// -// - Usage correction -type BillingCreditAdjustment struct { // Description Optional description of the resource. // // Maximum 1024 characters. Description *string `json:"description,omitempty"` + // Discounts The discounts applied to the charge. + Discounts *BillingChargeFlatFeeDiscounts `json:"discounts,omitempty"` + + // FeatureKey The feature associated with the charge, when applicable. + FeatureKey *string `json:"feature_key,omitempty"` + + // FullServicePeriod The full, unprorated service period of the charge. + FullServicePeriod ClosedPeriod `json:"full_service_period"` + Id ULID `json:"id"` + + // InvoiceAt The timestamp when the charge is intended to be invoiced. + InvoiceAt DateTime `json:"invoice_at"` + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. // // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". Labels *Labels `json:"labels,omitempty"` + // LifecycleController Indicates whether the charge lifecycle is controlled by OpenMeter or manually + // overridden by the API user. + LifecycleController BillingLifecycleController `json:"lifecycle_controller"` + // Name Display name of the resource. // // Between 1 and 256 characters. Name string `json:"name"` -} -// BillingCreditAvailabilityPolicy When credits become available for consumption. -// -// - `on_creation`: Credits are available as soon as the grant is created. -// - `on_authorization`: Credits are available once the payment is authorized. -// - `on_settlement`: Credits are available once the payment is settled. -type BillingCreditAvailabilityPolicy string + // PaymentTerm Payment term of the flat fee charge. + PaymentTerm BillingPricePaymentTerm `json:"payment_term"` -// BillingCreditBalances The balances of the credits of a customer. -type BillingCreditBalances struct { - // Balances The balances by currencies. - Balances []CreditBalance `json:"balances"` + // Price The price of the charge. + Price BillingPrice `json:"price"` - // RetrievedAt The timestamp of the balance retrieval. - RetrievedAt DateTime `json:"retrieved_at"` -} + // ProrationConfiguration The proration configuration of the charge. + ProrationConfiguration BillingRateCardProrationConfiguration `json:"proration_configuration"` -// BillingCreditFundingMethod The funding method describes how the grant is funded. -// -// - `none`: No funding workflow applies, for example promotional grants -// - `invoice`: The grant is funded by an in-system invoice flow -// - `external`: The grant is funded outside the system (e.g., wire transfer, -// external invoice, or manual reconciliation) -type BillingCreditFundingMethod string + // ServicePeriod The effective service period covered by the charge. + ServicePeriod ClosedPeriod `json:"service_period"` -// BillingCreditGrant A credit grant allocates credits to a customer. -// -// Credits are drawn down against charges according to the settlement mode -// configured on the rate card. -type BillingCreditGrant struct { - // Amount Granted credit amount. - Amount Numeric `json:"amount"` + // SettlementMode Settlement mode of the charge. + SettlementMode BillingSettlementMode `json:"settlement_mode"` - // CreatedAt An ISO-8601 timestamp representation of entity creation date. - CreatedAt DateTime `json:"created_at"` + // Status The lifecycle status of the charge. + Status BillingChargeStatus `json:"status"` - // Currency The currency of the granted credits. - Currency BillingCurrencyCode `json:"currency"` + // Subscription The subscription that originated the charge, when the charge was created from a + // subscription item. + Subscription *BillingSubscriptionReference `json:"subscription,omitempty"` + + // TaxConfig Tax configuration of the charge. + TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` + + // Type The type of the charge. + Type BillingChargeFlatFeeType `json:"type"` + + // UniqueReferenceId Unique reference ID of the charge. + UniqueReferenceId *string `json:"unique_reference_id,omitempty"` + + // UpdatedAt An ISO-8601 timestamp representation of entity last update date. + UpdatedAt DateTime `json:"updated_at"` +} + +// BillingChargeFlatFeeType The type of the charge. +type BillingChargeFlatFeeType string + +// BillingChargeFlatFeeDiscounts Discounts applicable to flat fee charges. +// +// This is the same as `ProductCatalog.Discounts` but without the `usage` field, +// which is not applicable to flat fee charges. +type BillingChargeFlatFeeDiscounts struct { + // Percentage Percentage discount applied to the price (0–100). + Percentage *float32 `json:"percentage,omitempty"` +} + +// BillingChargeReference Reference to a charge associated with an invoice line. +type BillingChargeReference struct { + // Id Unique identifier for the charge. + Id ULID `json:"id"` +} + +// BillingChargeStatus Lifecycle status of a charge. +// +// Values: +// +// - `created`: The charge has been created but is not active yet. +// - `active`: The charge is active. +// - `final`: The charge is fully finalized and no further changes are expected. +// - `deleted`: The charge has been deleted. +type BillingChargeStatus string + +// BillingChargeTotals The totals of a change. +// +// RealTime is only expanded when the `real_time_usage` expand is used. +type BillingChargeTotals struct { + // Booked The amount of the charge already booked to the internal accounting system. + Booked BillingTotals `json:"booked"` + + // Realtime The realtime amount of the charge. + // + // Requires the `realtime_usage` expand. + Realtime *BillingTotals `json:"realtime,omitempty"` +} + +// BillingChargeUsageBased A usage-based charge for a customer. +type BillingChargeUsageBased struct { + // AdvanceAfter The earliest time when the charge should be advanced again by background + // processing. + AdvanceAfter *DateTime `json:"advance_after,omitempty"` + + // BillingPeriod The billing period the charge belongs to. + BillingPeriod ClosedPeriod `json:"billing_period"` + + // CreatedAt An ISO-8601 timestamp representation of entity creation date. + CreatedAt DateTime `json:"created_at"` + + // Currency The currency of the charge. + Currency CurrencyCode `json:"currency"` + + // Customer The customer owning the charge. + Customer BillingCustomerReference `json:"customer"` + + // DeletedAt An ISO-8601 timestamp representation of entity deletion date. + DeletedAt *DateTime `json:"deleted_at,omitempty"` + + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // Discounts Discounts applied to the usage-based charge. + Discounts *BillingRateCardDiscounts `json:"discounts,omitempty"` + + // FeatureKey The feature associated with the charge. + FeatureKey string `json:"feature_key"` + + // FullServicePeriod The full, unprorated service period of the charge. + FullServicePeriod ClosedPeriod `json:"full_service_period"` + Id ULID `json:"id"` + + // InvoiceAt The timestamp when the charge is intended to be invoiced. + InvoiceAt DateTime `json:"invoice_at"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // LifecycleController Indicates whether the charge lifecycle is controlled by OpenMeter or manually + // overridden by the API user. + LifecycleController BillingLifecycleController `json:"lifecycle_controller"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // Price The price of the charge. + Price BillingPrice `json:"price"` + + // ServicePeriod The effective service period covered by the charge. + ServicePeriod ClosedPeriod `json:"service_period"` + + // SettlementMode Settlement mode of the charge. + SettlementMode BillingSettlementMode `json:"settlement_mode"` + + // Status The lifecycle status of the charge. + Status BillingChargeStatus `json:"status"` + + // Subscription The subscription that originated the charge, when the charge was created from a + // subscription item. + Subscription *BillingSubscriptionReference `json:"subscription,omitempty"` + + // TaxConfig Tax configuration of the charge. + TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` + + // Totals Aggregated booked and realtime totals for the charge. + Totals BillingChargeTotals `json:"totals"` + + // Type The type of the charge. + Type BillingChargeUsageBasedType `json:"type"` + + // UniqueReferenceId Unique reference ID of the charge. + UniqueReferenceId *string `json:"unique_reference_id,omitempty"` + + // UpdatedAt An ISO-8601 timestamp representation of entity last update date. + UpdatedAt DateTime `json:"updated_at"` +} + +// BillingChargeUsageBasedType The type of the charge. +type BillingChargeUsageBasedType string + +// BillingChargesExpand Expands for customer charges. +// +// Values: +// +// - `real_time_usage`: The charge's real-time usage. +type BillingChargesExpand string + +// BillingCostBasis Describes currency basis supported by billing system. +type BillingCostBasis struct { + // CreatedAt An ISO-8601 timestamp representation of entity creation date. + CreatedAt DateTime `json:"created_at"` + + // EffectiveFrom An ISO-8601 timestamp representation of the date from which the cost basis is + // effective. If not provided, it will be effective immediately and will be set to + // `now` by the system. + EffectiveFrom *DateTime `json:"effective_from,omitempty"` + + // FiatCode The fiat currency code for the cost basis. + FiatCode CurrencyCode `json:"fiat_code"` + Id ULID `json:"id"` + + // Rate The cost rate for the currency. + Rate Numeric `json:"rate"` +} + +// BillingCreditAdjustment A credit adjustment can be used to make manual adjustments to a customer's +// credit balance. +// +// Supported use-cases: +// +// - Usage correction +type BillingCreditAdjustment struct { + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` +} + +// BillingCreditAvailabilityPolicy When credits become available for consumption. +// +// - `on_creation`: Credits are available as soon as the grant is created. +// - `on_authorization`: Credits are available once the payment is authorized. +// - `on_settlement`: Credits are available once the payment is settled. +type BillingCreditAvailabilityPolicy string + +// BillingCreditBalances The balances of the credits of a customer. +type BillingCreditBalances struct { + // Balances The balances by currencies. + Balances []CreditBalance `json:"balances"` + + // RetrievedAt The timestamp of the balance retrieval. + RetrievedAt DateTime `json:"retrieved_at"` +} + +// BillingCreditFundingMethod The funding method describes how the grant is funded. +// +// - `none`: No funding workflow applies, for example promotional grants +// - `invoice`: The grant is funded by an in-system invoice flow +// - `external`: The grant is funded outside the system (e.g., wire transfer, +// external invoice, or manual reconciliation) +type BillingCreditFundingMethod string + +// BillingCreditGrant A credit grant allocates credits to a customer. +// +// Credits are drawn down against charges according to the settlement mode +// configured on the rate card. +type BillingCreditGrant struct { + // Amount Granted credit amount. + Amount Numeric `json:"amount"` + + // CreatedAt An ISO-8601 timestamp representation of entity creation date. + CreatedAt DateTime `json:"created_at"` + + // Currency The currency of the granted credits. + Currency BillingCurrencyCode `json:"currency"` // DeletedAt An ISO-8601 timestamp representation of entity deletion date. DeletedAt *DateTime `json:"deleted_at,omitempty"` @@ -2479,7 +2771,7 @@ type BillingCurrencyType string // have access to features. type BillingCustomer struct { // BillingAddress The billing address of the customer. Used for tax and invoicing. - BillingAddress *BillingAddress `json:"billing_address,omitempty"` + BillingAddress *Address `json:"billing_address,omitempty"` // CreatedAt An ISO-8601 timestamp representation of entity creation date. CreatedAt DateTime `json:"created_at"` @@ -2669,26 +2961,243 @@ type BillingFeatureUnitCost struct { union json.RawMessage } -// BillingFlatFeeCharge A flat fee charge for a customer. -type BillingFlatFeeCharge struct { - // AdvanceAfter The earliest time when the charge should be advanced again by background - // processing. - AdvanceAfter *DateTime `json:"advance_after,omitempty"` +// BillingInvoice An invoice issued to a customer. +// +// The `type` field determines the concrete variant: +// +// - `standard`: a standard invoice for charges owed. +type BillingInvoice struct { + union json.RawMessage +} - // AmountAfterProration The amount after proration of the charge. - AmountAfterProration CurrencyAmount `json:"amount_after_proration"` +// BillingInvoiceAvailableActionDetails Details about an available invoice action including the resulting state. +type BillingInvoiceAvailableActionDetails struct { + // ResultingState The extended status the invoice will transition to after performing this action. + ResultingState string `json:"resulting_state"` +} - // BillingPeriod The billing period the charge belongs to. - BillingPeriod ClosedPeriod `json:"billing_period"` +// BillingInvoiceAvailableActions The set of state-transition actions available for an invoice in its current +// status. +// +// A field is present only when that action is permitted from the current state. +type BillingInvoiceAvailableActions struct { + // Advance Advance the invoice to the next workflow step. + Advance *BillingInvoiceAvailableActionDetails `json:"advance,omitempty"` + + // Approve Approve the invoice for issuance. + Approve *BillingInvoiceAvailableActionDetails `json:"approve,omitempty"` + + // Delete Delete the invoice. + Delete *BillingInvoiceAvailableActionDetails `json:"delete,omitempty"` + + // Retry Retry a failed workflow step. + Retry *BillingInvoiceAvailableActionDetails `json:"retry,omitempty"` + + // SnapshotQuantities Snapshot the current usage quantities. + SnapshotQuantities *BillingInvoiceAvailableActionDetails `json:"snapshot_quantities,omitempty"` +} + +// BillingInvoiceCustomer Snapshot of the customer's information at the time the invoice was issued. +type BillingInvoiceCustomer struct { + // BillingAddress The billing address of the customer. Used for tax and invoicing. + BillingAddress *Address `json:"billing_address,omitempty"` + + // Id ULID (Universally Unique Lexicographically Sortable Identifier). + Id ULID `json:"id"` + + // Key Optional external resource key for the customer. + // + // Omitted when the customer was created without a key. Unlike on the customer + // resource itself, the key is optional here because the invoice snapshot may + // predate or omit it. + Key *ExternalResourceKey `json:"key,omitempty"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // UsageAttribution Mapping to attribute metered usage to the customer by the event subject. + UsageAttribution *BillingCustomerUsageAttribution `json:"usage_attribution,omitempty"` +} + +// BillingInvoiceDetailedLine A detailed (child) sub-line belonging to a parent invoice line. +// +// Detailed lines represent the individual flat-fee components that make up a +// usage-based parent line after quantity snapshotting. +type BillingInvoiceDetailedLine struct { + // Category The cost category of this detailed line. + Category BillingInvoiceDetailedLineCostCategory `json:"category"` // CreatedAt An ISO-8601 timestamp representation of entity creation date. CreatedAt DateTime `json:"created_at"` - // Currency The currency of the charge. + // CreditsApplied Credit applied to this detailed line. + CreditsApplied *[]BillingInvoiceLineCreditsApplied `json:"credits_applied,omitempty"` + + // DeletedAt An ISO-8601 timestamp representation of entity deletion date. + DeletedAt *DateTime `json:"deleted_at,omitempty"` + + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // Discounts Discounts applied to this detailed line. + Discounts *BillingInvoiceLineDiscounts `json:"discounts,omitempty"` + + // ExternalReferences External identifiers for this detailed line. + ExternalReferences *BillingInvoiceLineExternalReferences `json:"external_references,omitempty"` + Id ULID `json:"id"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // Quantity The quantity of the detailed line. + Quantity Numeric `json:"quantity"` + + // ServicePeriod The service period covered by this detailed line. + ServicePeriod ClosedPeriod `json:"service_period"` + + // Totals Aggregated financial totals for the detailed line. + Totals BillingTotals `json:"totals"` + + // UnitPrice The unit price of the detailed line. + UnitPrice Numeric `json:"unit_price"` + + // UpdatedAt An ISO-8601 timestamp representation of entity last update date. + UpdatedAt DateTime `json:"updated_at"` +} + +// BillingInvoiceDetailedLineCostCategory Cost category of a detailed invoice line item. +type BillingInvoiceDetailedLineCostCategory string + +// BillingInvoiceDiscountReason The reason a discount was applied to an invoice line. +type BillingInvoiceDiscountReason string + +// BillingInvoiceExternalReferences External identifiers assigned to an invoice by third-party systems. +type BillingInvoiceExternalReferences struct { + // InvoicingId The ID assigned by the external invoicing app (e.g. Stripe invoice ID). + InvoicingId *string `json:"invoicing_id,omitempty"` + + // PaymentId The ID assigned by the external payment app (e.g. Stripe payment intent ID). + PaymentId *string `json:"payment_id,omitempty"` +} + +// BillingInvoiceLine A top-level line item on an invoice. +// +// Each line represents a single charge, typically associated with a rate card from +// a subscription. Detailed (child) lines are nested under `detailed_lines` when +// present. +type BillingInvoiceLine struct { + union json.RawMessage +} + +// BillingInvoiceLineAmountDiscount A monetary amount discount applied to an invoice line item. +type BillingInvoiceLineAmountDiscount struct { + // Amount The monetary amount deducted. + Amount Numeric `json:"amount"` + + // Description Optional human-readable description of the discount. + Description *string `json:"description,omitempty"` + + // ExternalReferences External identifiers for this discount. + ExternalReferences *BillingInvoiceLineExternalReferences `json:"external_references,omitempty"` + + // Id Unique identifier for the discount. + Id ULID `json:"id"` + + // Reason The reason this discount was applied. + Reason BillingInvoiceDiscountReason `json:"reason"` +} + +// BillingInvoiceLineCreditsApplied A credit allocation applied to an invoice line item. +type BillingInvoiceLineCreditsApplied struct { + // Amount The monetary amount credited. + Amount Numeric `json:"amount"` + + // Description Optional human-readable description of the credit allocation. + Description *string `json:"description,omitempty"` +} + +// BillingInvoiceLineDiscounts Discounts applied to an invoice line item. +type BillingInvoiceLineDiscounts struct { + // Amount Monetary amount discounts (e.g. from maximum spend commitments). + Amount *[]BillingInvoiceLineAmountDiscount `json:"amount,omitempty"` + + // Usage Usage quantity discounts (e.g. free tier usage allowances). + Usage *[]BillingInvoiceLineUsageDiscount `json:"usage,omitempty"` +} + +// BillingInvoiceLineExternalReferences External identifiers for an invoice line item assigned by third-party systems. +type BillingInvoiceLineExternalReferences struct { + // InvoicingId The ID assigned by the external invoicing app. + InvoicingId *string `json:"invoicing_id,omitempty"` +} + +// BillingInvoiceLineRateCard Rate card configuration snapshot for a usage-based invoice line. +type BillingInvoiceLineRateCard struct { + // Discounts Discount configuration from the rate card. + Discounts *BillingRateCardDiscounts `json:"discounts,omitempty"` + + // FeatureKey The feature key associated with this line's rate card. + FeatureKey *ResourceKey `json:"feature_key,omitempty"` + + // Price The price definition used to calculate charges for this line. + Price BillingPrice `json:"price"` + + // TaxConfig Tax configuration snapshot for this line. + TaxConfig *BillingRateCardTaxConfig `json:"tax_config,omitempty"` +} + +// BillingInvoiceLineUsageDiscount A usage quantity discount applied to an invoice line item. +type BillingInvoiceLineUsageDiscount struct { + // Description Optional human-readable description of the discount. + Description *string `json:"description,omitempty"` + + // ExternalReferences External identifiers for this discount. + ExternalReferences *BillingInvoiceLineExternalReferences `json:"external_references,omitempty"` + + // Id Unique identifier for the discount. + Id ULID `json:"id"` + + // Quantity The usage quantity deducted (in billing units). + Quantity Numeric `json:"quantity"` + + // Reason The reason this discount was applied. + Reason BillingInvoiceDiscountReason `json:"reason"` +} + +// BillingInvoiceNumber InvoiceNumber is a unique identifier for the invoice, generated by the invoicing +// app. +// +// The uniqueness depends on a lot of factors: +// +// - app setting (unique per app or unique per customer) +// - multiple app scenarios (multiple apps generating invoices with the same +// prefix) +type BillingInvoiceNumber = string + +// BillingInvoiceStandard A standard invoice for charges owed by the customer. +type BillingInvoiceStandard struct { + // CollectionAt Timestamp when collection was initiated for this invoice. + CollectionAt *DateTime `json:"collection_at,omitempty"` + + // CreatedAt An ISO-8601 timestamp representation of entity creation date. + CreatedAt DateTime `json:"created_at"` + + // Currency Three-letter ISO 4217 currency code for the invoice. Currency CurrencyCode `json:"currency"` - // Customer The customer owning the charge. - Customer BillingCustomerReference `json:"customer"` + // Customer Snapshot of the customer's information at the time the invoice was issued. + Customer BillingInvoiceCustomer `json:"customer"` // DeletedAt An ISO-8601 timestamp representation of entity deletion date. DeletedAt *DateTime `json:"deleted_at,omitempty"` @@ -2698,78 +3207,265 @@ type BillingFlatFeeCharge struct { // Maximum 1024 characters. Description *string `json:"description,omitempty"` - // Discounts The discounts applied to the charge. - Discounts *BillingFlatFeeDiscounts `json:"discounts,omitempty"` + // DraftUntil Timestamp until which the invoice remains in draft state. + // + // The invoice advances automatically once this time is reached. + DraftUntil *DateTime `json:"draft_until,omitempty"` - // FeatureKey The feature associated with the charge, when applicable. - FeatureKey *string `json:"feature_key,omitempty"` + // DueAt Timestamp when payment is due. + DueAt *DateTime `json:"due_at,omitempty"` - // FullServicePeriod The full, unprorated service period of the charge. - FullServicePeriod ClosedPeriod `json:"full_service_period"` - Id ULID `json:"id"` + // ExternalReferences External identifiers assigned to this invoice by third-party systems. + ExternalReferences *BillingInvoiceExternalReferences `json:"external_references,omitempty"` + Id ULID `json:"id"` + + // IssuedAt Timestamp when the invoice was issued to the customer. + IssuedAt *DateTime `json:"issued_at,omitempty"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // Lines Line items on this invoice. + // + // Always returned on single-resource GET; omitted on list endpoints unless + // explicitly expanded. + Lines *[]BillingInvoiceLine `json:"lines,omitempty"` + + // Number Human-readable invoice number generated by the invoicing app. + Number BillingInvoiceNumber `json:"number"` + + // QuantitySnapshottedAt Timestamp when usage quantities were last snapshotted for this invoice. + QuantitySnapshottedAt *DateTime `json:"quantity_snapshotted_at,omitempty"` + + // SentToCustomerAt Timestamp when the invoice was sent to the customer. + SentToCustomerAt *DateTime `json:"sent_to_customer_at,omitempty"` + + // ServicePeriod The service period covered by this invoice. + // + // For flat fee the service period can be empty which means `from` will be equals + // to `to`. In other cases those fields will be filled with the actual service + // period. + ServicePeriod ClosedPeriod `json:"service_period"` + + // Status Current lifecycle status of the invoice. + Status BillingInvoiceStandardStatus `json:"status"` + + // StatusDetails Detailed status information including available actions and workflow state. + StatusDetails BillingInvoiceStatusDetails `json:"status_details"` + + // Supplier Snapshot of the supplier's contact information at the time the invoice was + // issued. + Supplier BillingSupplier `json:"supplier"` + + // Totals Aggregated financial totals for the invoice. + Totals BillingTotals `json:"totals"` + + // Type Discriminator field identifying this as a standard invoice. + Type BillingInvoiceStandardType `json:"type"` + + // UpdatedAt An ISO-8601 timestamp representation of entity last update date. + UpdatedAt DateTime `json:"updated_at"` + + // ValidationIssues Validation issues found during invoice processing. + // + // Present only when there are one or more validation findings. An empty list is + // omitted. + ValidationIssues *[]BillingInvoiceValidationIssue `json:"validation_issues,omitempty"` + + // Workflow Workflow configuration snapshot captured at invoice creation time. + Workflow BillingInvoiceWorkflowSettings `json:"workflow"` +} + +// BillingInvoiceStandardType Discriminator field identifying this as a standard invoice. +type BillingInvoiceStandardType string + +// BillingInvoiceStandardLine A top-level line item on an invoice. +// +// Each line represents a single charge, typically associated with a rate card from +// a subscription. Detailed (child) lines are nested under `detailed_lines` when +// present. +type BillingInvoiceStandardLine struct { + // Charge Reference to the charge associated with this line item. + Charge *BillingChargeReference `json:"charge,omitempty"` + + // CreatedAt An ISO-8601 timestamp representation of entity creation date. + CreatedAt DateTime `json:"created_at"` + + // CreditsApplied Credit applied to this line item. + CreditsApplied *[]BillingInvoiceLineCreditsApplied `json:"credits_applied,omitempty"` + + // DeletedAt An ISO-8601 timestamp representation of entity deletion date. + DeletedAt *DateTime `json:"deleted_at,omitempty"` + + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // DetailedLines Detailed sub-lines that this line has been broken down into. + // + // Present when line has individual details. + DetailedLines []BillingInvoiceDetailedLine `json:"detailed_lines"` + + // Discounts Discounts applied to this line item. + Discounts *BillingInvoiceLineDiscounts `json:"discounts,omitempty"` + + // ExternalReferences External identifiers for this line item assigned by third-party systems. + ExternalReferences *BillingInvoiceLineExternalReferences `json:"external_references,omitempty"` + Id ULID `json:"id"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // LifecycleController Indicates whether this line item's lifecycle is controlled by OpenMeter or + // manually overridden by the API user. + LifecycleController BillingLifecycleController `json:"lifecycle_controller"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // RateCard The rate card configuration snapshot used to price this line item. + RateCard BillingInvoiceLineRateCard `json:"rate_card"` + + // ServicePeriod The service period covered by this invoice, spanning the earliest line start to + // the latest line end across all of its lines. + // + // For an invoice with no lines the period is empty, which means `from` will be + // equal to `to`. + ServicePeriod ClosedPeriod `json:"service_period"` + + // Subscription Reference to the subscription item that generated this line. + Subscription *BillingSubscriptionReference `json:"subscription,omitempty"` + + // Totals Aggregated financial totals for the line item. + Totals BillingTotals `json:"totals"` + + // Type The type of charge this line item represents. + Type BillingInvoiceStandardLineType `json:"type"` + + // UpdatedAt An ISO-8601 timestamp representation of entity last update date. + UpdatedAt DateTime `json:"updated_at"` +} + +// BillingInvoiceStandardLineType The type of charge this line item represents. +type BillingInvoiceStandardLineType string + +// BillingInvoiceStandardStatus Lifecycle status of a standard invoice. +type BillingInvoiceStandardStatus string + +// BillingInvoiceStatusDetails Detailed status information for a standard invoice. +type BillingInvoiceStatusDetails struct { + // AvailableActions The set of state-transition actions currently available for this invoice. + AvailableActions BillingInvoiceAvailableActions `json:"available_actions"` + + // ExtendedStatus Fine-grained internal status string providing additional workflow detail beyond + // the top-level status enum. + ExtendedStatus string `json:"extended_status"` + + // Failed Whether the invoice is in a failed state. + Failed bool `json:"failed"` - // InvoiceAt The timestamp when the charge is intended to be invoiced. - InvoiceAt DateTime `json:"invoice_at"` + // Immutable Whether the invoice is immutable (i.e. cannot be modified or deleted). + Immutable bool `json:"immutable"` +} - // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. - // - // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". - Labels *Labels `json:"labels,omitempty"` +// BillingInvoiceValidationIssue A validation issue found during invoice processing. +// +// Converges on the same structure used by plan and subscription validation errors: +// a machine-readable `code`, a human-readable `message`, optional structured +// `attributes`, plus a `severity` and optional `field` path. +type BillingInvoiceValidationIssue struct { + // Attributes Additional structured context. + Attributes *map[string]interface{} `json:"attributes,omitempty"` - // ManagedBy The charge is managed by the following entity. - ManagedBy ResourceManagedBy `json:"managed_by"` + // Code Machine-readable error code. + Code string `json:"code"` - // Name Display name of the resource. + // Field JSON path to the field that caused this validation issue, if applicable. // - // Between 1 and 256 characters. - Name string `json:"name"` + // For example: `lines/0/rate_card/price`. + Field *string `json:"field,omitempty"` - // PaymentTerm Payment term of the flat fee charge. - PaymentTerm BillingPricePaymentTerm `json:"payment_term"` + // Message Human-readable description of the error. + Message string `json:"message"` - // Price The price of the charge. - Price BillingPrice `json:"price"` + // Severity Severity of the validation issue. + Severity BillingInvoiceValidationIssueSeverity `json:"severity"` +} - // ProrationConfiguration The proration configuration of the charge. - ProrationConfiguration BillingRateCardProrationConfiguration `json:"proration_configuration"` +// BillingInvoiceValidationIssueSeverity Severity level of an invoice validation issue. +type BillingInvoiceValidationIssueSeverity string - // ServicePeriod The effective service period covered by the charge. - ServicePeriod ClosedPeriod `json:"service_period"` +// BillingInvoiceWorkflow Invoice-level snapshot of the workflow configuration. +// +// Contains only the settings that are meaningful for an already-created invoice: +// invoicing behaviour and payment settings. Collection alignment and tax policy +// are gather-time / profile-wide concerns and are not included. +type BillingInvoiceWorkflow struct { + // Invoicing Invoicing settings for this invoice. + Invoicing *BillingInvoiceWorkflowInvoicingSettings `json:"invoicing,omitempty"` + + // Payment Payment settings for this invoice. + Payment *BillingWorkflowPaymentSettings `json:"payment,omitempty"` +} - // SettlementMode Settlement mode of the charge. - SettlementMode BillingSettlementMode `json:"settlement_mode"` +// BillingInvoiceWorkflowAppsReferences BillingInvoiceWorkflowAppsReferences represents the references (id) to the apps +// used by a billing profile +type BillingInvoiceWorkflowAppsReferences struct { + // Invoicing The invoicing app used for this workflow + Invoicing BillingAppReference `json:"invoicing"` - // Status The lifecycle status of the charge. - Status BillingChargeStatus `json:"status"` + // Payment The payment app used for this workflow + Payment BillingAppReference `json:"payment"` - // Subscription The subscription that originated the charge, when the charge was created from a - // subscription item. - Subscription *BillingSubscriptionReference `json:"subscription,omitempty"` + // Tax The tax app used for this workflow + Tax BillingAppReference `json:"tax"` +} - // TaxConfig Tax configuration of the charge. - TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` +// BillingInvoiceWorkflowInvoicingSettings Invoice-level invoicing settings. +// +// A subset of BillingWorkflowInvoicingSettings limited to fields that are +// meaningful per-invoice. progressive_billing is omitted as it is a gather-time / +// profile-level decision. +type BillingInvoiceWorkflowInvoicingSettings struct { + // AutoAdvance Whether to automatically issue the invoice after the draft_period has passed. + AutoAdvance *bool `json:"auto_advance,omitempty"` - // Type The type of the charge. - Type BillingFlatFeeChargeType `json:"type"` + // DraftPeriod The period for the invoice to be kept in draft status for manual reviews. + DraftPeriod *string `json:"draft_period,omitempty"` +} - // UniqueReferenceId Unique reference ID of the charge. - UniqueReferenceId *string `json:"unique_reference_id,omitempty"` +// BillingInvoiceWorkflowSettings Snapshot of the billing workflow configuration captured at invoice creation. +type BillingInvoiceWorkflowSettings struct { + // Apps The apps that will be used to orchestrate the invoice's workflow. + Apps *BillingInvoiceWorkflowAppsReferences `json:"apps,omitempty"` - // UpdatedAt An ISO-8601 timestamp representation of entity last update date. - UpdatedAt DateTime `json:"updated_at"` -} + // SourceBillingProfile The billing profile that was the source of this workflow snapshot. + SourceBillingProfile BillingProfileReference `json:"source_billing_profile"` -// BillingFlatFeeChargeType The type of the charge. -type BillingFlatFeeChargeType string + // Workflow The workflow configuration that was active when the invoice was created. + // + // Only the fields that are meaningful at the per-invoice level are included: + // invoicing behaviour (auto-advance, draft period) and payment settings + // (collection method, due date). Profile-wide settings such as collection + // alignment, progressive billing, and tax policy are omitted. + Workflow BillingInvoiceWorkflow `json:"workflow"` +} -// BillingFlatFeeDiscounts Discounts applicable to flat fee charges. +// BillingLifecycleController Identifies whether a resource lifecycle is controlled by OpenMeter or manually +// overridden by the API user. // -// This is the same as `ProductCatalog.Discounts` but without the `usage` field, -// which is not applicable to flat fee charges. -type BillingFlatFeeDiscounts struct { - // Percentage Percentage discount applied to the price (0–100). - Percentage *float32 `json:"percentage,omitempty"` -} +// Values: +// +// - `system`: The resource lifecycle is controlled by OpenMeter. +// - `manual`: The resource lifecycle was manually overridden by the API user. +type BillingLifecycleController string // BillingParty Party represents a person or business entity. type BillingParty struct { @@ -3231,7 +3927,7 @@ type BillingRateCardTaxConfig struct { Behavior *BillingTaxBehavior `json:"behavior,omitempty"` // Code TaxCode reference. - Code TaxCodeReferenceItem `json:"code"` + Code TaxCodeReference `json:"code"` } // BillingSettlementMode Settlement mode for billing. @@ -3480,6 +4176,26 @@ type BillingSubscriptionReference struct { // BillingSubscriptionStatus Subscription status. type BillingSubscriptionStatus string +// BillingSupplier Snapshot of the supplier's information at the time the invoice was issued. +// +// Structurally a read-only subset of `BillingParty` (the type configured on the +// billing profile), so the snapshot stays aligned with the source. `key` is +// omitted because it is not part of the snapshotted supplier data. +type BillingSupplier struct { + // Addresses Address for where information should be sent if needed. + Addresses *BillingPartyAddresses `json:"addresses,omitempty"` + + // Id Unique identifier for the party. + Id *string `json:"id,omitempty"` + + // Name Legal name or representation of the party. + Name *string `json:"name,omitempty"` + + // TaxId The entity's legal identification used for tax purposes. They may have other + // numbers, but we're only interested in those valid for tax purposes. + TaxId *BillingPartyTaxIdentity `json:"tax_id,omitempty"` +} + // BillingTaxBehavior Tax behavior. // // This enum is used to specify whether tax is included in the price or excluded @@ -3672,93 +4388,6 @@ type BillingUnitConfigOperation string // - `none`: No rounding; the converted value is used as-is. type BillingUnitConfigRoundingMode string -// BillingUsageBasedCharge A usage-based charge for a customer. -type BillingUsageBasedCharge struct { - // AdvanceAfter The earliest time when the charge should be advanced again by background - // processing. - AdvanceAfter *DateTime `json:"advance_after,omitempty"` - - // BillingPeriod The billing period the charge belongs to. - BillingPeriod ClosedPeriod `json:"billing_period"` - - // CreatedAt An ISO-8601 timestamp representation of entity creation date. - CreatedAt DateTime `json:"created_at"` - - // Currency The currency of the charge. - Currency CurrencyCode `json:"currency"` - - // Customer The customer owning the charge. - Customer BillingCustomerReference `json:"customer"` - - // DeletedAt An ISO-8601 timestamp representation of entity deletion date. - DeletedAt *DateTime `json:"deleted_at,omitempty"` - - // Description Optional description of the resource. - // - // Maximum 1024 characters. - Description *string `json:"description,omitempty"` - - // Discounts Discounts applied to the usage-based charge. - Discounts *BillingRateCardDiscounts `json:"discounts,omitempty"` - - // FeatureKey The feature associated with the charge. - FeatureKey string `json:"feature_key"` - - // FullServicePeriod The full, unprorated service period of the charge. - FullServicePeriod ClosedPeriod `json:"full_service_period"` - Id ULID `json:"id"` - - // InvoiceAt The timestamp when the charge is intended to be invoiced. - InvoiceAt DateTime `json:"invoice_at"` - - // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. - // - // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". - Labels *Labels `json:"labels,omitempty"` - - // ManagedBy The charge is managed by the following entity. - ManagedBy ResourceManagedBy `json:"managed_by"` - - // Name Display name of the resource. - // - // Between 1 and 256 characters. - Name string `json:"name"` - - // Price The price of the charge. - Price BillingPrice `json:"price"` - - // ServicePeriod The effective service period covered by the charge. - ServicePeriod ClosedPeriod `json:"service_period"` - - // SettlementMode Settlement mode of the charge. - SettlementMode BillingSettlementMode `json:"settlement_mode"` - - // Status The lifecycle status of the charge. - Status BillingChargeStatus `json:"status"` - - // Subscription The subscription that originated the charge, when the charge was created from a - // subscription item. - Subscription *BillingSubscriptionReference `json:"subscription,omitempty"` - - // TaxConfig Tax configuration of the charge. - TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` - - // Totals Aggregated booked and realtime totals for the charge. - Totals BillingChargeTotals `json:"totals"` - - // Type The type of the charge. - Type BillingUsageBasedChargeType `json:"type"` - - // UniqueReferenceId Unique reference ID of the charge. - UniqueReferenceId *string `json:"unique_reference_id,omitempty"` - - // UpdatedAt An ISO-8601 timestamp representation of entity last update date. - UpdatedAt DateTime `json:"updated_at"` -} - -// BillingUsageBasedChargeType The type of the charge. -type BillingUsageBasedChargeType string - // BillingWorkflow Billing workflow settings. type BillingWorkflow struct { // Collection The collection settings for this workflow @@ -3987,19 +4616,139 @@ type CreateBillingProfileRequest struct { // Between 1 and 256 characters. Name string `json:"name"` - // Supplier The name and contact information for the supplier this billing profile - // represents - Supplier BillingParty `json:"supplier"` + // Supplier The name and contact information for the supplier this billing profile + // represents + Supplier BillingParty `json:"supplier"` + + // Workflow The billing workflow settings for this profile + Workflow BillingWorkflow `json:"workflow"` +} + +// CreateChargeFlatFeeRequest Flat fee charge create request. +type CreateChargeFlatFeeRequest struct { + // AmountBeforeProration The amount before proration of the charge. + AmountBeforeProration CurrencyAmount `json:"amount_before_proration"` + + // BillingPeriod The billing period the charge belongs to. + BillingPeriod *ClosedPeriod `json:"billing_period,omitempty"` + + // Currency The currency of the charge. + Currency CurrencyCode `json:"currency"` + + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // Discounts The discounts applied to the charge. + Discounts *BillingChargeFlatFeeDiscounts `json:"discounts,omitempty"` + + // FeatureKey The feature associated with the charge, when applicable. + FeatureKey *string `json:"feature_key,omitempty"` + + // FullServicePeriod The full, unprorated service period of the charge. + FullServicePeriod *ClosedPeriod `json:"full_service_period,omitempty"` + + // InvoiceAt The timestamp when the charge is intended to be invoiced. + InvoiceAt DateTime `json:"invoice_at"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // PaymentTerm Payment term of the flat fee charge. + PaymentTerm BillingPricePaymentTerm `json:"payment_term"` + + // ProrationConfiguration The proration configuration of the charge. + ProrationConfiguration BillingRateCardProrationConfiguration `json:"proration_configuration"` + + // ServicePeriod The effective service period covered by the charge. + ServicePeriod ClosedPeriod `json:"service_period"` + + // SettlementMode Settlement mode of the charge. + SettlementMode BillingSettlementMode `json:"settlement_mode"` + + // TaxConfig Tax configuration of the charge. + TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` + + // Type The type of the charge. + Type CreateChargeFlatFeeRequestType `json:"type"` + + // UniqueReferenceId Unique reference ID of the charge. + UniqueReferenceId *string `json:"unique_reference_id,omitempty"` +} + +// CreateChargeFlatFeeRequestType The type of the charge. +type CreateChargeFlatFeeRequestType string + +// CreateChargeRequest Customer charge. +type CreateChargeRequest struct { + union json.RawMessage +} + +// CreateChargeUsageBasedRequest Usage-based charge create request. +type CreateChargeUsageBasedRequest struct { + // BillingPeriod The billing period the charge belongs to. + BillingPeriod *ClosedPeriod `json:"billing_period,omitempty"` + + // Currency The currency of the charge. + Currency CurrencyCode `json:"currency"` + + // Description Optional description of the resource. + // + // Maximum 1024 characters. + Description *string `json:"description,omitempty"` + + // Discounts Discounts applied to the usage-based charge. + Discounts *BillingRateCardDiscounts `json:"discounts,omitempty"` + + // FeatureKey The feature associated with the charge. + FeatureKey string `json:"feature_key"` + + // FullServicePeriod The full, unprorated service period of the charge. + FullServicePeriod *ClosedPeriod `json:"full_service_period,omitempty"` + + // InvoiceAt The timestamp when the charge is intended to be invoiced. + InvoiceAt DateTime `json:"invoice_at"` + + // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. + // + // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". + Labels *Labels `json:"labels,omitempty"` + + // Name Display name of the resource. + // + // Between 1 and 256 characters. + Name string `json:"name"` + + // Price The price of the charge. + Price BillingPrice `json:"price"` - // Workflow The billing workflow settings for this profile - Workflow BillingWorkflow `json:"workflow"` -} + // ServicePeriod The effective service period covered by the charge. + ServicePeriod ClosedPeriod `json:"service_period"` -// CreateChargeRequest Customer charge. -type CreateChargeRequest struct { - union json.RawMessage + // SettlementMode Settlement mode of the charge. + SettlementMode BillingSettlementMode `json:"settlement_mode"` + + // TaxConfig Tax configuration of the charge. + TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` + + // Type The type of the charge. + Type CreateChargeUsageBasedRequestType `json:"type"` + + // UniqueReferenceId Unique reference ID of the charge. + UniqueReferenceId *string `json:"unique_reference_id,omitempty"` } +// CreateChargeUsageBasedRequestType The type of the charge. +type CreateChargeUsageBasedRequestType string + // CreateCostBasisRequest CostBasis create request. type CreateCostBasisRequest struct { // EffectiveFrom An ISO-8601 timestamp representation of the date from which the cost basis is @@ -4152,7 +4901,7 @@ type CreateCurrencyCustomRequest struct { // CreateCustomerRequest Customer create request. type CreateCustomerRequest struct { // BillingAddress The billing address of the customer. Used for tax and invoicing. - BillingAddress *BillingAddress `json:"billing_address,omitempty"` + BillingAddress *Address `json:"billing_address,omitempty"` // Currency Currency of the customer. Used for billing, tax and invoicing. Currency *CurrencyCode `json:"currency,omitempty"` @@ -4213,69 +4962,6 @@ type CreateFeatureRequest struct { UnitCost *BillingFeatureUnitCost `json:"unit_cost,omitempty"` } -// CreateFlatFeeChargeRequest Flat fee charge create request. -type CreateFlatFeeChargeRequest struct { - // AmountBeforeProration The amount before proration of the charge. - AmountBeforeProration CurrencyAmount `json:"amount_before_proration"` - - // BillingPeriod The billing period the charge belongs to. - BillingPeriod *ClosedPeriod `json:"billing_period,omitempty"` - - // Currency The currency of the charge. - Currency CurrencyCode `json:"currency"` - - // Description Optional description of the resource. - // - // Maximum 1024 characters. - Description *string `json:"description,omitempty"` - - // Discounts The discounts applied to the charge. - Discounts *BillingFlatFeeDiscounts `json:"discounts,omitempty"` - - // FeatureKey The feature associated with the charge, when applicable. - FeatureKey *string `json:"feature_key,omitempty"` - - // FullServicePeriod The full, unprorated service period of the charge. - FullServicePeriod *ClosedPeriod `json:"full_service_period,omitempty"` - - // InvoiceAt The timestamp when the charge is intended to be invoiced. - InvoiceAt DateTime `json:"invoice_at"` - - // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. - // - // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". - Labels *Labels `json:"labels,omitempty"` - - // Name Display name of the resource. - // - // Between 1 and 256 characters. - Name string `json:"name"` - - // PaymentTerm Payment term of the flat fee charge. - PaymentTerm BillingPricePaymentTerm `json:"payment_term"` - - // ProrationConfiguration The proration configuration of the charge. - ProrationConfiguration BillingRateCardProrationConfiguration `json:"proration_configuration"` - - // ServicePeriod The effective service period covered by the charge. - ServicePeriod ClosedPeriod `json:"service_period"` - - // SettlementMode Settlement mode of the charge. - SettlementMode BillingSettlementMode `json:"settlement_mode"` - - // TaxConfig Tax configuration of the charge. - TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` - - // Type The type of the charge. - Type CreateFlatFeeChargeRequestType `json:"type"` - - // UniqueReferenceId Unique reference ID of the charge. - UniqueReferenceId *string `json:"unique_reference_id,omitempty"` -} - -// CreateFlatFeeChargeRequestType The type of the charge. -type CreateFlatFeeChargeRequestType string - // CreateMeterRequest Meter create request. type CreateMeterRequest struct { // Aggregation The aggregation type to use for the meter. @@ -4417,63 +5103,6 @@ type CreateTaxCodeRequest struct { Name string `json:"name"` } -// CreateUsageBasedChargeRequest Usage-based charge create request. -type CreateUsageBasedChargeRequest struct { - // BillingPeriod The billing period the charge belongs to. - BillingPeriod *ClosedPeriod `json:"billing_period,omitempty"` - - // Currency The currency of the charge. - Currency CurrencyCode `json:"currency"` - - // Description Optional description of the resource. - // - // Maximum 1024 characters. - Description *string `json:"description,omitempty"` - - // Discounts Discounts applied to the usage-based charge. - Discounts *BillingRateCardDiscounts `json:"discounts,omitempty"` - - // FeatureKey The feature associated with the charge. - FeatureKey string `json:"feature_key"` - - // FullServicePeriod The full, unprorated service period of the charge. - FullServicePeriod *ClosedPeriod `json:"full_service_period,omitempty"` - - // InvoiceAt The timestamp when the charge is intended to be invoiced. - InvoiceAt DateTime `json:"invoice_at"` - - // Labels Labels store metadata of an entity that can be used for filtering an entity list or for searching across entity types. - // - // Keys must be of length 1-63 characters, and cannot start with "kong", "konnect", "mesh", "kic", or "_". - Labels *Labels `json:"labels,omitempty"` - - // Name Display name of the resource. - // - // Between 1 and 256 characters. - Name string `json:"name"` - - // Price The price of the charge. - Price BillingPrice `json:"price"` - - // ServicePeriod The effective service period covered by the charge. - ServicePeriod ClosedPeriod `json:"service_period"` - - // SettlementMode Settlement mode of the charge. - SettlementMode BillingSettlementMode `json:"settlement_mode"` - - // TaxConfig Tax configuration of the charge. - TaxConfig *BillingTaxConfig `json:"tax_config,omitempty"` - - // Type The type of the charge. - Type CreateUsageBasedChargeRequestType `json:"type"` - - // UniqueReferenceId Unique reference ID of the charge. - UniqueReferenceId *string `json:"unique_reference_id,omitempty"` -} - -// CreateUsageBasedChargeRequestType The type of the charge. -type CreateUsageBasedChargeRequestType string - // CreditBalance The credit balance by currency. type CreditBalance struct { // Available Credits that can be consumed right now. Derived from cleared grants after @@ -5638,15 +6267,6 @@ type RecurringPeriod struct { // ResourceKey A key is a unique string that is used to identify a resource. type ResourceKey = string -// ResourceManagedBy Identifies which system manages a resource. -// -// Values: -// -// - `manual`: The resource is managed manually (overridden by our API users). -// - `system`: The resource is managed by the system. -// - `subscription`: The resource is managed by the subscription. -type ResourceManagedBy string - // SortQuery The `asc` suffix is optional as the default sort order is ascending. // The `desc` suffix is used to specify a descending order. // Multiple sort attributes may be provided via a comma separated list. @@ -5735,12 +6355,6 @@ type TaxCodeReference struct { Id ULID `json:"id"` } -// TaxCodeReferenceItem TaxCode reference. -type TaxCodeReferenceItem struct { - // Id ULID (Universally Unique Lexicographically Sortable Identifier). - Id ULID `json:"id"` -} - // ULID ULID (Universally Unique Lexicographically Sortable Identifier). type ULID = string @@ -5881,7 +6495,7 @@ type UpsertCustomerBillingDataRequest struct { // UpsertCustomerRequest Customer upsert request. type UpsertCustomerRequest struct { // BillingAddress The billing address of the customer. Used for tax and invoicing. - BillingAddress *BillingAddress `json:"billing_address,omitempty"` + BillingAddress *Address `json:"billing_address,omitempty"` // Currency Currency of the customer. Used for billing, tax and invoicing. Currency *CurrencyCode `json:"currency,omitempty"` @@ -6556,23 +7170,23 @@ func (t *BillingApp) UnmarshalJSON(b []byte) error { return err } -// AsBillingFlatFeeCharge returns the union data inside the BillingCharge as a BillingFlatFeeCharge -func (t BillingCharge) AsBillingFlatFeeCharge() (BillingFlatFeeCharge, error) { - var body BillingFlatFeeCharge +// AsBillingChargeFlatFee returns the union data inside the BillingCharge as a BillingChargeFlatFee +func (t BillingCharge) AsBillingChargeFlatFee() (BillingChargeFlatFee, error) { + var body BillingChargeFlatFee err := json.Unmarshal(t.union, &body) return body, err } -// FromBillingFlatFeeCharge overwrites any union data inside the BillingCharge as the provided BillingFlatFeeCharge -func (t *BillingCharge) FromBillingFlatFeeCharge(v BillingFlatFeeCharge) error { +// FromBillingChargeFlatFee overwrites any union data inside the BillingCharge as the provided BillingChargeFlatFee +func (t *BillingCharge) FromBillingChargeFlatFee(v BillingChargeFlatFee) error { v.Type = "flat_fee" b, err := json.Marshal(v) t.union = b return err } -// MergeBillingFlatFeeCharge performs a merge with any union data inside the BillingCharge, using the provided BillingFlatFeeCharge -func (t *BillingCharge) MergeBillingFlatFeeCharge(v BillingFlatFeeCharge) error { +// MergeBillingChargeFlatFee performs a merge with any union data inside the BillingCharge, using the provided BillingChargeFlatFee +func (t *BillingCharge) MergeBillingChargeFlatFee(v BillingChargeFlatFee) error { v.Type = "flat_fee" b, err := json.Marshal(v) if err != nil { @@ -6584,23 +7198,23 @@ func (t *BillingCharge) MergeBillingFlatFeeCharge(v BillingFlatFeeCharge) error return err } -// AsBillingUsageBasedCharge returns the union data inside the BillingCharge as a BillingUsageBasedCharge -func (t BillingCharge) AsBillingUsageBasedCharge() (BillingUsageBasedCharge, error) { - var body BillingUsageBasedCharge +// AsBillingChargeUsageBased returns the union data inside the BillingCharge as a BillingChargeUsageBased +func (t BillingCharge) AsBillingChargeUsageBased() (BillingChargeUsageBased, error) { + var body BillingChargeUsageBased err := json.Unmarshal(t.union, &body) return body, err } -// FromBillingUsageBasedCharge overwrites any union data inside the BillingCharge as the provided BillingUsageBasedCharge -func (t *BillingCharge) FromBillingUsageBasedCharge(v BillingUsageBasedCharge) error { +// FromBillingChargeUsageBased overwrites any union data inside the BillingCharge as the provided BillingChargeUsageBased +func (t *BillingCharge) FromBillingChargeUsageBased(v BillingChargeUsageBased) error { v.Type = "usage_based" b, err := json.Marshal(v) t.union = b return err } -// MergeBillingUsageBasedCharge performs a merge with any union data inside the BillingCharge, using the provided BillingUsageBasedCharge -func (t *BillingCharge) MergeBillingUsageBasedCharge(v BillingUsageBasedCharge) error { +// MergeBillingChargeUsageBased performs a merge with any union data inside the BillingCharge, using the provided BillingChargeUsageBased +func (t *BillingCharge) MergeBillingChargeUsageBased(v BillingChargeUsageBased) error { v.Type = "usage_based" b, err := json.Marshal(v) if err != nil { @@ -6627,9 +7241,9 @@ func (t BillingCharge) ValueByDiscriminator() (interface{}, error) { } switch discriminator { case "flat_fee": - return t.AsBillingFlatFeeCharge() + return t.AsBillingChargeFlatFee() case "usage_based": - return t.AsBillingUsageBasedCharge() + return t.AsBillingChargeUsageBased() default: return nil, errors.New("unknown discriminator value: " + discriminator) } @@ -6823,6 +7437,124 @@ func (t *BillingFeatureUnitCost) UnmarshalJSON(b []byte) error { return err } +// AsBillingInvoiceStandard returns the union data inside the BillingInvoice as a BillingInvoiceStandard +func (t BillingInvoice) AsBillingInvoiceStandard() (BillingInvoiceStandard, error) { + var body BillingInvoiceStandard + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBillingInvoiceStandard overwrites any union data inside the BillingInvoice as the provided BillingInvoiceStandard +func (t *BillingInvoice) FromBillingInvoiceStandard(v BillingInvoiceStandard) error { + v.Type = "standard" + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBillingInvoiceStandard performs a merge with any union data inside the BillingInvoice, using the provided BillingInvoiceStandard +func (t *BillingInvoice) MergeBillingInvoiceStandard(v BillingInvoiceStandard) error { + v.Type = "standard" + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t BillingInvoice) Discriminator() (string, error) { + var discriminator struct { + Discriminator string `json:"type"` + } + err := json.Unmarshal(t.union, &discriminator) + return discriminator.Discriminator, err +} + +func (t BillingInvoice) ValueByDiscriminator() (interface{}, error) { + discriminator, err := t.Discriminator() + if err != nil { + return nil, err + } + switch discriminator { + case "standard": + return t.AsBillingInvoiceStandard() + default: + return nil, errors.New("unknown discriminator value: " + discriminator) + } +} + +func (t BillingInvoice) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *BillingInvoice) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsBillingInvoiceStandardLine returns the union data inside the BillingInvoiceLine as a BillingInvoiceStandardLine +func (t BillingInvoiceLine) AsBillingInvoiceStandardLine() (BillingInvoiceStandardLine, error) { + var body BillingInvoiceStandardLine + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBillingInvoiceStandardLine overwrites any union data inside the BillingInvoiceLine as the provided BillingInvoiceStandardLine +func (t *BillingInvoiceLine) FromBillingInvoiceStandardLine(v BillingInvoiceStandardLine) error { + v.Type = "standard_line" + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBillingInvoiceStandardLine performs a merge with any union data inside the BillingInvoiceLine, using the provided BillingInvoiceStandardLine +func (t *BillingInvoiceLine) MergeBillingInvoiceStandardLine(v BillingInvoiceStandardLine) error { + v.Type = "standard_line" + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t BillingInvoiceLine) Discriminator() (string, error) { + var discriminator struct { + Discriminator string `json:"type"` + } + err := json.Unmarshal(t.union, &discriminator) + return discriminator.Discriminator, err +} + +func (t BillingInvoiceLine) ValueByDiscriminator() (interface{}, error) { + discriminator, err := t.Discriminator() + if err != nil { + return nil, err + } + switch discriminator { + case "standard_line": + return t.AsBillingInvoiceStandardLine() + default: + return nil, errors.New("unknown discriminator value: " + discriminator) + } +} + +func (t BillingInvoiceLine) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *BillingInvoiceLine) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // AsBillingPriceFree returns the union data inside the BillingPrice as a BillingPriceFree func (t BillingPrice) AsBillingPriceFree() (BillingPriceFree, error) { var body BillingPriceFree @@ -7361,23 +8093,23 @@ func (t *BillingWorkflowPaymentSettings) UnmarshalJSON(b []byte) error { return err } -// AsCreateFlatFeeChargeRequest returns the union data inside the CreateChargeRequest as a CreateFlatFeeChargeRequest -func (t CreateChargeRequest) AsCreateFlatFeeChargeRequest() (CreateFlatFeeChargeRequest, error) { - var body CreateFlatFeeChargeRequest +// AsCreateChargeFlatFeeRequest returns the union data inside the CreateChargeRequest as a CreateChargeFlatFeeRequest +func (t CreateChargeRequest) AsCreateChargeFlatFeeRequest() (CreateChargeFlatFeeRequest, error) { + var body CreateChargeFlatFeeRequest err := json.Unmarshal(t.union, &body) return body, err } -// FromCreateFlatFeeChargeRequest overwrites any union data inside the CreateChargeRequest as the provided CreateFlatFeeChargeRequest -func (t *CreateChargeRequest) FromCreateFlatFeeChargeRequest(v CreateFlatFeeChargeRequest) error { +// FromCreateChargeFlatFeeRequest overwrites any union data inside the CreateChargeRequest as the provided CreateChargeFlatFeeRequest +func (t *CreateChargeRequest) FromCreateChargeFlatFeeRequest(v CreateChargeFlatFeeRequest) error { v.Type = "flat_fee" b, err := json.Marshal(v) t.union = b return err } -// MergeCreateFlatFeeChargeRequest performs a merge with any union data inside the CreateChargeRequest, using the provided CreateFlatFeeChargeRequest -func (t *CreateChargeRequest) MergeCreateFlatFeeChargeRequest(v CreateFlatFeeChargeRequest) error { +// MergeCreateChargeFlatFeeRequest performs a merge with any union data inside the CreateChargeRequest, using the provided CreateChargeFlatFeeRequest +func (t *CreateChargeRequest) MergeCreateChargeFlatFeeRequest(v CreateChargeFlatFeeRequest) error { v.Type = "flat_fee" b, err := json.Marshal(v) if err != nil { @@ -7389,23 +8121,23 @@ func (t *CreateChargeRequest) MergeCreateFlatFeeChargeRequest(v CreateFlatFeeCha return err } -// AsCreateUsageBasedChargeRequest returns the union data inside the CreateChargeRequest as a CreateUsageBasedChargeRequest -func (t CreateChargeRequest) AsCreateUsageBasedChargeRequest() (CreateUsageBasedChargeRequest, error) { - var body CreateUsageBasedChargeRequest +// AsCreateChargeUsageBasedRequest returns the union data inside the CreateChargeRequest as a CreateChargeUsageBasedRequest +func (t CreateChargeRequest) AsCreateChargeUsageBasedRequest() (CreateChargeUsageBasedRequest, error) { + var body CreateChargeUsageBasedRequest err := json.Unmarshal(t.union, &body) return body, err } -// FromCreateUsageBasedChargeRequest overwrites any union data inside the CreateChargeRequest as the provided CreateUsageBasedChargeRequest -func (t *CreateChargeRequest) FromCreateUsageBasedChargeRequest(v CreateUsageBasedChargeRequest) error { +// FromCreateChargeUsageBasedRequest overwrites any union data inside the CreateChargeRequest as the provided CreateChargeUsageBasedRequest +func (t *CreateChargeRequest) FromCreateChargeUsageBasedRequest(v CreateChargeUsageBasedRequest) error { v.Type = "usage_based" b, err := json.Marshal(v) t.union = b return err } -// MergeCreateUsageBasedChargeRequest performs a merge with any union data inside the CreateChargeRequest, using the provided CreateUsageBasedChargeRequest -func (t *CreateChargeRequest) MergeCreateUsageBasedChargeRequest(v CreateUsageBasedChargeRequest) error { +// MergeCreateChargeUsageBasedRequest performs a merge with any union data inside the CreateChargeRequest, using the provided CreateChargeUsageBasedRequest +func (t *CreateChargeRequest) MergeCreateChargeUsageBasedRequest(v CreateChargeUsageBasedRequest) error { v.Type = "usage_based" b, err := json.Marshal(v) if err != nil { @@ -7432,9 +8164,9 @@ func (t CreateChargeRequest) ValueByDiscriminator() (interface{}, error) { } switch discriminator { case "flat_fee": - return t.AsCreateFlatFeeChargeRequest() + return t.AsCreateChargeFlatFeeRequest() case "usage_based": - return t.AsCreateUsageBasedChargeRequest() + return t.AsCreateChargeUsageBasedRequest() default: return nil, errors.New("unknown discriminator value: " + discriminator) } @@ -7619,6 +8351,9 @@ type ServerInterface interface { // Get app // (GET /openmeter/apps/{appId}) GetApp(w http.ResponseWriter, r *http.Request, appId ULID) + // Get a billing invoice + // (GET /openmeter/billing/invoices/{invoiceId}) + GetInvoice(w http.ResponseWriter, r *http.Request, invoiceId ULID) // List currencies // (GET /openmeter/currencies) ListCurrencies(w http.ResponseWriter, r *http.Request, params ListCurrenciesParams) @@ -7907,6 +8642,12 @@ func (_ Unimplemented) GetApp(w http.ResponseWriter, r *http.Request, appId ULID w.WriteHeader(http.StatusNotImplemented) } +// Get a billing invoice +// (GET /openmeter/billing/invoices/{invoiceId}) +func (_ Unimplemented) GetInvoice(w http.ResponseWriter, r *http.Request, invoiceId ULID) { + w.WriteHeader(http.StatusNotImplemented) +} + // List currencies // (GET /openmeter/currencies) func (_ Unimplemented) ListCurrencies(w http.ResponseWriter, r *http.Request, params ListCurrenciesParams) { @@ -8606,6 +9347,31 @@ func (siw *ServerInterfaceWrapper) GetApp(w http.ResponseWriter, r *http.Request handler.ServeHTTP(w, r) } +// GetInvoice operation middleware +func (siw *ServerInterfaceWrapper) GetInvoice(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "invoiceId" ------------- + var invoiceId ULID + + err = runtime.BindStyledParameterWithOptions("simple", "invoiceId", chi.URLParam(r, "invoiceId"), &invoiceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invoiceId", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetInvoice(w, r, invoiceId) + })) + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + handler = siw.HandlerMiddlewares[i](handler) + } + + handler.ServeHTTP(w, r) +} + // ListCurrencies operation middleware func (siw *ServerInterfaceWrapper) ListCurrencies(w http.ResponseWriter, r *http.Request) { @@ -10877,6 +11643,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/openmeter/apps/{appId}", wrapper.GetApp) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/openmeter/billing/invoices/{invoiceId}", wrapper.GetInvoice) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/openmeter/currencies", wrapper.ListCurrencies) }) @@ -11112,699 +11881,769 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/v3/handlers/addons/convert.go b/api/v3/handlers/addons/convert.go index 8623427a25..2f52f5d364 100644 --- a/api/v3/handlers/addons/convert.go +++ b/api/v3/handlers/addons/convert.go @@ -469,7 +469,7 @@ func ToAPIBillingRateCardTaxConfig(tc *productcatalog.TaxConfig) *apiv3.BillingR } if tc.TaxCodeID != nil { - result.Code = apiv3.TaxCodeReferenceItem{Id: *tc.TaxCodeID} + result.Code = apiv3.TaxCodeReference{Id: *tc.TaxCodeID} } return result diff --git a/api/v3/handlers/billinginvoices/convert.go b/api/v3/handlers/billinginvoices/convert.go new file mode 100644 index 0000000000..ee4943a11f --- /dev/null +++ b/api/v3/handlers/billinginvoices/convert.go @@ -0,0 +1,448 @@ +package billinginvoices + +import ( + "fmt" + + "github.com/samber/lo" + + api "github.com/openmeterio/openmeter/api/v3" + "github.com/openmeterio/openmeter/api/v3/handlers/addons" + "github.com/openmeterio/openmeter/api/v3/handlers/billingprofiles" + chargeshandler "github.com/openmeterio/openmeter/api/v3/handlers/customers/charges" + "github.com/openmeterio/openmeter/api/v3/handlers/plans" + "github.com/openmeterio/openmeter/api/v3/labels" + "github.com/openmeterio/openmeter/openmeter/billing" + "github.com/openmeterio/openmeter/openmeter/billing/charges/meta" + "github.com/openmeterio/openmeter/openmeter/billing/models/creditsapplied" + "github.com/openmeterio/openmeter/openmeter/billing/models/externalid" +) + +// ToAPIBillingInvoice converts a billing.Invoice domain union to the v3 API type. +func ToAPIBillingInvoice(inv billing.Invoice) (api.BillingInvoice, error) { + var out api.BillingInvoice + + switch inv.Type() { + case billing.InvoiceTypeStandard: + std, err := inv.AsStandardInvoice() + if err != nil { + return out, fmt.Errorf("reading standard invoice: %w", err) + } + + stdAPI, err := toAPIStandardInvoice(std) + if err != nil { + return out, err + } + + if err := out.FromBillingInvoiceStandard(stdAPI); err != nil { + return out, fmt.Errorf("setting standard invoice union: %w", err) + } + + default: + genericInv, _ := inv.AsGenericInvoice() + + return out, billing.NotFoundError{ + ID: genericInv.GetID(), + Entity: billing.EntityInvoice, + Err: fmt.Errorf("unsupported invoice type %q", inv.Type()), + } + } + + return out, nil +} + +func toAPIStandardInvoice(std billing.StandardInvoice) (api.BillingInvoiceStandard, error) { + // Sort lines for consistent output — matches v1 behavior. + std.SortLines() + + workflow, err := toAPIWorkflow(std.Workflow) + if err != nil { + return api.BillingInvoiceStandard{}, fmt.Errorf("converting workflow: %w", err) + } + + outLines, err := mapLines(std.Lines.OrEmpty()) + if err != nil { + return api.BillingInvoiceStandard{}, err + } + + return api.BillingInvoiceStandard{ + Id: std.ID, + Number: std.Number, + Description: std.Description, + Labels: labels.FromMetadata(std.Metadata), + CreatedAt: std.CreatedAt, + UpdatedAt: std.UpdatedAt, + DeletedAt: std.DeletedAt, + IssuedAt: std.IssuedAt, + DueAt: std.DueAt, + CollectionAt: lo.ToPtr(lo.FromPtrOr(std.CollectionAt, std.CreatedAt)), + DraftUntil: std.DraftUntil, + SentToCustomerAt: std.SentToCustomerAt, + QuantitySnapshottedAt: std.QuantitySnapshotedAt, + ServicePeriod: api.ClosedPeriod(lo.FromPtr(std.Period)), + Currency: api.CurrencyCode(std.Currency), + Type: api.BillingInvoiceStandardTypeStandard, + Status: api.BillingInvoiceStandardStatus(std.Status.ShortStatus()), + StatusDetails: toAPIStatusDetails(std.StatusDetails, std.Status), + Customer: toAPIInvoiceCustomer(std.Customer), + Supplier: billingprofiles.ToAPIBillingSupplier(std.Supplier), + Totals: chargeshandler.ToAPIBillingTotals(std.Totals), + ValidationIssues: mapValidationIssues(std.ValidationIssues), + ExternalReferences: toAPIInvoiceExternalReferences(std.ExternalIDs), + Workflow: workflow, + Lines: outLines, + }, nil +} + +func toAPIStatusDetails(d billing.StandardInvoiceStatusDetails, status billing.StandardInvoiceStatus) api.BillingInvoiceStatusDetails { + return api.BillingInvoiceStatusDetails{ + Immutable: d.Immutable, + Failed: d.Failed, + ExtendedStatus: string(status), + AvailableActions: api.BillingInvoiceAvailableActions{ + Advance: toAPIActionDetails(d.AvailableActions.Advance), + Approve: toAPIActionDetails(d.AvailableActions.Approve), + Delete: toAPIActionDetails(d.AvailableActions.Delete), + Retry: toAPIActionDetails(d.AvailableActions.Retry), + SnapshotQuantities: toAPIActionDetails(d.AvailableActions.SnapshotQuantities), + // Void and Invoice actions are not exposed in v3. + }, + } +} + +func toAPIActionDetails(d *billing.StandardInvoiceAvailableActionDetails) *api.BillingInvoiceAvailableActionDetails { + if d == nil { + return nil + } + + return &api.BillingInvoiceAvailableActionDetails{ + ResultingState: string(d.ResultingState), + } +} + +func toAPIInvoiceCustomer(c billing.InvoiceCustomer) api.BillingInvoiceCustomer { + out := api.BillingInvoiceCustomer{ + Id: c.CustomerID, + Key: c.Key, + Name: c.Name, + } + + if c.UsageAttribution != nil { + out.UsageAttribution = &api.BillingCustomerUsageAttribution{ + SubjectKeys: c.UsageAttribution.SubjectKeys, + } + } + + if c.BillingAddress != nil && !lo.IsEmpty(*c.BillingAddress) { + var country *api.CountryCode + if c.BillingAddress.Country != nil { + country = lo.ToPtr(api.CountryCode(*c.BillingAddress.Country)) + } + out.BillingAddress = &api.Address{ + City: c.BillingAddress.City, + Country: country, + Line1: c.BillingAddress.Line1, + Line2: c.BillingAddress.Line2, + PhoneNumber: c.BillingAddress.PhoneNumber, + PostalCode: c.BillingAddress.PostalCode, + State: c.BillingAddress.State, + } + } + + return out +} + +func toAPIWorkflow(w billing.InvoiceWorkflow) (api.BillingInvoiceWorkflowSettings, error) { + config := w.Config + + invoicing := &api.BillingInvoiceWorkflowInvoicingSettings{ + AutoAdvance: lo.ToPtr(config.Invoicing.AutoAdvance), + DraftPeriod: lo.ToPtr(config.Invoicing.DraftPeriod.String()), + } + + var payment *api.BillingWorkflowPaymentSettings + switch config.Payment.CollectionMethod { + case billing.CollectionMethodChargeAutomatically: + p := api.BillingWorkflowPaymentSettings{} + if err := p.FromBillingWorkflowPaymentChargeAutomaticallySettings(api.BillingWorkflowPaymentChargeAutomaticallySettings{ + CollectionMethod: "charge_automatically", + }); err != nil { + return api.BillingInvoiceWorkflowSettings{}, fmt.Errorf("converting payment settings: %w", err) + } + payment = &p + case billing.CollectionMethodSendInvoice: + p := api.BillingWorkflowPaymentSettings{} + if err := p.FromBillingWorkflowPaymentSendInvoiceSettings(api.BillingWorkflowPaymentSendInvoiceSettings{ + CollectionMethod: "send_invoice", + DueAfter: lo.ToPtr(config.Invoicing.DueAfter.String()), + }); err != nil { + return api.BillingInvoiceWorkflowSettings{}, fmt.Errorf("converting payment settings: %w", err) + } + payment = &p + } + + return api.BillingInvoiceWorkflowSettings{ + Apps: &api.BillingInvoiceWorkflowAppsReferences{ + Invoicing: api.BillingAppReference{ + Id: w.AppReferences.Invoicing.ID, + }, + Payment: api.BillingAppReference{ + Id: w.AppReferences.Payment.ID, + }, + Tax: api.BillingAppReference{ + Id: w.AppReferences.Tax.ID, + }, + }, + SourceBillingProfile: api.BillingProfileReference{ + Id: w.SourceBillingProfileID, + }, + Workflow: api.BillingInvoiceWorkflow{ + Invoicing: invoicing, + Payment: payment, + }, + }, nil +} + +func mapValidationIssues(issues []billing.ValidationIssue) *[]api.BillingInvoiceValidationIssue { + if len(issues) == 0 { + return nil + } + + out := lo.Map(issues, func(v billing.ValidationIssue, _ int) api.BillingInvoiceValidationIssue { + return api.BillingInvoiceValidationIssue{ + Severity: api.BillingInvoiceValidationIssueSeverity(v.Severity), + Message: v.Message, + Code: v.Code, + Field: lo.EmptyableToPtr(v.Path), + } + }) + + return &out +} + +func toAPIInvoiceExternalReferences(e externalid.InvoiceExternalIDs) *api.BillingInvoiceExternalReferences { + if e.Invoicing == "" && e.Payment == "" { + return nil + } + + return &api.BillingInvoiceExternalReferences{ + InvoicingId: lo.EmptyableToPtr(e.Invoicing), + PaymentId: lo.EmptyableToPtr(e.Payment), + } +} + +func mapLines(lines []*billing.StandardLine) (*[]api.BillingInvoiceLine, error) { + if len(lines) == 0 { + return nil, nil + } + + out, err := lo.MapErr(lines, func(line *billing.StandardLine, _ int) (api.BillingInvoiceLine, error) { + mapped, err := mapStandardLine(line) + if err != nil { + return api.BillingInvoiceLine{}, fmt.Errorf("mapping line[%s]: %w", line.ID, err) + } + + var invoiceLine api.BillingInvoiceLine + if err := invoiceLine.FromBillingInvoiceStandardLine(mapped); err != nil { + return api.BillingInvoiceLine{}, fmt.Errorf("setting standard line union: %w", err) + } + + return invoiceLine, nil + }) + if err != nil { + return nil, err + } + + return &out, nil +} + +func mapStandardLine(line *billing.StandardLine) (api.BillingInvoiceStandardLine, error) { + rateCard, err := mapRateCard(line) + if err != nil { + return api.BillingInvoiceStandardLine{}, fmt.Errorf("mapping rate card: %w", err) + } + + line.SortDetailedLines() + detailedLines, err := mapDetailedLines(line.DetailedLines) + if err != nil { + return api.BillingInvoiceStandardLine{}, fmt.Errorf("mapping detailed lines: %w", err) + } + + var chargeRef *api.BillingChargeReference + if line.ChargeID != nil { + chargeRef = &api.BillingChargeReference{Id: *line.ChargeID} + } + + var subRef *api.BillingSubscriptionReference + if line.Subscription != nil { + subRef = lo.ToPtr(chargeshandler.ConvertSubscriptionRefToAPI(meta.SubscriptionReference{ + SubscriptionID: line.Subscription.SubscriptionID, + PhaseID: line.Subscription.PhaseID, + ItemID: line.Subscription.ItemID, + })) + } + + return api.BillingInvoiceStandardLine{ + Id: line.ID, + Name: line.Name, + Description: line.Description, + Labels: labels.FromMetadata(line.Metadata), + CreatedAt: line.CreatedAt, + UpdatedAt: line.UpdatedAt, + DeletedAt: line.DeletedAt, + Type: api.BillingInvoiceStandardLineTypeStandardLine, + LifecycleController: chargeshandler.ConvertLifecycleControllerToAPI(line.ManagedBy), + ServicePeriod: chargeshandler.ConvertClosedPeriodToAPI(line.Period), + Totals: chargeshandler.ToAPIBillingTotals(line.Totals), + Charge: chargeRef, + Subscription: subRef, + ExternalReferences: toAPILineExternalReferences(line.ExternalIDs), + CreditsApplied: mapCreditApplies(line.CreditsApplied), + Discounts: mapLineDiscounts(line.Discounts), + RateCard: rateCard, + DetailedLines: detailedLines, + }, nil +} + +func mapRateCard(line *billing.StandardLine) (api.BillingInvoiceLineRateCard, error) { + if line.UsageBased == nil { + return api.BillingInvoiceLineRateCard{}, fmt.Errorf("standard line %s has no usage-based configuration", line.ID) + } + + if line.UsageBased.Price == nil { + return api.BillingInvoiceLineRateCard{}, fmt.Errorf("standard line %s has no price set", line.ID) + } + + price, err := plans.ToAPIBillingPrice(line.UsageBased.Price) + if err != nil { + return api.BillingInvoiceLineRateCard{}, fmt.Errorf("mapping price: %w", err) + } + + rc := api.BillingInvoiceLineRateCard{ + Price: price, + FeatureKey: lo.EmptyableToPtr(line.UsageBased.FeatureKey), + Discounts: toAPIRateCardDiscounts(line.RateCardDiscounts), + TaxConfig: addons.ToAPIBillingRateCardTaxConfig(line.TaxConfig.ToProductCatalog()), + } + + return rc, nil +} + +func mapDetailedLines(dls billing.DetailedLines) ([]api.BillingInvoiceDetailedLine, error) { + if len(dls) == 0 { + return lo.Empty[[]api.BillingInvoiceDetailedLine](), nil + } + + return lo.MapErr(dls, func(dl billing.DetailedLine, _ int) (api.BillingInvoiceDetailedLine, error) { + mapped, err := mapDetailedLine(dl) + if err != nil { + return api.BillingInvoiceDetailedLine{}, fmt.Errorf("mapping detailed line[%s]: %w", dl.ID, err) + } + return mapped, nil + }) +} + +func mapDetailedLine(dl billing.DetailedLine) (api.BillingInvoiceDetailedLine, error) { + return api.BillingInvoiceDetailedLine{ + Id: dl.ID, + Name: dl.Name, + Description: dl.Description, + CreatedAt: dl.CreatedAt, + UpdatedAt: dl.UpdatedAt, + DeletedAt: dl.DeletedAt, + Category: api.BillingInvoiceDetailedLineCostCategory(dl.Category), + ServicePeriod: chargeshandler.ConvertClosedPeriodToAPI(dl.ServicePeriod), + Quantity: dl.Quantity.String(), + UnitPrice: dl.PerUnitAmount.String(), + Totals: chargeshandler.ToAPIBillingTotals(dl.Totals), + CreditsApplied: mapCreditApplies(dl.CreditsApplied), + Discounts: mapAmountDiscounts(dl.AmountDiscounts), + ExternalReferences: toAPILineExternalReferences(dl.ExternalIDs), + }, nil +} + +func toAPIRateCardDiscounts(d billing.Discounts) *api.BillingRateCardDiscounts { + if d.IsEmpty() { + return nil + } + + result := &api.BillingRateCardDiscounts{} + + if d.Percentage != nil { + pct := float32(d.Percentage.Percentage.InexactFloat64()) + result.Percentage = &pct + } + + if d.Usage != nil { + s := d.Usage.Quantity.String() + result.Usage = &s + } + + return result +} + +func mapCreditApplies(ca creditsapplied.CreditsApplied) *[]api.BillingInvoiceLineCreditsApplied { + if len(ca) == 0 { + return nil + } + + out := lo.Map(ca, func(c creditsapplied.CreditApplied, _ int) api.BillingInvoiceLineCreditsApplied { + return api.BillingInvoiceLineCreditsApplied{ + Amount: c.Amount.String(), + Description: lo.EmptyableToPtr(c.Description), + } + }) + + return &out +} + +// mapLineDiscounts maps usage discounts from a parent StandardLine (amount discounts live on +// child detailed lines and are mapped separately via mapAmountDiscounts). +func mapLineDiscounts(d billing.StandardLineDiscounts) *api.BillingInvoiceLineDiscounts { + if len(d.Usage) == 0 { + return nil + } + + usageDiscounts := lo.Map(d.Usage, func(ud billing.UsageLineDiscountManaged, _ int) api.BillingInvoiceLineUsageDiscount { + return api.BillingInvoiceLineUsageDiscount{ + Id: ud.ID, + Quantity: ud.Quantity.String(), + Description: ud.Description, + ExternalReferences: toAPILineExternalReferences(ud.ExternalIDs), + Reason: api.BillingInvoiceDiscountReason(ud.Reason.Type()), + } + }) + + return &api.BillingInvoiceLineDiscounts{ + Usage: &usageDiscounts, + } +} + +func mapAmountDiscounts(d billing.AmountLineDiscountsManaged) *api.BillingInvoiceLineDiscounts { + if len(d) == 0 { + return nil + } + + amountDiscounts := lo.Map(d, func(ad billing.AmountLineDiscountManaged, _ int) api.BillingInvoiceLineAmountDiscount { + return api.BillingInvoiceLineAmountDiscount{ + Id: ad.ID, + Amount: ad.Amount.String(), + Description: ad.Description, + ExternalReferences: toAPILineExternalReferences(ad.ExternalIDs), + Reason: api.BillingInvoiceDiscountReason(ad.Reason.Type()), + } + }) + + return &api.BillingInvoiceLineDiscounts{ + Amount: &amountDiscounts, + } +} + +func toAPILineExternalReferences(e externalid.LineExternalIDs) *api.BillingInvoiceLineExternalReferences { + if e.Invoicing == "" { + return nil + } + + return &api.BillingInvoiceLineExternalReferences{ + InvoicingId: lo.ToPtr(e.Invoicing), + } +} diff --git a/api/v3/handlers/billinginvoices/error_encoder.go b/api/v3/handlers/billinginvoices/error_encoder.go new file mode 100644 index 0000000000..f43609deb2 --- /dev/null +++ b/api/v3/handlers/billinginvoices/error_encoder.go @@ -0,0 +1,20 @@ +package billinginvoices + +import ( + "context" + "net/http" + + "github.com/openmeterio/openmeter/openmeter/billing" + "github.com/openmeterio/openmeter/pkg/framework/commonhttp" + "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport/encoder" +) + +func errorEncoder() encoder.ErrorEncoder { + return func(ctx context.Context, err error, w http.ResponseWriter, r *http.Request) bool { + return commonhttp.HandleErrorIfTypeMatches[billing.NotFoundError](ctx, http.StatusNotFound, err, w, billing.EncodeValidationIssues) || + commonhttp.HandleErrorIfTypeMatches[billing.ValidationError](ctx, http.StatusBadRequest, err, w, billing.EncodeValidationIssues) || + commonhttp.HandleErrorIfTypeMatches[billing.UpdateAfterDeleteError](ctx, http.StatusConflict, err, w, billing.EncodeValidationIssues) || + commonhttp.HandleErrorIfTypeMatches[billing.ValidationIssue](ctx, http.StatusBadRequest, err, w, billing.EncodeValidationIssues) || + commonhttp.HandleErrorIfTypeMatches[billing.AppError](ctx, http.StatusBadRequest, err, w) + } +} diff --git a/api/v3/handlers/billinginvoices/get.go b/api/v3/handlers/billinginvoices/get.go new file mode 100644 index 0000000000..8b9bfac109 --- /dev/null +++ b/api/v3/handlers/billinginvoices/get.go @@ -0,0 +1,54 @@ +package billinginvoices + +import ( + "context" + "net/http" + + api "github.com/openmeterio/openmeter/api/v3" + "github.com/openmeterio/openmeter/api/v3/apierrors" + "github.com/openmeterio/openmeter/openmeter/billing" + "github.com/openmeterio/openmeter/pkg/framework/commonhttp" + "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport" + "github.com/openmeterio/openmeter/pkg/models" +) + +type ( + GetBillingInvoiceRequest = billing.GetInvoiceByIdInput + GetBillingInvoiceResponse = api.BillingInvoice + GetBillingInvoiceParams = string + GetBillingInvoiceHandler = httptransport.HandlerWithArgs[GetBillingInvoiceRequest, GetBillingInvoiceResponse, GetBillingInvoiceParams] +) + +func (h *handler) GetBillingInvoice() GetBillingInvoiceHandler { + return httptransport.NewHandlerWithArgs( + func(ctx context.Context, r *http.Request, invoiceId GetBillingInvoiceParams) (GetBillingInvoiceRequest, error) { + ns, err := h.resolveNamespace(ctx) + if err != nil { + return GetBillingInvoiceRequest{}, err + } + + return GetBillingInvoiceRequest{ + Invoice: billing.InvoiceID(models.NamespacedID{ + Namespace: ns, + ID: invoiceId, + }), + Expand: billing.InvoiceExpandAll, + }, nil + }, + func(ctx context.Context, request GetBillingInvoiceRequest) (GetBillingInvoiceResponse, error) { + inv, err := h.service.GetInvoiceById(ctx, request) + if err != nil { + return GetBillingInvoiceResponse{}, err + } + + return ToAPIBillingInvoice(inv) + }, + commonhttp.JSONResponseEncoderWithStatus[GetBillingInvoiceResponse](http.StatusOK), + httptransport.AppendOptions( + h.options, + httptransport.WithOperationName("get-billing-invoice"), + httptransport.WithErrorEncoder(apierrors.GenericErrorEncoder()), + httptransport.WithErrorEncoder(errorEncoder()), + )..., + ) +} diff --git a/api/v3/handlers/billinginvoices/handler.go b/api/v3/handlers/billinginvoices/handler.go new file mode 100644 index 0000000000..f4915df533 --- /dev/null +++ b/api/v3/handlers/billinginvoices/handler.go @@ -0,0 +1,30 @@ +package billinginvoices + +import ( + "context" + + "github.com/openmeterio/openmeter/openmeter/billing" + "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport" +) + +type Handler interface { + GetBillingInvoice() GetBillingInvoiceHandler +} + +type handler struct { + resolveNamespace func(ctx context.Context) (string, error) + service billing.Service + options []httptransport.HandlerOption +} + +func New( + resolveNamespace func(ctx context.Context) (string, error), + service billing.Service, + options ...httptransport.HandlerOption, +) Handler { + return &handler{ + resolveNamespace: resolveNamespace, + service: service, + options: options, + } +} diff --git a/api/v3/handlers/billingprofiles/convert.go b/api/v3/handlers/billingprofiles/convert.go index 51a20feb85..cabb4d6964 100644 --- a/api/v3/handlers/billingprofiles/convert.go +++ b/api/v3/handlers/billingprofiles/convert.go @@ -141,7 +141,12 @@ func ToAPIBillingParty(supplier billing.SupplierContact) api.BillingParty { Name: &supplier.Name, } - if supplier.Address.Country != nil { + // Emit the billing address whenever any address field is present. Gating on + // Country alone would drop line1/city/state/phone-only addresses from + // supplier snapshots, since every address field is optional in the API shape. + addr := supplier.Address + if addr.Country != nil || addr.PostalCode != nil || addr.State != nil || + addr.City != nil || addr.Line1 != nil || addr.Line2 != nil || addr.PhoneNumber != nil { party.Addresses = &api.BillingPartyAddresses{ BillingAddress: ToAPIAddress(supplier.Address), } @@ -156,6 +161,19 @@ func ToAPIBillingParty(supplier billing.SupplierContact) api.BillingParty { return party } +// ToAPIBillingSupplier converts billing.SupplierContact to the invoice's +// BillingSupplier snapshot, a read-only subset of BillingParty. +func ToAPIBillingSupplier(supplier billing.SupplierContact) api.BillingSupplier { + party := ToAPIBillingParty(supplier) + + return api.BillingSupplier{ + Id: party.Id, + Name: party.Name, + TaxId: party.TaxId, + Addresses: party.Addresses, + } +} + // FromAPIBillingParty converts API BillingParty to billing.SupplierContact func FromAPIBillingParty(party api.BillingParty) billing.SupplierContact { supplier := billing.SupplierContact{ diff --git a/api/v3/handlers/customers/charges/convert.go b/api/v3/handlers/customers/charges/convert.go index 1be06a5d43..01b0a5387d 100644 --- a/api/v3/handlers/customers/charges/convert.go +++ b/api/v3/handlers/customers/charges/convert.go @@ -27,7 +27,7 @@ import ( var ConvertMetadataToLabels = labels.FromMetadata[models.Metadata] // convertFlatFeeChargeToAPI maps a flatfee.Charge to the API representation. -func convertFlatFeeChargeToAPI(source flatfee.Charge) (api.BillingFlatFeeCharge, error) { +func convertFlatFeeChargeToAPI(source flatfee.Charge) (api.BillingChargeFlatFee, error) { // TODO: when the base intent is not manually managed, expose the system/base // state too so API clients can see what the charge would look like without // the customer-facing override. @@ -38,10 +38,10 @@ func convertFlatFeeChargeToAPI(source flatfee.Charge) (api.BillingFlatFeeCharge, Amount: intent.AmountBeforeProration.String(), Type: api.BillingPriceFlatTypeFlat, }); err != nil { - return api.BillingFlatFeeCharge{}, fmt.Errorf("setting flat fee price union: %w", err) + return api.BillingChargeFlatFee{}, fmt.Errorf("setting flat fee price union: %w", err) } - return api.BillingFlatFeeCharge{ + return api.BillingChargeFlatFee{ AdvanceAfter: source.State.AdvanceAfter, AmountAfterProration: ConvertDecimalToCurrencyAmount(source.ChargeBase.State.AmountAfterProration), BillingPeriod: ConvertClosedPeriodToAPI(intent.BillingPeriod), @@ -56,7 +56,7 @@ func convertFlatFeeChargeToAPI(source flatfee.Charge) (api.BillingFlatFeeCharge, Id: source.ChargeBase.ManagedResource.ID, InvoiceAt: intent.InvoiceAt, Labels: ConvertMetadataToLabels(intent.Metadata), - ManagedBy: ConvertManagedByToAPI(intent.ManagedBy), + LifecycleController: ConvertLifecycleControllerToAPI(intent.ManagedBy), Name: intent.Name, PaymentTerm: ConvertPaymentTermToAPI(intent.PaymentTerm), Price: price, @@ -66,17 +66,17 @@ func convertFlatFeeChargeToAPI(source flatfee.Charge) (api.BillingFlatFeeCharge, Status: ConvertChargeStatusToAPI(meta.ChargeStatus(source.Status)), Subscription: subscriptionRefPtrToAPI(source.ChargeBase.Intent.GetSubscription()), TaxConfig: convertTaxCodeConfigToAPI(intent.TaxConfig), - Type: api.BillingFlatFeeChargeTypeFlatFee, + Type: api.BillingChargeFlatFeeTypeFlatFee, UniqueReferenceId: source.ChargeBase.Intent.GetUniqueReferenceID(), UpdatedAt: source.ChargeBase.ManagedResource.ManagedModel.UpdatedAt, }, nil } // convertUsageBasedChargeToAPI maps a usagebased.Charge to the API representation. -func convertUsageBasedChargeToAPI(source usagebased.Charge) (api.BillingUsageBasedCharge, error) { +func convertUsageBasedChargeToAPI(source usagebased.Charge) (api.BillingChargeUsageBased, error) { status, err := ConvertUsageBasedStatusToAPI(source.ChargeBase.Status) if err != nil { - return api.BillingUsageBasedCharge{}, fmt.Errorf("converting usage based charge status: %w", err) + return api.BillingChargeUsageBased{}, fmt.Errorf("converting usage based charge status: %w", err) } // TODO: when the base intent is not manually managed, expose the system/base @@ -86,35 +86,35 @@ func convertUsageBasedChargeToAPI(source usagebased.Charge) (api.BillingUsageBas price, err := toAPIBillingPrice(intent.Price) if err != nil { - return api.BillingUsageBasedCharge{}, fmt.Errorf("converting price: %w", err) - } - - return api.BillingUsageBasedCharge{ - AdvanceAfter: source.State.AdvanceAfter, - BillingPeriod: ConvertClosedPeriodToAPI(intent.BillingPeriod), - CreatedAt: source.ChargeBase.ManagedResource.ManagedModel.CreatedAt, - Currency: ConvertCurrencyCodeToAPI(source.ChargeBase.Intent.GetCurrency()), - Customer: ConvertCustomerIDToReference(source.ChargeBase.Intent.GetCustomerID()), - DeletedAt: source.ChargeBase.ManagedResource.ManagedModel.DeletedAt, - Description: intent.Description, - Discounts: convertUsageBasedDiscounts(intent.Discounts), - FeatureKey: intent.FeatureKey, - FullServicePeriod: ConvertClosedPeriodToAPI(intent.FullServicePeriod), - Id: source.ChargeBase.ManagedResource.ID, - InvoiceAt: intent.InvoiceAt, - Labels: ConvertMetadataToLabels(intent.Metadata), - ManagedBy: ConvertManagedByToAPI(intent.ManagedBy), - Name: intent.Name, - Price: price, - ServicePeriod: ConvertClosedPeriodToAPI(intent.ServicePeriod), - SettlementMode: ConvertSettlementModeToAPI(source.ChargeBase.Intent.GetSettlementMode()), - Status: lo.FromPtr(status), - Subscription: subscriptionRefPtrToAPI(source.ChargeBase.Intent.GetSubscription()), - TaxConfig: convertTaxCodeConfigToAPI(intent.TaxConfig), - Totals: convertUsageBasedChargeTotals(source), - Type: api.BillingUsageBasedChargeTypeUsageBased, - UniqueReferenceId: source.ChargeBase.Intent.GetUniqueReferenceID(), - UpdatedAt: source.ChargeBase.ManagedResource.ManagedModel.UpdatedAt, + return api.BillingChargeUsageBased{}, fmt.Errorf("converting price: %w", err) + } + + return api.BillingChargeUsageBased{ + AdvanceAfter: source.State.AdvanceAfter, + BillingPeriod: ConvertClosedPeriodToAPI(intent.BillingPeriod), + CreatedAt: source.ChargeBase.ManagedResource.ManagedModel.CreatedAt, + Currency: ConvertCurrencyCodeToAPI(source.ChargeBase.Intent.GetCurrency()), + Customer: ConvertCustomerIDToReference(source.ChargeBase.Intent.GetCustomerID()), + DeletedAt: source.ChargeBase.ManagedResource.ManagedModel.DeletedAt, + Description: intent.Description, + Discounts: convertUsageBasedDiscounts(intent.Discounts), + FeatureKey: intent.FeatureKey, + FullServicePeriod: ConvertClosedPeriodToAPI(intent.FullServicePeriod), + Id: source.ChargeBase.ManagedResource.ID, + InvoiceAt: intent.InvoiceAt, + Labels: ConvertMetadataToLabels(intent.Metadata), + LifecycleController: ConvertLifecycleControllerToAPI(intent.ManagedBy), + Name: intent.Name, + Price: price, + ServicePeriod: ConvertClosedPeriodToAPI(intent.ServicePeriod), + SettlementMode: ConvertSettlementModeToAPI(source.ChargeBase.Intent.GetSettlementMode()), + Status: lo.FromPtr(status), + Subscription: subscriptionRefPtrToAPI(source.ChargeBase.Intent.GetSubscription()), + TaxConfig: convertTaxCodeConfigToAPI(intent.TaxConfig), + Totals: convertUsageBasedChargeTotals(source), + Type: api.BillingChargeUsageBasedTypeUsageBased, + UniqueReferenceId: source.ChargeBase.Intent.GetUniqueReferenceID(), + UpdatedAt: source.ChargeBase.ManagedResource.ManagedModel.UpdatedAt, }, nil } @@ -141,7 +141,7 @@ func convertChargeToAPI(charge billingcharges.Charge) (api.BillingCharge, error) if err != nil { return out, err } - if err := out.FromBillingFlatFeeCharge(apiFF); err != nil { + if err := out.FromBillingChargeFlatFee(apiFF); err != nil { return out, fmt.Errorf("setting flat fee charge union: %w", err) } @@ -154,7 +154,7 @@ func convertChargeToAPI(charge billingcharges.Charge) (api.BillingCharge, error) if err != nil { return out, err } - if err := out.FromBillingUsageBasedCharge(apiUB); err != nil { + if err := out.FromBillingChargeUsageBased(apiUB); err != nil { return out, fmt.Errorf("setting usage based charge union: %w", err) } @@ -173,18 +173,18 @@ func convertChargeToAPI(charge billingcharges.Charge) (api.BillingCharge, error) // convertUsageBasedChargeTotals aggregates booked totals from persisted realization runs. func convertUsageBasedChargeTotals(charge usagebased.Charge) api.BillingChargeTotals { out := api.BillingChargeTotals{ - Booked: toAPIBillingTotals(charge.Realizations.Sum()), + Booked: ToAPIBillingTotals(charge.Realizations.Sum()), } if charge.Expands.RealtimeUsage != nil { - out.Realtime = lo.ToPtr(toAPIBillingTotals(*charge.Expands.RealtimeUsage)) + out.Realtime = lo.ToPtr(ToAPIBillingTotals(*charge.Expands.RealtimeUsage)) } return out } -// toAPIBillingTotals maps a domain totals.Totals to the API BillingTotals type. -func toAPIBillingTotals(t totals.Totals) api.BillingTotals { +// ToAPIBillingTotals maps a domain totals.Totals to the API BillingTotals type. +func ToAPIBillingTotals(t totals.Totals) api.BillingTotals { return api.BillingTotals{ Amount: t.Amount.String(), ChargesTotal: t.ChargesTotal.String(), @@ -282,12 +282,12 @@ func toAPIBillingPriceTier(t productcatalog.PriceTier, _ int) api.BillingPriceTi } // convertFlatFeeDiscounts maps the optional percentage discount to the anonymous API struct. -func convertFlatFeeDiscounts(pd *productcatalog.PercentageDiscount) *api.BillingFlatFeeDiscounts { +func convertFlatFeeDiscounts(pd *productcatalog.PercentageDiscount) *api.BillingChargeFlatFeeDiscounts { if pd == nil { return nil } pct := float32(pd.Percentage.InexactFloat64()) - return &api.BillingFlatFeeDiscounts{Percentage: &pct} + return &api.BillingChargeFlatFeeDiscounts{Percentage: &pct} } // convertUsageBasedDiscounts maps usage-based discounts to the API type. @@ -369,9 +369,14 @@ func ConvertPaymentTermToAPI(pt productcatalog.PaymentTermType) api.BillingPrice return api.BillingPricePaymentTerm(pt) } -// ConvertManagedByToAPI casts an InvoiceLineManagedBy to its API equivalent. -func ConvertManagedByToAPI(mb billing.InvoiceLineManagedBy) api.ResourceManagedBy { - return api.ResourceManagedBy(mb) +// ConvertLifecycleControllerToAPI maps the internal lifecycle owner to the public +// lifecycle controller. Subscription-owned resources are OpenMeter-controlled. +func ConvertLifecycleControllerToAPI(mb billing.InvoiceLineManagedBy) api.BillingLifecycleController { + if mb == billing.ManuallyManagedLine { + return api.BillingLifecycleControllerManual + } + + return api.BillingLifecycleControllerSystem } // ConvertCurrencyCodeToAPI casts a currencyx.Code to an API CurrencyCode. @@ -413,7 +418,7 @@ func convertAPIChargeStatus(s string) (meta.ChargeStatus, error) { } } -func convertFlatFeeChargeAPIToIntent(customerID string, flatFee api.CreateFlatFeeChargeRequest) (billingcharges.ChargeIntent, error) { +func convertFlatFeeChargeAPIToIntent(customerID string, flatFee api.CreateChargeFlatFeeRequest) (billingcharges.ChargeIntent, error) { var zero billingcharges.ChargeIntent taxConfig, err := billingprofiles.FromAPIBillingTaxConfig(flatFee.TaxConfig) @@ -483,7 +488,7 @@ func convertFlatFeeChargeAPIToIntent(customerID string, flatFee api.CreateFlatFe }), nil } -func convertUsageBaseChargeAPIToIntent(customerID string, usageBasedFee api.CreateUsageBasedChargeRequest) (billingcharges.ChargeIntent, error) { +func convertUsageBaseChargeAPIToIntent(customerID string, usageBasedFee api.CreateChargeUsageBasedRequest) (billingcharges.ChargeIntent, error) { var zero billingcharges.ChargeIntent taxConfig, err := billingprofiles.FromAPIBillingTaxConfig(usageBasedFee.TaxConfig) diff --git a/api/v3/handlers/customers/charges/create.go b/api/v3/handlers/customers/charges/create.go index 59019cf5ff..08cceba55e 100644 --- a/api/v3/handlers/customers/charges/create.go +++ b/api/v3/handlers/customers/charges/create.go @@ -52,8 +52,8 @@ func (h *handler) CreateCustomerCharge() CreateCustomerChargesHandler { } switch discriminator { - case string(api.BillingFlatFeeChargeTypeFlatFee): - flatFee, err := body.AsCreateFlatFeeChargeRequest() + case string(api.BillingChargeFlatFeeTypeFlatFee): + flatFee, err := body.AsCreateChargeFlatFeeRequest() if err != nil { return CreateCustomerChargesRequest{}, apierrors.NewBadRequestError(ctx, err, apierrors.InvalidParameters{ { @@ -76,8 +76,8 @@ func (h *handler) CreateCustomerCharge() CreateCustomerChargesHandler { } input.Intents = append(input.Intents, intent) - case string(api.BillingUsageBasedChargeTypeUsageBased): - usageBasedFee, err := body.AsCreateUsageBasedChargeRequest() + case string(api.BillingChargeUsageBasedTypeUsageBased): + usageBasedFee, err := body.AsCreateChargeUsageBasedRequest() if err != nil { return CreateCustomerChargesRequest{}, apierrors.NewBadRequestError(ctx, err, apierrors.InvalidParameters{ { diff --git a/api/v3/handlers/customers/convert.gen.go b/api/v3/handlers/customers/convert.gen.go index b923c15539..3672b6b976 100644 --- a/api/v3/handlers/customers/convert.gen.go +++ b/api/v3/handlers/customers/convert.gen.go @@ -35,7 +35,7 @@ func init() { currencyxCode := currencyx.Code(*source.Currency) customerCustomerMutate.Currency = ¤cyxCode } - customerCustomerMutate.BillingAddress = pV3BillingAddressToPModelsAddress(source.BillingAddress) + customerCustomerMutate.BillingAddress = pV3AddressToPModelsAddress(source.BillingAddress) pModelsMetadata, err := ConvertLabelsToMetadata(source.Labels) if err != nil { return customerCustomerMutate, err @@ -53,7 +53,7 @@ func init() { currencyxCode := currencyx.Code(*source.Currency) customerCustomerMutate.Currency = ¤cyxCode } - customerCustomerMutate.BillingAddress = pV3BillingAddressToPModelsAddress(source.BillingAddress) + customerCustomerMutate.BillingAddress = pV3AddressToPModelsAddress(source.BillingAddress) pModelsMetadata, err := ConvertLabelsToMetadata(source.Labels) if err != nil { return customerCustomerMutate, err @@ -63,7 +63,7 @@ func init() { } ToAPIBillingCustomer = func(source customer.Customer) v3.BillingCustomer { var v3BillingCustomer v3.BillingCustomer - v3BillingCustomer.BillingAddress = pModelsAddressToPV3BillingAddress(source.BillingAddress) + v3BillingCustomer.BillingAddress = pModelsAddressToPV3Address(source.BillingAddress) v3BillingCustomer.CreatedAt = timeTimeToTimeTime(source.ManagedResource.ManagedModel.CreatedAt) if source.Currency != nil { xstring := string(*source.Currency) @@ -103,25 +103,25 @@ func pCustomerCustomerUsageAttributionToPV3BillingCustomerUsageAttribution(sourc } return pV3BillingCustomerUsageAttribution } -func pModelsAddressToPV3BillingAddress(source *models.Address) *v3.BillingAddress { - var pV3BillingAddress *v3.BillingAddress +func pModelsAddressToPV3Address(source *models.Address) *v3.Address { + var pV3Address *v3.Address if source != nil { - var v3BillingAddress v3.BillingAddress - v3BillingAddress.City = (*source).City + var v3Address v3.Address + v3Address.City = (*source).City if (*source).Country != nil { xstring := string(*(*source).Country) - v3BillingAddress.Country = &xstring + v3Address.Country = &xstring } - v3BillingAddress.Line1 = (*source).Line1 - v3BillingAddress.Line2 = (*source).Line2 - v3BillingAddress.PhoneNumber = (*source).PhoneNumber - v3BillingAddress.PostalCode = (*source).PostalCode - v3BillingAddress.State = (*source).State - pV3BillingAddress = &v3BillingAddress + v3Address.Line1 = (*source).Line1 + v3Address.Line2 = (*source).Line2 + v3Address.PhoneNumber = (*source).PhoneNumber + v3Address.PostalCode = (*source).PostalCode + v3Address.State = (*source).State + pV3Address = &v3Address } - return pV3BillingAddress + return pV3Address } -func pV3BillingAddressToPModelsAddress(source *v3.BillingAddress) *models.Address { +func pV3AddressToPModelsAddress(source *v3.Address) *models.Address { var pModelsAddress *models.Address if source != nil { var modelsAddress models.Address diff --git a/api/v3/handlers/plans/convert.go b/api/v3/handlers/plans/convert.go index 4a8be7667c..a716af185b 100644 --- a/api/v3/handlers/plans/convert.go +++ b/api/v3/handlers/plans/convert.go @@ -400,7 +400,7 @@ func ToAPIBillingRateCardTaxConfig(c *productcatalog.TaxConfig, tc *taxcode.TaxC } result := &api.BillingRateCardTaxConfig{ - Code: api.TaxCodeReferenceItem{ + Code: api.TaxCodeReference{ Id: tc.ID, }, } diff --git a/api/v3/handlers/plans/convert_test.go b/api/v3/handlers/plans/convert_test.go index 508bc10508..6c85d0621d 100644 --- a/api/v3/handlers/plans/convert_test.go +++ b/api/v3/handlers/plans/convert_test.go @@ -1376,7 +1376,7 @@ func TestToBillingPriceTiers(t *testing.T) { func TestToBillingTaxConfig(t *testing.T) { t.Run("maps code ID", func(t *testing.T) { tc := api.BillingRateCardTaxConfig{ - Code: api.TaxCodeReferenceItem{Id: "01TAXCODE000"}, + Code: api.TaxCodeReference{Id: "01TAXCODE000"}, } result := FromAPIBillingRateCardTaxConfig(tc) @@ -1388,7 +1388,7 @@ func TestToBillingTaxConfig(t *testing.T) { t.Run("maps behavior", func(t *testing.T) { tc := api.BillingRateCardTaxConfig{ - Code: api.TaxCodeReferenceItem{Id: "01TAXCODE000"}, + Code: api.TaxCodeReference{Id: "01TAXCODE000"}, Behavior: lo.ToPtr(api.BillingTaxBehavior("inclusive")), } diff --git a/api/v3/openapi.yaml b/api/v3/openapi.yaml index 412dff5f4d..775ea317ad 100644 --- a/api/v3/openapi.yaml +++ b/api/v3/openapi.yaml @@ -328,6 +328,38 @@ paths: $ref: '#/components/responses/NotFound' tags: - OpenMeter Apps + /openmeter/billing/invoices/{invoiceId}: + get: + operationId: get-invoice + summary: Get a billing invoice + description: |- + Get a billing invoice by ID. + + Returns the full invoice resource including line items, status details, totals, + and workflow configuration snapshot. + parameters: + - name: invoiceId + in: path + required: true + schema: + $ref: '#/components/schemas/ULID' + responses: + '200': + description: Invoice response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingInvoice' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + tags: + - OpenMeter Billing Settings /openmeter/currencies: get: operationId: list-currencies @@ -3209,42 +3241,6 @@ components: $ref: '#/components/schemas/PaginatedMeta' additionalProperties: false description: Page paginated response. - BillingAddress: - type: object - properties: - country: - allOf: - - $ref: '#/components/schemas/CountryCode' - description: |- - Country code in [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) - alpha-2 format. - title: Country - postal_code: - type: string - description: Postal code. - title: Postal Code - state: - type: string - description: State or province. - title: State - city: - type: string - description: City. - title: City - line1: - type: string - description: First line of the address. - title: Line 1 - line2: - type: string - description: Second line of the address. - title: Line 2 - phone_number: - type: string - description: Phone number. - title: Phone Number - additionalProperties: false - description: Address BillingApp: type: object oneOf: @@ -4089,189 +4085,36 @@ components: BillingCharge: type: object oneOf: - - $ref: '#/components/schemas/BillingFlatFeeCharge' - - $ref: '#/components/schemas/BillingUsageBasedCharge' + - $ref: '#/components/schemas/BillingChargeFlatFee' + - $ref: '#/components/schemas/BillingChargeUsageBased' discriminator: propertyName: type mapping: - flat_fee: '#/components/schemas/BillingFlatFeeCharge' - usage_based: '#/components/schemas/BillingUsageBasedCharge' + flat_fee: '#/components/schemas/BillingChargeFlatFee' + usage_based: '#/components/schemas/BillingChargeUsageBased' description: Customer charge. title: Customer charge - BillingChargeStatus: - type: string - enum: - - created - - active - - final - - deleted - description: |- - Lifecycle status of a charge. - - Values: - - - `created`: The charge has been created but is not active yet. - - `active`: The charge is active. - - `final`: The charge is fully finalized and no further changes are expected. - - `deleted`: The charge has been deleted. - title: Charge status - BillingChargeTotals: - type: object - required: - - booked - properties: - booked: - allOf: - - $ref: '#/components/schemas/BillingTotals' - description: The amount of the charge already booked to the internal accounting system. - title: Booked - readOnly: true - realtime: - allOf: - - $ref: '#/components/schemas/BillingTotals' - description: |- - The realtime amount of the charge. - - Requires the `realtime_usage` expand. - title: Realtime totals - readOnly: true - additionalProperties: false - description: |- - The totals of a change. - - RealTime is only expanded when the `real_time_usage` expand is used. - BillingChargesExpand: - type: string - enum: - - real_time_usage - description: |- - Expands for customer charges. - - Values: - - - `real_time_usage`: The charge's real-time usage. - title: Customer charge expands - BillingCostBasis: - type: object - required: - - id - - fiat_code - - rate - - created_at - properties: - id: - allOf: - - $ref: '#/components/schemas/ULID' - readOnly: true - fiat_code: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: The fiat currency code for the cost basis. - rate: - allOf: - - $ref: '#/components/schemas/Numeric' - description: The cost rate for the currency. - effective_from: - allOf: - - $ref: '#/components/schemas/DateTime' - description: |- - An ISO-8601 timestamp representation of the date from which the cost basis is - effective. If not provided, it will be effective immediately and will be set to - `now` by the system. - created_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: An ISO-8601 timestamp representation of entity creation date. - readOnly: true - additionalProperties: false - description: Describes currency basis supported by billing system. - BillingCreditAdjustment: - type: object - required: - - name - properties: - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - Display name of the resource. - - Between 1 and 256 characters. - description: - type: string - maxLength: 1024 - description: |- - Optional description of the resource. - - Maximum 1024 characters. - labels: - $ref: '#/components/schemas/Labels' - additionalProperties: false - description: |- - A credit adjustment can be used to make manual adjustments to a customer's - credit balance. - - Supported use-cases: - - - Usage correction - title: Credit adjustment - BillingCreditAvailabilityPolicy: - type: string - enum: - - on_creation - description: |- - When credits become available for consumption. - - - `on_creation`: Credits are available as soon as the grant is created. - - `on_authorization`: Credits are available once the payment is authorized. - - `on_settlement`: Credits are available once the payment is settled. - title: Credit availability policy - BillingCreditBalances: - type: object - required: - - retrieved_at - - balances - properties: - retrieved_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: The timestamp of the balance retrieval. - readOnly: true - balances: - type: array - items: - $ref: '#/components/schemas/CreditBalance' - description: The balances by currencies. - readOnly: true - additionalProperties: false - description: The balances of the credits of a customer. - title: Credit balances - BillingCreditFundingMethod: - type: string - enum: - - none - - invoice - - external - description: |- - The funding method describes how the grant is funded. - - - `none`: No funding workflow applies, for example promotional grants - - `invoice`: The grant is funded by an in-system invoice flow - - `external`: The grant is funded outside the system (e.g., wire transfer, - external invoice, or manual reconciliation) - title: Credit funding method - BillingCreditGrant: + BillingChargeFlatFee: type: object required: - id - name - created_at - updated_at - - funding_method + - type + - customer + - lifecycle_controller - currency - - amount - status + - invoice_at + - service_period + - full_service_period + - billing_period + - settlement_mode + - payment_term + - proration_configuration + - amount_after_proration + - price properties: id: allOf: @@ -4309,209 +4152,1375 @@ components: - $ref: '#/components/schemas/DateTime' description: An ISO-8601 timestamp representation of entity deletion date. readOnly: true - funding_method: + type: + type: string + enum: + - flat_fee + description: The type of the charge. + title: Type + customer: allOf: - - $ref: '#/components/schemas/BillingCreditFundingMethod' - description: Funding method of the grant. - currency: + - $ref: '#/components/schemas/BillingCustomerReference' + description: The customer owning the charge. + title: Customer + readOnly: true + lifecycle_controller: allOf: - - $ref: '#/components/schemas/BillingCurrencyCode' - description: The currency of the granted credits. - amount: + - $ref: '#/components/schemas/BillingLifecycleController' + description: |- + Indicates whether the charge lifecycle is controlled by OpenMeter or manually + overridden by the API user. + title: Lifecycle controller + readOnly: true + subscription: allOf: - - $ref: '#/components/schemas/Numeric' - description: Granted credit amount. - purchase: + - $ref: '#/components/schemas/BillingSubscriptionReference' + description: |- + The subscription that originated the charge, when the charge was created from a + subscription item. + title: Subscription + readOnly: true + currency: allOf: - - $ref: '#/components/schemas/BillingCreditGrantPurchase' - description: Present when a funding workflow applies (funding_method is not `none`). - tax_config: + - $ref: '#/components/schemas/CurrencyCode' + description: The currency of the charge. + title: Currency + status: allOf: - - $ref: '#/components/schemas/BillingCreditGrantTaxConfig' - description: |- - Tax configuration for the grant. - - For `invoice` and `external` funding methods, tax configuration should be - provided to ensure correct revenue recognition. When not provided, the default - credit grant tax code is applied, if that's not set the global default taxcode - is used. - invoice: + - $ref: '#/components/schemas/BillingChargeStatus' + description: The lifecycle status of the charge. + title: Status + readOnly: true + invoice_at: allOf: - - $ref: '#/components/schemas/BillingCreditGrantInvoiceReference' - description: Available when `funding_method` is `invoice`. + - $ref: '#/components/schemas/DateTime' + description: The timestamp when the charge is intended to be invoiced. + title: Invoice at + service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The effective service period covered by the charge. + title: Service period + full_service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The full, unprorated service period of the charge. + title: Full service period readOnly: true - filters: - $ref: '#/components/schemas/BillingCreditGrantFilters' - priority: - type: integer - format: int16 - minimum: 1 - maximum: 1000 - description: Draw-down priority of the grant. Lower values have higher priority. - default: 10 - expires_at: + billing_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The billing period the charge belongs to. + title: Billing period + readOnly: true + advance_after: allOf: - $ref: '#/components/schemas/DateTime' description: |- - The timestamp when the credit grant expires. - - Calculated from the grant effective time and `expires_after` if provided. + The earliest time when the charge should be advanced again by background + processing. + title: Advance after readOnly: true - voided_at: + unique_reference_id: + type: string + description: Unique reference ID of the charge. + title: Unique reference ID + settlement_mode: allOf: - - $ref: '#/components/schemas/DateTime' - description: Timestamp when the grant was voided. + - $ref: '#/components/schemas/BillingSettlementMode' + description: Settlement mode of the charge. + title: Settlement mode + tax_config: + allOf: + - $ref: '#/components/schemas/BillingTaxConfig' + description: Tax configuration of the charge. + title: Tax configuration + payment_term: + allOf: + - $ref: '#/components/schemas/BillingPricePaymentTerm' + description: Payment term of the flat fee charge. + title: Payment term + discounts: + allOf: + - $ref: '#/components/schemas/BillingChargeFlatFeeDiscounts' + description: The discounts applied to the charge. + title: Discounts + feature_key: + type: string + description: The feature associated with the charge, when applicable. + title: Feature key + proration_configuration: + allOf: + - $ref: '#/components/schemas/BillingRateCardProrationConfiguration' + description: The proration configuration of the charge. + title: Proration configuration + amount_after_proration: + allOf: + - $ref: '#/components/schemas/CurrencyAmount' + description: The amount after proration of the charge. + title: Amount after proration readOnly: true - status: + price: allOf: - - $ref: '#/components/schemas/BillingCreditGrantStatus' - description: Current lifecycle status of the grant. + - $ref: '#/components/schemas/BillingPrice' + description: The price of the charge. + title: Price readOnly: true additionalProperties: false - description: |- - A credit grant allocates credits to a customer. - - Credits are drawn down against charges according to the settlement mode - configured on the rate card. - title: Credit grant - BillingCreditGrantFilters: + description: A flat fee charge for a customer. + title: Flat fee charge + BillingChargeFlatFeeDiscounts: type: object properties: - features: - type: array - items: - $ref: '#/components/schemas/ResourceKey' - description: |- - Limit the credit grant to specific features. If no features are specified, the - credit grant can be used for any feature. - example: - - input_tokens - - output_tokens + percentage: + type: number + minimum: 0 + maximum: 100 + description: Percentage discount applied to the price (0–100). additionalProperties: false - description: Filters for the credit grant. - BillingCreditGrantInvoiceReference: + description: |- + Discounts applicable to flat fee charges. + + This is the same as `ProductCatalog.Discounts` but without the `usage` field, + which is not applicable to flat fee charges. + title: Flat fee charge discounts + BillingChargeReference: type: object + required: + - id properties: id: allOf: - $ref: '#/components/schemas/ULID' - description: Identifier of the invoice associated with the grant. - readOnly: true - line: - type: object - properties: - id: - $ref: '#/components/schemas/ULID' - required: - - id - additionalProperties: false - description: Identifier of the invoice line associated with the grant. + description: Unique identifier for the charge. + title: ID readOnly: true additionalProperties: false - description: Invoice references for the grant. - BillingCreditGrantPurchase: + description: Reference to a charge associated with an invoice line. + BillingChargeStatus: + type: string + enum: + - created + - active + - final + - deleted + description: |- + Lifecycle status of a charge. + + Values: + + - `created`: The charge has been created but is not active yet. + - `active`: The charge is active. + - `final`: The charge is fully finalized and no further changes are expected. + - `deleted`: The charge has been deleted. + title: Charge status + BillingChargeTotals: type: object required: - - currency - - amount + - booked properties: - currency: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: Currency of the purchase amount. - per_unit_cost_basis: - allOf: - - $ref: '#/components/schemas/Numeric' - description: |- - Cost basis per credit unit used to calculate the purchase amount. - - If `per_unit_cost_basis` is 0.50 and credit amount is $100.00, the total charge - is $50.00. The value must be greater than 0. If the cost basis is 0, use - `funding_method=none` instead. - - Defaults to 1.0. - default: '1.0' - amount: + booked: allOf: - - $ref: '#/components/schemas/Numeric' - description: The purchase amount. Calculated from `per_unit_cost_basis` and credit `amount`. + - $ref: '#/components/schemas/BillingTotals' + description: The amount of the charge already booked to the internal accounting system. + title: Booked readOnly: true - availability_policy: + realtime: allOf: - - $ref: '#/components/schemas/BillingCreditAvailabilityPolicy' + - $ref: '#/components/schemas/BillingTotals' description: |- - Controls when credits become available for consumption. + The realtime amount of the charge. - Defaults to `on_creation`. - default: on_creation - settlement_status: - allOf: - - $ref: '#/components/schemas/BillingCreditPurchasePaymentSettlementStatus' - description: Current payment settlement status. + Requires the `realtime_usage` expand. + title: Realtime totals readOnly: true additionalProperties: false - description: Purchase and payment terms of the grant. - BillingCreditGrantStatus: - type: string - enum: - - pending - - active - - expired - - voided description: |- - Credit grant lifecycle status. + The totals of a change. - - `pending`: The credit block has been created but is not yet valid. - (`effective_at` is in the future or availability_policy is not met) - - `active`: The credit block is currently valid and eligible for consumption. - (`effective_at` is in the past, `expires_at` is in the future and - availability_policy is met) - - `expired`: The credit block expired with remaining unused balance, - `expires_at` time has passed. - - `voided`: The credit block was voided. Remaining balance is forfeited. - title: Credit grant lifecycle status - BillingCreditGrantTaxConfig: + RealTime is only expanded when the `real_time_usage` expand is used. + BillingChargeUsageBased: type: object - properties: - behavior: - allOf: - - $ref: '#/components/schemas/BillingTaxBehavior' - description: Tax behavior applied to the invoice line item. - tax_code: - allOf: - - $ref: '#/components/schemas/TaxCodeReference' - description: Tax code applied to the invoice line item. - additionalProperties: false - description: |- - Tax configuration for a credit grant. - - Tax configuration should be provided to ensure correct revenue recognition, - including for externally funded grants. + required: + - id + - name + - created_at + - updated_at + - type + - customer + - lifecycle_controller + - currency + - status + - invoice_at + - service_period + - full_service_period + - billing_period + - settlement_mode + - feature_key + - totals + - price + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity creation date. + readOnly: true + updated_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity last update date. + readOnly: true + deleted_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity deletion date. + readOnly: true + type: + type: string + enum: + - usage_based + description: The type of the charge. + title: Type + customer: + allOf: + - $ref: '#/components/schemas/BillingCustomerReference' + description: The customer owning the charge. + title: Customer + readOnly: true + lifecycle_controller: + allOf: + - $ref: '#/components/schemas/BillingLifecycleController' + description: |- + Indicates whether the charge lifecycle is controlled by OpenMeter or manually + overridden by the API user. + title: Lifecycle controller + readOnly: true + subscription: + allOf: + - $ref: '#/components/schemas/BillingSubscriptionReference' + description: |- + The subscription that originated the charge, when the charge was created from a + subscription item. + title: Subscription + readOnly: true + currency: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: The currency of the charge. + title: Currency + status: + allOf: + - $ref: '#/components/schemas/BillingChargeStatus' + description: The lifecycle status of the charge. + title: Status + readOnly: true + invoice_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: The timestamp when the charge is intended to be invoiced. + title: Invoice at + service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The effective service period covered by the charge. + title: Service period + full_service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The full, unprorated service period of the charge. + title: Full service period + readOnly: true + billing_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The billing period the charge belongs to. + title: Billing period + readOnly: true + advance_after: + allOf: + - $ref: '#/components/schemas/DateTime' + description: |- + The earliest time when the charge should be advanced again by background + processing. + title: Advance after + readOnly: true + unique_reference_id: + type: string + description: Unique reference ID of the charge. + title: Unique reference ID + settlement_mode: + allOf: + - $ref: '#/components/schemas/BillingSettlementMode' + description: Settlement mode of the charge. + title: Settlement mode + tax_config: + allOf: + - $ref: '#/components/schemas/BillingTaxConfig' + description: Tax configuration of the charge. + title: Tax configuration + discounts: + allOf: + - $ref: '#/components/schemas/BillingRateCardDiscounts' + description: Discounts applied to the usage-based charge. + title: Discounts + feature_key: + type: string + description: The feature associated with the charge. + title: Feature key + totals: + allOf: + - $ref: '#/components/schemas/BillingChargeTotals' + description: Aggregated booked and realtime totals for the charge. + title: Totals for the charge + readOnly: true + price: + allOf: + - $ref: '#/components/schemas/BillingPrice' + description: The price of the charge. + title: Price + additionalProperties: false + description: A usage-based charge for a customer. + title: Usage-based charge + BillingChargesExpand: + type: string + enum: + - real_time_usage + description: |- + Expands for customer charges. + + Values: + + - `real_time_usage`: The charge's real-time usage. + title: Customer charge expands + BillingCostBasis: + type: object + required: + - id + - fiat_code + - rate + - created_at + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + fiat_code: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: The fiat currency code for the cost basis. + rate: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The cost rate for the currency. + effective_from: + allOf: + - $ref: '#/components/schemas/DateTime' + description: |- + An ISO-8601 timestamp representation of the date from which the cost basis is + effective. If not provided, it will be effective immediately and will be set to + `now` by the system. + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity creation date. + readOnly: true + additionalProperties: false + description: Describes currency basis supported by billing system. + BillingCreditAdjustment: + type: object + required: + - name + properties: + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + additionalProperties: false + description: |- + A credit adjustment can be used to make manual adjustments to a customer's + credit balance. + + Supported use-cases: + + - Usage correction + title: Credit adjustment + BillingCreditAvailabilityPolicy: + type: string + enum: + - on_creation + description: |- + When credits become available for consumption. + + - `on_creation`: Credits are available as soon as the grant is created. + - `on_authorization`: Credits are available once the payment is authorized. + - `on_settlement`: Credits are available once the payment is settled. + title: Credit availability policy + BillingCreditBalances: + type: object + required: + - retrieved_at + - balances + properties: + retrieved_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: The timestamp of the balance retrieval. + readOnly: true + balances: + type: array + items: + $ref: '#/components/schemas/CreditBalance' + description: The balances by currencies. + readOnly: true + additionalProperties: false + description: The balances of the credits of a customer. + title: Credit balances + BillingCreditFundingMethod: + type: string + enum: + - none + - invoice + - external + description: |- + The funding method describes how the grant is funded. + + - `none`: No funding workflow applies, for example promotional grants + - `invoice`: The grant is funded by an in-system invoice flow + - `external`: The grant is funded outside the system (e.g., wire transfer, + external invoice, or manual reconciliation) + title: Credit funding method + BillingCreditGrant: + type: object + required: + - id + - name + - created_at + - updated_at + - funding_method + - currency + - amount + - status + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity creation date. + readOnly: true + updated_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity last update date. + readOnly: true + deleted_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity deletion date. + readOnly: true + funding_method: + allOf: + - $ref: '#/components/schemas/BillingCreditFundingMethod' + description: Funding method of the grant. + currency: + allOf: + - $ref: '#/components/schemas/BillingCurrencyCode' + description: The currency of the granted credits. + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Granted credit amount. + purchase: + allOf: + - $ref: '#/components/schemas/BillingCreditGrantPurchase' + description: Present when a funding workflow applies (funding_method is not `none`). + tax_config: + allOf: + - $ref: '#/components/schemas/BillingCreditGrantTaxConfig' + description: |- + Tax configuration for the grant. + + For `invoice` and `external` funding methods, tax configuration should be + provided to ensure correct revenue recognition. When not provided, the default + credit grant tax code is applied, if that's not set the global default taxcode + is used. + invoice: + allOf: + - $ref: '#/components/schemas/BillingCreditGrantInvoiceReference' + description: Available when `funding_method` is `invoice`. + readOnly: true + filters: + $ref: '#/components/schemas/BillingCreditGrantFilters' + priority: + type: integer + format: int16 + minimum: 1 + maximum: 1000 + description: Draw-down priority of the grant. Lower values have higher priority. + default: 10 + expires_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: |- + The timestamp when the credit grant expires. + + Calculated from the grant effective time and `expires_after` if provided. + readOnly: true + voided_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when the grant was voided. + readOnly: true + status: + allOf: + - $ref: '#/components/schemas/BillingCreditGrantStatus' + description: Current lifecycle status of the grant. + readOnly: true + additionalProperties: false + description: |- + A credit grant allocates credits to a customer. + + Credits are drawn down against charges according to the settlement mode + configured on the rate card. + title: Credit grant + BillingCreditGrantFilters: + type: object + properties: + features: + type: array + items: + $ref: '#/components/schemas/ResourceKey' + description: |- + Limit the credit grant to specific features. If no features are specified, the + credit grant can be used for any feature. + example: + - input_tokens + - output_tokens + additionalProperties: false + description: Filters for the credit grant. + BillingCreditGrantInvoiceReference: + type: object + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + description: Identifier of the invoice associated with the grant. + readOnly: true + line: + type: object + properties: + id: + $ref: '#/components/schemas/ULID' + required: + - id + additionalProperties: false + description: Identifier of the invoice line associated with the grant. + readOnly: true + additionalProperties: false + description: Invoice references for the grant. + BillingCreditGrantPurchase: + type: object + required: + - currency + - amount + properties: + currency: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: Currency of the purchase amount. + per_unit_cost_basis: + allOf: + - $ref: '#/components/schemas/Numeric' + description: |- + Cost basis per credit unit used to calculate the purchase amount. + + If `per_unit_cost_basis` is 0.50 and credit amount is $100.00, the total charge + is $50.00. The value must be greater than 0. If the cost basis is 0, use + `funding_method=none` instead. + + Defaults to 1.0. + default: '1.0' + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The purchase amount. Calculated from `per_unit_cost_basis` and credit `amount`. + readOnly: true + availability_policy: + allOf: + - $ref: '#/components/schemas/BillingCreditAvailabilityPolicy' + description: |- + Controls when credits become available for consumption. + + Defaults to `on_creation`. + default: on_creation + settlement_status: + allOf: + - $ref: '#/components/schemas/BillingCreditPurchasePaymentSettlementStatus' + description: Current payment settlement status. + readOnly: true + additionalProperties: false + description: Purchase and payment terms of the grant. + BillingCreditGrantStatus: + type: string + enum: + - pending + - active + - expired + - voided + description: |- + Credit grant lifecycle status. + + - `pending`: The credit block has been created but is not yet valid. + (`effective_at` is in the future or availability_policy is not met) + - `active`: The credit block is currently valid and eligible for consumption. + (`effective_at` is in the past, `expires_at` is in the future and + availability_policy is met) + - `expired`: The credit block expired with remaining unused balance, + `expires_at` time has passed. + - `voided`: The credit block was voided. Remaining balance is forfeited. + title: Credit grant lifecycle status + BillingCreditGrantTaxConfig: + type: object + properties: + behavior: + allOf: + - $ref: '#/components/schemas/BillingTaxBehavior' + description: Tax behavior applied to the invoice line item. + tax_code: + allOf: + - $ref: '#/components/schemas/TaxCodeReference' + description: Tax code applied to the invoice line item. + additionalProperties: false + description: |- + Tax configuration for a credit grant. + + Tax configuration should be provided to ensure correct revenue recognition, + including for externally funded grants. title: Tax configuration for a credit grant BillingCreditPurchasePaymentSettlementStatus: type: string enum: - - pending - - authorized - - settled + - pending + - authorized + - settled + description: |- + Credit purchase payment settlement status. + + - `pending`: Payment has been initiated and is not yet authorized. + - `authorized`: Payment has been authorized. + - `settled`: Payment has been settled. + title: Credit purchase payment settlement status + BillingCreditTransaction: + type: object + required: + - id + - name + - created_at + - booked_at + - type + - currency + - amount + - available_balance + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity creation date. + readOnly: true + booked_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: The date and time the transaction was booked. + readOnly: true + type: + allOf: + - $ref: '#/components/schemas/BillingCreditTransactionType' + description: The type of credit transaction. + readOnly: true + currency: + allOf: + - $ref: '#/components/schemas/BillingCurrencyCode' + description: Currency of the balance affected by the transaction. + readOnly: true + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: |- + Signed amount of the credit movement. Positive values add balance, negative + values reduce balance. + readOnly: true + available_balance: + type: object + properties: + before: + $ref: '#/components/schemas/Numeric' + after: + $ref: '#/components/schemas/Numeric' + required: + - before + - after + additionalProperties: false + description: The available balance before and after the transaction. + readOnly: true + additionalProperties: false + description: |- + A credit transaction represents a single credit movement on the customer's + balance. + + Credit transactions are immutable. + title: Credit transaction + BillingCreditTransactionType: + type: string + enum: + - funded + - consumed + - expired + description: |- + The type of the credit transaction. + + - `funded`: Credit granted and available for consumption. + - `consumed`: Credit consumed by usage or fees. + - `expired`: Credit removed because it expired before being used. + BillingCurrency: + type: object + oneOf: + - $ref: '#/components/schemas/BillingCurrencyFiat' + - $ref: '#/components/schemas/BillingCurrencyCustom' + discriminator: + propertyName: type + mapping: + fiat: '#/components/schemas/BillingCurrencyFiat' + custom: '#/components/schemas/BillingCurrencyCustom' + description: Fiat or custom currency. + BillingCurrencyCode: + type: string + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: Fiat or custom currency code. + x-go-type: string + BillingCurrencyCodeCustom: + type: string + minLength: 3 + maxLength: 24 + description: |- + Custom currency code. It should be a unique code but not conflicting with any + existing fiat currency codes. + BillingCurrencyCustom: + type: object + required: + - id + - type + - name + - code + - created_at + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + type: + type: string + enum: + - custom + description: The type of the currency. + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + The name of the currency. It should be a human-readable string that represents + the name of the currency, such as "US Dollar" or "Euro". + description: + type: string + minLength: 1 + maxLength: 256 + description: Description of the currency. + symbol: + type: string + minLength: 1 + description: |- + The symbol of the currency. It should be a string that represents the symbol of + the currency, such as "$" for US Dollar or "€" for Euro. + code: + $ref: '#/components/schemas/BillingCurrencyCodeCustom' + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of the custom currency creation date. + readOnly: true + additionalProperties: false + description: Describes custom currency. + BillingCurrencyFiat: + type: object + required: + - id + - type + - name + - code + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + type: + type: string + enum: + - fiat + description: The type of the currency. + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + The name of the currency. It should be a human-readable string that represents + the name of the currency, such as "US Dollar" or "Euro". + description: + type: string + minLength: 1 + maxLength: 256 + description: Description of the currency. + symbol: + type: string + minLength: 1 + description: |- + The symbol of the currency. It should be a string that represents the symbol of + the currency, such as "$" for US Dollar or "€" for Euro. + code: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + readOnly: true + additionalProperties: false + description: Currency describes a currency supported by the billing system. + BillingCurrencyType: + type: string + enum: + - fiat + - custom + description: |- + Currency type for custom currencies. It should be a unique code but not + conflicting with any existing standard currency codes. + BillingCustomer: + type: object + required: + - id + - name + - created_at + - updated_at + - key + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + readOnly: true + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + created_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity creation date. + readOnly: true + updated_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity last update date. + readOnly: true + deleted_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity deletion date. + readOnly: true + key: + $ref: '#/components/schemas/ExternalResourceKey' + usage_attribution: + allOf: + - $ref: '#/components/schemas/BillingCustomerUsageAttribution' + description: Mapping to attribute metered usage to the customer by the event subject. + title: Usage Attribution + primary_email: + type: string + description: The primary email address of the customer. + title: Primary Email + currency: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: Currency of the customer. Used for billing, tax and invoicing. + title: Currency + billing_address: + allOf: + - $ref: '#/components/schemas/Address' + description: The billing address of the customer. Used for tax and invoicing. + title: Billing Address + additionalProperties: false + description: |- + Customers can be individuals or organizations that can subscribe to plans and + have access to features. + BillingCustomerData: + type: object + properties: + billing_profile: + allOf: + - $ref: '#/components/schemas/BillingProfileReference' + description: |- + The billing profile for the customer. + + If not provided, the default billing profile will be used. + title: Billing profile + app_data: + allOf: + - $ref: '#/components/schemas/BillingAppCustomerData' + description: App customer data. + title: App customer data + additionalProperties: false + description: Billing customer data. + BillingCustomerReference: + type: object + required: + - id + properties: + id: + allOf: + - $ref: '#/components/schemas/ULID' + description: The ID of the customer. + additionalProperties: false + description: Customer reference. + BillingCustomerStripeCreateCheckoutSessionRequest: + type: object + required: + - stripe_options + properties: + stripe_options: + allOf: + - $ref: '#/components/schemas/BillingAppStripeCreateCheckoutSessionRequestOptions' + description: |- + Options for configuring the Stripe Checkout Session. + + These options are passed directly to Stripe's + [checkout session creation API](https://docs.stripe.com/api/checkout/sessions/create). + additionalProperties: false + description: |- + Request to create a Stripe Checkout Session for the customer. + + Checkout Sessions are used to collect payment method information from customers + in a secure, Stripe-hosted interface. This integration uses setup mode to + collect payment methods that can be charged later for subscription billing. + BillingCustomerStripeCreateCustomerPortalSessionRequest: + type: object + required: + - stripe_options + properties: + stripe_options: + allOf: + - $ref: '#/components/schemas/BillingAppStripeCreateCustomerPortalSessionOptions' + description: Options for configuring the Stripe Customer Portal Session. + additionalProperties: false + description: |- + Request to create a Stripe Customer Portal Session for the customer. + + Useful to redirect the customer to the Stripe Customer Portal to manage their + payment methods, change their billing address and access their invoice history. + Only returns URL if the customer billing profile is linked to a stripe app and + customer. + BillingCustomerUsageAttribution: + type: object + required: + - subject_keys + properties: + subject_keys: + type: array + items: + $ref: '#/components/schemas/UsageAttributionSubjectKey' + minItems: 0 + description: |- + The subjects that are attributed to the customer. Can be empty when no usage + event subjects are associated with the customer. + title: Subject Keys + additionalProperties: false + description: |- + Mapping to attribute metered usage to the customer. One customer can have zero + or more subjects, but one subject can only belong to one customer. + BillingEntitlementAccessResult: + type: object + required: + - type + - feature_key + - has_access + properties: + type: + allOf: + - $ref: '#/components/schemas/BillingEntitlementType' + description: The type of the entitlement. + example: static + readOnly: true + feature_key: + allOf: + - $ref: '#/components/schemas/ResourceKey' + description: The feature key of the entitlement. + example: available_models + readOnly: true + has_access: + type: boolean + description: |- + Whether the customer has access to the feature. Always true for `boolean` and + `static` entitlements. Depends on balance for `metered` entitlements. + example: true + readOnly: true + config: + type: string + description: |- + Only available for static entitlements. Config is the JSON parsable + configuration of the entitlement. Useful to describe per customer configuration. + example: '{ "availableModels": ["gpt-5", "gpt-4o"] }' + readOnly: true + additionalProperties: false + description: Entitlement access result. + BillingEntitlementType: + type: string + enum: + - metered + - static + - boolean + description: The type of the entitlement. + BillingFeatureLLMTokenType: + type: string + enum: + - input + - output + - cache_read + - cache_write + - reasoning + - request + - response + description: Token type for LLM cost lookup. + BillingFeatureLLMUnitCost: + type: object + required: + - type + properties: + type: + type: string + enum: + - llm + description: The type discriminator for LLM unit cost. + provider_property: + type: string + description: |- + Meter group-by property that holds the LLM provider. Use this when the meter has + a group-by dimension for provider. Mutually exclusive with `provider`. + title: Provider property + provider: + type: string + description: |- + Static LLM provider value (e.g., "openai", "anthropic"). Use this when the + feature tracks a single provider. Mutually exclusive with `provider_property`. + title: Provider + model_property: + type: string + description: |- + Meter group-by property that holds the model ID. Use this when the meter has a + group-by dimension for model. Mutually exclusive with `model`. + title: Model property + model: + type: string + description: |- + Static model ID value (e.g., "gpt-4", "claude-3-5-sonnet"). Use this when the + feature tracks a single model. Mutually exclusive with `model_property`. + title: Model + token_type_property: + type: string + description: |- + Meter group-by property that holds the token type. Use this when the meter has a + group-by dimension for token type. Mutually exclusive with `token_type`. + title: Token type property + token_type: + allOf: + - $ref: '#/components/schemas/BillingFeatureLLMTokenType' + description: |- + Static token type value. Use this when the feature tracks a single token type + (e.g., only input tokens). `request` is an alias for `input`, `response` is an + alias for `output`. Mutually exclusive with `token_type_property`. + title: Token type + pricing: + allOf: + - $ref: '#/components/schemas/BillingFeatureLLMUnitCostPricing' + description: |- + Resolved per-token pricing from the LLM cost database. Populated in responses + when the provider and model can be determined, either from static values or from + meter group-by filters with exact matches. + title: Resolved pricing + readOnly: true + additionalProperties: false description: |- - Credit purchase payment settlement status. + LLM cost lookup configuration. Each dimension (provider, model, token type) can + be specified as either a static value or a meter group-by property name + (mutually exclusive). + BillingFeatureLLMUnitCostPricing: + type: object + required: + - input_per_token + - output_per_token + properties: + input_per_token: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Cost per input token in USD. + title: Input per token + output_per_token: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Cost per output token in USD. + title: Output per token + cache_read_per_token: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Cost per cache read token in USD. + title: Cache read per token + reasoning_per_token: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Cost per reasoning token in USD. + title: Reasoning per token + cache_write_per_token: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Cost per cache write token in USD. + title: Cache write per token + additionalProperties: false + description: Resolved per-token pricing from the LLM cost database. + BillingFeatureManualUnitCost: + type: object + required: + - type + - amount + properties: + type: + type: string + enum: + - manual + description: The type discriminator for manual unit cost. + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: Fixed per-unit cost amount in USD. + additionalProperties: false + description: A fixed per-unit cost amount. + BillingFeatureUnitCost: + type: object + oneOf: + - $ref: '#/components/schemas/BillingFeatureManualUnitCost' + - $ref: '#/components/schemas/BillingFeatureLLMUnitCost' + discriminator: + propertyName: type + mapping: + manual: '#/components/schemas/BillingFeatureManualUnitCost' + llm: '#/components/schemas/BillingFeatureLLMUnitCost' + description: |- + Per-unit cost configuration for a feature. Either a fixed manual amount or a + dynamic LLM cost lookup. + BillingInvoice: + type: object + oneOf: + - $ref: '#/components/schemas/BillingInvoiceStandard' + discriminator: + propertyName: type + mapping: + standard: '#/components/schemas/BillingInvoiceStandard' + description: |- + An invoice issued to a customer. - - `pending`: Payment has been initiated and is not yet authorized. - - `authorized`: Payment has been authorized. - - `settled`: Payment has been settled. - title: Credit purchase payment settlement status - BillingCreditTransaction: + The `type` field determines the concrete variant: + + - `standard`: a standard invoice for charges owed. + BillingInvoiceAvailableActionDetails: + type: object + required: + - resulting_state + properties: + resulting_state: + type: string + description: The extended status the invoice will transition to after performing this action. + title: Resulting state + readOnly: true + additionalProperties: false + description: Details about an available invoice action including the resulting state. + BillingInvoiceAvailableActions: + type: object + properties: + advance: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActionDetails' + description: Advance the invoice to the next workflow step. + title: Advance + readOnly: true + approve: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActionDetails' + description: Approve the invoice for issuance. + title: Approve + readOnly: true + delete: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActionDetails' + description: Delete the invoice. + title: Delete + readOnly: true + retry: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActionDetails' + description: Retry a failed workflow step. + title: Retry + readOnly: true + snapshot_quantities: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActionDetails' + description: Snapshot the current usage quantities. + title: Snapshot quantities + readOnly: true + additionalProperties: false + description: |- + The set of state-transition actions available for an invoice in its current + status. + + A field is present only when that action is permitted from the current state. + BillingInvoiceCustomer: type: object required: - id - name - - created_at - - booked_at - - type - - currency - - amount - - available_balance + properties: + id: + $ref: '#/components/schemas/ULID' + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + usage_attribution: + allOf: + - $ref: '#/components/schemas/BillingCustomerUsageAttribution' + description: Mapping to attribute metered usage to the customer by the event subject. + title: Usage Attribution + billing_address: + allOf: + - $ref: '#/components/schemas/Address' + description: The billing address of the customer. Used for tax and invoicing. + title: Billing Address + key: + allOf: + - $ref: '#/components/schemas/ExternalResourceKey' + description: |- + Optional external resource key for the customer. + + Omitted when the customer was created without a key. Unlike on the customer + resource itself, the key is optional here because the invoice snapshot may + predate or omit it. + additionalProperties: false + description: Snapshot of the customer's information at the time the invoice was issued. + BillingInvoiceDetailedLine: + type: object + required: + - id + - name + - created_at + - updated_at + - service_period + - totals + - category + - quantity + - unit_price properties: id: allOf: @@ -4539,201 +5548,303 @@ components: - $ref: '#/components/schemas/DateTime' description: An ISO-8601 timestamp representation of entity creation date. readOnly: true - booked_at: + updated_at: allOf: - $ref: '#/components/schemas/DateTime' - description: The date and time the transaction was booked. + description: An ISO-8601 timestamp representation of entity last update date. readOnly: true - type: + deleted_at: allOf: - - $ref: '#/components/schemas/BillingCreditTransactionType' - description: The type of credit transaction. + - $ref: '#/components/schemas/DateTime' + description: An ISO-8601 timestamp representation of entity deletion date. readOnly: true - currency: + service_period: allOf: - - $ref: '#/components/schemas/BillingCurrencyCode' - description: Currency of the balance affected by the transaction. + - $ref: '#/components/schemas/ClosedPeriod' + description: The service period covered by this detailed line. + title: Service period readOnly: true - amount: + totals: + allOf: + - $ref: '#/components/schemas/BillingTotals' + description: Aggregated financial totals for the detailed line. + title: Totals + readOnly: true + category: + allOf: + - $ref: '#/components/schemas/BillingInvoiceDetailedLineCostCategory' + description: The cost category of this detailed line. + title: Category + default: regular + readOnly: true + discounts: + allOf: + - $ref: '#/components/schemas/BillingInvoiceLineDiscounts' + description: Discounts applied to this detailed line. + title: Discounts + readOnly: true + credits_applied: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceLineCreditsApplied' + description: Credit applied to this detailed line. + title: Credit applied + readOnly: true + external_references: + allOf: + - $ref: '#/components/schemas/BillingInvoiceLineExternalReferences' + description: External identifiers for this detailed line. + title: External references + readOnly: true + quantity: allOf: - $ref: '#/components/schemas/Numeric' - description: |- - Signed amount of the credit movement. Positive values add balance, negative - values reduce balance. + description: The quantity of the detailed line. + title: Quantity readOnly: true - available_balance: - type: object - properties: - before: - $ref: '#/components/schemas/Numeric' - after: - $ref: '#/components/schemas/Numeric' - required: - - before - - after - additionalProperties: false - description: The available balance before and after the transaction. + unit_price: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The unit price of the detailed line. + title: Unit Price readOnly: true additionalProperties: false description: |- - A credit transaction represents a single credit movement on the customer's - balance. + A detailed (child) sub-line belonging to a parent invoice line. - Credit transactions are immutable. - title: Credit transaction - BillingCreditTransactionType: + Detailed lines represent the individual flat-fee components that make up a + usage-based parent line after quantity snapshotting. + BillingInvoiceDetailedLineCostCategory: type: string enum: - - funded - - consumed - - expired - description: |- - The type of the credit transaction. - - - `funded`: Credit granted and available for consumption. - - `consumed`: Credit consumed by usage or fees. - - `expired`: Credit removed because it expired before being used. - BillingCurrency: + - regular + - commitment + description: Cost category of a detailed invoice line item. + BillingInvoiceDiscountReason: + type: string + enum: + - maximum_spend + - ratecard_percentage + - ratecard_usage + description: The reason a discount was applied to an invoice line. + BillingInvoiceExternalReferences: + type: object + properties: + invoicing_id: + type: string + description: The ID assigned by the external invoicing app (e.g. Stripe invoice ID). + title: Invoicing ID + readOnly: true + payment_id: + type: string + description: The ID assigned by the external payment app (e.g. Stripe payment intent ID). + title: Payment ID + readOnly: true + additionalProperties: false + description: External identifiers assigned to an invoice by third-party systems. + BillingInvoiceLine: type: object oneOf: - - $ref: '#/components/schemas/BillingCurrencyFiat' - - $ref: '#/components/schemas/BillingCurrencyCustom' + - $ref: '#/components/schemas/BillingInvoiceStandardLine' discriminator: propertyName: type mapping: - fiat: '#/components/schemas/BillingCurrencyFiat' - custom: '#/components/schemas/BillingCurrencyCustom' - description: Fiat or custom currency. - BillingCurrencyCode: - type: string - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: Fiat or custom currency code. - x-go-type: string - BillingCurrencyCodeCustom: - type: string - minLength: 3 - maxLength: 24 + standard_line: '#/components/schemas/BillingInvoiceStandardLine' description: |- - Custom currency code. It should be a unique code but not conflicting with any - existing fiat currency codes. - BillingCurrencyCustom: + A top-level line item on an invoice. + + Each line represents a single charge, typically associated with a rate card from + a subscription. Detailed (child) lines are nested under `detailed_lines` when + present. + BillingInvoiceLineAmountDiscount: type: object required: - id - - type - - name - - code - - created_at + - reason + - amount properties: id: allOf: - $ref: '#/components/schemas/ULID' + description: Unique identifier for the discount. + title: ID readOnly: true - type: - type: string - enum: - - custom - description: The type of the currency. + reason: + allOf: + - $ref: '#/components/schemas/BillingInvoiceDiscountReason' + description: The reason this discount was applied. + title: Reason readOnly: true - name: + description: type: string - minLength: 1 - maxLength: 256 - description: |- - The name of the currency. It should be a human-readable string that represents - the name of the currency, such as "US Dollar" or "Euro". + description: Optional human-readable description of the discount. + title: Description + readOnly: true + external_references: + allOf: + - $ref: '#/components/schemas/BillingInvoiceLineExternalReferences' + description: External identifiers for this discount. + title: External references + readOnly: true + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The monetary amount deducted. + title: Amount + readOnly: true + additionalProperties: false + description: A monetary amount discount applied to an invoice line item. + BillingInvoiceLineCreditsApplied: + type: object + required: + - amount + properties: + amount: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The monetary amount credited. + title: Amount + readOnly: true description: type: string - minLength: 1 - maxLength: 256 - description: Description of the currency. - symbol: + description: Optional human-readable description of the credit allocation. + title: Description + readOnly: true + additionalProperties: false + description: A credit allocation applied to an invoice line item. + BillingInvoiceLineDiscounts: + type: object + properties: + amount: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceLineAmountDiscount' + description: Monetary amount discounts (e.g. from maximum spend commitments). + title: Amount discounts + readOnly: true + usage: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceLineUsageDiscount' + description: Usage quantity discounts (e.g. free tier usage allowances). + title: Usage discounts + readOnly: true + additionalProperties: false + description: Discounts applied to an invoice line item. + BillingInvoiceLineExternalReferences: + type: object + properties: + invoicing_id: type: string - minLength: 1 - description: |- - The symbol of the currency. It should be a string that represents the symbol of - the currency, such as "$" for US Dollar or "€" for Euro. - code: - $ref: '#/components/schemas/BillingCurrencyCodeCustom' - created_at: + description: The ID assigned by the external invoicing app. + title: Invoicing ID + readOnly: true + additionalProperties: false + description: External identifiers for an invoice line item assigned by third-party systems. + BillingInvoiceLineRateCard: + type: object + required: + - price + properties: + price: allOf: - - $ref: '#/components/schemas/DateTime' - description: An ISO-8601 timestamp representation of the custom currency creation date. + - $ref: '#/components/schemas/BillingPrice' + description: The price definition used to calculate charges for this line. + title: Price + readOnly: true + tax_config: + allOf: + - $ref: '#/components/schemas/BillingRateCardTaxConfig' + description: Tax configuration snapshot for this line. + title: Tax config + readOnly: true + feature_key: + allOf: + - $ref: '#/components/schemas/ResourceKey' + description: The feature key associated with this line's rate card. + title: Feature key + readOnly: true + discounts: + allOf: + - $ref: '#/components/schemas/BillingRateCardDiscounts' + description: Discount configuration from the rate card. + title: Discounts readOnly: true additionalProperties: false - description: Describes custom currency. - BillingCurrencyFiat: + description: Rate card configuration snapshot for a usage-based invoice line. + BillingInvoiceLineUsageDiscount: type: object required: - id - - type - - name - - code + - reason + - quantity properties: id: allOf: - $ref: '#/components/schemas/ULID' + description: Unique identifier for the discount. + title: ID readOnly: true - type: - type: string - enum: - - fiat - description: The type of the currency. + reason: + allOf: + - $ref: '#/components/schemas/BillingInvoiceDiscountReason' + description: The reason this discount was applied. + title: Reason readOnly: true - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - The name of the currency. It should be a human-readable string that represents - the name of the currency, such as "US Dollar" or "Euro". description: type: string - minLength: 1 - maxLength: 256 - description: Description of the currency. - symbol: - type: string - minLength: 1 - description: |- - The symbol of the currency. It should be a string that represents the symbol of - the currency, such as "$" for US Dollar or "€" for Euro. - code: + description: Optional human-readable description of the discount. + title: Description + readOnly: true + external_references: allOf: - - $ref: '#/components/schemas/CurrencyCode' + - $ref: '#/components/schemas/BillingInvoiceLineExternalReferences' + description: External identifiers for this discount. + title: External references + readOnly: true + quantity: + allOf: + - $ref: '#/components/schemas/Numeric' + description: The usage quantity deducted (in billing units). + title: Quantity readOnly: true additionalProperties: false - description: Currency describes a currency supported by the billing system. - BillingCurrencyType: + description: A usage quantity discount applied to an invoice line item. + BillingInvoiceNumber: type: string - enum: - - fiat - - custom + minLength: 1 + maxLength: 256 description: |- - Currency type for custom currencies. It should be a unique code but not - conflicting with any existing standard currency codes. - BillingCustomer: + InvoiceNumber is a unique identifier for the invoice, generated by the invoicing + app. + + The uniqueness depends on a lot of factors: + + - app setting (unique per app or unique per customer) + - multiple app scenarios (multiple apps generating invoices with the same + prefix) + example: INV-2024-01-01-01 + BillingInvoiceStandard: type: object required: - id - - name - created_at - updated_at - - key + - number + - currency + - supplier + - customer + - totals + - service_period + - type + - status + - status_details + - workflow properties: id: allOf: - $ref: '#/components/schemas/ULID' readOnly: true - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - Display name of the resource. - - Between 1 and 256 characters. description: type: string maxLength: 1024 @@ -4758,294 +5869,144 @@ components: - $ref: '#/components/schemas/DateTime' description: An ISO-8601 timestamp representation of entity deletion date. readOnly: true - key: - $ref: '#/components/schemas/ExternalResourceKey' - usage_attribution: + number: allOf: - - $ref: '#/components/schemas/BillingCustomerUsageAttribution' - description: Mapping to attribute metered usage to the customer by the event subject. - title: Usage Attribution - primary_email: - type: string - description: The primary email address of the customer. - title: Primary Email + - $ref: '#/components/schemas/BillingInvoiceNumber' + description: Human-readable invoice number generated by the invoicing app. + title: Number + readOnly: true currency: allOf: - $ref: '#/components/schemas/CurrencyCode' - description: Currency of the customer. Used for billing, tax and invoicing. + description: Three-letter ISO 4217 currency code for the invoice. title: Currency - billing_address: - allOf: - - $ref: '#/components/schemas/BillingAddress' - description: The billing address of the customer. Used for tax and invoicing. - title: Billing Address - additionalProperties: false - description: |- - Customers can be individuals or organizations that can subscribe to plans and - have access to features. - BillingCustomerData: - type: object - properties: - billing_profile: + readOnly: true + supplier: allOf: - - $ref: '#/components/schemas/BillingProfileReference' + - $ref: '#/components/schemas/BillingSupplier' description: |- - The billing profile for the customer. - - If not provided, the default billing profile will be used. - title: Billing profile - app_data: + Snapshot of the supplier's contact information at the time the invoice was + issued. + title: Supplier + readOnly: true + customer: allOf: - - $ref: '#/components/schemas/BillingAppCustomerData' - description: App customer data. - title: App customer data - additionalProperties: false - description: Billing customer data. - BillingCustomerReference: - type: object - required: - - id - properties: - id: + - $ref: '#/components/schemas/BillingInvoiceCustomer' + description: Snapshot of the customer's information at the time the invoice was issued. + title: Customer + readOnly: true + totals: allOf: - - $ref: '#/components/schemas/ULID' - description: The ID of the customer. - additionalProperties: false - description: Customer reference. - BillingCustomerStripeCreateCheckoutSessionRequest: - type: object - required: - - stripe_options - properties: - stripe_options: + - $ref: '#/components/schemas/BillingTotals' + description: Aggregated financial totals for the invoice. + title: Totals + readOnly: true + service_period: allOf: - - $ref: '#/components/schemas/BillingAppStripeCreateCheckoutSessionRequestOptions' + - $ref: '#/components/schemas/ClosedPeriod' description: |- - Options for configuring the Stripe Checkout Session. - - These options are passed directly to Stripe's - [checkout session creation API](https://docs.stripe.com/api/checkout/sessions/create). - additionalProperties: false - description: |- - Request to create a Stripe Checkout Session for the customer. - - Checkout Sessions are used to collect payment method information from customers - in a secure, Stripe-hosted interface. This integration uses setup mode to - collect payment methods that can be charged later for subscription billing. - BillingCustomerStripeCreateCustomerPortalSessionRequest: - type: object - required: - - stripe_options - properties: - stripe_options: - allOf: - - $ref: '#/components/schemas/BillingAppStripeCreateCustomerPortalSessionOptions' - description: Options for configuring the Stripe Customer Portal Session. - additionalProperties: false - description: |- - Request to create a Stripe Customer Portal Session for the customer. + The service period covered by this invoice. - Useful to redirect the customer to the Stripe Customer Portal to manage their - payment methods, change their billing address and access their invoice history. - Only returns URL if the customer billing profile is linked to a stripe app and - customer. - BillingCustomerUsageAttribution: - type: object - required: - - subject_keys - properties: - subject_keys: + For flat fee the service period can be empty which means `from` will be equals + to `to`. In other cases those fields will be filled with the actual service + period. + title: Service period + readOnly: true + validation_issues: type: array items: - $ref: '#/components/schemas/UsageAttributionSubjectKey' - minItems: 0 + $ref: '#/components/schemas/BillingInvoiceValidationIssue' description: |- - The subjects that are attributed to the customer. Can be empty when no usage - event subjects are associated with the customer. - title: Subject Keys - additionalProperties: false - description: |- - Mapping to attribute metered usage to the customer. One customer can have zero - or more subjects, but one subject can only belong to one customer. - BillingEntitlementAccessResult: - type: object - required: - - type - - feature_key - - has_access - properties: - type: - allOf: - - $ref: '#/components/schemas/BillingEntitlementType' - description: The type of the entitlement. - example: static + Validation issues found during invoice processing. + + Present only when there are one or more validation findings. An empty list is + omitted. + title: Validation issues readOnly: true - feature_key: + external_references: allOf: - - $ref: '#/components/schemas/ResourceKey' - description: The feature key of the entitlement. - example: available_models - readOnly: true - has_access: - type: boolean - description: |- - Whether the customer has access to the feature. Always true for `boolean` and - `static` entitlements. Depends on balance for `metered` entitlements. - example: true - readOnly: true - config: - type: string - description: |- - Only available for static entitlements. Config is the JSON parsable - configuration of the entitlement. Useful to describe per customer configuration. - example: '{ "availableModels": ["gpt-5", "gpt-4o"] }' + - $ref: '#/components/schemas/BillingInvoiceExternalReferences' + description: External identifiers assigned to this invoice by third-party systems. + title: External references readOnly: true - additionalProperties: false - description: Entitlement access result. - BillingEntitlementType: - type: string - enum: - - metered - - static - - boolean - description: The type of the entitlement. - BillingFeatureLLMTokenType: - type: string - enum: - - input - - output - - cache_read - - cache_write - - reasoning - - request - - response - description: Token type for LLM cost lookup. - BillingFeatureLLMUnitCost: - type: object - required: - - type - properties: type: type: string enum: - - llm - description: The type discriminator for LLM unit cost. - provider_property: - type: string - description: |- - Meter group-by property that holds the LLM provider. Use this when the meter has - a group-by dimension for provider. Mutually exclusive with `provider`. - title: Provider property - provider: - type: string - description: |- - Static LLM provider value (e.g., "openai", "anthropic"). Use this when the - feature tracks a single provider. Mutually exclusive with `provider_property`. - title: Provider - model_property: - type: string - description: |- - Meter group-by property that holds the model ID. Use this when the meter has a - group-by dimension for model. Mutually exclusive with `model`. - title: Model property - model: - type: string - description: |- - Static model ID value (e.g., "gpt-4", "claude-3-5-sonnet"). Use this when the - feature tracks a single model. Mutually exclusive with `model_property`. - title: Model - token_type_property: - type: string - description: |- - Meter group-by property that holds the token type. Use this when the meter has a - group-by dimension for token type. Mutually exclusive with `token_type`. - title: Token type property - token_type: + - standard + description: Discriminator field identifying this as a standard invoice. + title: Type + readOnly: true + status: allOf: - - $ref: '#/components/schemas/BillingFeatureLLMTokenType' - description: |- - Static token type value. Use this when the feature tracks a single token type - (e.g., only input tokens). `request` is an alias for `input`, `response` is an - alias for `output`. Mutually exclusive with `token_type_property`. - title: Token type - pricing: + - $ref: '#/components/schemas/BillingInvoiceStandardStatus' + description: Current lifecycle status of the invoice. + title: Status + readOnly: true + status_details: allOf: - - $ref: '#/components/schemas/BillingFeatureLLMUnitCostPricing' - description: |- - Resolved per-token pricing from the LLM cost database. Populated in responses - when the provider and model can be determined, either from static values or from - meter group-by filters with exact matches. - title: Resolved pricing + - $ref: '#/components/schemas/BillingInvoiceStatusDetails' + description: Detailed status information including available actions and workflow state. + title: Status details readOnly: true - additionalProperties: false - description: |- - LLM cost lookup configuration. Each dimension (provider, model, token type) can - be specified as either a static value or a meter group-by property name - (mutually exclusive). - BillingFeatureLLMUnitCostPricing: - type: object - required: - - input_per_token - - output_per_token - properties: - input_per_token: + issued_at: allOf: - - $ref: '#/components/schemas/Numeric' - description: Cost per input token in USD. - title: Input per token - output_per_token: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when the invoice was issued to the customer. + title: Issued at + readOnly: true + draft_until: allOf: - - $ref: '#/components/schemas/Numeric' - description: Cost per output token in USD. - title: Output per token - cache_read_per_token: + - $ref: '#/components/schemas/DateTime' + description: |- + Timestamp until which the invoice remains in draft state. + + The invoice advances automatically once this time is reached. + title: Draft until + readOnly: true + quantity_snapshotted_at: allOf: - - $ref: '#/components/schemas/Numeric' - description: Cost per cache read token in USD. - title: Cache read per token - reasoning_per_token: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when usage quantities were last snapshotted for this invoice. + title: Quantity snapshotted at + readOnly: true + collection_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when collection was initiated for this invoice. + title: Collection at + readOnly: true + due_at: allOf: - - $ref: '#/components/schemas/Numeric' - description: Cost per reasoning token in USD. - title: Reasoning per token - cache_write_per_token: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when payment is due. + title: Due at + readOnly: true + sent_to_customer_at: allOf: - - $ref: '#/components/schemas/Numeric' - description: Cost per cache write token in USD. - title: Cache write per token - additionalProperties: false - description: Resolved per-token pricing from the LLM cost database. - BillingFeatureManualUnitCost: - type: object - required: - - type - - amount - properties: - type: - type: string - enum: - - manual - description: The type discriminator for manual unit cost. - amount: + - $ref: '#/components/schemas/DateTime' + description: Timestamp when the invoice was sent to the customer. + title: Sent to customer at + readOnly: true + workflow: allOf: - - $ref: '#/components/schemas/Numeric' - description: Fixed per-unit cost amount in USD. + - $ref: '#/components/schemas/BillingInvoiceWorkflowSettings' + description: Workflow configuration snapshot captured at invoice creation time. + title: Workflow + readOnly: true + lines: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceLine' + description: |- + Line items on this invoice. + + Always returned on single-resource GET; omitted on list endpoints unless + explicitly expanded. + title: Lines + readOnly: true additionalProperties: false - description: A fixed per-unit cost amount. - BillingFeatureUnitCost: - type: object - oneOf: - - $ref: '#/components/schemas/BillingFeatureManualUnitCost' - - $ref: '#/components/schemas/BillingFeatureLLMUnitCost' - discriminator: - propertyName: type - mapping: - manual: '#/components/schemas/BillingFeatureManualUnitCost' - llm: '#/components/schemas/BillingFeatureLLMUnitCost' - description: |- - Per-unit cost configuration for a feature. Either a fixed manual amount or a - dynamic LLM cost lookup. - BillingFlatFeeCharge: + description: A standard invoice for charges owed by the customer. + BillingInvoiceStandardLine: type: object required: - id @@ -5053,19 +6014,11 @@ components: - created_at - updated_at - type - - customer - - managed_by - - currency - - status - - invoice_at + - lifecycle_controller - service_period - - full_service_period - - billing_period - - settlement_mode - - payment_term - - proration_configuration - - amount_after_proration - - price + - totals + - rate_card + - detailed_lines properties: id: allOf: @@ -5106,133 +6059,300 @@ components: type: type: string enum: - - flat_fee - description: The type of the charge. + - standard_line + description: The type of charge this line item represents. title: Type - customer: - allOf: - - $ref: '#/components/schemas/BillingCustomerReference' - description: The customer owning the charge. - title: Customer readOnly: true - managed_by: + lifecycle_controller: allOf: - - $ref: '#/components/schemas/ResourceManagedBy' - description: The charge is managed by the following entity. - title: Managed by + - $ref: '#/components/schemas/BillingLifecycleController' + description: |- + Indicates whether this line item's lifecycle is controlled by OpenMeter or + manually overridden by the API user. + title: Lifecycle controller readOnly: true - subscription: + service_period: allOf: - - $ref: '#/components/schemas/BillingSubscriptionReference' + - $ref: '#/components/schemas/ClosedPeriod' description: |- - The subscription that originated the charge, when the charge was created from a - subscription item. - title: Subscription + The service period covered by this invoice, spanning the earliest line start to + the latest line end across all of its lines. + + For an invoice with no lines the period is empty, which means `from` will be + equal to `to`. + title: Service period readOnly: true - currency: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: The currency of the charge. - title: Currency - status: + totals: allOf: - - $ref: '#/components/schemas/BillingChargeStatus' - description: The lifecycle status of the charge. - title: Status + - $ref: '#/components/schemas/BillingTotals' + description: Aggregated financial totals for the line item. + title: Totals readOnly: true - invoice_at: + discounts: allOf: - - $ref: '#/components/schemas/DateTime' - description: The timestamp when the charge is intended to be invoiced. - title: Invoice at - service_period: + - $ref: '#/components/schemas/BillingInvoiceLineDiscounts' + description: Discounts applied to this line item. + title: Discounts + readOnly: true + credits_applied: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceLineCreditsApplied' + description: Credit applied to this line item. + title: Credit applied + readOnly: true + external_references: allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The effective service period covered by the charge. - title: Service period - full_service_period: + - $ref: '#/components/schemas/BillingInvoiceLineExternalReferences' + description: External identifiers for this line item assigned by third-party systems. + title: External references + readOnly: true + subscription: allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The full, unprorated service period of the charge. - title: Full service period + - $ref: '#/components/schemas/BillingSubscriptionReference' + description: Reference to the subscription item that generated this line. + title: Subscription reference readOnly: true - billing_period: + rate_card: allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The billing period the charge belongs to. - title: Billing period + - $ref: '#/components/schemas/BillingInvoiceLineRateCard' + description: The rate card configuration snapshot used to price this line item. + title: Rate card readOnly: true - advance_after: + detailed_lines: + type: array + items: + $ref: '#/components/schemas/BillingInvoiceDetailedLine' + description: |- + Detailed sub-lines that this line has been broken down into. + + Present when line has individual details. + title: Detailed lines + readOnly: true + charge: allOf: - - $ref: '#/components/schemas/DateTime' + - $ref: '#/components/schemas/BillingChargeReference' + description: Reference to the charge associated with this line item. + title: Charge + readOnly: true + additionalProperties: false + description: |- + A top-level line item on an invoice. + + Each line represents a single charge, typically associated with a rate card from + a subscription. Detailed (child) lines are nested under `detailed_lines` when + present. + BillingInvoiceStandardStatus: + type: string + enum: + - draft + - issuing + - issued + - payment_processing + - overdue + - paid + - uncollectible + - voided + description: Lifecycle status of a standard invoice. + BillingInvoiceStatusDetails: + type: object + required: + - immutable + - failed + - extended_status + - available_actions + properties: + immutable: + type: boolean + description: Whether the invoice is immutable (i.e. cannot be modified or deleted). + title: Immutable + readOnly: true + failed: + type: boolean + description: Whether the invoice is in a failed state. + title: Failed + readOnly: true + extended_status: + type: string description: |- - The earliest time when the charge should be advanced again by background - processing. - title: Advance after + Fine-grained internal status string providing additional workflow detail beyond + the top-level status enum. + title: Extended status readOnly: true - unique_reference_id: + available_actions: + allOf: + - $ref: '#/components/schemas/BillingInvoiceAvailableActions' + description: The set of state-transition actions currently available for this invoice. + title: Available actions + readOnly: true + additionalProperties: false + description: Detailed status information for a standard invoice. + BillingInvoiceValidationIssue: + type: object + required: + - code + - message + - severity + properties: + code: type: string - description: Unique reference ID of the charge. - title: Unique reference ID - settlement_mode: + description: Machine-readable error code. + title: Code + readOnly: true + message: + type: string + description: Human-readable description of the error. + title: Message + readOnly: true + attributes: + type: object + additionalProperties: {} + description: Additional structured context. + title: Attributes + readOnly: true + severity: allOf: - - $ref: '#/components/schemas/BillingSettlementMode' - description: Settlement mode of the charge. - title: Settlement mode - tax_config: + - $ref: '#/components/schemas/BillingInvoiceValidationIssueSeverity' + description: Severity of the validation issue. + title: Severity + readOnly: true + field: + type: string + description: |- + JSON path to the field that caused this validation issue, if applicable. + + For example: `lines/0/rate_card/price`. + title: Field path + readOnly: true + additionalProperties: false + description: |- + A validation issue found during invoice processing. + + Converges on the same structure used by plan and subscription validation errors: + a machine-readable `code`, a human-readable `message`, optional structured + `attributes`, plus a `severity` and optional `field` path. + BillingInvoiceValidationIssueSeverity: + type: string + enum: + - critical + - warning + description: Severity level of an invoice validation issue. + BillingInvoiceWorkflow: + type: object + properties: + invoicing: allOf: - - $ref: '#/components/schemas/BillingTaxConfig' - description: Tax configuration of the charge. - title: Tax configuration - payment_term: + - $ref: '#/components/schemas/BillingInvoiceWorkflowInvoicingSettings' + description: Invoicing settings for this invoice. + title: Invoicing settings + readOnly: true + payment: allOf: - - $ref: '#/components/schemas/BillingPricePaymentTerm' - description: Payment term of the flat fee charge. - title: Payment term - discounts: + - $ref: '#/components/schemas/BillingWorkflowPaymentSettings' + description: Payment settings for this invoice. + title: Payment settings + readOnly: true + additionalProperties: false + description: |- + Invoice-level snapshot of the workflow configuration. + + Contains only the settings that are meaningful for an already-created invoice: + invoicing behaviour and payment settings. Collection alignment and tax policy + are gather-time / profile-wide concerns and are not included. + BillingInvoiceWorkflowAppsReferences: + type: object + required: + - tax + - invoicing + - payment + properties: + tax: allOf: - - $ref: '#/components/schemas/BillingFlatFeeDiscounts' - description: The discounts applied to the charge. - title: Discounts - feature_key: + - $ref: '#/components/schemas/BillingAppReference' + description: The tax app used for this workflow + readOnly: true + invoicing: + allOf: + - $ref: '#/components/schemas/BillingAppReference' + description: The invoicing app used for this workflow + readOnly: true + payment: + allOf: + - $ref: '#/components/schemas/BillingAppReference' + description: The payment app used for this workflow + readOnly: true + additionalProperties: false + description: |- + BillingInvoiceWorkflowAppsReferences represents the references (id) to the apps + used by a billing profile + BillingInvoiceWorkflowInvoicingSettings: + type: object + properties: + auto_advance: + type: boolean + description: Whether to automatically issue the invoice after the draft_period has passed. + default: true + readOnly: true + draft_period: type: string - description: The feature associated with the charge, when applicable. - title: Feature key - proration_configuration: + format: ISO8601 + description: The period for the invoice to be kept in draft status for manual reviews. + example: P1D + default: P0D + readOnly: true + additionalProperties: false + description: |- + Invoice-level invoicing settings. + + A subset of BillingWorkflowInvoicingSettings limited to fields that are + meaningful per-invoice. progressive_billing is omitted as it is a gather-time / + profile-level decision. + BillingInvoiceWorkflowSettings: + type: object + required: + - source_billing_profile + - workflow + properties: + apps: allOf: - - $ref: '#/components/schemas/BillingRateCardProrationConfiguration' - description: The proration configuration of the charge. - title: Proration configuration - amount_after_proration: + - $ref: '#/components/schemas/BillingInvoiceWorkflowAppsReferences' + description: The apps that will be used to orchestrate the invoice's workflow. + title: Application that generated the invoice + readOnly: true + source_billing_profile: allOf: - - $ref: '#/components/schemas/CurrencyAmount' - description: The amount after proration of the charge. - title: Amount after proration + - $ref: '#/components/schemas/BillingProfileReference' + description: The billing profile that was the source of this workflow snapshot. + title: Source billing profile readOnly: true - price: + workflow: allOf: - - $ref: '#/components/schemas/BillingPrice' - description: The price of the charge. - title: Price + - $ref: '#/components/schemas/BillingInvoiceWorkflow' + description: |- + The workflow configuration that was active when the invoice was created. + + Only the fields that are meaningful at the per-invoice level are included: + invoicing behaviour (auto-advance, draft period) and payment settings + (collection method, due date). Profile-wide settings such as collection + alignment, progressive billing, and tax policy are omitted. + title: Workflow config readOnly: true additionalProperties: false - description: A flat fee charge for a customer. - title: Flat fee charge - BillingFlatFeeDiscounts: - type: object - properties: - percentage: - type: number - minimum: 0 - maximum: 100 - description: Percentage discount applied to the price (0–100). - additionalProperties: false + description: Snapshot of the billing workflow configuration captured at invoice creation. + BillingLifecycleController: + type: string + enum: + - system + - manual description: |- - Discounts applicable to flat fee charges. + Identifies whether a resource lifecycle is controlled by OpenMeter or manually + overridden by the API user. - This is the same as `ProductCatalog.Discounts` but without the `usage` field, - which is not applicable to flat fee charges. - title: Flat fee charge discounts + Values: + + - `system`: The resource lifecycle is controlled by OpenMeter. + - `manual`: The resource lifecycle was manually overridden by the API user. + title: Lifecycle controller BillingParty: type: object properties: @@ -5984,7 +7104,7 @@ components: behavior: $ref: '#/components/schemas/BillingTaxBehavior' code: - $ref: '#/components/schemas/TaxCodeReferenceItem' + $ref: '#/components/schemas/TaxCodeReference' additionalProperties: false description: The tax config of the rate card. BillingSettlementMode: @@ -6381,6 +7501,32 @@ components: - canceled - scheduled description: Subscription status. + BillingSupplier: + type: object + properties: + id: + type: string + description: Unique identifier for the party. + name: + type: string + description: Legal name or representation of the party. + tax_id: + allOf: + - $ref: '#/components/schemas/BillingPartyTaxIdentity' + description: |- + The entity's legal identification used for tax purposes. They may have other + numbers, but we're only interested in those valid for tax purposes. + addresses: + allOf: + - $ref: '#/components/schemas/BillingPartyAddresses' + description: Address for where information should be sent if needed. + additionalProperties: false + description: |- + Snapshot of the supplier's information at the time the invoice was issued. + + Structurally a read-only subset of `BillingParty` (the type configured on the + billing profile), so the snapshot stays aligned with the source. `key` is + omitted because it is not part of the snapshotted supplier data. BillingTaxBehavior: type: string enum: @@ -6645,224 +7791,63 @@ components: type: string description: |- A human-readable label for the converted unit shown on invoices and in the - customer portal (e.g., "GB", "hours", "M tokens"). - - Optional. When omitted, no unit label is rendered. - title: Display unit label - additionalProperties: false - description: |- - Unit conversion configuration. - - Transforms raw metered quantities into billing-ready units before pricing and - entitlement evaluation. Applied at the rate card level so the same feature can - be billed in different units across plans. - - Examples: - - - Meter bytes, bill GB: operation=divide, conversionFactor=1e9, - rounding=ceiling, displayUnit="GB" - - Meter seconds, bill hours: operation=divide, conversionFactor=3600, - rounding=ceiling, displayUnit="hours" - - Cost + 20% margin: operation=multiply, conversionFactor=1.2 - - Bill per million tokens: operation=divide, conversionFactor=1e6, - rounding=ceiling, displayUnit="M" - - v1 equivalents: - - - DynamicPrice(multiplier): operation=multiply, conversionFactor=multiplier + - UnitPrice(amount=1) - - PackagePrice(amount, quantityPerPkg): operation=divide, - conversionFactor=quantityPerPkg, rounding=ceiling + UnitPrice(amount) - BillingUnitConfigOperation: - type: string - enum: - - divide - - multiply - description: |- - The arithmetic operation used to convert raw metered units into billing units. - - - `divide`: Divide the metered quantity by the conversion factor (e.g., bytes ÷ - 1e9 = GB). - - `multiply`: Multiply the metered quantity by the conversion factor (e.g., cost - × 1.2 = cost + 20% margin). - BillingUnitConfigRoundingMode: - type: string - enum: - - ceiling - - floor - - half_up - - none - description: |- - The rounding mode applied to the converted quantity for invoicing. - - Rounding is applied only to the invoiced quantity. Entitlement balance checks - use the precise decimal value after conversion. - - - `ceiling`: Round up to the next integer (typical for package-style billing). - - `floor`: Round down to the previous integer. - - `half_up`: Round to the nearest integer, with 0.5 rounding up. - - `none`: No rounding; the converted value is used as-is. - BillingUsageBasedCharge: - type: object - required: - - id - - name - - created_at - - updated_at - - type - - customer - - managed_by - - currency - - status - - invoice_at - - service_period - - full_service_period - - billing_period - - settlement_mode - - feature_key - - totals - - price - properties: - id: - allOf: - - $ref: '#/components/schemas/ULID' - readOnly: true - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - Display name of the resource. - - Between 1 and 256 characters. - description: - type: string - maxLength: 1024 - description: |- - Optional description of the resource. - - Maximum 1024 characters. - labels: - $ref: '#/components/schemas/Labels' - created_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: An ISO-8601 timestamp representation of entity creation date. - readOnly: true - updated_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: An ISO-8601 timestamp representation of entity last update date. - readOnly: true - deleted_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: An ISO-8601 timestamp representation of entity deletion date. - readOnly: true - type: - type: string - enum: - - usage_based - description: The type of the charge. - title: Type - customer: - allOf: - - $ref: '#/components/schemas/BillingCustomerReference' - description: The customer owning the charge. - title: Customer - readOnly: true - managed_by: - allOf: - - $ref: '#/components/schemas/ResourceManagedBy' - description: The charge is managed by the following entity. - title: Managed by - readOnly: true - subscription: - allOf: - - $ref: '#/components/schemas/BillingSubscriptionReference' - description: |- - The subscription that originated the charge, when the charge was created from a - subscription item. - title: Subscription - readOnly: true - currency: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: The currency of the charge. - title: Currency - status: - allOf: - - $ref: '#/components/schemas/BillingChargeStatus' - description: The lifecycle status of the charge. - title: Status - readOnly: true - invoice_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: The timestamp when the charge is intended to be invoiced. - title: Invoice at - service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The effective service period covered by the charge. - title: Service period - full_service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The full, unprorated service period of the charge. - title: Full service period - readOnly: true - billing_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The billing period the charge belongs to. - title: Billing period - readOnly: true - advance_after: - allOf: - - $ref: '#/components/schemas/DateTime' - description: |- - The earliest time when the charge should be advanced again by background - processing. - title: Advance after - readOnly: true - unique_reference_id: - type: string - description: Unique reference ID of the charge. - title: Unique reference ID - settlement_mode: - allOf: - - $ref: '#/components/schemas/BillingSettlementMode' - description: Settlement mode of the charge. - title: Settlement mode - tax_config: - allOf: - - $ref: '#/components/schemas/BillingTaxConfig' - description: Tax configuration of the charge. - title: Tax configuration - discounts: - allOf: - - $ref: '#/components/schemas/BillingRateCardDiscounts' - description: Discounts applied to the usage-based charge. - title: Discounts - feature_key: - type: string - description: The feature associated with the charge. - title: Feature key - totals: - allOf: - - $ref: '#/components/schemas/BillingChargeTotals' - description: Aggregated booked and realtime totals for the charge. - title: Totals for the charge - readOnly: true - price: - allOf: - - $ref: '#/components/schemas/BillingPrice' - description: The price of the charge. - title: Price + customer portal (e.g., "GB", "hours", "M tokens"). + + Optional. When omitted, no unit label is rendered. + title: Display unit label additionalProperties: false - description: A usage-based charge for a customer. - title: Usage-based charge + description: |- + Unit conversion configuration. + + Transforms raw metered quantities into billing-ready units before pricing and + entitlement evaluation. Applied at the rate card level so the same feature can + be billed in different units across plans. + + Examples: + + - Meter bytes, bill GB: operation=divide, conversionFactor=1e9, + rounding=ceiling, displayUnit="GB" + - Meter seconds, bill hours: operation=divide, conversionFactor=3600, + rounding=ceiling, displayUnit="hours" + - Cost + 20% margin: operation=multiply, conversionFactor=1.2 + - Bill per million tokens: operation=divide, conversionFactor=1e6, + rounding=ceiling, displayUnit="M" + + v1 equivalents: + + - DynamicPrice(multiplier): operation=multiply, conversionFactor=multiplier + + UnitPrice(amount=1) + - PackagePrice(amount, quantityPerPkg): operation=divide, + conversionFactor=quantityPerPkg, rounding=ceiling + UnitPrice(amount) + BillingUnitConfigOperation: + type: string + enum: + - divide + - multiply + description: |- + The arithmetic operation used to convert raw metered units into billing units. + + - `divide`: Divide the metered quantity by the conversion factor (e.g., bytes ÷ + 1e9 = GB). + - `multiply`: Multiply the metered quantity by the conversion factor (e.g., cost + × 1.2 = cost + 20% margin). + BillingUnitConfigRoundingMode: + type: string + enum: + - ceiling + - floor + - half_up + - none + description: |- + The rounding mode applied to the converted quantity for invoicing. + + Rounding is applied only to the invoiced quantity. Entitlement balance checks + use the precise decimal value after conversion. + + - `ceiling`: Round up to the next integer (typical for package-style billing). + - `floor`: Round down to the previous integer. + - `half_up`: Round to the nearest integer, with 0.5 rounding up. + - `none`: No rounding; the converted value is used as-is. BillingWorkflow: type: object properties: @@ -7203,44 +8188,235 @@ components: Between 1 and 256 characters. description: type: string - maxLength: 1024 - description: |- - Optional description of the resource. - - Maximum 1024 characters. - labels: - $ref: '#/components/schemas/Labels' - supplier: + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + supplier: + allOf: + - $ref: '#/components/schemas/BillingParty' + description: |- + The name and contact information for the supplier this billing profile + represents + workflow: + allOf: + - $ref: '#/components/schemas/BillingWorkflow' + description: The billing workflow settings for this profile + apps: + allOf: + - $ref: '#/components/schemas/BillingProfileAppReferences' + description: The applications used by this billing profile. + default: + type: boolean + description: Whether this is the default profile. + additionalProperties: false + description: BillingProfile create request. + CreateChargeFlatFeeRequest: + type: object + required: + - name + - type + - currency + - invoice_at + - service_period + - settlement_mode + - payment_term + - proration_configuration + - amount_before_proration + properties: + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + type: + type: string + enum: + - flat_fee + description: The type of the charge. + title: Type + currency: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: The currency of the charge. + title: Currency + invoice_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: The timestamp when the charge is intended to be invoiced. + title: Invoice at + service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The effective service period covered by the charge. + title: Service period + unique_reference_id: + type: string + description: Unique reference ID of the charge. + title: Unique reference ID + settlement_mode: + allOf: + - $ref: '#/components/schemas/BillingSettlementMode' + description: Settlement mode of the charge. + title: Settlement mode + tax_config: + allOf: + - $ref: '#/components/schemas/BillingTaxConfig' + description: Tax configuration of the charge. + title: Tax configuration + payment_term: + allOf: + - $ref: '#/components/schemas/BillingPricePaymentTerm' + description: Payment term of the flat fee charge. + title: Payment term + discounts: + allOf: + - $ref: '#/components/schemas/BillingChargeFlatFeeDiscounts' + description: The discounts applied to the charge. + title: Discounts + feature_key: + type: string + description: The feature associated with the charge, when applicable. + title: Feature key + proration_configuration: + allOf: + - $ref: '#/components/schemas/BillingRateCardProrationConfiguration' + description: The proration configuration of the charge. + title: Proration configuration + amount_before_proration: + allOf: + - $ref: '#/components/schemas/CurrencyAmount' + description: The amount before proration of the charge. + title: Amount before proration + full_service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The full, unprorated service period of the charge. + title: Full service period + billing_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The billing period the charge belongs to. + title: Billing period + additionalProperties: false + description: Flat fee charge create request. + CreateChargeRequest: + type: object + oneOf: + - $ref: '#/components/schemas/CreateChargeFlatFeeRequest' + - $ref: '#/components/schemas/CreateChargeUsageBasedRequest' + discriminator: + propertyName: type + mapping: + flat_fee: '#/components/schemas/CreateChargeFlatFeeRequest' + usage_based: '#/components/schemas/CreateChargeUsageBasedRequest' + description: Customer charge. + title: Customer charge create request. + CreateChargeUsageBasedRequest: + type: object + required: + - name + - type + - currency + - invoice_at + - service_period + - settlement_mode + - feature_key + - price + properties: + name: + type: string + minLength: 1 + maxLength: 256 + description: |- + Display name of the resource. + + Between 1 and 256 characters. + description: + type: string + maxLength: 1024 + description: |- + Optional description of the resource. + + Maximum 1024 characters. + labels: + $ref: '#/components/schemas/Labels' + type: + type: string + enum: + - usage_based + description: The type of the charge. + title: Type + currency: + allOf: + - $ref: '#/components/schemas/CurrencyCode' + description: The currency of the charge. + title: Currency + invoice_at: + allOf: + - $ref: '#/components/schemas/DateTime' + description: The timestamp when the charge is intended to be invoiced. + title: Invoice at + service_period: + allOf: + - $ref: '#/components/schemas/ClosedPeriod' + description: The effective service period covered by the charge. + title: Service period + unique_reference_id: + type: string + description: Unique reference ID of the charge. + title: Unique reference ID + settlement_mode: + allOf: + - $ref: '#/components/schemas/BillingSettlementMode' + description: Settlement mode of the charge. + title: Settlement mode + tax_config: + allOf: + - $ref: '#/components/schemas/BillingTaxConfig' + description: Tax configuration of the charge. + title: Tax configuration + discounts: + allOf: + - $ref: '#/components/schemas/BillingRateCardDiscounts' + description: Discounts applied to the usage-based charge. + title: Discounts + feature_key: + type: string + description: The feature associated with the charge. + title: Feature key + price: allOf: - - $ref: '#/components/schemas/BillingParty' - description: |- - The name and contact information for the supplier this billing profile - represents - workflow: + - $ref: '#/components/schemas/BillingPrice' + description: The price of the charge. + title: Price + full_service_period: allOf: - - $ref: '#/components/schemas/BillingWorkflow' - description: The billing workflow settings for this profile - apps: + - $ref: '#/components/schemas/ClosedPeriod' + description: The full, unprorated service period of the charge. + title: Full service period + billing_period: allOf: - - $ref: '#/components/schemas/BillingProfileAppReferences' - description: The applications used by this billing profile. - default: - type: boolean - description: Whether this is the default profile. + - $ref: '#/components/schemas/ClosedPeriod' + description: The billing period the charge belongs to. + title: Billing period additionalProperties: false - description: BillingProfile create request. - CreateChargeRequest: - type: object - oneOf: - - $ref: '#/components/schemas/CreateFlatFeeChargeRequest' - - $ref: '#/components/schemas/CreateUsageBasedChargeRequest' - discriminator: - propertyName: type - mapping: - flat_fee: '#/components/schemas/CreateFlatFeeChargeRequest' - usage_based: '#/components/schemas/CreateUsageBasedChargeRequest' - description: Customer charge. - title: Customer charge create request. + description: Usage-based charge create request. CreateCostBasisRequest: type: object required: @@ -7506,7 +8682,7 @@ components: title: Currency billing_address: allOf: - - $ref: '#/components/schemas/BillingAddress' + - $ref: '#/components/schemas/Address' description: The billing address of the customer. Used for tax and invoicing. title: Billing Address additionalProperties: false @@ -7553,107 +8729,6 @@ components: title: Unit cost additionalProperties: false description: Feature create request. - CreateFlatFeeChargeRequest: - type: object - required: - - name - - type - - currency - - invoice_at - - service_period - - settlement_mode - - payment_term - - proration_configuration - - amount_before_proration - properties: - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - Display name of the resource. - - Between 1 and 256 characters. - description: - type: string - maxLength: 1024 - description: |- - Optional description of the resource. - - Maximum 1024 characters. - labels: - $ref: '#/components/schemas/Labels' - type: - type: string - enum: - - flat_fee - description: The type of the charge. - title: Type - currency: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: The currency of the charge. - title: Currency - invoice_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: The timestamp when the charge is intended to be invoiced. - title: Invoice at - service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The effective service period covered by the charge. - title: Service period - unique_reference_id: - type: string - description: Unique reference ID of the charge. - title: Unique reference ID - settlement_mode: - allOf: - - $ref: '#/components/schemas/BillingSettlementMode' - description: Settlement mode of the charge. - title: Settlement mode - tax_config: - allOf: - - $ref: '#/components/schemas/BillingTaxConfig' - description: Tax configuration of the charge. - title: Tax configuration - payment_term: - allOf: - - $ref: '#/components/schemas/BillingPricePaymentTerm' - description: Payment term of the flat fee charge. - title: Payment term - discounts: - allOf: - - $ref: '#/components/schemas/BillingFlatFeeDiscounts' - description: The discounts applied to the charge. - title: Discounts - feature_key: - type: string - description: The feature associated with the charge, when applicable. - title: Feature key - proration_configuration: - allOf: - - $ref: '#/components/schemas/BillingRateCardProrationConfiguration' - description: The proration configuration of the charge. - title: Proration configuration - amount_before_proration: - allOf: - - $ref: '#/components/schemas/CurrencyAmount' - description: The amount before proration of the charge. - title: Amount before proration - full_service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The full, unprorated service period of the charge. - title: Full service period - billing_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The billing period the charge belongs to. - title: Billing period - additionalProperties: false - description: Flat fee charge create request. CreateMeterRequest: type: object required: @@ -7868,96 +8943,6 @@ components: title: App type to tax code mappings additionalProperties: false description: TaxCode create request. - CreateUsageBasedChargeRequest: - type: object - required: - - name - - type - - currency - - invoice_at - - service_period - - settlement_mode - - feature_key - - price - properties: - name: - type: string - minLength: 1 - maxLength: 256 - description: |- - Display name of the resource. - - Between 1 and 256 characters. - description: - type: string - maxLength: 1024 - description: |- - Optional description of the resource. - - Maximum 1024 characters. - labels: - $ref: '#/components/schemas/Labels' - type: - type: string - enum: - - usage_based - description: The type of the charge. - title: Type - currency: - allOf: - - $ref: '#/components/schemas/CurrencyCode' - description: The currency of the charge. - title: Currency - invoice_at: - allOf: - - $ref: '#/components/schemas/DateTime' - description: The timestamp when the charge is intended to be invoiced. - title: Invoice at - service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The effective service period covered by the charge. - title: Service period - unique_reference_id: - type: string - description: Unique reference ID of the charge. - title: Unique reference ID - settlement_mode: - allOf: - - $ref: '#/components/schemas/BillingSettlementMode' - description: Settlement mode of the charge. - title: Settlement mode - tax_config: - allOf: - - $ref: '#/components/schemas/BillingTaxConfig' - description: Tax configuration of the charge. - title: Tax configuration - discounts: - allOf: - - $ref: '#/components/schemas/BillingRateCardDiscounts' - description: Discounts applied to the usage-based charge. - title: Discounts - feature_key: - type: string - description: The feature associated with the charge. - title: Feature key - price: - allOf: - - $ref: '#/components/schemas/BillingPrice' - description: The price of the charge. - title: Price - full_service_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The full, unprorated service period of the charge. - title: Full service period - billing_period: - allOf: - - $ref: '#/components/schemas/ClosedPeriod' - description: The billing period the charge belongs to. - title: Billing period - additionalProperties: false - description: Usage-based charge create request. CreditBalance: type: object required: @@ -9707,21 +10692,6 @@ components: description: A key is a unique string that is used to identify a resource. title: Resource Key example: resource_key - ResourceManagedBy: - type: string - enum: - - manual - - system - - subscription - description: |- - Identifies which system manages a resource. - - Values: - - - `manual`: The resource is managed manually (overridden by our API users). - - `system`: The resource is managed by the system. - - `subscription`: The resource is managed by the subscription. - title: Resource managed by StringFieldFilter: anyOf: - type: string @@ -9933,15 +10903,6 @@ components: $ref: '#/components/schemas/ULID' additionalProperties: false description: TaxCode reference. - TaxCodeReferenceItem: - type: object - required: - - id - properties: - id: - $ref: '#/components/schemas/ULID' - additionalProperties: false - description: TaxCode reference. ULID: type: string pattern: ^[0-7][0-9A-HJKMNP-TV-Z]{25}$ @@ -10202,7 +11163,7 @@ components: title: Currency billing_address: allOf: - - $ref: '#/components/schemas/BillingAddress' + - $ref: '#/components/schemas/Address' description: The billing address of the customer. Used for tax and invoicing. title: Billing Address additionalProperties: false diff --git a/api/v3/server/routes.go b/api/v3/server/routes.go index 27f7b664f5..205dcffb8a 100644 --- a/api/v3/server/routes.go +++ b/api/v3/server/routes.go @@ -167,6 +167,12 @@ func (s *Server) UpdateBillingProfile(w http.ResponseWriter, r *http.Request, id s.billingProfilesHandler.UpdateBillingProfile().With(id).ServeHTTP(w, r) } +// Billing Invoices + +func (s *Server) GetInvoice(w http.ResponseWriter, r *http.Request, invoiceId api.ULID) { + s.billingInvoicesHandler.GetBillingInvoice().With(invoiceId).ServeHTTP(w, r) +} + // Customer Billing func (s *Server) GetCustomerBilling(w http.ResponseWriter, r *http.Request, customerId api.ULID) { diff --git a/api/v3/server/server.go b/api/v3/server/server.go index c14518230b..61561a56e7 100644 --- a/api/v3/server/server.go +++ b/api/v3/server/server.go @@ -17,6 +17,7 @@ import ( "github.com/openmeterio/openmeter/api/v3/apierrors" addonshandler "github.com/openmeterio/openmeter/api/v3/handlers/addons" appshandler "github.com/openmeterio/openmeter/api/v3/handlers/apps" + billinginvoiceshandler "github.com/openmeterio/openmeter/api/v3/handlers/billinginvoices" billingprofileshandler "github.com/openmeterio/openmeter/api/v3/handlers/billingprofiles" currencieshandler "github.com/openmeterio/openmeter/api/v3/handlers/currencies" customershandler "github.com/openmeterio/openmeter/api/v3/handlers/customers" @@ -255,6 +256,7 @@ type Server struct { subscriptionsHandler subscriptionshandler.Handler subscriptionAddonsHandler subscriptionaddonshandler.Handler billingProfilesHandler billingprofileshandler.Handler + billingInvoicesHandler billinginvoiceshandler.Handler plansHandler planshandler.Handler planAddonsHandler planaddonshandler.Handler chargesHandler chargeshandler.Handler @@ -320,6 +322,7 @@ func NewServer(config *Config) (*Server, error) { subscriptionsHandler := subscriptionshandler.New(resolveNamespace, config.CustomerService, config.PlanService, config.PlanSubscriptionService, config.SubscriptionService, httptransport.WithErrorHandler(config.ErrorHandler)) subscriptionAddonsHandler := subscriptionaddonshandler.New(resolveNamespace, config.SubscriptionAddonService, httptransport.WithErrorHandler(config.ErrorHandler)) billingProfilesHandler := billingprofileshandler.New(resolveNamespace, config.BillingService, httptransport.WithErrorHandler(config.ErrorHandler)) + billingInvoicesHandler := billinginvoiceshandler.New(resolveNamespace, config.BillingService, httptransport.WithErrorHandler(config.ErrorHandler)) plansHandler := planshandler.New(resolveNamespace, config.PlanService, config.UnitConfig.Enabled, httptransport.WithErrorHandler(config.ErrorHandler)) planAddonsHandler := planaddonshandler.New(resolveNamespace, config.PlanService, config.PlanAddonService, httptransport.WithErrorHandler(config.ErrorHandler)) taxcodesHandler := taxcodeshandler.New(resolveNamespace, config.TaxCodeService, httptransport.WithErrorHandler(config.ErrorHandler)) @@ -358,6 +361,7 @@ func NewServer(config *Config) (*Server, error) { subscriptionsHandler: subscriptionsHandler, subscriptionAddonsHandler: subscriptionAddonsHandler, billingProfilesHandler: billingProfilesHandler, + billingInvoicesHandler: billingInvoicesHandler, plansHandler: plansHandler, planAddonsHandler: planAddonsHandler, chargesHandler: chargesH, diff --git a/e2e/billinginvoices_v3_test.go b/e2e/billinginvoices_v3_test.go new file mode 100644 index 0000000000..2714eaefbe --- /dev/null +++ b/e2e/billinginvoices_v3_test.go @@ -0,0 +1,256 @@ +package e2e + +import ( + "net/http" + "testing" + "time" + + "github.com/samber/lo" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + api "github.com/openmeterio/openmeter/api/client/go" + apiv3 "github.com/openmeterio/openmeter/api/v3" +) + +// TestV3GetBillingInvoice exercises GET /api/v3/openmeter/billing/invoices/{invoiceId}. +// +// Flow: +// - Create a customer (v3) +// - Create a meter and feature for usage-based billing (v3) +// - Create and publish a plan with a unit rate card backed by the feature (v3) +// - Create a subscription for the customer (v3) +// - Advance the gathering invoice via the v1 InvoicePendingLinesAction to create a standard invoice +// - List the customer's invoices via the v1 SDK; separate standard from gathering +// - GET the standard invoice via the v3 endpoint and assert the response shape +// - GET the gathering invoice via the v3 endpoint → 404 (gathering invoices are not exposed) +// - GET with an unknown ID → 404 +func TestV3GetBillingInvoice(t *testing.T) { + c := newV3Client(t) + v1 := initClient(t) + + var ( + customerID string + customerKey string + planID string + feature *apiv3.Feature + invoiceID string // standard invoice ID + gatheringInvoiceID string // gathering invoice ID + ) + + t.Run("Should create a customer", func(t *testing.T) { + key := uniqueKey("inv_customer") + currency := apiv3.CurrencyCode("USD") + + status, customer, problem := c.CreateCustomer(apiv3.CreateCustomerRequest{ + Key: key, + Name: "Invoice Test Customer", + Currency: ¤cy, + }) + require.Equal(t, http.StatusCreated, status, "problem: %+v", problem) + require.NotNil(t, customer) + require.NotEmpty(t, customer.Id) + + customerID = customer.Id + customerKey = key + }) + + t.Run("Should create a meter and a feature for usage-based billing", func(t *testing.T) { + status, meter, problem := c.CreateMeter(apiv3.CreateMeterRequest{ + Key: uniqueKey("inv_meter"), + Name: "Invoice Test Meter", + Aggregation: apiv3.MeterAggregationCount, + EventType: uniqueKey("inv_event"), + }) + require.Equal(t, http.StatusCreated, status, "problem: %+v", problem) + require.NotNil(t, meter) + + status, f, problem := c.CreateFeature(apiv3.CreateFeatureRequest{ + Key: uniqueKey("inv_feature"), + Name: "Invoice Test Feature", + Meter: &apiv3.FeatureMeterReference{Id: meter.Id}, + }) + require.Equal(t, http.StatusCreated, status, "problem: %+v", problem) + require.NotNil(t, f) + + feature = f + }) + + t.Run("Should create and publish a plan with a unit rate card", func(t *testing.T) { + require.NotNil(t, feature, "depends on feature creation") + + status, plan, problem := c.CreatePlan(apiv3.CreatePlanRequest{ + Key: uniqueKey("inv_plan"), + Name: "Invoice Test Plan", + Currency: "USD", + BillingCadence: apiv3.ISO8601Duration("P1M"), + Phases: []apiv3.BillingPlanPhase{{ + Key: "phase_1", + Name: "Test Phase", + RateCards: []apiv3.BillingRateCard{validUnitRateCard(*feature)}, + }}, + }) + require.Equal(t, http.StatusCreated, status, "problem: %+v", problem) + require.NotNil(t, plan) + + planID = plan.Id + + status, plan, problem = c.PublishPlan(planID) + require.Equal(t, http.StatusOK, status, "problem: %+v", problem) + require.NotNil(t, plan) + assert.Equal(t, apiv3.BillingPlanStatusActive, plan.Status) + }) + + t.Run("Should create a subscription for the customer", func(t *testing.T) { + require.NotEmpty(t, customerID, "depends on customer creation") + require.NotEmpty(t, planID, "depends on plan creation") + + status, sub, problem := c.CreateSubscription(apiv3.BillingSubscriptionCreate{ + Customer: struct { + Id *apiv3.ULID `json:"id,omitempty"` + Key *apiv3.ExternalResourceKey `json:"key,omitempty"` + }{ + Id: lo.ToPtr(customerID), + }, + Plan: struct { + Id *apiv3.ULID `json:"id,omitempty"` + Key *apiv3.ResourceKey `json:"key,omitempty"` + Version *int `json:"version,omitempty"` + }{ + Id: lo.ToPtr(planID), + }, + }) + require.Equal(t, http.StatusCreated, status, "problem: %+v", problem) + require.NotNil(t, sub) + }) + + t.Run("Should create a single gathering invoice", func(t *testing.T) { + require.NotEmpty(t, customerID, "depends on customer creation") + + now := time.Now().UTC() + price := api.RateCardUsageBasedPrice{} + require.NoError(t, price.FromFlatPriceWithPaymentTerm(api.FlatPriceWithPaymentTerm{ + Amount: api.Numeric("10.00"), + Type: api.FlatPriceWithPaymentTermTypeFlat, + PaymentTerm: lo.ToPtr(api.PricePaymentTermInAdvance), + })) + + lineResp, err := v1.CreatePendingInvoiceLineWithResponse(t.Context(), customerID, api.InvoicePendingLineCreateInput{ + Currency: "USD", + Lines: []api.InvoicePendingLineCreate{ + { + Name: uniqueKey("inv_gathering_line_name"), + InvoiceAt: now.Add(-10 * time.Hour), + Period: api.Period{ + From: now.Add(-24 * time.Hour), + To: now.Add(time.Hour), + }, + Price: &price, + }, + }, + }) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, lineResp.StatusCode(), "line: %s", string(lineResp.Body)) + require.NotNil(t, lineResp.JSON201) + + gatheringInvoiceID = (*lineResp.JSON201).Invoice.Id + require.NotEmpty(t, gatheringInvoiceID) + }) + + t.Run("Should create a single standard invoice", func(t *testing.T) { + require.NotEmpty(t, customerID, "depends on customer creation") + + now := time.Now().UTC() + price := api.RateCardUsageBasedPrice{} + require.NoError(t, price.FromFlatPriceWithPaymentTerm(api.FlatPriceWithPaymentTerm{ + Amount: api.Numeric("10.00"), + Type: api.FlatPriceWithPaymentTermTypeFlat, + PaymentTerm: lo.ToPtr(api.PricePaymentTermInAdvance), + })) + + lineResp, err := v1.CreatePendingInvoiceLineWithResponse(t.Context(), customerID, api.InvoicePendingLineCreateInput{ + Currency: "USD", + Lines: []api.InvoicePendingLineCreate{ + { + Name: uniqueKey("inv_std_line_name"), + InvoiceAt: now.Add(-10 * time.Hour), + Period: api.Period{ + From: now.Add(-24 * time.Hour), + To: now.Add(time.Hour), + }, + Price: &price, + }, + }, + }) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, lineResp.StatusCode(), "line: %s", string(lineResp.Body)) + require.NotNil(t, lineResp.JSON201) + + resp, err := v1.InvoicePendingLinesActionWithResponse(t.Context(), api.InvoicePendingLinesActionInput{ + CustomerId: customerID, + ProgressiveBillingOverride: lo.ToPtr(true), + AsOf: lo.ToPtr(now.Add(-1 * time.Hour)), + }) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, resp.StatusCode(), "advance: %s", string(resp.Body)) + require.NotNil(t, resp.JSON201) + require.NotEmpty(t, *resp.JSON201, "expected at least one standard invoice to be created") + + invoiceID = (*resp.JSON201)[0].Id + require.NotEmpty(t, invoiceID) + }) + + t.Run("Should list invoices and find one for the customer via v1 SDK", func(t *testing.T) { + require.NotEmpty(t, customerID, "depends on customer creation") + + customers := api.InvoiceListParamsCustomers{customerID} + listResp, err := v1.ListInvoicesWithResponse(t.Context(), &api.ListInvoicesParams{ + Customers: &customers, + }) + require.NoError(t, err) + require.Equal(t, http.StatusOK, listResp.StatusCode(), "list invoices: %s", string(listResp.Body)) + require.NotNil(t, listResp.JSON200) + require.NotEmpty(t, listResp.JSON200.Items, "expected at least one invoice for customer %s (key: %s)", customerID, customerKey) + + _, foundStandard := lo.Find(listResp.JSON200.Items, func(inv api.Invoice) bool { + return inv.Status != api.InvoiceStatusGathering + }) + require.True(t, foundStandard, "expected at least one non-gathering invoice in the list") + }) + + t.Run("Should return the invoice via v3 GET", func(t *testing.T) { + require.NotEmpty(t, invoiceID, "depends on invoice advance step") + + status, inv, problem := c.GetBillingInvoice(invoiceID) + require.Equal(t, http.StatusOK, status, "problem: %+v", problem) + require.NotNil(t, inv) + + // The union must decode as a standard invoice. + stdInv, err := inv.AsBillingInvoiceStandard() + require.NoError(t, err, "expected invoice to decode as BillingInvoiceStandard") + + assert.Equal(t, invoiceID, stdInv.Id) + assert.Equal(t, apiv3.BillingInvoiceStandardTypeStandard, stdInv.Type) + assert.Equal(t, apiv3.CurrencyCode("USD"), stdInv.Currency) + assert.NotEmpty(t, stdInv.Status) + assert.NotEmpty(t, stdInv.CreatedAt) + }) + + t.Run("Should return 404 for the gathering invoice", func(t *testing.T) { + if gatheringInvoiceID == "" { + t.Skip("no gathering invoice found in the list; skipping") + } + + status, inv, problem := c.GetBillingInvoice(gatheringInvoiceID) + assert.Equal(t, http.StatusNotFound, status, "body: %+v", inv) + assert.Nil(t, inv) + assert.NotNil(t, problem) + }) + + t.Run("Should return 404 for an unknown invoice ID", func(t *testing.T) { + status, inv, problem := c.GetBillingInvoice("01JAAAAAAAAAAAAAAAAAAAAAAA") + assert.Equal(t, http.StatusNotFound, status) + assert.Nil(t, inv) + assert.NotNil(t, problem) + }) +} diff --git a/e2e/v3helpers_test.go b/e2e/v3helpers_test.go index b9c0a95a64..d50507f24c 100644 --- a/e2e/v3helpers_test.go +++ b/e2e/v3helpers_test.go @@ -307,6 +307,13 @@ func (c *v3Client) CreateSubscription(body apiv3.BillingSubscriptionCreate) (int return decodeTyped[apiv3.BillingSubscription](c, status, raw, problem, http.StatusCreated) } +// --- Billing invoices --- + +func (c *v3Client) GetBillingInvoice(invoiceID string) (int, *apiv3.BillingInvoice, *v3Problem) { + status, raw, problem := c.do(http.MethodGet, "/billing/invoices/"+invoiceID, nil) + return decodeTyped[apiv3.BillingInvoice](c, status, raw, problem, http.StatusOK) +} + // --- List pagination options --- // listOptions controls pagination query params for list endpoints. The server