Anatomia de uma confirmação de entrega SMPP
Quando você envia um SMS com registered_delivery igual a 1, o SMSC devolve depois uma PDU deliver_sm por um bind receptor ou transceptor. O bit 0x04 do esm_class indica que é uma confirmação de entrega, e não uma mensagem recebida, e o short_message traz a confirmação em texto. O anexo B da especificação SMPP v3.4 apresenta esse formato como exemplo, e quase todos os SMSCs o seguem: id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DDDDDDD err:E text:….
Como o anexo B é um exemplo, e não uma regra rígida, as confirmações reais variam: chaves em minúsculas, espaços extras, submit_date com sublinhado, datas de 12 dígitos com segundos ou ausência do campo text. Este decodificador aceita todas essas variações e informa quais campos estão faltando.
- id: o identificador que o SMSC retornou no submit_sm_resp. É ele que liga a confirmação à sua mensagem. O exemplo da especificação mostra 10 caracteres, mas muitos SMSCs usam IDs mais longos, às vezes em hexadecimal.
- sub e dlvrd: o número de mensagens enviadas e entregues, com 3 dígitos. Importam principalmente em listas de distribuição; para um SMS individual, costumam ser 001 e 001 (ou 000).
- submit date e done date: quando a mensagem foi enviada e quando chegou ao estado final, pelo relógio do SMSC.
- stat: o estado final ou intermediário, como um código de 7 letras, por exemplo DELIVRD.
- err: um código de erro de 3 caracteres, específico da rede ou do SMSC; 000 significa sem erro.
- text: os primeiros 20 caracteres da mensagem original, muitas vezes cortados ou vazios.
- TLVs opcionais podem repetir esses dados de forma mais limpa: receipted_message_id (0x001E), message_state (0x0427) e network_error_code (0x0423).
Códigos stat do DLR e o que significam
O SMPP v3.4 define oito estados de mensagem. ENROUTE e ACCEPTD são intermediários; os demais são finais. Nossa API normaliza todos os canais em seis status de webhook (SUBMITTED, SENT, DELIVERED, READ, FAILED, REJECTED), e o decodificador mostra a correspondência mais próxima para cada valor de stat. Considere esse mapeamento indicativo: a regra exata da sua conta é confirmada no onboarding.
- DELIVRD (message_state 2): entregue no aparelho. Status de webhook mais próximo: DELIVERED.
- ACCEPTD (6): formalmente “lida manualmente pelo atendimento em nome do assinante”, mas a maioria dos SMSCs a envia como confirmação intermediária de “aceita pela rede”. Mais próximo: SENT.
- ENROUTE (1): ainda em trânsito, por exemplo na fila para nova tentativa. Mais próximo: SENT.
- UNDELIV (5): não entregável, por exemplo um número inválido ou inativo. Mais próximo: FAILED.
- EXPIRED (3): o período de validade terminou antes de alcançar o aparelho, muitas vezes desligado ou sem sinal. Mais próximo: FAILED.
- DELETED (4): excluída antes da entrega, por exemplo via cancel_sm. Mais próximo: FAILED.
- REJECTD (8): recusada pela rede ou por um firewall de SMS, por exemplo por ID de remetente (Sender ID) não registrado ou conteúdo bloqueado. Mais próximo: REJECTED.
- UNKNOWN (7): o SMSC não tem estado final. Trate como não confirmado, e não como falha comprovada.
Códigos err: por que não existe uma lista universal
O campo err tem três caracteres, e a especificação SMPP não define seus valores. 000 sempre significa sem erro, mas os demais valores vêm do fabricante do SMSC, da operadora ou de um agregador no caminho. Alguns SMSCs repassam causas de erro GSM MAP (por exemplo, o erro MAP 1 é assinante desconhecido e o 27 é assinante ausente), enquanto outros usam tabelas próprias.
Se a confirmação trouxer o TLV network_error_code (0x0423), ele é mais confiável: o primeiro octeto indica o tipo de rede (3 significa GSM) e os dois seguintes, o código de erro. Uma confirmação DELIVRD com err diferente de zero é inconsistente e vale a pena levar ao seu provedor; o decodificador destaca esse caso.
Erros command_status versus confirmações de entrega
O SMPP informa problemas em dois momentos. O command_status do submit_sm_resp chega em milissegundos e diz se o SMSC aceitou sua requisição; 0x00000000 (ESME_ROK) significa aceita, não entregue. A confirmação de entrega chega de segundos a dias depois e traz o resultado final.
Os valores de command_status estão definidos na seção 5.1.3 do SMPP v3.4. Os mais comuns em produção são 0x00000058 ESME_RTHROTTLED (você excedeu as mensagens por segundo combinadas: reduza o ritmo e tente de novo com backoff exponencial), 0x00000014 ESME_RMSGQFUL (fila cheia: aguarde), 0x0000000A e 0x0000000B (endereço de origem ou de destino inválido) e 0x0000000D ou 0x0000000E (falha no bind ou senha incorreta). Os valores 0x00000400 a 0x000004FF são reservados a erros específicos do fabricante do SMSC; consulte seu provedor.
Datas, fusos horários e latência de entrega
As datas das confirmações usam AAMMDDhhmm, e muitos SMSCs acrescentam os segundos (AAMMDDhhmmss). Não há fuso horário: vale o relógio do SMSC, normalmente UTC. O decodificador mostra as datas como estão e calcula a latência como done date menos submit date, o que independe do fuso enquanto ambas vierem do mesmo relógio.
A latência é um bom indicador de qualidade. Um OTP para um aparelho disponível costuma ser entregue em segundos. Latências longas seguidas de EXPIRED indicam aparelhos desligados ou em roaming, e uma done date anterior à submit date mostra relógios dessincronizados. Datas com precisão de minuto não medem latências abaixo de um minuto, então prefira SMSCs que enviam os segundos.
Processando confirmações com confiabilidade em produção
Responda a cada deliver_sm com deliver_sm_resp, mesmo que seu processamento falhe; caso contrário, o SMSC reenvia e pode limitar o bind. Armazene a confirmação bruta e processe de forma assíncrona e idempotente pelo ID da mensagem, porque confirmações podem chegar duplicadas ou fora de ordem: um ENROUTE atrasado nunca deve sobrescrever um DELIVRD.
Se preferir não interpretar confirmações, nossa API REST de SMS entrega as mesmas informações como status de webhook normalizados, e confirmações perdidas podem ser reenviadas com POST /sms/resendDlr. Binds SMPP sobre TLS estão disponíveis para grandes volumes e revendedores.
