This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Official Java SDK for FiscalAPI - a Mexican CFDI electronic invoicing service (SAT integration). Provides CFDI 4.0 invoicing, certificate management, mass downloads, payroll, and SAT catalog queries. Published to Maven Central as com.fiscalapi:fiscalapi.
mvn clean compile # Compile
mvn package # Create JAR
mvn clean deploy -Prelease # Deploy to Maven Central (requires GPG + settings.xml credentials)No unit tests exist in this project currently. No linting or formatting tools are configured.
FiscalApiClient.create(FiscalApiSettings) - Factory method creating the main client with all 11 services.
IFiscalApiClient (facade)
├── getInvoiceService() → IInvoiceService (cancel, status, getPdf, send, getXml)
├── getPersonService() → IPersonService
├── getProductService() → IProductService
├── getTaxFileService() → ITaxFileService (getDefaultReferences, getDefaultValues)
├── getCatalogService() → ICatalogService (custom search/query)
├── getApiKeyService() → IApiKeyService
├── getStampService() → IStampService (transfer, withdraw; creditType selects stamps or validation credits)
├── getSatValidationService() → ISatValidationService (getTypes, getTypeById, getStatuses, validate)
├── getManifestService() → IManifestService (sign; firma la carta manifiesto con la FIEL)
├── getDownloadCatalogService() → IDownloadCatalogService
├── getDownloadRuleService() → IDownloadRuleService
└── getDownloadRequestService() → IDownloadRequestService (cancel, retry, delete)
Services over a CRUD resource extend BaseFiscalApiService<T>, which implements standard CRUD:
getList(pageNumber, pageSize)→ApiResponse<PagedList<T>>getById(id, details)→ApiResponse<T>create(model)→ApiResponse<T>update(model)→ApiResponse<T>delete(id)→ApiResponse<Boolean>
Subclasses must implement getTypeParameterClass() to return the entity type for Jackson deserialization.
SatValidationService and ManifestService are the exception: sat-validations and manifests are not CRUD resources, so they implement their interfaces directly and build their own endpoint, the same way EmployerService and EmployeeService do for their nested resources. ManifestService.sign posts to manifests and reuses the existing FileResponse model, which already matches the API's file payload.
SerializableDto (toString() returns pretty-printed JSON)
→ AuditableDto (createdAt, updatedAt: LocalDateTime)
→ BaseDto (id: String)
All models extend BaseDto. Responses wrapped in ApiResponse<T>.
OkHttpClientFactory- Creates/caches OkHttpClient instances with auth headers (X-API-KEY, X-TENANT-KEY, X-API-VERSION, X-TIME-ZONE). Cache key covers api key, tenant, url, api version and time zone. Default timezone: America/Mexico_City.FiscalApiHttpClient- Wraps OkHttp with Jackson. Deserialization is driven by a JacksonJavaType, so generic shapes keep their element type:get/post/put/deletefor single objects,getList/postListfor JSON arrays andgetPagedListfor paged responses. ObjectMapper configured with:JavaTimeModule(LocalDateTime/ZonedDateTime support)FAIL_ON_UNKNOWN_PROPERTIES = falseWRITE_BIGDECIMAL_AS_PLAIN = true- Non-null serialization inclusion
- Custom
BigDecimalSerializerinserialization/(avoids scientific notation)
Decimal scale is load-bearing. BigDecimalSerializer writes toPlainString() as a JSON string, so the scale survives the wire. It is not registered globally: every new BigDecimal field needs @JsonSerialize(using = BigDecimalSerializer.class) on the field itself. Losing the trailing zeros makes the PAC reject the CFDI - CCE122 when TotalUSD is not 2 decimals, CFDI40179 when TasaOCuota is not 6. Callers must build values from strings (new BigDecimal("0.160000")), never from a double.
abstractions/- Service interfaces (all prefixed withI)common/- ApiResponse, PagedList, FiscalApiSettings, BaseDto hierarchyhttp/- HTTP client implementationmodels/- All DTOsmodels/invoicing/- Invoice, InvoiceItem, InvoiceIssuer, InvoiceRecipient, etc.models/invoicing/payroll/- 13 payroll CFDI types (Payroll, EmployeeData, PayrollEarning, etc.)models/invoicing/paymentComplement/- Payment complement modelsmodels/invoicing/localTaxes/- Local tax modelsmodels/invoicing/foreignTrade/- Comercio Exterior complement models (all prefixedComercioExterior*to avoid colliding with thebillOfLadingtypes). The emisor address is catalog-based (coloniaId,estadoId,codigoPostalId) while the receptor/destinatario addresses are free text (colonia,estado,codigoPostal) - that asymmetry mirrors the backend and must not be collapsed into one shared type.models/manifests/-SignManifestRequest(base64Cer, base64Key, password)models/downloading/- Mass download modelsmodels/satValidations/- SAT validation models and theSatValidationTypeIds/SatValidationStatusIdsconstants
services/- Service implementationsserialization/- Custom Jackson serializersexamples/- Usage examples (payroll, local taxes, bill of lading, stamps, SAT validations, comercio exterior, manifests). They live insrc/main/java, so they ship in the published jar and must compile. Credentials are placeholders (<API_KEY>,<TENANT_KEY>); never commit a real key.
The SDK supports two invoicing modes (see examples/):
- By references - Pass entity IDs, server resolves full data
- By values - Pass complete entity data inline
FiscalApiSettings settings = new FiscalApiSettings();
settings.setApiUrl("https://test.fiscalapi.com"); // or https://live.fiscalapi.com
settings.setApiKey("sk_test_...");
settings.setTenant("...");
settings.setDebugMode(true); // Logs requests/responses to console
// settings.setApiVersion("v4"); // default
// settings.setTimeZone("America/Mexico_City"); // default
FiscalApiClient client = FiscalApiClient.create(settings);Spring Boot integration: Use @Value properties + @Bean registration (see README.md for full pattern).
{apiUrl}/api/{apiVersion}/{resource}/{id?}/{action?}
Example: POST api/v4/invoices, GET api/v4/invoices/{id}?details=true
GitHub Actions workflow (.github/workflows/deploy.yml): manual dispatch, builds with Java 8 Temurin, signs with GPG, deploys to Maven Central.
- OkHttp3 4.12.0 (HTTP)
- Jackson 2.14.2 + JSR310 module (JSON + Java 8 time)
- Java 8+ (source/target)