Skip to main content

Overview

SUNAT provides two separate environments for electronic invoicing:
  • Beta (Testing) - For development and testing
  • Production - For real business documents
Documents sent to Beta are not legally valid. Use Production environment for all real business transactions.

Environment Comparison

Purpose: Development, testing, and trainingCharacteristics:
  • No legal validity
  • Test credentials provided by SUNAT
  • Relaxed validation rules
  • May have downtime for maintenance
  • Free to use
When to Use:
  • Initial integration development
  • Testing new document types
  • Training users
  • Debugging issues
Endpoints:
  • Invoicing: https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService
  • Dispatch Guides (GRE): https://api-cpe-beta.sunat.gob.pe/v1/
Test Credentials:
RUC: 20161515648
Usuario SOL: MODDATOS
Clave SOL: MODDATOS

Configuration

Company Model

Environment configuration is managed at the company level: Location: app/Models/Company.php:14
app/Models/Company.php
protected $fillable = [
    'ruc',
    'razon_social',
    'usuario_sol',              // SOL credentials
    'clave_sol',
    'endpoint_beta',            // Beta environment endpoint
    'endpoint_produccion',      // Production environment endpoint
    'modo_produccion',          // Boolean: false = Beta, true = Production
    'gre_client_id_beta',       // GRE credentials for Beta
    'gre_client_secret_beta',
    'gre_client_id_produccion', // GRE credentials for Production
    'gre_client_secret_produccion',
];

protected $casts = [
    'modo_produccion' => 'boolean',
];

Default Endpoints

Endpoints are automatically configured when creating a company: Location: app/Models/Company.php:130
app/Models/Company.php
protected static function boot()
{
    parent::boot();
    
    static::creating(function ($company) {
        // Set default Beta endpoint
        if (empty($company->endpoint_beta)) {
            $company->endpoint_beta = 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService';
        }
        
        // Set default Production endpoint
        if (empty($company->endpoint_produccion)) {
            $company->endpoint_produccion = 'https://e-factura.sunat.gob.pe/ol-ti-itcpfegem/billService';
        }
        
        // Default to Beta mode
        $company->modo_produccion = $company->modo_produccion ?? false;
    });
}

Environment Switching

Switch between Beta and Production by updating modo_produccion:
// Switch to Production
$company->update(['modo_produccion' => true]);

// Switch to Beta
$company->update(['modo_produccion' => false]);
API Endpoint:
PATCH /api/companies/{id}
Request Body:
{
  "modo_produccion": true
}

Service Endpoints

SUNAT has different endpoints for different document types.

Invoicing Endpoints (Facturas, Boletas, Notas)

Configuration: app/Traits/HasCompanyConfigurations.php:586
'config_type' => 'service_endpoints',
'environment' => 'beta',
'service_type' => 'facturacion',
'config_data' => [
    'endpoint' => 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService',
    'wsdl' => 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService?wsdl',
    'timeout' => 30,
]
Documents Supported:
  • Facturas (01)
  • Boletas (03)
  • Credit Notes (07)
  • Debit Notes (08)
  • Daily Summaries
  • Voided Documents

Dispatch Guide Endpoints (Guías de Remisión - GRE)

'config_type' => 'service_endpoints',
'environment' => 'beta',
'service_type' => 'guias_remision',
'config_data' => [
    'endpoint' => 'https://gre-test.nubefact.com/v1',
    'api_endpoint' => 'https://api-cpe-beta.sunat.gob.pe/v1/',
    'wsdl' => 'https://e-beta.sunat.gob.pe/ol-ti-itcpgre-beta/billService?wsdl',
    'timeout' => 30,
]
GRE uses OAuth2 authentication instead of SOAP. Requires client_id and client_secret.

Dynamic Endpoint Selection

The system automatically selects endpoints based on modo_produccion: Location: app/Traits/HasCompanyConfigurations.php:368
app/Traits/HasCompanyConfigurations.php
public function getInvoiceEndpoint(): string
{
    return $this->getSunatEndpoint('facturacion', 'endpoint');
}

