Skip to content

Commit ee87487

Browse files
JesusMendozaclaude
authored andcommitted
Add StampService export and update documentation
- Add StampService to services/__init__.py exports - Update CLAUDE.md with complete service list, example files, and new sections - Add StampService documentation to payroll-requirements.md - Update implementation checklist with completed items - Bump version to 4.0.360 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b55f30d commit ee87487

File tree

4 files changed

+165
-29
lines changed

4 files changed

+165
-29
lines changed

CLAUDE.md

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## Project Overview
66

7-
FiscalAPI Python SDK - Official SDK for integrating with FiscalAPI, Mexico's electronic invoicing (CFDI 4.0) and fiscal services platform. Simplifies integration with SAT (Mexico's tax authority) for invoice creation, tax certificate management, and bulk downloads.
7+
FiscalAPI Python SDK - Official SDK for integrating with FiscalAPI, Mexico's electronic invoicing (CFDI 4.0) and fiscal services platform. Simplifies integration with SAT (Mexico's tax authority) for invoice creation, tax certificate management, payroll invoices (CFDI de Nomina), and bulk downloads.
88

99
## Build and Publish Commands
1010

@@ -21,9 +21,12 @@ twine check dist/*
2121

2222
# Publish to PyPI (requires PYPI_API_TOKEN)
2323
twine upload --username __token__ --password $PYPI_API_TOKEN dist/*
24+
25+
# Clean build artifacts
26+
rm -rf dist build fiscalapi.egg-info
2427
```
2528

26-
**Version management:** Version is defined in `setup.py`. CI/CD requires the version to match the git tag (vX.Y.Z format).
29+
**Version management:** Version is defined in `setup.py` (line 5: `VERSION = "X.Y.Z"`). CI/CD is manually triggered via `workflow_dispatch`.
2730

2831
## Architecture
2932

@@ -35,13 +38,16 @@ FiscalApiClient (Facade)
3538
├── FiscalApiSettings (Configuration)
3639
3740
└── Services (all inherit from BaseService)
38-
├── invoice_service.py → Invoice CRUD, PDF, XML, cancellation, SAT status
39-
├── people_service.py → Person/entity management
40-
├── product_service.py → Product/service catalog
41-
├── tax_file_servive.py → CSD/FIEL certificate uploads
42-
├── api_key_service.py → API key management
43-
├── catalog_service.py → SAT catalog searches
44-
└── download_*_service.py → Bulk download management
41+
├── invoice_service.py → Invoice CRUD, PDF, XML, cancellation, SAT status
42+
├── people_service.py → Person/entity management
43+
│ ├── employee_service.py → Employee data (sub-service for payroll)
44+
│ └── employer_service.py → Employer data (sub-service for payroll)
45+
├── product_service.py → Product/service catalog
46+
├── tax_file_service.py → CSD/FIEL certificate uploads
47+
├── api_key_service.py → API key management
48+
├── catalog_service.py → SAT catalog searches
49+
├── stamp_service.py → Stamp (timbres) transactions
50+
└── download_*_service.py → Bulk download management
4551
```
4652

4753
**Entry Point Pattern:**
@@ -54,23 +60,35 @@ client = FiscalApiClient(settings=settings)
5460
# Access services through client
5561
client.invoices.create(invoice)
5662
client.people.get_list(page_num, page_size)
63+
client.stamps.get_list(page_num, page_size)
5764
```
5865

5966
### Models (Pydantic v2)
6067

6168
Located in `fiscalapi/models/`:
6269
- **common_models.py** - Base DTOs: `ApiResponse[T]`, `PagedList[T]`, `ValidationFailure`, `FiscalApiSettings`
63-
- **fiscalapi_models.py** - Domain models: `Invoice`, `Person`, `Product`, `TaxFile`, and related entities
70+
- **fiscalapi_models.py** - Domain models: `Invoice`, `Person`, `Product`, `TaxFile`, payroll complements, stamp transactions
6471

6572
**Key Pattern - Field Aliasing:** Models use Pydantic `Field(alias="...")` for API JSON field mapping. When serializing, use `by_alias=True` and `exclude_none=True`.
6673

74+
### Public API Exports
75+
76+
All types are exported from the main package (`fiscalapi/__init__.py`):
77+
```python
78+
from fiscalapi import Invoice, Person, Product, FiscalApiClient, ApiResponse
79+
```
80+
81+
Also available via submodules:
82+
```python
83+
from fiscalapi.models import Invoice, Person
84+
from fiscalapi.services import InvoiceService, StampService
85+
```
86+
6787
### Two Operation Modes
6888

6989
1. **By References** - Use pre-created object IDs (faster, less data transfer)
7090
2. **By Values** - Send all field data directly (self-contained, no prior setup)
7191

72-
See `examples.py` and README.md for detailed examples of both modes.
73-
7492
### Request/Response Flow
7593

7694
1. Service method receives domain object
@@ -86,12 +104,22 @@ See `examples.py` and README.md for detailed examples of both modes.
86104

87105
## Key Files
88106

89-
- `fiscalapi/__init__.py` - Central exports for all models and services
107+
- `fiscalapi/__init__.py` - Central exports for all 85 public types (models + services)
90108
- `fiscalapi/services/base_service.py` - HTTP client, serialization, response handling
91109
- `fiscalapi/services/fiscalapi_client.py` - Main client facade
92-
- `examples.py` - 3600+ lines of usage examples (commented out)
93110
- `setup.py` - Package metadata, version, and dependencies
94111

112+
## Example Files
113+
114+
- `examples.py` - General usage examples (all invoice types)
115+
- `ejemplos-facturas-de-nomina.py` - Payroll invoice examples (13 types)
116+
- `ejemplos-facturas-de-complemento-pago.py` - Payment complement examples
117+
- `ejemplos-timbres.py` - Stamp service examples
118+
119+
## Reference Documentation
120+
121+
- `payroll-requirements.md` - Detailed payroll implementation spec with all models, services, and SAT codes
122+
95123
## Dependencies
96124

97125
- Python >= 3.9 (CI/CD uses Python 3.9.13)
@@ -102,7 +130,7 @@ See `examples.py` and README.md for detailed examples of both modes.
102130
## Development Setup
103131

104132
```bash
105-
# Create virtual environment with Python 3.9.13
133+
# Create virtual environment with Python 3.9+
106134
python -m venv venv
107135

108136
# Activate (Windows)
@@ -130,8 +158,15 @@ pip install -r requirements.txt
130158
- Use `Optional[T]` only for truly optional fields
131159
- `ApiResponse[T]` supports any type T (not just BaseModel subclasses)
132160

161+
### Adding New Services
162+
163+
1. Create service class inheriting from `BaseService` in `fiscalapi/services/`
164+
2. Export from `fiscalapi/services/__init__.py`
165+
3. Export from `fiscalapi/__init__.py`
166+
4. Add property to `FiscalApiClient` class
167+
133168
## External Resources
134169

135170
- API Documentation: https://docs.fiscalapi.com
136171
- Test Certificates: https://docs.fiscalapi.com/recursos/descargas
137-
- Postman Collection: Available in docs
172+
- Postman Collection: https://documenter.getpostman.com/view/4346593/2sB2j4eqXr

fiscalapi/services/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .invoice_service import InvoiceService
1313
from .people_service import PeopleService
1414
from .product_service import ProductService
15+
from .stamp_service import StampService
1516
from .tax_file_service import TaxFileService
1617

1718
__all__ = [
@@ -27,5 +28,6 @@
2728
"InvoiceService",
2829
"PeopleService",
2930
"ProductService",
31+
"StampService",
3032
"TaxFileService",
3133
]

payroll-requirements.md

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ This document describes the requirements for implementing payroll invoice (CFDI
99
1. [Overview](#overview)
1010
2. [New Models Required](#new-models-required)
1111
3. [New Services Required](#new-services-required)
12+
- [EmployeeService](#1-employeeservice)
13+
- [EmployerService](#2-employerservice)
14+
- [PeopleService Updates](#3-peopleservice-updates)
15+
- [StampService](#4-stampservice)
1216
4. [Person Model Updates](#person-model-updates)
1317
5. [Invoice Model Updates](#invoice-model-updates)
1418
6. [Two Operation Modes](#two-operation-modes)
@@ -248,6 +252,82 @@ client.people.employee -> EmployeeService
248252
client.people.employer -> EmployerService
249253
```
250254

255+
### 4. StampService
256+
257+
Service for managing stamp transactions (timbres fiscales). Stamps are the digital fiscal tokens required to certify CFDI invoices.
258+
259+
```
260+
Endpoint pattern: stamps
261+
```
262+
263+
| Method | HTTP | Endpoint | Description |
264+
|--------|------|----------|-------------|
265+
| get_list(page_number, page_size) | GET | stamps?pageNumber={n}&pageSize={s} | List stamp transactions with pagination |
266+
| get_by_id(transaction_id) | GET | stamps/{transactionId} | Get a stamp transaction by ID |
267+
| transfer_stamps(request) | POST | stamps | Transfer stamps from one person to another |
268+
| withdraw_stamps(request) | POST | stamps | Withdraw stamps (alias for transfer_stamps) |
269+
270+
#### Stamp Models
271+
272+
##### UserLookupDto
273+
274+
Lookup DTO for user/person references in stamp transactions.
275+
276+
| Field | JSON Alias | Type | Description |
277+
|-------|------------|------|-------------|
278+
| tin | tin | string | RFC of the user |
279+
| legal_name | legalName | string | Legal name of the user |
280+
281+
##### StampTransaction
282+
283+
Represents a stamp transfer/withdrawal transaction.
284+
285+
| Field | JSON Alias | Type | Description |
286+
|-------|------------|------|-------------|
287+
| consecutive | consecutive | int | Transaction consecutive number |
288+
| from_person | fromPerson | UserLookupDto | Source person of the transfer |
289+
| to_person | toPerson | UserLookupDto | Destination person of the transfer |
290+
| amount | amount | int | Number of stamps transferred |
291+
| transaction_type | transactionType | int | Type of transaction |
292+
| transaction_status | transactionStatus | int | Status of the transaction |
293+
| reference_id | referenceId | string | Transaction reference ID |
294+
| comments | comments | string | Transaction comments |
295+
296+
##### StampTransactionParams
297+
298+
Request parameters for stamp transfer/withdraw operations.
299+
300+
| Field | JSON Alias | Type | Required | Description |
301+
|-------|------------|------|----------|-------------|
302+
| from_person_id | fromPersonId | string | Yes | ID of the source person |
303+
| to_person_id | toPersonId | string | Yes | ID of the destination person |
304+
| amount | amount | int | Yes | Number of stamps to transfer |
305+
| comments | comments | string | No | Transfer comments |
306+
307+
#### Example: Transfer Stamps
308+
309+
```
310+
// Transfer 100 stamps from master account to sub-account
311+
params = StampTransactionParams(
312+
from_person_id: "master-account-id",
313+
to_person_id: "sub-account-id",
314+
amount: 100,
315+
comments: "Monthly stamp allocation"
316+
)
317+
318+
response = client.stamps.transfer_stamps(params)
319+
```
320+
321+
#### Example: List Stamp Transactions
322+
323+
```
324+
// Get paginated list of stamp transactions
325+
response = client.stamps.get_list(page_number=1, page_size=10)
326+
327+
for transaction in response.data.items:
328+
print(f"Transfer: {transaction.amount} stamps from {transaction.from_person.legal_name}")
329+
```
330+
251331
---
252332

253333
## Person Model Updates
@@ -475,6 +555,14 @@ POST /api/{version}/invoices
475555

476556
With `type_code: "N"` for payroll invoices.
477557

558+
### Stamp Endpoints
559+
560+
```
561+
GET /api/{version}/stamps?pageNumber={n}&pageSize={s}
562+
GET /api/{version}/stamps/{transactionId}
563+
POST /api/{version}/stamps
564+
```
565+
478566
---
479567

480568
## Field Mappings (JSON Aliases)
@@ -692,22 +780,33 @@ response = client.invoices.create(invoice)
692780

693781
## Implementation Checklist
694782

695-
- [ ] Add `curp` field to Person model
696-
- [ ] Create EmployeeData model
697-
- [ ] Create EmployerData model
698-
- [ ] Create InvoiceIssuerEmployerData model
699-
- [ ] Create InvoiceRecipientEmployeeData model
700-
- [ ] Create PayrollComplement and all sub-models
701-
- [ ] Add employer_data to InvoiceIssuer model
702-
- [ ] Add employee_data to InvoiceRecipient model
703-
- [ ] Add payroll to InvoiceComplement model
704-
- [ ] Create EmployeeService with CRUD operations
705-
- [ ] Create EmployerService with CRUD operations
706-
- [ ] Add employee and employer properties to PeopleService
783+
### Models
784+
- [x] Add `curp` field to Person model
785+
- [x] Create EmployeeData model
786+
- [x] Create EmployerData model
787+
- [x] Create InvoiceIssuerEmployerData model
788+
- [x] Create InvoiceRecipientEmployeeData model
789+
- [x] Create PayrollComplement and all sub-models
790+
- [x] Add employer_data to InvoiceIssuer model
791+
- [x] Add employee_data to InvoiceRecipient model
792+
- [x] Add payroll to InvoiceComplement model
793+
- [x] Create StampTransaction model
794+
- [x] Create StampTransactionParams model
795+
- [x] Create UserLookupDto model
796+
797+
### Services
798+
- [x] Create EmployeeService with CRUD operations
799+
- [x] Create EmployerService with CRUD operations
800+
- [x] Add employee and employer properties to PeopleService
801+
- [x] Create StampService with get_list, get_by_id, transfer_stamps, withdraw_stamps
802+
803+
### Examples & Testing
707804
- [ ] Create examples for all 13 payroll types (by values)
708805
- [ ] Create examples for all 13 payroll types (by references)
709806
- [ ] Create setup data methods for by-references mode
807+
- [ ] Create stamp service examples
710808
- [ ] Test all payroll types successfully
809+
- [ ] Test stamp transactions successfully
711810

712811
---
713812

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
from setuptools import setup, find_packages
44

5-
VERSION = "4.0.270"
5+
VERSION = "4.0.360"
66

77
DESCRIPTION = "Genera facturas CFDI válidas ante el SAT consumiendo el API de https://www.fiscalapi.com"
88

0 commit comments

Comments
 (0)