From bf48534b2cd78bd2fcdf63de10b1429fd20bfa0e Mon Sep 17 00:00:00 2001 From: "raul@facturapi.io" Date: Mon, 19 Oct 2026 19:37:27 -0600 Subject: [PATCH] fix(openapi): avoid incompatible schema intersections --- website/openapi_v2.en.yaml | 204 ++++++++++++++++++++++++++++++------- website/openapi_v2.yaml | 202 +++++++++++++++++++++++++++++------- 2 files changed, 338 insertions(+), 68 deletions(-) diff --git a/website/openapi_v2.en.yaml b/website/openapi_v2.en.yaml index 9749c8dee..46318ae8e 100644 --- a/website/openapi_v2.en.yaml +++ b/website/openapi_v2.en.yaml @@ -16423,25 +16423,51 @@ components: description: ISO 3166-1 alpha-3. CustomerUpdateInput: description: On update without createEditLink=true, omitted fields retain their value. A null value clears fields that accept null; an optional field can be omitted without necessarily accepting null. Null is not allowed for legal_name, tax_id, tax_system, or address. For email, phone, and the optional address fields street, exterior, interior, neighborhood, city, municipality, and state, empty or whitespace-only strings normalize to null. Empty postal codes are not accepted. - allOf: - - $ref: '#/components/schemas/CustomerEditableInput' - - type: object + type: object + properties: + legal_name: + type: string + minLength: 1 + description: | + Legal name or business name of the customer. *without* the corporate regime (e.g.: S.A. de C.V.). + example: Dunder Mifflin + tax_id: + type: string + minLength: 1 + example: ABC101010111 + description: | + In Mexican clients, it contains the customer's RFC. For foreigners, it is optional and represents the tax identification number, that is, the equivalent to the RFC in the customer's country. + email: + $ref: '#/components/schemas/CustomerEmailUpdateInput' + phone: *customer_phone + external_id: *customer_external_id_input + default_invoice_use: *customer_default_invoice_use_input + tax_system: + type: string + example: '601' + maxLength: 3 + minLength: 3 + description: | + Required for national clients. Key of the customer's tax regime, from the [Tax Regime Catalog](#tax-regime). + address: + type: object properties: - legal_name: + street: *customer_address_street_input + exterior: *customer_address_exterior_input + interior: *customer_address_interior_input + neighborhood: *customer_address_neighborhood_input + city: *customer_address_city_input + municipality: *customer_address_municipality_input + zip: type: string minLength: 1 - tax_id: + description: Postal code + example: '86500' + state: *customer_address_state_input + country: type: string - minLength: 1 - tax_system: - allOf: - - *customer_tax_system - - type: string - address: - type: object - properties: - country: - type: string + default: MEX + description: ISO 3166-1 alpha-3. CustomerUpdateWithEditLinkInput: description: With createEditLink=true, omitted fields retain their value and null clears the existing value, including fiscal fields. Non-null values must be valid. For email, phone, and the optional address fields street, exterior, interior, neighborhood, city, municipality, and state, empty or whitespace-only strings normalize to null. Empty postal codes are not accepted. type: object @@ -17376,11 +17402,102 @@ components: $ref: "#/components/schemas/InvoiceZipRequest" Invoice: title: Invoice - oneOf: - - $ref: '#/components/schemas/InvoiceStamped' - - $ref: '#/components/schemas/InvoiceDraft' - - $ref: '#/components/schemas/InvoicePending' - - $ref: '#/components/schemas/InvoiceFailed' + allOf: + - $ref: '#/components/schemas/ResourceAutoGeneratedProps' + - $ref: '#/components/schemas/InvoiceCommonProperties' + - anyOf: + - title: Stamped + type: object + required: [date, status, uuid, stamp] + properties: + status: + type: string + enum: [valid, canceled] + date: + type: string + format: date-time + uuid: + type: string + format: uuid + stamp: + type: object + description: Information about the digital fiscal stamp added by the PAC. + required: [date, sat_signature, sat_cert_number, signature, complement_string] + properties: + signature: + type: string + description: Digital stamp of the fiscal document. + date: + type: string + description: "SAT FechaTimbrado: local date and time without a timezone offset. Preserved as text." + example: "2026-09-17T06:59:16" + complement_string: + type: string + description: Original string of the fiscal stamp. + rfc_provider_cert: + type: string + description: Tax ID of the provider that certified the document. + sat_cert_number: + type: string + description: SAT certificate serial number used for stamping. + sat_signature: + type: string + description: Digital stamp of the fiscal document. + - title: Draft + type: object + required: [date, status] + properties: + status: + type: string + const: draft + date: + type: [string, 'null'] + format: date-time + description: Issue date in ISO8601 format. May be null for drafts. + uuid: + type: 'null' + stamp: + type: 'null' + - title: Pending + type: object + required: [date, status] + properties: + status: + type: string + const: pending + date: + type: [string, 'null'] + format: date-time + description: Issue date in ISO8601 format. May be null for drafts. + uuid: + type: [string, 'null'] + format: uuid + description: Fiscal folio of the invoice, assigned by the SAT. For unstamped drafts it can be null or omitted. + example: 39c85a3f-275b-4341-b259-e8971d9f8a94 + stamp: + anyOf: + - $ref: '#/components/schemas/Stamp' + - type: 'null' + - title: Failed + type: object + required: [date, status] + properties: + status: + type: string + const: failed + date: + type: [string, 'null'] + format: date-time + description: Issue date in ISO8601 format. May be null for drafts. + uuid: + type: [string, 'null'] + format: uuid + description: Fiscal folio of the invoice, assigned by the SAT. For unstamped drafts it can be null or omitted. + example: 39c85a3f-275b-4341-b259-e8971d9f8a94 + stamp: + anyOf: + - $ref: '#/components/schemas/Stamp' + - type: 'null' InvoiceStamped: title: Stamped allOf: @@ -17399,12 +17516,29 @@ components: type: string format: uuid stamp: - allOf: - - $ref: '#/components/schemas/Stamp' + type: object + description: Information about the digital fiscal stamp added by the PAC. required: [date, sat_signature, sat_cert_number, signature, complement_string] properties: + signature: + type: string + description: Digital stamp of the fiscal document. + date: + type: string + description: "SAT FechaTimbrado: local date and time without a timezone offset. Preserved as text." + example: "2026-09-17T06:59:16" complement_string: type: string + description: Original string of the fiscal stamp. + rfc_provider_cert: + type: string + description: Tax ID of the provider that certified the document. + sat_cert_number: + type: string + description: SAT certificate serial number used for stamping. + sat_signature: + type: string + description: Digital stamp of the fiscal document. InvoicePending: title: Pending allOf: @@ -17431,7 +17565,7 @@ components: required: [status] properties: status: - $ref: '#/components/schemas/InvoiceCommonProperties/properties/cancellation_status' + $ref: '#/components/schemas/InvoiceCancellationStatus' requested_at: type: string format: date-time @@ -17451,6 +17585,18 @@ components: type: string format: uuid description: UUID of the replacement invoice, when applicable. + InvoiceCancellationStatus: + type: string + enum: + - none + - verifying + - pending + - accepted + - rejected + - expired + description: | + Current status of the cancellation request, if it has been made. `verifying` means the SAT has received the request and is validating it; Facturapi will keep checking until it changes to a final status. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section. + example: none InvoiceDraft: title: Invoice object with draft status allOf: @@ -17506,17 +17652,7 @@ components: cancellation: $ref: '#/components/schemas/InvoiceCancellation' cancellation_status: - type: string - enum: - - none - - verifying - - pending - - accepted - - rejected - - expired - description: | - Current status of the cancellation request, if it has been made. `verifying` means the SAT has received the request and is validating it; Facturapi will keep checking until it changes to a final status. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section. - example: none + $ref: '#/components/schemas/InvoiceCancellationStatus' canceled_at: type: - string diff --git a/website/openapi_v2.yaml b/website/openapi_v2.yaml index 2249e199d..591aa9671 100644 --- a/website/openapi_v2.yaml +++ b/website/openapi_v2.yaml @@ -16423,25 +16423,49 @@ components: description: ISO 3166-1 alpha-3. CustomerUpdateInput: description: En una actualización sin createEditLink=true, los campos omitidos conservan su valor. Un valor null borra los campos que admiten null; un campo opcional puede omitirse sin que necesariamente admita null. No se permite null en legal_name, tax_id, tax_system ni address. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. - allOf: - - $ref: '#/components/schemas/CustomerEditableInput' - - type: object + type: object + properties: + legal_name: + type: string + minLength: 1 + description: | + Nombre Fiscal o Razón Social del cliente. *sin* el régimen societario (ej.: S.A. de C.V.). + example: Dunder Mifflin + tax_id: + type: string + minLength: 1 + example: ABC101010111 + description: En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + email: + $ref: '#/components/schemas/CustomerEmailUpdateInput' + phone: *customer_phone + external_id: *customer_external_id_input + default_invoice_use: *customer_default_invoice_use_input + tax_system: + type: string + example: '601' + maxLength: 3 + minLength: 3 + description: Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](#r%C3%A9gimen-fiscal). + address: + type: object properties: - legal_name: + street: *customer_address_street_input + exterior: *customer_address_exterior_input + interior: *customer_address_interior_input + neighborhood: *customer_address_neighborhood_input + city: *customer_address_city_input + municipality: *customer_address_municipality_input + zip: type: string minLength: 1 - tax_id: + description: Código postal + example: '86500' + state: *customer_address_state_input + country: type: string - minLength: 1 - tax_system: - allOf: - - *customer_tax_system - - type: string - address: - type: object - properties: - country: - type: string + default: MEX + description: ISO 3166-1 alpha-3. CustomerUpdateWithEditLinkInput: description: Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. type: object @@ -17330,11 +17354,102 @@ components: $ref: "#/components/schemas/InvoiceZipRequest" Invoice: title: Invoice - oneOf: - - $ref: '#/components/schemas/InvoiceStamped' - - $ref: '#/components/schemas/InvoiceDraft' - - $ref: '#/components/schemas/InvoicePending' - - $ref: '#/components/schemas/InvoiceFailed' + allOf: + - $ref: '#/components/schemas/ResourceAutoGeneratedProps' + - $ref: '#/components/schemas/InvoiceCommonProperties' + - anyOf: + - title: Timbrada + type: object + required: [date, status, uuid, stamp] + properties: + status: + type: string + enum: [valid, canceled] + date: + type: string + format: date-time + uuid: + type: string + format: uuid + stamp: + type: object + description: Información sobre el timbre fiscal digital agregado por el PAC. + required: [date, sat_signature, sat_cert_number, signature, complement_string] + properties: + signature: + type: string + description: Sello digital del comprobante fiscal. + date: + type: string + description: "FechaTimbrado del SAT: fecha y hora local sin offset de zona horaria. Se conserva como texto." + example: "2026-09-17T06:59:16" + complement_string: + type: string + description: Cadena original del timbre fiscal digital. + rfc_provider_cert: + type: string + description: RFC del proveedor que certificó el comprobante. + sat_cert_number: + type: string + description: Número de serie del certificado del SAT usado para timbrar. + sat_signature: + type: string + description: Sello digital del timbre fiscal digital. + - title: Borrador + type: object + required: [date, status] + properties: + status: + type: string + const: draft + date: + type: [string, 'null'] + format: date-time + description: Fecha de expedición en formato ISO8601. Puede ser null en borradores. + uuid: + type: 'null' + stamp: + type: 'null' + - title: Pendiente + type: object + required: [date, status] + properties: + status: + type: string + const: pending + date: + type: [string, 'null'] + format: date-time + description: Fecha de expedición en formato ISO8601. Puede ser null en borradores. + uuid: + type: [string, 'null'] + format: uuid + description: Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + example: 39c85a3f-275b-4341-b259-e8971d9f8a94 + stamp: + anyOf: + - $ref: '#/components/schemas/Stamp' + - type: 'null' + - title: Fallida + type: object + required: [date, status] + properties: + status: + type: string + const: failed + date: + type: [string, 'null'] + format: date-time + description: Fecha de expedición en formato ISO8601. Puede ser null en borradores. + uuid: + type: [string, 'null'] + format: uuid + description: Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + example: 39c85a3f-275b-4341-b259-e8971d9f8a94 + stamp: + anyOf: + - $ref: '#/components/schemas/Stamp' + - type: 'null' InvoiceStamped: title: Timbrada allOf: @@ -17353,12 +17468,29 @@ components: type: string format: uuid stamp: - allOf: - - $ref: '#/components/schemas/Stamp' + type: object + description: Información sobre el timbre fiscal digital agregado por el PAC. required: [date, sat_signature, sat_cert_number, signature, complement_string] properties: + signature: + type: string + description: Sello digital del comprobante fiscal. + date: + type: string + description: "FechaTimbrado del SAT: fecha y hora local sin offset de zona horaria. Se conserva como texto." + example: "2026-09-17T06:59:16" complement_string: type: string + description: Cadena original del timbre fiscal digital. + rfc_provider_cert: + type: string + description: RFC del proveedor que certificó el comprobante. + sat_cert_number: + type: string + description: Número de serie del certificado del SAT usado para timbrar. + sat_signature: + type: string + description: Sello digital del timbre fiscal digital. InvoicePending: title: Pendiente allOf: @@ -17385,7 +17517,7 @@ components: required: [status] properties: status: - $ref: '#/components/schemas/InvoiceCommonProperties/properties/cancellation_status' + $ref: '#/components/schemas/InvoiceCancellationStatus' requested_at: type: string format: date-time @@ -17405,6 +17537,18 @@ components: type: string format: uuid description: UUID de la factura sustituta, cuando aplica. + InvoiceCancellationStatus: + type: string + enum: + - none + - pending + - accepted + - rejected + - expired + - verifying + description: | + Estado actual de la solicitud de cancelación, en caso de haberla realizado. Puedes leer más a detalle en la sección de [Cancelar Factura](#tag/invoice/operation/deleteInvoice)). + example: none InvoiceDraft: title: Objeto Invoice con status draft allOf: @@ -17460,17 +17604,7 @@ components: cancellation: $ref: '#/components/schemas/InvoiceCancellation' cancellation_status: - type: string - enum: - - none - - pending - - accepted - - rejected - - expired - - verifying - description: | - Estado actual de la solicitud de cancelación, en caso de haberla realizado. Puedes leer más a detalle en la sección de [Cancelar Factura](#tag/invoice/operation/deleteInvoice)). - example: none + $ref: '#/components/schemas/InvoiceCancellationStatus' canceled_at: type: - string