Skip to main content

O quê / quando

Tentativa de entrega sem sucesso. Motivo tipado em CteDeliveryFailureReason. Se Other, informe reasonJustification (≥ 15 caracteres).

Exemplo

use Suot\Fiscal\Core\Exception\InfrastructureException;
use Suot\Fiscal\Core\Result\RetryMode;
use Suot\Fiscal\Cte\ValueObject\CteDeliveryFailurePayload;
use Suot\Fiscal\Cte\ValueObject\CteDeliveryFailureReason;

$now = (new DateTimeImmutable('now', new DateTimeZone('America/Sao_Paulo')))
    ->format('Y-m-d\TH:i:sP');

$payload = new CteDeliveryFailurePayload(
    authorizationProtocol: $nProt,
    attemptedAt: $now,
    reason: CteDeliveryFailureReason::ReceiverRefused,
    // reasonJustification: obrigatório se reason === Other
    attemptNumber: '001',
    failedNfeKeys: [],
);

try {
    $result = $cte->deliveryFailure()
        ->forOperation('ie-1')
        ->inHomologation()
        ->accessKey($chave44)
        ->emitterCnpj($cnpj)
        ->deliveryFailure($payload)
        ->handle();
} catch (InfrastructureException $e) {
    $failure = $e->toFailure('delivery_failure');
    // Host: alertar; QueryBeforeRetry se timeout após envio
    throw $e;
}

if (! $result->isRejected()) {
    // Host: persistir protocolNumber do evento, responseXml, accessKey, operationId
}

if ($result->isRejected()) {
    $failure = $result->failure();
    $policy = $result->retryPolicy();
    match ($policy?->mode) {
        RetryMode::AfterCorrection => /* corrigir motivo/justificativa/datas e tentar de novo */,
        RetryMode::QueryBeforeRetry => /* reconciliar eventos antes de reenviar */,
        RetryMode::AfterDelay, RetryMode::Immediate => /* filar conforme política */,
        RetryMode::Never, null => /* definitivo; não reenviar */,
    };
}
Motivos: ReceiverNotFound, ReceiverRefused, AddressNotFound, Other. Resultado: DeliveryFailureCteResultisRejected(), failure(), protocolo do evento.
Há também $cte->cancelDeliveryFailure() para cancelar o evento de insucesso quando aplicável — use o mesmo envelope de exception + Result.