Estrutura do Payload
Formato geral
Seção intitulada “Formato geral”O payload TRP segue o formato TLV (Tag-Length-Value) com prefixo fixo:
trp01 + [CAMPO][TAMANHO][VALOR] + ... + [99][04][CRC]Cada campo é composto por:
- Tag (2 dígitos): identificador do campo
- Length (2 dígitos): tamanho do valor em caracteres
- Value (N caracteres): conteúdo do campo
Anatomia
Seção intitulada “Anatomia”trp01 0148UQBJ6gU8... 0208store123 030510000 0404USDT 0508tx123456 99045D57
| | | | | | || | | | | | +- CRC16-CCITT| | | | | +- Transaction ID| | | | +- Currency| | | +- Amount (centavos)| | +- Merchant ID| +- TON Wallet (48 chars)+- Prefixo TRP v1- O payload deve começar com
trp01 - Tamanho mínimo: 15 caracteres
- Tamanho máximo: 512 caracteres
- Campos podem aparecer em qualquer ordem, exceto o CRC que é sempre o último
- O tamanho do campo deve ser numérico e ter exatamente 2 dígitos
Cálculo do CRC
Seção intitulada “Cálculo do CRC”O CRC16-CCITT é calculado sobre o payload completo sem o valor do CRC, mas com o header do campo 99:
crc_input = payload_sem_crc + "9904"crc = CRC16_CCITT(crc_input) // polinômio 0x1021, inicial 0xFFFFO resultado é um hexadecimal de 4 caracteres (uppercase).
Exemplo em Python
Seção intitulada “Exemplo em Python”def crc16_ccitt(data: str) -> str: crc = 0xFFFF for byte in data.encode('utf-8'): crc ^= byte << 8 for _ in range(8): if crc & 0x8000: crc = (crc << 1) ^ 0x1021 else: crc = crc << 1 crc &= 0xFFFF return format(crc, '04X')Exemplo em TypeScript
Seção intitulada “Exemplo em TypeScript”function crc16Ccitt(data: string): string { let crc = 0xffff for (let i = 0; i < data.length; i++) { crc ^= data.charCodeAt(i) << 8 for (let j = 0; j < 8; j++) { crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1 crc &= 0xffff } } return crc.toString(16).toUpperCase().padStart(4, '0')}