# ESTI Bulgaria Integration Guide
## Overview
This module provides integration with the Bulgarian Unified Tourism Information System (ΠΠ‘Π’Π - ΠΠ΄ΠΈΠ½Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° ΡΡΡΠΈΡΡΠΈΡΠ΅ΡΠΊΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ). It supports two communication methods:
1. **CSV Export** - Generate CSV files for manual upload to ESTI
2. **RegiX Integration** - System-to-system automated communication via RegiX (requires certificates)
## Architecture
### Components
- **DTOs** (`app/Services/Esti/DTOs/`) - Data transfer objects for ESTI structures
- **CSV Export Service** (`app/Services/Esti/EstiCsvExportService.php`) - Handles CSV generation
- **RegiX Service** (`app/Services/Esti/EstiRegixService.php`) - Handles RegiX SOAP communication
- **Controller** (`app/Http/Controllers/Api/EstiController.php`) - API endpoints
- **Models** - `EstiSubmission`, updated `BookingGuest`, updated `Venue`
- **Configuration** (`config/esti.php`) - ESTI settings
## Installation
### 1. Run Migration
```bash
php artisan migrate
```
This will create:
- `esti_submissions` table - Tracks all ESTI submissions
- Add ESTI fields to `venues` table
- Add ESTI fields to `booking_guests` table
### 2. Configure Environment Variables
Add to your `.env` file:
```env
# Required for CSV Export
ESTI_ACCOMMODATION_PLACE_UIN=your_accommodation_uin
# Communication Method (csv or regix)
ESTI_COMMUNICATION_METHOD=csv
# Optional: Auto-submission settings
ESTI_AUTO_SUBMIT_ENABLED=false
ESTI_AUTO_SUBMIT_ON_COMPLETED_CHECKOUT=false
# Optional: Logging
ESTI_LOGGING_ENABLED=true
ESTI_LOG_CHANNEL=daily
```
### 3. For RegiX Integration (Advanced)
If you want to use system-to-system communication via RegiX, you need:
```env
# RegiX Test Environment
ESTI_REGIX_ENVIRONMENT=test
ESTI_REGIX_TEST_ENDPOINT=https://test.regix.egov.bg/...
ESTI_REGIX_TEST_OID=your_oid
ESTI_REGIX_TEST_CERT_PATH=/path/to/certificate.p12
ESTI_REGIX_TEST_CERT_PASSWORD=certificate_password
ESTI_REGIX_TEST_OPERATION=SendInfoForAccomodationRegister
# RegiX Production Environment
ESTI_REGIX_PROD_ENDPOINT=https://regix.egov.bg/...
ESTI_REGIX_PROD_OID=your_prod_oid
ESTI_REGIX_PROD_CERT_PATH=/path/to/prod_certificate.p12
ESTI_REGIX_PROD_CERT_PASSWORD=prod_certificate_password
ESTI_REGIX_PROD_OPERATION=SendInfoForAccomodationRegister
```
## Configuration
### Accommodation Place UIN
The `ESTI_ACCOMMODATION_PLACE_UIN` is the unique identifier for your accommodation place from the National Tourism Register (ΠΠ°ΡΠΈΠΎΠ½Π°Π»Π΅Π½ Π’ΡΡΠΈΡΡΠΈΡΠ΅ΡΠΊΠΈ Π Π΅Π³ΠΈΡΡΡΡ). This is required for all ESTI submissions.
To obtain this:
1. Register your accommodation in the National Tourism Register
2. Receive your unique UIN
3. Add it to the `.env` file or venue-specific settings
### Venue-Specific UIN
You can also set UIN per venue in the database:
```php
$venue->esti_accommodation_place_uin = 'venue_specific_uin';
$venue->esti_enabled = true;
$venue->save();
```
## API Endpoints
All endpoints require authentication (`auth:sanctum` middleware).
### CSV Export
#### Export CSV for Date Range
```
GET /api/esti/export/csv
```
**Parameters:**
- `start_date` (required) - Start date (YYYY-MM-DD)
- `end_date` (required) - End date (YYYY-MM-DD)
- `registration_type` (optional) - NEW, UPD, DEL (default: NEW)
- `status` (optional) - Filter by booking status
- `venue_id` (optional) - Filter by venue
**Response:** CSV file download
**Example:**
```bash
curl -X GET "https://your-domain.com/api/esti/export/csv?start_date=2025-01-01&end_date=2025-01-31®istration_type=NEW" \
-H "Authorization: Bearer your_token"
```
#### Export CSV for Single Booking
```
GET /api/esti/export/booking/{id}/csv
```
**Parameters:**
- `registration_type` (optional) - NEW, UPD, DEL (default: NEW)
**Response:** CSV file download
**Example:**
```bash
curl -X GET "https://your-domain.com/api/esti/export/booking/123/csv" \
-H "Authorization: Bearer your_token"
```
### Validation
#### Validate Booking for ESTI
```
GET /api/esti/validate/booking/{id}
```
**Response:**
```json
{
"valid": true,
"validation_results": {
"booking": [],
"guests": {
"1": []
}
}
}
```
### RegiX Integration
#### Send New Registration
```
POST /api/esti/regix/insert
```
**Body:**
```json
{
"booking_id": 123,
"guest_id": 456
}
```
#### Send Update
```
POST /api/esti/regix/update
```
**Body:**
```json
{
"registration_id": "esti_registration_id",
"booking_id": 123,
"guest_id": 456
}
```
#### Send Cancellation
```
POST /api/esti/regix/cancel
```
**Body:**
```json
{
"registration_id": "esti_registration_id"
}
```
#### Test RegiX Connection
```
GET /api/esti/regix/test-connection
```
**Response:**
```json
{
"success": true,
"message": "Successfully connected to RegiX",
"configuration_status": { ... }
}
```
### Configuration Status
```
GET /api/esti/configuration
```
**Response:**
```json
{
"csv": {
"enabled": true,
"accommodation_place_uin_configured": true
},
"regix": {
"configured": false,
"status": { ... }
},
"communication_method": "csv"
}
```
## CSV Format
The generated CSV follows the official ESTI specification:
- **Delimiter:** Semicolon (;)
- **Encoding:** UTF-8 with BOM
- **Date Format:** DD.MM.YYYY
- **DateTime Format:** DD.MM.YYYY HH:MI
### CSV Columns
1. `AccomodationPlaceUin` - Unique accommodation identifier
2. `AccomodationRegisterUin` - Booking number with guest ID
3. `RegistrationDate` - Registration date/time
4. `IdentityNumber` - EGN or LNCH
5. `FirstName` - First name
6. `MiddleName` - Middle name
7. `LastName` - Last name
8. `BirthDate` - Date of birth (DD.MM.YYYY)
9. `GenderTypeCode` - M or F
10. `IdentityDocumentTypeCode` - ICA, PAS, or DRL
11. `IdentityDocumentNumber` - Document number
12. `IdentityDocumentCountryCode` - ISO 3166-1 alpha-2
13. `Floor` - Floor number
14. `Room` - Room number
15. `CheckInDate` - Check-in date/time
16. `CheckOutDate` - Check-out date/time
17. `TouristPackage` - TRUE or FALSE
18. `AvgNightPrice` - Average price per night
19. `RegistrationTypeCode` - NEW, UPD, or DEL
The exporter rejects rows rather than inventing missing guest data. It enforces the official header order, semicolon delimiter, UTF-8 BOM, date/time formats, decimal point, mandatory names/birth date/sex/document type/document country, field length limits, and registration code list. Both stay and booking export paths require a completed, non-future actual checkout.
## Document Type Codes
- **ICA** - ID Card (ΠΠΈΡΠ½Π° ΠΊΠ°ΡΡΠ°)
- **PAS** - Passport (ΠΠ°ΡΠΏΠΎΡΡ)
- **DRL** - Driving License (Π¨ΠΎΡΡΠΎΡΡΠΊΠ° ΠΊΠ½ΠΈΠΆΠΊΠ°)
## Gender Codes
- **M** - Male (ΠΡΠΆ)
- **F** - Female (ΠΠ΅Π½Π°)
## Registration Type Codes
- **NEW** - New registration
- **UPD** - Update registration
- **DEL** - Delete/cancel registration
## EU/EEA/Swiss Countries
The following countries have less strict ESTI requirements (document details not always required):
BG, AT, BE, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IS, IE, IT, LV, LI, LT, LU, MT, NL, NO, PL, PT, RO, SK, SI, ES, SE, CH
## RegiX Setup Instructions
### Prerequisites
1. **Profile in ESTI Test Environment**
- Register at: https://estitest.tourism.government.bg/
- Obtain test credentials
2. **RegiX Access Application**
- Submit application to MEU (Ministry of e-Governance)
- Apply for test environment access first
- Information: https://e-gov.bg/wps/portal/agency/about-us/administrationservice/info-administrations/info-integration/regix
3. **OID Number**
- After approval, receive OID (Object Identifier)
- This identifies your installation
4. **Digital Certificate**
- Generate certificate request with OID
- Instructions: https://info-regix.egov.bg/public/guides/07.03.RegixInfo.md
- Receive certificate from MEU
- Convert to P12 format if needed
### Certificate Setup
1. Place certificate file in secure location on server
2. Set proper file permissions (600)
3. Configure path in `.env`:
```env
ESTI_REGIX_TEST_CERT_PATH=/secure/path/to/certificate.p12
ESTI_REGIX_TEST_CERT_PASSWORD=your_password
```
### Testing Process
1. Test with RegiX test environment first
2. Verify CSV exports include only stays with completed checkout
3. Test RegiX connection: `GET /api/esti/regix/test-connection`
4. Submit test registrations
5. Verify in ESTI test environment
6. After successful testing, repeat for production
### Production Setup
1. Apply for production RegiX access
2. Obtain production OID and certificate
3. Update `.env` with production credentials
4. Change environment: `ESTI_REGIX_ENVIRONMENT=production`
5. Test connection thoroughly
## Usage Examples
### Using CSV Export Service Directly
```php
use App\Services\Esti\EstiCsvExportService;
$csvService = app(EstiCsvExportService::class);
// Get bookings for export
$startDate = new \DateTime('2025-01-01');
$endDate = new \DateTime('2025-01-31');
$bookings = $csvService->getBookingsForExport($startDate, $endDate);
// Generate CSV
$csvContent = $csvService->generateCsv($bookings, 'NEW');
// Save to file
$filename = $csvService->generateFilename();
$filepath = $csvService->saveCsvToFile($csvContent, $filename);
```
### Using RegiX Service Directly
```php
use App\Services\Esti\EstiRegixService;
use App\Services\Esti\DTOs\EstiInsertAccommodation;
$regixService = app(EstiRegixService::class);
// Check configuration
if (!$regixService->isConfigured()) {
// Handle configuration error
}
// Create data
$data = EstiInsertAccommodation::fromBookingAndGuest($booking, $guest);
// Send to ESTI
$result = $regixService->sendInsertAccommodation($data);
if ($result['success']) {
// Handle success
} else {
// Handle error
Log::error('ESTI submission failed', ['error' => $result['error']]);
}
```
### Tracking Submissions
```php
use App\Models\EstiSubmission;
// Create submission record
$submission = EstiSubmission::create([
'booking_id' => $booking->id,
'booking_guest_id' => $guest->id,
'venue_id' => $booking->venue_id,
'submission_type' => 'csv',
'registration_type' => 'NEW',
'accommodation_place_uin' => config('esti.accommodation_place_uin'),
'status' => 'pending',
]);
// Update status
$submission->markAsSubmitted($submittedData);
$submission->markAsAccepted($responseData);
// or
$submission->markAsFailed($errorMessage);
```
## Validation Rules
### Required for All Bookings
- Check-in date
- Check-out date
- Total amount
- Accommodation Place UIN
### Required for Bulgarian Citizens
- EGN (Identity Number)
### Required for Non-EU/EEA/Swiss Citizens
- First name
- Last name
- Document type (ICA/PAS/DRL)
- Document number
- Document country code
### Optional Fields
- Middle name
- Floor
- Room (defaults to venue object name)
## Troubleshooting
### CSV Export Issues
**Problem:** Empty CSV file
- **Solution:** Check that bookings exist within date range and match filters
**Problem:** Validation errors
- **Solution:** Use `/api/esti/validate/booking/{id}` to check specific errors
**Problem:** Wrong date format
- **Solution:** Ensure dates are in DD.MM.YYYY or DD.MM.YYYY HH:MI format
### RegiX Issues
**Problem:** Certificate not found
- **Solution:** Verify certificate path in `.env` and file exists with correct permissions
**Problem:** Connection timeout
- **Solution:** Check network connectivity and RegiX endpoint URL
**Problem:** Authentication failed
- **Solution:** Verify certificate password and OID are correct
**Problem:** Invalid OID
- **Solution:** Ensure OID matches the certificate and is approved by MEU
### Common Errors
**"Accommodation Place UIN is not configured"**
- Add `ESTI_ACCOMMODATION_PLACE_UIN` to `.env` or set per venue
**"Non-EU citizen requires document details"**
- Ensure document type, number, and country are provided for non-EU guests
**"RegiX is not properly configured"**
- Complete RegiX setup process or use CSV export method
## Database Schema
### esti_submissions Table
- `id` - Primary key
- `booking_id` - Foreign key to bookings
- `booking_guest_id` - Foreign key to booking_guests (nullable)
- `venue_id` - Foreign key to venues (nullable)
- `submission_type` - csv or regix
- `registration_type` - NEW, UPD, DEL
- `registration_uid` - ESTI unique identifier
- `accommodation_place_uin` - UIN used for submission
- `status` - pending, submitted, accepted, rejected, failed
- `error_message` - Error details if failed
- `response_data` - Full response from ESTI (JSON)
- `csv_file_path` - Path to CSV file (if CSV type)
- `csv_exported_at` - Timestamp of CSV export
- `regix_request_id` - RegiX request ID
- `regix_submitted_at` - Timestamp of RegiX submission
- `submitted_data` - Copy of data sent to ESTI (JSON)
- `submitted_at` - Submission timestamp
- `response_received_at` - Response timestamp
- `created_at`, `updated_at` - Laravel timestamps
### New Venue Fields
- `esti_accommodation_place_uin` - Venue-specific ESTI UIN
- `esti_enabled` - Whether ESTI is enabled for this venue
### New BookingGuest Fields
- `id_document_type` - ICA, PAS, DRL
- `id_document_country_code` - ISO 3166-1 alpha-2
- `sex` - M or F
- `esti_registration_id` - ESTI registration ID for updates
## Security Considerations
1. **Certificate Security**
- Store certificates in secure directory with proper permissions
- Never commit certificates to version control
- Use environment variables for passwords
2. **Data Protection**
- Guest personal data is encrypted in database
- Only authorized users can access ESTI endpoints
- Log sensitive operations appropriately
3. **API Security**
- All endpoints require authentication
- Implement rate limiting if needed
- Validate all input data
## References
- **Official ESTI section:** https://www.tourism.government.bg/bg/taxonomy/term/201/all
- **RegiX Information:** https://e-gov.bg/wps/portal/agency/about-us/administrationservice/info-administrations/info-integration/regix
- **RegiX catalogue and guides:** https://info-regix.egov.bg/public
- **RegiX Certificate Guide:** https://info-regix.egov.bg/public/guides/07.03.RegixInfo.md
- **ESTI API Structure:** https://inforegix.egov.bg/public/administrations/MT/registries/operations/TechnoLogica.RegiX.MtEstiAdapter.APIService.IMtEstiAPI/SendInfoForAccomodationRegister
## Support
For issues related to:
- **ESTI System:** Contact the Ministry of Tourism through its official ESTI section
- **RegiX Integration:** Contact MEU support
- **This Module:** Check application logs and documentation
## Changelog
### Version 1.0.0 (2025-01-15)
- Initial release
- CSV export functionality
- RegiX service structure
- API endpoints
- Database migration
- Documentation