public function getGuideEndpoint(): string
{
    return $this->getSunatEndpoint('guias_remision', 'endpoint');
}

public function getGuideApiEndpoint(): string
{
    return $this->getSunatEndpoint('guias_remision', 'api_endpoint');
}

private function getSunatEndpoint(string $serviceType, string $type = 'endpoint'): string
{
    $environment = $this->modo_produccion ? 'produccion' : 'beta';
    $endpoints = $this->getSunatEndpoints($serviceType);
    return $endpoints[$type] ?? '';
}

GreenterService Configuration

GreenterService initializes with environment-specific settings: Location: app/Services/GreenterService.php:50
app/Services/GreenterService.php
protected function initializeSee(): See
{
    $see = new See();
    
    // Get endpoint based on company's mode
    $endpoint = $this->company->getInvoiceEndpoint();
    $see->setService($endpoint);
    
    Log::info("Greenter initialized", [
        'mode' => $this->company->modo_produccion ? 'PRODUCTION' : 'BETA',
        'endpoint' => $endpoint,
        'ruc' => $this->company->ruc
    ]);
    
    // Load certificate
    $certificadoPath = storage_path('app/public/certificado/certificado.pem');
    $certificadoContent = file_get_contents($certificadoPath);
    $see->setCertificate($certificadoContent);
    
    // Set SOL credentials
    $see->setClaveSOL(
        $this->company->ruc,
        $this->company->usuario_sol,
        $this->company->clave_sol
    );
    
    return $see;
}

Testing in Beta

Setup Beta Testing

1

Create Test Company

POST /api/companies
{
  "ruc": "20161515648",
  "razon_social": "EMPRESA DE PRUEBA",
  "usuario_sol": "MODDATOS",
  "clave_sol": "MODDATOS",
  "modo_produccion": false
}
2

Configure Test Certificate

Use SUNAT’s test certificate or your own test certificate.
cp test-certificate.pem storage/app/public/certificado/certificado.pem
3

Create Test Documents

POST /api/invoices
Use test client data:
{
  "client": {
    "tipo_documento": "6",
    "numero_documento": "20123456789",
    "razon_social": "CLIENTE DE PRUEBA"
  }
}
4

Verify Beta Response

Check that documents are accepted by Beta environment:
{
  "estado_sunat": "ACEPTADO",
  "respuesta_sunat": {
    "code": "0",
    "description": "La Factura numero F001-123 ha sido aceptada"
  }
}

Beta Testing Checklist

  • Facturas (01)
  • Boletas (03)
  • Credit Notes (07)
  • Debit Notes (08)
  • Daily Summaries
  • Voided Documents
  • Dispatch Guides (09)
  • Gravada (IGV 18%)
  • Exonerada (No IGV)
  • Inafecta (No IGV)
  • Gratuita (Free items)
  • IVAP (Rice tax)
  • ISC (Selective consumption)
  • ICBPER (Plastic bag tax)
  • Contado (Cash)
  • Crédito (Credit with installments)
  • Multiple installments
  • Invalid RUC
  • Missing required fields
  • Invalid tax calculations
  • Network timeouts
  • SUNAT rejection codes

Production Deployment

Pre-Production Checklist

1

Verify Company Registration

  • Company is registered with SUNAT for electronic invoicing
  • Valid SOL credentials obtained from SUNAT
  • Production digital certificate acquired from approved CA
2

Update Credentials

PATCH /api/companies/{id}
{
  "ruc": "20123456789",
  "razon_social": "MI EMPRESA SAC",
  "usuario_sol": "[YOUR_SOL_USER]",
  "clave_sol": "[YOUR_SOL_PASSWORD]"
}
3

Install Production Certificate

cp production-certificate.pem storage/app/public/certificado/certificado.pem
chmod 600 storage/app/public/certificado/certificado.pem
Verify:
php artisan certificate:validate
4

