Search by

techsolutions / euronet-simo-sdk

TECHSOLUTIONS-PROJECTS

Biblioteca Laravel para gestão de pagamentos por entidade e referência (referência SIMO MOD 97-10 e API Validate/Notify Ren).

Package info

github.com/TECHSOLUTIONS-PROJECTS/euronet-simo-sdk

pkg:composer/techsolutions/euronet-simo-sdk

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.0.1 2026-09-16 14:58 UTC

This package is auto-updated.

Last update: 2026-09-16 15:08:06 UTC


README

Biblioteca Laravel para gestão de pagamentos por entidade e referência. Cobre dois domínios complementares:

  1. Referência SIMO — geração e validação de referências de 11 dígitos com dígitos de controlo ISO/IEC 7064, MOD 97-10.
  2. API Validate/Notify da Ren — recepção e resposta às mensagens BPVAL (validação) e NTFY1 (notificação) de pagamentos de serviços, com a lógica de negócio ligada por contracts.

Instalação

composer require techsolutions/euronet-simo-sdk
php artisan vendor:publish --tag="simo-config"
php artisan vendor:publish --tag="simo-migrations" # opcional, só para auditoria
php artisan migrate                                 # opcional

Configuração

No .env:

SIMO_ENTITY=10203
SIMO_ROUTE_PREFIX=

Em config/simo.php liga as tuas implementações dos contratos:

'handlers' => [
    'validator' => App\Simo\PaymentValidator::class,
    'notifications' => App\Simo\PaymentNotificationHandler::class,
],

Referências

use Techsolutions\EuronetSimoSdk\Facades\SIMO;

// Gerar (entidade recai na configurada por omissão: 10203)
$ref = SIMO::generate('123456789');
$ref->reference(); // "12345678985"  (RRRRRRRRRXX)
$ref->full();      // "1020312345678985" (EEEEE + referência)

// Validar
SIMO::validate('12345678985');          // true
SIMO::validate('12345678945', '12345'); // true, com entidade explícita
SIMO::validate('12345678945');          // false: dígitos de controlo de outra entidade

// Decompor
$parsed = SIMO::parse('12345678985');
$parsed?->baseReference; // "123456789"
$parsed?->checkDigits;   // "85"

Validate / Notify

O pacote regista automaticamente os endpoints (desactiváveis na config):

Operação Método Rota MsgFctn
Validate POST customer/BillPay BPVAL
Notify POST BillPay NTFY1

Implementa os contratos com a tua lógica:

use Techsolutions\EuronetSimoSdk\Contracts\ValidatesPayments;
use Techsolutions\EuronetSimoSdk\DataTransferObjects\ValidatePaymentRequest;
use Techsolutions\EuronetSimoSdk\DataTransferObjects\ValidatePaymentResponse;
use Techsolutions\EuronetSimoSdk\Enums\PaymentStatus;

final class PaymentValidator implements ValidatesPayments
{
    public function validate(ValidatePaymentRequest $request): ValidatePaymentResponse
    {
        $factura = Factura::where('referencia', $request->refNum)->first();

        if ($factura === null) {
            return ValidatePaymentResponse::decline(PaymentStatus::Invalid, 'Referência não encontrada.');
        }

        if ($factura->expirada()) {
            return ValidatePaymentResponse::decline(PaymentStatus::Expired, 'Factura expirada.');
        }

        return ValidatePaymentResponse::allow();
    }
}
use Techsolutions\EuronetSimoSdk\Contracts\HandlesPaymentNotifications;
use Techsolutions\EuronetSimoSdk\DataTransferObjects\NotifyPaymentRequest;
use Techsolutions\EuronetSimoSdk\DataTransferObjects\NotifyPaymentResponse;
use Techsolutions\EuronetSimoSdk\Enums\PaymentStatus;

final class PaymentNotificationHandler implements HandlesPaymentNotifications
{
    public function handle(NotifyPaymentRequest $request): NotifyPaymentResponse
    {
        $factura = Factura::where('referencia', $request->refNum)->first();

        if ($factura?->paga) {
            return NotifyPaymentResponse::reject(PaymentStatus::Duplicated, 'Pagamento já confirmado.');
        }

        // Creditar a conta / registar o movimento.
        return NotifyPaymentResponse::acknowledge();
    }
}

Códigos de resposta (RsCd)

A aplicação responde com um estado (PaymentStatus) e o pacote converte-o no código RsCd definido em config/simo.php, numa tabela para o Validate (validate_status) e noutra para o Notify (notify_status):

Estado Quando usar Por omissão
Success pagamento validado / notificação confirmada 0
Duplicated factura já paga / notificação já confirmada 1
Expired factura expirada 1
Invalid referência inexistente na base de dados 1
Insufficient valor não conforme 1
Malformed mensagem que não pôde ser interpretada 1

Para usar os códigos acordados com a Ren, altera a config ou o .env:

SIMO_NOTIFY_DUPLICATED=12
SIMO_NOTIFY_EXPIRED=13
SIMO_VALIDATE_INVALID=21

decline() e reject() não aceitam o estado Success. Um código de falha igual ao de sucesso é recusado com InvalidConfigurationException, para que uma falha nunca chegue à Ren como sucesso.

Comportamento do protocolo

  • A resposta ecoa MsgFctn, MsgUUID e PrtcolVrsn do pedido, com escape XML. Sem MsgFctn no pedido, usa BPVAL ou NTFY1 conforme o endpoint.
  • Amount: o atributo da moeda é aceite como code ou Code. O código tem 3 dígitos (ISO 4217) e o valor só dígitos, com casas decimais implícitas.
  • AllowPayment é escrito como 0 ou 1.
  • AllowPayment só é 1 no estado Success.
  • Mensagens malformadas (XML inválido, elemento em falta ou Amount inválido) recebem HTTP 200 com o RsCd do estado malformed, Reason "Mensagem malformada." e, no Validate, AllowPayment = 0. A excepção é reportada ao exception handler da aplicação.
  • A segurança da ligação fica a cargo da aplicação: acrescenta o middleware apropriado em config('simo.routes.middleware').

Testes, análise estática e refactoring

composer test            # Pest
composer test:coverage   # Pest com cobertura; falha abaixo de 95% (requer PCOV ou Xdebug)
composer analyse         # Larastan nível 8
composer test:refactor   # Rector em modo dry-run (só mostra as alterações)
composer refactor        # Rector aplica as alterações

Estrutura

src/
├── Actions/            Orquestração (Generate, Validate, Notify)
├── Contracts/          Interfaces a implementar pela aplicação
├── DataTransferObjects/ DTOs imutáveis (readonly)
├── Enums/              MessageFunction, PaymentStatus
├── Exceptions/         Excepções do domínio
├── Facades/            Facade SIMO
├── Http/Controllers/   Endpoints invocáveis Validate/Notify
├── Models/             SimoPayment (auditoria opcional)
├── Reference/          Mod9710, ReferenceGenerator, ReferenceValidator
├── Support/            ResponseCodes (códigos RsCd da configuração)
├── Xml/                Parser e builder do protocolo Ren
├── Simo.php            Gestor principal
└── SimoServiceProvider.php

Licença

MIT.