esolutions/xml 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

esolutions/xml

Composer 安装命令:

composer require esolutions/xml

包简介

Generacion, firma, validacion y envio SUNAT/OSE de XML UBL para comprobantes electronicos (Peru)

README 文档

README

Generación, firma, validación y envío SUNAT/OSE de comprobantes electrónicos peruanos (XML UBL) para proyectos Laravel. Independiente del proyecto consumidor: la entrada es un array payload documentado y la configuración entra por objetos propios — sin dependencias a modelos Eloquent externos.

Tipos de documento soportados

Documento Código Plantilla UBL Envío
Factura / Boleta 01 / 03 invoice 2.1 sendBill (síncrono, CDR inmediato)
Nota de crédito 07 credit-note 2.1 sendBill
Nota de débito 08 debit-note 2.1 sendBill
Guía de remisión — remitente 09 despatch 2.1 REST GRE 2022 (GreRestClient)
Guía de remisión — transportista 31 despatch-carrier 2.1 REST GRE 2022
Retención 20 retention 2.0 sendBill (endpoint propio)
Percepción 40 perception 2.0 sendBill (endpoint propio)
Resumen diario RC summary 2.0 sendSummary → ticket → getStatus
Comunicación de baja RA voided 2.0 sendSummary → ticket → getStatus

Envíos verificados en homologación (SUNAT beta / Nubefact): factura/boleta, guía remitente (todas las variantes de motivo + múltiples conductores/vehículos), guía transportista (pipeline), exportación con DAM, resumen, baja, retención y percepción — todos aceptados con CDR. Ver docs/sending-verified.md.

Dos entradas: contrato interno o API español

use ESolutions\Xml\Contracts\XmlDocumentGeneratorContract;

$gen = app(XmlDocumentGeneratorContract::class);

// 1) Contrato interno (todos los tipos)
$res = $gen->generate('01', $payload);

// 2) API en español, estilo Greenter/camelCase (todos los tipos)
$res = $gen->generateFromEs('01', $payloadEs);   // tipoDoc, serie, client{}, details[]...

if ($res->isOk()) {
    $signedXml = $res->xml;
} else {
    $errores = $res->validation->errors;   // [PAYLOAD] / [XSD] / reglas
}

El payload interno se documenta por tipo en docs/payloads/; el camelCase del API español, en docs/spanish-api.md. El mapeo desde tus modelos vive en tu proyecto (patrón anti-corruption).

Validación (XSD + reglas SUNAT + reconciliaciones)

  • XSD oficial UBL 2.0/2.1.
  • Reglas SUNAT del cliente (SunatRulesValidator): extraídas del XSLT del SFS de SUNAT (motor de primitivas + catálogos), por tipo de documento.
  • OwnRules: reconciliaciones server-side que el XSLT no trae (3294 sumatoria de impuestos, 3305 total precio venta) y reglas fechadas (ver abajo).
  • Catálogo de códigos: error-codes.php (2077 códigos oficiales del Excel de SUNAT) superpuesto sobre CatalogoErrores.xml.

Enviar a SUNAT / OSE

use ESolutions\Xml\Sending\{DocumentSender, SenderConfig, FilenameBuilder};

$config = SenderConfig::fromArray([
    'provider' => 'sunat',            // 'sunat' | 'nubefact'
    'environment' => 'demo',          // 'demo' (beta) | 'production'
    'username' => '20123456789MODDATOS',
    'password' => 'moddatos',
    'gre_client_id' => '...',         // solo GRE (guías); en demo usa las beta públicas
    'gre_client_secret' => '...',
]);

$sender = new DocumentSender($config);
$result = $sender->send($filename, $signedXml);   // resuelve sendBill vs sendSummary

if ($result->isAccepted()) {
    $cdrXml = $result->getCdrXml();
} elseif ($result->isRejected()) {
    $motivo = $result->getMessage();
}
  • Resúmenes/bajas (async): sendSummary() → ticket → getStatus($ticket) (isInProcess() = 98).
  • Guías (GRE 2022): GreRestClient::fromSenderConfig($config)->sendDespatch($filename, $xml) → ticket → getStatus(). Ver docs/gre.md.
  • Reconsulta de CDR (caso 1033): ConsultCdrService::getStatusCdr(...).

Origen del error (conexión / sistema / SUNAT)

Los results exponen errorSource() para decidir la acción sin combinar banderas:

$result->errorSource();
// 'conexion' → no llegó a SUNAT       → REINTENTAR
// 'sunat'    → respondió y rechazó     → CORREGIR el comprobante
// 'sistema'  → llegó pero falló parseo → REVISAR
// null       → aceptado / en proceso

Bucle de mejora de validaciones (feedback)

RejectionAnalyzer + RejectionSink (JSONL o Eloquent propio) capturan los rechazos reales de SUNAT y marcan si el validador local los habría atrapado — los que no, son los huecos a agregar a OwnRules. Ver docs/feedback-loop.md.

Cambios de reglas SUNAT fechados (date-gating)

SUNAT publica cambios con fecha de vigencia y valida cada comprobante según su fecha de emisión. El paquete convive ambas eras en una sola versión: cada regla/campo nuevo se aplica solo a documentos con fechaEmision >= vigencia. Las fechas son configurables (config('esolutions_xml.rule_dates')) por si SUNAT posterga. Los cambios con vigencia 2026-08-01 (código de producto obligatorio, tipo 13 de ND, gratuitas desagregadas en el resumen, etc.) ya están implementados. Ver docs/sunat-changes-2026-08.md.

La fuente autoritativa es el Excel oficial de reglas de SUNAT; tools/extract_from_excel.php extrae los códigos de retorno y hace inventario de reglas por documento — re-correr en cada Excel nuevo + git diff.

Tests

Suite PHPUnit + Orchestra Testbench que recorre los fixtures JSON (que también son ejemplos de payload) y valida generación + XSD + reglas por cada tipo:

composer install
composer test        # o vendor/bin/phpunit

Ver docs/testing.md. Los fixtures viven en tests/fixtures/payloads/ (interno) y tests/fixtures/payloads-es/ (español).

Firma

XMLDSig enveloped (RSA-SHA1 + C14N) en el <ext:ExtensionContent/> vacío del template. Certificado por config('esolutions_xml.signing'); sin configurar usa el demo de SUNAT beta (RUC 10417844398, solo homologación). Los .pfx/.p12 se convierten a PEM al vuelo.

Índice de documentación

Requisitos e instalación

composer require esolutions/xml
php artisan vendor:publish --tag=esolutions-xml-config   # opcional

PHP ^8.2, Laravel ^11|^12|^13, extensiones dom, libxml, openssl, soap, zip. Provider por auto-discovery.

Limitaciones conocidas

  • Guía transportista (31) en homologación: el pipeline (envío/ticket/CDR) está probado, pero la aceptación requiere un RUC registrado como transportista con autorización MTC (dato real, no fabricable en beta demo).
  • Importación (08) de guía: estructura DAM completa; la aceptación requiere un establecimiento aduanero de tercero registrado en SUNAT.
  • Los certificados .pem empaquetados son los demo públicos de SUNAT beta — nunca en producción.
  • El sender nunca lanza excepciones de conexión (retorna errorSource() = 'conexion'); el consumidor decide el reintento (no hay cola integrada).

esolutions/xml 适用场景与选型建议

esolutions/xml 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 07 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「xml」 「cpe」 「sunat」 「peru」 「ubl」 「facturacion-electronica」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 esolutions/xml 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 esolutions/xml 我们能提供哪些服务?
定制开发 / 二次开发

基于 esolutions/xml 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: proprietary
  • 更新时间: 2026-07-15