Switch to Production Mode

PATCH /api/companies/{id}
{
  "modo_produccion": true
}
After this step, all documents will be legally valid and reported to SUNAT.
5

Test First Document

Create a test invoice with small amount:
{
  "serie": "F001",
  "cliente": {...},
  "items": [
    {
      "descripcion": "PRODUCTO DE PRUEBA",
      "cantidad": 1,
      "precio_unitario": 1.00
    }
  ]
}
Verify acceptance from SUNAT.

Environment Comparison

FeatureBetaProduction
Legal ValidityNoYes
CredentialsTest credentialsReal SOL credentials
CertificateTest or realMust be real
ValidationRelaxedStrict
AvailabilityMay have downtimeHigh availability
CostFreeFree (service), certificate costs vary
Document StorageTemporaryPermanent
CDR ResponseSimilar formatOfficial format
MonitoringNot monitoredSubject to SUNAT audits

Environment-Specific Configurations

Configuration Trait

The HasCompanyConfigurations trait manages environment-specific settings: Location: app/Traits/HasCompanyConfigurations.php:44
app/Traits/HasCompanyConfigurations.php
public function getConfig(string $configType, string $environment = null, string $serviceType = null)
{
    // Auto-select environment based on modo_produccion
    $environment = $environment ?? ($this->modo_produccion ? 'produccion' : 'beta');
    
    return Cache::remember($cacheKey, 3600, function () use ($configType, $environment, $serviceType) {
        $config = $this->activeConfigurations()
            ->where('config_type', $configType)
            ->where('environment', $environment)
            ->when($serviceType, fn($q) => $q->where('service_type', $serviceType))
            ->first();
        
        return $config ? $config->config_data : null;
    });
}

GRE Credentials by Environment

Location: app/Traits/HasCompanyConfigurations.php:210
app/Traits/HasCompanyConfigurations.php
public function getGreClientId(): ?string
{
    return $this->modo_produccion 
        ? $this->gre_client_id_produccion 
        : $this->gre_client_id_beta;
}

public function getGreClientSecret(): ?string
{
    return $this->modo_produccion 
        ? $this->gre_client_secret_produccion 
        : $this->gre_client_secret_beta;
}

Logging and Monitoring

The system logs environment information for debugging:
Log::info("Document sent to SUNAT", [
    'environment' => $company->modo_produccion ? 'PRODUCTION' : 'BETA',
    'endpoint' => $endpoint,
    'document_type' => $document->tipo_documento,
    'document_number' => $document->numero_completo,
    'estado_sunat' => $document->estado_sunat,
]);

Best Practices

Test Thoroughly in Beta

Complete all testing scenarios in Beta before switching to Production

Use Separate Databases

Maintain separate databases for Beta and Production environments

Monitor Production

Set up alerts for SUNAT rejections and errors in Production

Backup Before Switching

Back up database and configurations before switching environments

Common Issues

Cause: Using test credentials (MODDATOS) in Production mode.Solution:
$company->update([
    'usuario_sol' => '[YOUR_REAL_SOL_USER]',
    'clave_sol' => '[YOUR_REAL_SOL_PASSWORD]',
]);
Cause: Using test certificate in Production or certificate doesn’t match RUC.Solution:
  • Verify certificate CN matches company RUC
  • Ensure certificate is from SUNAT-approved CA
  • Check certificate hasn’t expired
Cause: Production has stricter validation than Beta.Solution:
  • Review SUNAT rejection message
  • Ensure all required fields are present
  • Verify tax calculations are exact
  • Check document series is authorized by SUNAT
Cause: Once in Production, switching back can confuse document tracking.Solution:
  • Use separate companies for Beta and Production
  • If you must switch, ensure all pending documents are completed first
$company->update(['modo_produccion' => false]);

Next Steps

Create Your First Invoice

Start sending documents to SUNAT

API Reference

Explore all available endpoints

Build docs developers (and LLMs) love