import { AccessTicket, TokenStore } from '@ar-agents/identity/wsaa'; import { W as WsfeEnv, C as CbteTipoCode, a as ConsultarComprobanteResult, U as UltimoComprobanteResult, D as DummyResult, S as SolicitarCaeInput, b as SolicitarCaeResult, c as WsfeError } from './types-YZrnSVLy.js'; export { A as AlicuotaIva, d as AlicuotaIvaCode, e as CbteAsociado, f as CbteTipo, g as Concepto, h as ConceptoCode, i as CondicionIvaReceptor, j as CondicionIvaReceptorCode, k as DocTipo, l as DocTipoCode, I as IvaItem, M as Moneda, m as MonedaCode, O as OpcionalItem, T as TributoItem, n as WsfeEvento, o as WsfeObservacion, p as WsfeResultado, q as describeCbteTipo } from './types-YZrnSVLy.js'; import { ToolSet } from 'ai'; import { ArAgentsError } from '@ar-agents/core'; /** * AFIP/ARCA WSFE (Web Service de Factura Electrónica) operations. * * These build SOAP envelopes, POST them to AFIP, and parse the responses. * Reuses `fetchWithRetry` from `@ar-agents/identity/wsaa` for production * robustez (timeout / retry / SOAP-fault detection / observability hook). * * # Endpoints * * - **Producción**: `https://servicios1.afip.gov.ar/wsfev1/service.asmx` * - **Homologación**: `https://wswhomo.afip.gov.ar/wsfev1/service.asmx` * * # WSDL targetNamespace * * `http://ar.gov.afip.dif.FEV1/` — note: SOAPAction headers must include the * full operation name (e.g., `"http://ar.gov.afip.dif.FEV1/FECAESolicitar"`). * * # Service authorization * * The `wsfe` service must be authorized in your ARCA panel: * "Administrador de Relaciones de Clave Fiscal" → "Nueva Relación" → * "AFIP" → "WebServices" → "Servicio Web de Facturación Electrónica" → * select your alias. Once authorized, the same X.509 cert that powers * `@ar-agents/identity` works against WSFE too. */ declare const WSFE_SERVICE_NAME: "wsfe"; interface CommonRequestOptions { ta: AccessTicket; env: WsfeEnv; cuit: string; endpointOverride?: string; fetchImpl?: typeof fetch; requestTimeoutMs?: number; maxRetries?: number; onCall?: (event: { label: string; durationMs: number; httpStatus: number | null; retried: number; success: boolean; }) => void; } /** * Health check. Returns the status of AFIP's app/db/auth servers. * Should return all "OK" when WSFE is up. Use for /health endpoints and as * a pre-emission gate when you want to fail fast. * * Doesn't require auth — but the operation still needs CUIT in the SOAP body * per AFIP's WSDL contract (we send it through `callWsfe`). */ declare function dummy(opts: CommonRequestOptions): Promise; /** * Returns the last authorized comprobante number for a (PtoVta, CbteTipo) * pair. Returns 0 when no comprobante has ever been authorized — your next * emission then uses `cbteDesde: 1`. * * # Common usage * ```ts * const last = await consultarUltimoAutorizado({ * ta, env, cuit, * ptoVta: 1, cbteTipo: CbteTipo.FACTURA_C * }); * const next = last.cbteNro + 1; * await solicitarCAE({ ..., cbteDesde: next, cbteHasta: next }); * ``` */ declare function consultarUltimoAutorizado(opts: CommonRequestOptions & { ptoVta: number; cbteTipo: CbteTipoCode; }): Promise; /** * Look up the full details of a previously-authorized comprobante. Use this * to verify a CAE is valid and matches the data you have on record (e.g., * after migrating from another system). */ declare function consultarComprobante(opts: CommonRequestOptions & { ptoVta: number; cbteTipo: CbteTipoCode; cbteNro: number; }): Promise; declare function solicitarCAE(opts: CommonRequestOptions & SolicitarCaeInput): Promise; interface CatalogItem { id: number | string; desc: string; fchDesde?: string; fchHasta?: string; } /** Get the live AFIP comprobante-types catalog. */ declare function getTiposCbte(opts: CommonRequestOptions): Promise; /** Get the live AFIP document-types catalog. */ declare function getTiposDoc(opts: CommonRequestOptions): Promise; /** Get the live AFIP IVA-rates catalog. */ declare function getTiposIva(opts: CommonRequestOptions): Promise; /** Get the live AFIP concepto catalog (Productos / Servicios / both). */ declare function getTiposConcepto(opts: CommonRequestOptions): Promise; /** Get the live AFIP currencies catalog. */ declare function getTiposMonedas(opts: CommonRequestOptions): Promise; /** * Get the AFIP-published exchange rate for a foreign currency vs ARS. * Required when emitting Factura E or any multi-currency invoice. */ declare function getCotizacion(opts: CommonRequestOptions & { monId: string; }): Promise<{ monId: string; cotiz: number; fchCotiz: string; }>; interface WsfeClientOptions { /** X.509 cert PEM file path. Mutually exclusive with `certPem`. */ certPath?: string; /** RSA private key PEM file path. Mutually exclusive with `keyPem`. */ keyPath?: string; /** X.509 cert as a PEM string (for serverless: read from env var). */ certPem?: string; /** RSA private key as a PEM string. */ keyPem?: string; /** * The CUIT whose Clave Fiscal authorized the certificate. Goes in every * request as `Cuit` and is the issuer of all comprobantes emitted. */ cuit: string; /** "homo" for sandbox; "prod" for live. */ env: WsfeEnv; /** Override TA storage for multi-process setups (Redis, DB, etc.). */ tokenStore?: TokenStore; /** Override WSAA URL (testing only). */ wsaaEndpoint?: string; /** Override WSFE URL (testing only). */ wsfeEndpoint?: string; /** Custom fetch (testing). */ fetchImpl?: typeof fetch; /** Per-request timeout in ms. Default 30s. */ requestTimeoutMs?: number; /** Retries on 5xx + transient errors. Default 1. */ maxRetries?: number; /** * Observability hook fired after every WSAA + WSFE request. */ onCall?: (event: { label: string; durationMs: number; httpStatus: number | null; retried: number; success: boolean; }) => void; } declare class WsfeClient { private readonly cache; private readonly cuit; private readonly env; private readonly wsfeEndpoint; private readonly fetchImpl; private readonly requestTimeoutMs; private readonly maxRetries; private readonly onCall; constructor(options: WsfeClientOptions); private commonOps; /** AFIP WSFE health check. Returns `{ appServer, dbServer, authServer }`. */ dummy(): Promise; /** * Get the last authorized comprobante number for a (PtoVta, CbteTipo) pair. * Use `result.cbteNro + 1` as the next emission's `cbteDesde`. */ consultarUltimoAutorizado(ptoVta: number, cbteTipo: CbteTipoCode): Promise; /** Look up a previously-authorized comprobante by its number. */ consultarComprobante(ptoVta: number, cbteTipo: CbteTipoCode, cbteNro: number): Promise; /** * Solicit a CAE (Código de Autorización Electrónico) for a single * comprobante. The PRIMARY emission method. */ solicitarCAE(input: SolicitarCaeInput): Promise; /** Live AFIP catalog of comprobante types. */ getTiposCbte(): Promise; /** Live AFIP catalog of document types. */ getTiposDoc(): Promise; /** Live AFIP catalog of IVA rates. */ getTiposIva(): Promise; /** Live AFIP catalog of conceptos. */ getTiposConcepto(): Promise; /** Live AFIP catalog of currencies. */ getTiposMonedas(): Promise; /** Get the AFIP-published exchange rate for a foreign currency vs ARS. */ getCotizacion(monId: string): Promise<{ monId: string; cotiz: number; fchCotiz: string; }>; } interface FacturacionToolsOptions { /** * The configured `WsfeClient`. If you don't pass one, the tools return * `{ available: false, error: }` instead of crashing. * Useful for stub deployments or local dev without a cert. */ wsfe?: WsfeClient; /** * Override the agent-facing tool descriptions. Useful when the agent's * primary language isn't English/Spanish. */ descriptions?: Partial>; /** * Default punto de venta. When set, agents can omit `ptoVta` from inputs. * Most SaaS issue from a single PtoVta, passing it once at boot avoids * the agent having to remember it. */ defaultPtoVta?: number; } type FacturacionToolName = "emitir_factura" | "consultar_ultimo_comprobante" | "consultar_factura_emitida" | "obtener_tipos_comprobante" | "obtener_tipos_documento" | "obtener_alicuotas_iva" | "obtener_tipos_concepto" | "obtener_tipos_moneda" | "obtener_cotizacion" | "health_check_afip"; declare function facturacionTools(options?: FacturacionToolsOptions): ToolSet; /** * Pre-flight validation for `SolicitarCaeInput`. Catches the most common * AFIP rejection reasons LOCALLY so you don't burn a network round-trip on * a malformed request. * * The list here is curated from real production rejection patterns — every * check corresponds to an AFIP error code documented in `AGENTS.md`. * * Returns `{ valid: true }` when the input is internally consistent; * returns `{ valid: false, errors: [...] }` with Spanish-language error * messages otherwise. */ interface ValidationError { field: string; message: string; } interface ValidationResult { valid: boolean; errors: ValidationError[]; } /** * Validate a `SolicitarCaeInput` against AFIP's known constraints. Run this * BEFORE calling `solicitarCAE()` to catch errors locally. * * @example * ```ts * const v = validateSolicitarCae(input); * if (!v.valid) { * throw new WsfeValidationError( * `Factura inválida: ${v.errors.map(e => e.message).join("; ")}`, * v.errors, * ); * } * await wsfe.solicitarCAE(input); * ``` */ declare function validateSolicitarCae(input: SolicitarCaeInput): ValidationResult; /** * Errors emitted by `@ar-agents/facturacion` adapters and helpers. * * Extends `ArAgentsError` from `@ar-agents/core` so the family contract * (code / retryable / context) is uniform. */ type FacturacionErrorCode = "wsfe_not_configured" | "wsfe_validation_error" | "wsfe_authentication_failed" | "wsfe_request_rejected" | "wsfe_service_unavailable" | "wsfe_unknown_error"; declare class FacturacionError extends ArAgentsError { readonly code: FacturacionErrorCode; readonly details?: unknown; constructor(code: FacturacionErrorCode, message: string, details?: unknown); } /** * Thrown when the WsfeClient is constructed without the required cert/key * or CUIT. Surface the message verbatim — it's actionable. */ declare class WsfeNotConfiguredError extends FacturacionError { constructor(); } /** * Thrown when the request fails AFIP's pre-emission validation (e.g., the * `ImpTotal` doesn't equal the sum of components). Surface the message — * it tells the user exactly what to fix. */ declare class WsfeValidationError extends FacturacionError { errors?: WsfeError[] | undefined; constructor(message: string, errors?: WsfeError[] | undefined); } /** * Thrown when AFIP rejects the request (Resultado: "R"). Carries the * top-level errors and per-detail observaciones for diagnosis. */ declare class WsfeRejectedError extends FacturacionError { errors: WsfeError[]; observaciones: WsfeError[]; constructor(message: string, errors: WsfeError[], observaciones: WsfeError[]); } export { type CatalogItem, CbteTipoCode, ConsultarComprobanteResult, DummyResult, FacturacionError, type FacturacionErrorCode, type FacturacionToolName, type FacturacionToolsOptions, SolicitarCaeInput, SolicitarCaeResult, UltimoComprobanteResult, type ValidationError, type ValidationResult, WSFE_SERVICE_NAME, WsfeClient, type WsfeClientOptions, WsfeEnv, WsfeError, WsfeNotConfiguredError, WsfeRejectedError, WsfeValidationError, consultarComprobante, consultarUltimoAutorizado, dummy, facturacionTools, getCotizacion, getTiposCbte, getTiposConcepto, getTiposDoc, getTiposIva, getTiposMonedas, solicitarCAE, validateSolicitarCae };