{"content_id":"gyaevhk2bq","slug":"x402-payments-2026-v2-base-usdc-settlement-guide","locale":"pt","schema_type":"HowTo","category":"tutorial","category_name":"Tutorial","title":"x402 2026 v2: implementar pagamentos e validar liquidação","summary":"Exercício prático em Node.js para adicionar micropagamentos a uma API com x402 v2. Na Base Sepolia, selecione as condições de pagamento, solicite novamente a assinatura e valide a liquidação. Verifique os reenvios e as condições para a migração para a mainnet.","sponsorship_disclosure":null,"affiliate_disclosure":null,"commerce_disclosure":null,"author":{"name":"injoys","url":"https://injoys.com/ko/about"},"key_points":["Prepare o endereço de recebimento e a carteira para testes de pagamento e instale o SDK oficial do x402.","Integre o middleware de pagamento para a Base Sepolia e verifique a resposta 402 a uma requisição sem pagamento.","Selecione e assine apenas as condições que correspondam à rede, ao token, ao valor e ao destinatário autorizados pelo cliente.","Consulte o evento USDC Transfer usando o hash da transação presente na resposta de liquidação.","Teste o bloqueio em caso de falha e a recuperação de requisições duplicadas e, depois, revise as configurações da mainnet."],"content_markdown":"O pagamento x402 é implementado incluindo as condições de pagamento na resposta 402 da API. Prepare o Node.js e uma carteira de teste. Primeiro, valide a assinatura e a liquidação v2 na Base Sepolia. Configure o envio da resposta paga somente após o sucesso da liquidação.\n\nAs informações de valores e redes seguem a documentação oficial de x402, Base e Circle vinculada nas fontes.\n\n## Preparação e instalação para a prática\n\nPrepare um ambiente de desenvolvimento em que seja possível modificar a API e uma carteira de teste. O exemplo foi elaborado com Node.js 22 e x402 SDK 2.28.0. A estrutura de instalação segue o [guia oficial para vendedores](https://docs.x402.org/getting-started/quickstart-for-sellers).\n\n1. Prepare um endereço de carteira EVM para receber os pagamentos.\n2. Prepare uma carteira de teste separada para efetuar os pagamentos.\n3. Obtenha USDC de teste da Base Sepolia para a carteira de pagamento.\n4. Crie o projeto de prática com os comandos abaixo.\n5. Salve os arquivos TypeScript apresentados a seguir na mesma pasta.\n\n```bash\nmkdir x402-demo\ncd x402-demo\nnpm init -y\nnpm pkg set type=module\nnpm install --save-exact express@5.3.0 viem@2.57.12 @x402/core@2.28.0 @x402/express@2.28.0 @x402/evm@2.28.0 @x402/fetch@2.28.0\nnpm install --save-dev --save-exact typescript tsx @types/node @types/express\n```\n\nO servidor que recebe os pagamentos não precisa da chave privada da carteira recebedora. Configure a chave privada usada para pagar de modo que ela seja lida apenas pelo processo do cliente. O método de assinatura da carteira segue o [guia oficial para compradores](https://docs.x402.org/getting-started/quickstart-for-buyers).\n\nA validação deste exemplo abrange a checagem de tipos e um fluxo de pagamento simulado. Não é um exemplo em que a transferência real na rede de testes já foi concluída. Confira os resultados on-chain por conta própria nas etapas de execução abaixo.\n\n## Comparação entre x402 v1 e v2\n\nAo implementar a v2, é preciso adequar tanto os cabeçalhos quanto os campos do corpo. Alterar apenas os nomes dos cabeçalhos deixa a estrutura dos dados incompatível. A tabela a seguir se baseia no [guia oficial de migração](https://docs.x402.org/guides/migration-v1-to-v2).\n\n| Aspecto | v1 | v2 |\n|---|---|---|\n| Versão do protocolo | `x402Version: 1` | `x402Version: 2` |\n| Condições iniciais de pagamento | Corpo JSON da resposta 402 | Cabeçalho de resposta `PAYMENT-REQUIRED` |\n| Dados de pagamento assinados | Cabeçalho de requisição `X-PAYMENT` | Cabeçalho de requisição `PAYMENT-SIGNATURE` |\n| Resultado da liquidação | Cabeçalho de resposta `X-PAYMENT-RESPONSE` | Cabeçalho de resposta `PAYMENT-RESPONSE` |\n| Identificador da rede principal da Base | `base` | `eip155:8453` |\n| Identificador da Base Sepolia | `base-sepolia` | `eip155:84532` |\n| Campo de valor nas condições de pagamento | `maxAmountRequired` | `amount` |\n| Descrição do recurso | `resource` e outros campos dentro das condições de pagamento | Objeto `resource` no nível superior |\n| Condições no payload de pagamento | `scheme`, `network` e outros campos no nível superior | Objeto `accepted` com as condições selecionadas |\n| Exemplo de pacote TypeScript | `x402-express` | `@x402/express` |\n\nO local de envio das condições de pagamento na v1 está definido na [especificação HTTP v1](https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md). Na v2, o local padrão é o cabeçalho `PAYMENT-REQUIRED`. A implementação também pode retornar um corpo, mas use o cabeçalho como referência para o processamento.\n\nA [especificação HTTP v2](https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md) descreve o código de status da seguinte forma.\n\n\u003e O servidor indica que o pagamento é necessário usando o código de status HTTP 402 \"Pagamento necessário\".\n\u003e\n\u003e Fonte: especificação HTTP v2 do x402\n\nOs cabeçalhos de pagamento da v2 contêm valores JSON codificados em Base64. Base64 não é um método de criptografia. Use HTTPS em serviços externos.\n\n## Sequência de requisição HTTP 402 e pagamento\n\nEsta prática usa o fluxo básico de autorização do mecanismo EVM `exact`. `exact` é uma forma de pagamento de um valor definido. A sequência segue a [especificação central do x402 v2](https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md).\n\n1. O cliente faz uma requisição à API paga sem informações de pagamento.\n2. O servidor retorna HTTP 402 e `PAYMENT-REQUIRED`.\n3. O cliente seleciona uma das condições permitidas em `accepts`.\n4. O SDK assina uma autorização de pagamento compatível com a condição selecionada.\n5. O cliente repete a requisição incluindo `PAYMENT-SIGNATURE`.\n6. O servidor valida a autorização por meio de `/verify` do facilitador.\n7. Se a validação for aprovada, o servidor executa o processamento do recurso.\n8. O servidor solicita a liquidação por meio de `/settle`.\n9. Após o sucesso da liquidação, entrega o corpo pago e `PAYMENT-RESPONSE`.\n\nEssa não é uma sequência fixa comum a todos os métodos de pagamento. A v2 também define fluxos com outros momentos de liquidação. O código abaixo permite apenas o fluxo básico `authorization`.\n\n### Papéis do servidor de recursos e do facilitador\n\nO servidor de recursos determina o preço e as condições de acesso ao conteúdo. O facilitador é responsável pela validação do pagamento e pela liquidação. A divisão de papéis se baseia na [documentação oficial do facilitador](https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md).\n\n| Componente | Responsabilidade | Estado que não deve ser considerado sucesso |\n|---|---|---|\n| Cliente | Selecionar condições e assinar a autorização de pagamento | Apenas a geração da assinatura foi concluída |\n| Servidor de recursos | Declarar o preço e controlar a resposta paga | O cliente afirma que houve sucesso |\n| Facilitador `/verify` | Verificar a validade da assinatura e das condições de pagamento | Apenas `isValid: true` foi recebido |\n| Facilitador `/settle` | Nesta prática, executar o pagamento on-chain e retornar o resultado | A transação foi enviada, mas o resultado não foi confirmado |\n\n`/verify` é uma verificação que não altera o estado on-chain. Portanto, uma validação bem-sucedida não significa que o recebimento foi concluído. Mesmo após a validação, o saldo ou o estado da autorização pode mudar.\n\nSe a validação ou a liquidação falhar, bloqueie o corpo pago. Bloquear quando não é possível confirmar o sucesso é um comportamento chamado fail-closed. Esse comportamento também pode ser observado na [implementação oficial para Express](https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts).\n\n## Comparação entre a rede principal e a rede de testes da Base\n\nNa primeira execução, use apenas a Base Sepolia. A Circle declara que o USDC da rede de testes não tem valor financeiro. Os endereços seguem a [lista de contratos USDC da Circle](https://developers.circle.com/stablecoins/usdc-contract-addresses).\n\n| Item | Rede principal da Base | Rede de testes Base Sepolia |\n|---|---|---|\n| Finalidade | Pagamento com ativos reais | Testes de implementação e tratamento de falhas |\n| Chain ID | `8453` | `84532` |\n| Rede x402 v2 | `eip155:8453` | `eip155:84532` |\n| Contrato USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | `0x036CbD53842c5426634e7929541eC2318f3dCF7e` |\n| RPC público | `https://mainnet.base.org` | `https://sepolia.base.org` |\n| Valor financeiro do token | Ativo com valor financeiro real | Sem valor financeiro |\n\nConfira o Chain ID e o RPC na [documentação de rede da Base](https://docs.base.org/get-started/connect-to-base). Mesmo que o endereço da carteira seja o mesmo, os saldos são separados em redes diferentes. Não registre o sucesso na rede de testes como receita real.\n\nVocê pode solicitar USDC de teste no [Circle Testnet Faucet](https://faucet.circle.com/). Selecione Base Sepolia como rede. No endereço de recebimento, informe o endereço da carteira de teste usada para pagar.\n\n## Implementação de uma API paga com Node.js\n\nConecte `paymentMiddleware` antes da rota paga. O exemplo abaixo exige **0.001 USDC** por chamada. O valor usa o preço de exemplo do guia oficial para vendedores. (Valor conferido: 0.001 USDC por chamada · fonte: docs.x402.org · verificado em 2026-10-28)\n\n### Arquivo do servidor\n\nSalve o código a seguir como `server.ts`. O servidor recebe requisições apenas na interface local. O endereço de recebimento é lido da variável de ambiente `PAY_TO`.\n\n```typescript\nimport express from \"express\";\nimport { getAddress, zeroAddress } from \"viem\";\nimport { paymentMiddleware } from \"@x402/express\";\nimport { HTTPFacilitatorClient, x402ResourceServer } from \"@x402/core/server\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/server\";\n\nconst payTo = getAddress(process.env.PAY_TO ?? \"\");\nif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\nconst network = \"eip155:84532\";\nconst resourceServer = new x402ResourceServer(\n  new HTTPFacilitatorClient({ url: \"https://x402.org/facilitator\" }),\n).register(network, new ExactEvmScheme());\n\nconst app = express();\napp.use((_req, res, next) =\u003e {\n  res.setHeader(\"Cache-Control\", \"private, no-store\");\n  next();\n});\napp.use(paymentMiddleware({\n  \"GET /paid-data\": {\n    accepts: [{ scheme: \"exact\", price: \"$0.001\", network, payTo }],\n    description: \"Sample paid JSON\",\n    mimeType: \"application/json\",\n  },\n}, resourceServer));\napp.get(\"/paid-data\", (_req, res) =\u003e {\n  res.json({ content: \"Paid sample content\" });\n});\napp.listen(4021, \"127.0.0.1\");\n```\n\n`https://x402.org/facilitator` é o endereço de teste do guia oficial. Neste exemplo, ele é usado para a liquidação na Base Sepolia. Para escolher um facilitador para produção, consulte o [procedimento para a rede principal no guia para vendedores](https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet).\n\n### Exemplo de cálculo do preço\n\nO preço do exemplo corresponde a `1000` unidades mínimas de USDC. O USDC tem 6 casas decimais. A conversão de preço do SDK se baseia na [implementação do servidor EVM](https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts).\n\n```text\n0.001 USDC × 10^6 = 1000 최소 단위\n```\n\n| Valor a verificar | Valor esperado neste exemplo |\n|---|---|\n| `price` na configuração do servidor | `\"$0.001\"` |\n| `amount` nas condições de pagamento da resposta 402 | `\"1000\"` |\n| `asset` nas condições de pagamento | Contrato USDC da Base Sepolia |\n| `payTo` nas condições de pagamento | Endereço de recebimento configurado |\n| `network` nas condições de pagamento | `eip155:84532` |\n\n`price` é um valor de configuração do SDK. Nas condições de pagamento efetivas da v2, o campo enviado é `amount`. Compare valores inteiros como strings ou `bigint`.\n\n### Execução do servidor e verificação da resposta 402\n\nExecute o servidor no primeiro terminal Bash. O valor informado é o endereço público de recebimento, não uma chave privada. Mantenha esse terminal aberto durante a execução.\n\n```bash\nread -r -p '수취 지갑 주소: ' PAY_TO\nexport PAY_TO\nnpx tsx server.ts\n```\n\nEnvie uma requisição sem pagamento no segundo terminal. O comando abaixo não assina nenhum pagamento. Ele exibe o status HTTP e as condições de pagamento decodificadas.\n\n```bash\nnode --input-type=module \u003c\u003c'JS'\nconst response = await fetch(\"http://127.0.0.1:4021/paid-data\");\nconst header = response.headers.get(\"PAYMENT-REQUIRED\");\nconsole.log(response.status);\nconsole.log(header \u0026\u0026 JSON.parse(\n  Buffer.from(header, \"base64\").toString(\"utf8\")\n));\nJS\n```\n\nA resposta normal sem pagamento é HTTP 402. Compare as condições exibidas com a tabela acima. Se o conteúdo pago for retornado imediatamente, comece corrigindo a configuração de proteção da rota.\n\n## Seleção das condições de pagamento e implementação do cliente\n\nRestrinja o cliente para assinar apenas as condições permitidas. Este exemplo permite somente o preço definido em USDC da Base Sepolia. O filtro de opções de pagamento usa `registerPolicy` da [implementação oficial de x402Client](https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts).\n\n1. Salve o código abaixo como `client.ts`.\n2. Salve também o arquivo `check-transfer.ts` da próxima seção.\n3. Depois de preparar os dois arquivos, siga as etapas de execução.\n\n```typescript\nimport { writeFile } from \"node:fs/promises\";\nimport { getAddress, zeroAddress, type Hex, type Hash } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { x402Client, wrapFetchWithPayment } from \"@x402/fetch\";\nimport { decodePaymentResponseHeader } from \"@x402/core/http\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\nimport { checkTransfer } from \"./check-transfer.js\";\n\nconst key = process.env.EVM_PRIVATE_KEY ?? \"\";\nif (!/^0x[0-9a-fA-F]{64}$/.test(key)) throw new Error(\"Invalid test key\");\nconst signer = privateKeyToAccount(key as Hex);\nconst payTo = getAddress(process.env.PAY_TO ?? \"\");\nif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\nconst network = \"eip155:84532\";\nconst token = \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\";\nconst client = new x402Client().register(network, new ExactEvmScheme(signer));\nclient.registerPolicy((version, options) =\u003e version === 2\n  ? options.filter(r =\u003e\n      r.scheme === \"exact\" \u0026\u0026 r.network === network \u0026\u0026\n      r.asset.toLowerCase() === token.toLowerCase() \u0026\u0026\n      r.payTo.toLowerCase() === payTo.toLowerCase() \u0026\u0026 r.amount === \"1000\" \u0026\u0026\n      (!r.extra?.assetTransferMethod || r.extra.assetTransferMethod === \"eip3009\") \u0026\u0026\n      (!r.extra?.paymentFlow || r.extra.paymentFlow === \"authorization\"))\n  : []);\n\nconst paidFetch = wrapFetchWithPayment(fetch, client);\nconst response = await paidFetch(\"http://127.0.0.1:4021/paid-data\", {\n  redirect: \"error\",\n});\nconst raw = response.headers.get(\"PAYMENT-RESPONSE\");\nif (!raw) throw new Error(`No settlement receipt: HTTP ${response.status}`);\nconst settlement = decodePaymentResponseHeader(raw);\nawait writeFile(\"settlement.json\", JSON.stringify(settlement, null, 2));\nif (!response.ok || !settlement.success || settlement.network !== network) {\n  throw new Error(\"Payment unresolved; inspect settlement.json before retrying\");\n}\nconst evidence = await checkTransfer(\n  network, settlement.transaction as Hash, signer.address, payTo, 1000n,\n);\nawait writeFile(\"transfer.json\", JSON.stringify(evidence, null, 2));\nconsole.log(await response.text());\n```\n\n`wrapFetchWithPayment` cuida do tratamento da resposta 402 e do reenvio da requisição com assinatura. O uso segue o [exemplo oficial de fetch](https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch). Se não houver condições de pagamento permitidas, a geração do pagamento é interrompida.\n\nEste cliente também pode ser usado por agentes de IA. Porém, o limite de preço por chamada não é um limite de gasto acumulado. Gerencie separadamente o orçamento para chamadas repetidas do agente.\n\n## Validação do evento Transfer de USDC\n\nConfira os logs de transferência de USDC usando o hash da transação retornado no resultado da liquidação. O status de sucesso da transação, por si só, não confirma o destinatário. Os campos de `Transfer` seguem o [padrão ERC-20](https://eips.ethereum.org/EIPS/eip-20).\n\nA validação exige os seguintes itens.\n\n| Item de validação | Referência para comparação |\n|---|---|\n| Chain ID do RPC | Rede permitida pelo servidor |\n| `status` do recibo da transação | Estado de sucesso |\n| Endereço que emitiu o evento | Contrato oficial de USDC nessa rede |\n| `Transfer.from` | Pagador confirmado |\n| `Transfer.to` | Endereço de recebimento definido pelo servidor |\n| `Transfer.value` | Valor em unidades mínimas exigido pelo servidor |\n\nSalve o código abaixo como `check-transfer.ts`. A consulta usa [getTransactionReceipt](https://viem.sh/docs/actions/public/getTransactionReceipt) do viem. A interpretação dos eventos se baseia em [parseEventLogs](https://viem.sh/docs/contract/parseEventLogs).\n\n```typescript\nimport {\n  createPublicClient, http, getAddress, parseEventLogs,\n  erc20Abi, type Address, type Hash,\n} from \"viem\";\nimport { base, baseSepolia } from \"viem/chains\";\n\nconst configs = {\n  \"eip155:84532\": {\n    chain: baseSepolia,\n    rpc: \"https://sepolia.base.org\",\n    token: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n  },\n  \"eip155:8453\": {\n    chain: base,\n    rpc: \"https://mainnet.base.org\",\n    token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n  },\n} as const;\n\nexport async function checkTransfer(\n  network: keyof typeof configs, hash: Hash,\n  payer: Address, payTo: Address, amount: bigint,\n) {\n  const cfg = configs[network];\n  const rpc = createPublicClient({ chain: cfg.chain, transport: http(cfg.rpc) });\n  if (await rpc.getChainId() !== cfg.chain.id) throw new Error(\"Wrong chain\");\n  const receipt = await rpc.getTransactionReceipt({ hash });\n  if (receipt.status !== \"success\") throw new Error(\"Transaction failed\");\n  const logs = parseEventLogs({\n    abi: erc20Abi,\n    eventName: \"Transfer\",\n    logs: receipt.logs.filter(\n      log =\u003e getAddress(log.address) === getAddress(cfg.token),\n    ),\n    strict: true,\n  });\n  const transfer = logs.find(log =\u003e\n    getAddress(log.args.from) === getAddress(payer) \u0026\u0026\n    getAddress(log.args.to) === getAddress(payTo) \u0026\u0026\n    log.args.value === amount,\n  );\n  if (!transfer) throw new Error(\"Matching USDC Transfer not found\");\n  return {\n    network, transaction: hash, logIndex: transfer.logIndex,\n    blockHash: receipt.blockHash, blockNumber: receipt.blockNumber.toString(),\n  };\n}\n```\n\nEssa função confirma que houve uma transferência de USDC na transação em questão. É preciso verificar separadamente se ela está vinculada a um pedido específico da API. No servidor de produção, use as condições do pedido armazenadas como referência para comparação.\n\nNão confie no `transfer.json` enviado pelo cliente como prova para autorizar o acesso. O servidor deste exemplo usa os resultados de validação e liquidação do facilitador. Se quiser usar uma consulta independente como condição de autorização de acesso, ela deve ser executada no servidor.\n\nUma falha na consulta do recibo não significa necessariamente uma falha no pagamento. Se houver um erro de RPC, consulte novamente o hash da transação armazenado. Defina na política operacional o número de confirmações adicionais e o tratamento de reorganizações da rede.\n\n## Execução do pagamento de teste e verificação dos resultados\n\nDepois de salvar todos os arquivos, execute com a carteira de teste. A checagem de tipos não realiza assinaturas nem transferências. Os comandos abaixo usam as ferramentas TypeScript instaladas anteriormente.\n\n1. Verifique os tipos com o comando a seguir.\n2. No segundo terminal, informe o mesmo endereço de recebimento usado no servidor.\n3. Digite a chave privada da carteira de pagamento de teste com a entrada oculta.\n4. Execute o cliente uma vez.\n5. Confira o resultado da liquidação e o log de transferência salvos.\n\n```bash\nnpx tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext server.ts client.ts check-transfer.ts\nread -r -p '같은 수취 지갑 주소: ' PAY_TO\nread -r -s -p '테스트 결제 지갑 개인키: ' EVM_PRIVATE_KEY\nexport PAY_TO EVM_PRIVATE_KEY\nnpx tsx client.ts\nunset EVM_PRIVATE_KEY\n```\n\n| Resultado | Significado | O que verificar |\n|---|---|---|\n| `settlement.json` | Resultado da liquidação retornado pelo servidor | `success`, `network`, `transaction` |\n| `transfer.json` | Registro de transferência encontrado na consulta RPC | Rede, hash da transação, posição do log, informações do bloco |\n| Corpo pago no console | Dados exibidos após a validação deste cliente | Verificar se é o conteúdo solicitado |\n\nUma nova execução do cliente pode gerar um novo pagamento. Este exemplo mínimo não tem armazenamento para impedir duplicações por pedido. Adicione a funcionalidade de novas tentativas somente depois de atender às condições da próxima seção.\n\n## Tratamento por condição de falha de validação\n\nNos testes de falha, confirme que o corpo pago não é exposto. Verificar apenas o status HTTP pode deixar passar uma falha no bloqueio. Consulte o [middleware oficial para Express](https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts) como referência de comportamento.\n\n| Condição de teste | Tratamento esperado | Verificação adicional |\n|---|---|---|\n| Ausência do cabeçalho de pagamento | Retornar 402 e as condições de pagamento | Sem corpo pago |\n| Apresentação de outro token ou destinatário | Rejeitar pela política do cliente | Não gerar assinatura |\n| Assinatura inválida | Bloquear por falha de validação | Não executar o manipulador da rota paga |\n| Saldo insuficiente | Bloquear por falha de validação ou liquidação | Não registrar a liquidação como bem-sucedida |\n| Resultado de liquidação com falha | Bloquear a resposta paga | Não enviar nem mesmo o corpo já preparado |\n| Atraso na resposta do facilitador | Manter pendente, sem confirmação de sucesso | Não gerar automaticamente uma nova autorização |\n| Erro na consulta do recibo por RPC | Preservar o hash da transação e consultar novamente | Não concluir que o pagamento falhou |\n\nNo fluxo básico de autorização, o manipulador é executado antes da liquidação. Uma falha na liquidação não desfaz operações externas. Comece aplicando a consultas sem efeitos colaterais, como neste exemplo.\n\nO envio de e-mails ou a criação de pedidos externos exige um projeto separado. Registre juntos os estados do pagamento e da operação. Defina o que será reexecutado em caso de falha para reduzir operações duplicadas.\n\n## Perda da resposta após a liquidação e recuperação por reenvio\n\nArmazene a conclusão do pagamento e a conclusão da entrega do conteúdo como estados separados. O pagamento pode ser concluído, mas a conexão da resposta pode cair. A referência para tratar essa situação é a [documentação da extensão Payment-Identifier](https://docs.x402.org/extensions/payment-identifier).\n\nA propriedade de não duplicar o processamento quando a mesma operação é solicitada novamente se chama idempotência. `payment-identifier` fornece um identificador de pagamento para isso. Não é uma funcionalidade que fica pronta automaticamente apenas com a adição do identificador.\n\n### Comparação entre pagamento duplicado e reenvio\n\nÉ preciso distinguir a prevenção da reutilização da mesma assinatura da prevenção de pedidos duplicados. EIP-3009 impede a reutilização de um nonce de autorização já usado. Esse comportamento está definido na [especificação ERC-3009](https://eips.ethereum.org/EIPS/eip-3009).\n\n| Situação | Perspectiva da autorização on-chain | Perspectiva da operação da API |\n|---|---|---|\n| Liquidar novamente a mesma autorização | Sujeita à verificação de nonce já utilizado | É necessário consultar o resultado existente |\n| Gerar uma nova autorização para o mesmo pedido | Pode ser tratada como uma autorização separada | É necessário impedir o pagamento duplicado |\n| Perda da resposta após o sucesso da liquidação | A movimentação dos ativos pode estar concluída | É necessário entregar o conteúdo novamente |\n| Tempo limite após a solicitação de liquidação | O resultado ainda é incerto | É necessário manter um estado pendente e verificar a liquidação |\n\nO procedimento a seguir é uma proposta de projeto para conectar a extensão oficial ao armazenamento de produção. Ele não está incluído no código mínimo anterior. Para aplicá-lo em produção, adicione armazenamento persistente e controle de requisições simultâneas.\n\n1. Declare no servidor o suporte à extensão `payment-identifier`.\n2. Preserve no cliente o identificador da requisição lógica.\n3. No servidor, vincule o identificador ao pagador e ao conteúdo da requisição.\n4. Registre atomicamente o estado de processamento para impedir execuções simultâneas.\n5. Quando a liquidação tiver sucesso, salve as evidências da transação e o resultado da resposta.\n6. Se a autorização e o conteúdo da nova requisição forem os mesmos, retorne o resultado armazenado.\n7. Se o resultado da liquidação for incerto, verifique primeiro a autorização existente.\n\nO identificador de pagamento não é uma senha nem um token de acesso. Não retorne o cache pago para uma requisição que apenas conheça o identificador. Verifique também se ele está sendo reutilizado por outro usuário ou com outro corpo de requisição.\n\nNos registros operacionais, armazene juntos a rede, o hash da transação e a posição do log. Vincule esse registro ao pedido para impedir sua reutilização em outros pedidos. A correspondência de `Transfer`, por si só, não comprova o vínculo com o pedido.\n\n## Erros comuns na implementação de pagamentos\n\nConfundir campos de versão e sinais de sucesso leva a avaliações incorretas do pagamento. Use a tabela abaixo na revisão antes da implantação. As diferenças entre versões se baseiam no [guia de migração do x402](https://docs.x402.org/guides/migration-v1-to-v2).\n\n| Erro comum | Critério correto |\n|---|---|\n| Interpretar `extra.version: \"2\"` como a versão do x402 | Verificar a versão do protocolo em `x402Version` |\n| Usar `maxAmountRequired` na v2 | Usar `amount` para o valor nas condições de pagamento |\n| Criar arbitrariamente o cabeçalho `X-PAYMENT-REQUIRED` | Na v1, usar o corpo; na v2, usar `PAYMENT-REQUIRED` |\n| Tratar `isValid: true` como recebimento concluído | Verificar separadamente o resultado de `/settle` |\n| Tratar o `to` de nível superior da transação como destinatário do USDC | Verificar `Transfer.to` do USDC |\n| Presumir que o signatário é o mesmo que envia a transação | Comparar o pagador da autorização com `Transfer.from` |\n| Somar os valores recebidos na rede de testes à receita | Separar os registros da rede principal e da rede de testes |\n| Gerar um novo pagamento a cada tempo limite | Recuperar primeiro o pedido existente e o estado da autorização |\n| Equiparar a versão do pacote SDK à versão do protocolo | Gerenciar separadamente a versão do pacote e `x402Version` |\n\nAs informações de domínio da assinatura do USDC também contêm uma string de versão. Esse valor tem uma finalidade diferente da versão do protocolo x402. Consulte a estrutura do domínio de assinatura na [especificação ERC-3009](https://eips.ethereum.org/EIPS/eip-3009).\n\n## Verificação de segurança e limites de confiança em serviços externos\n\nControle no servidor a determinação de sucesso do pagamento. A resposta de um facilitador externo também exige uma decisão explícita de confiança. A estrutura que permite operar um facilitador próprio está descrita na [documentação do facilitador](https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md).\n\n- Não libere conteúdo com base na mensagem de sucesso do cliente.\n- Compare a rede, o token, o valor e o destinatário declarados pelo servidor.\n- Não registre chaves privadas nem frases-semente nos logs.\n- Exclua também as assinaturas completas de autorização dos logs comuns de acesso.\n- Limite o tamanho dos cabeçalhos de pagamento e o tempo de processamento das requisições.\n- Verifique se as respostas pagas não ficam armazenadas em caches compartilhados.\n- Separe os locais de armazenamento das chaves de teste e de produção.\n- Não crie uma rota alternativa sem pagamento quando o facilitador falhar.\n- Teste na prática a expiração das autorizações e as requisições duplicadas.\n\nAs dependências com versões fixadas nesta prática ainda apresentam alertas de verificação de segurança. `npm audit` relatou um aviso relacionado ao zod. Consulte os detalhes no [aviso de segurança do GitHub](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5).\n\n```bash\nnpm audit\n```\n\nAntes da implantação em produção, verifique a compatibilidade do SDK na versão corrigida. Forçar a troca de uma versão principal pode alterar o comportamento. Não use esta prática como uma configuração de implantação com validação de segurança concluída.\n\n### Comparação entre servidor próprio e Cloudflare Gateway\n\nAo usar o Cloudflare Gateway, a forma de validação no servidor de origem muda. A documentação de 30 de setembro de 2026 especifica o uso de x402 v2. A comparação a seguir se baseia na [documentação de x402 da Cloudflare](https://developers.cloudflare.com/monetization-gateway/x402/).\n\n| Aspecto | Abordagem com Express deste artigo | Cloudflare Monetization Gateway |\n|---|---|---|\n| Processamento do pagamento do cliente | Middleware Express | Gateway |\n| Ponto de validação no servidor de origem | Integração com o facilitador escolhido | Validação do JWT `PAYMENT-CONTEXT` |\n| Entrega do resultado da liquidação | `PAYMENT-RESPONSE` do middleware | O Gateway gera o recibo de liquidação |\n| Verificações adicionais | Redes compatíveis com o facilitador e autenticação | Validação da assinatura JWT e proteção do acesso à origem |\n\n`PAYMENT-CONTEXT` é um cabeçalho entre o Gateway e o servidor de origem. Não é o cabeçalho de assinatura de um cliente x402 comum. Para validar na origem, siga a [documentação Cloudflare Payment validation](https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/).\n\nMesmo quando a requisição passa pelo Gateway, não basta decodificar o JWT. Valide a assinatura com a chave indicada na documentação. Se o cabeçalho estiver ausente ou a validação falhar, bloqueie o conteúdo pago.\n\n## Distinção entre uso real e registros de liquidação\n\nA quantidade de transferências on-chain, por si só, não comprova o consumo de conteúdo. Agregue as métricas operacionais vinculando a liquidação à entrega da resposta. Esta é uma proposta de projeto baseada no fluxo de pagamento e no comportamento de reenvio.\n\n| Registro | Pergunta que permite responder | Registro adicional necessário |\n|---|---|---|\n| Resposta 402 | Quantas vezes as condições de pagamento foram solicitadas | Se houve pagamento de fato |\n| Validação bem-sucedida | Se a autorização era válida | Resultado da liquidação |\n| Transferência de USDC | Se houve movimentação de ativos | Vínculo com o pedido |\n| Liquidação concluída por pedido | Se a requisição paga foi paga | Estado de entrega da resposta |\n| Registro de nova entrega | Se uma requisição já paga foi recuperada | Identificador que a distinga de um novo pagamento |\n\nSepare as requisições de teste na apuração do uso real. Identifique também as novas tentativas do mesmo pedido separadamente. Não apresente o volume de transações, por si só, como demanda pela API ou garantia de receita.\n\n## Procedimento de migração para a rede principal da Base\n\nConsidere a rede principal depois de verificar os caminhos de sucesso e de falha na rede de testes. Alterar apenas a string de rede não conclui a migração. O procedimento de referência segue o [guia oficial para vendedores](https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet).\n\n1. Verifique se o facilitador escolhido oferece suporte à rede principal da Base.\n2. Em `/supported`, verifique o suporte a v2, `exact` e `eip155:8453`.\n3. Configure a autenticação e as condições de uso exigidas pelo provedor.\n4. Altere a rede no servidor e no cliente em conjunto.\n5. Altere o endereço USDC permitido no cliente para o endereço da rede principal.\n6. Confira novamente o valor da resposta 402 e o endereço real de recebimento.\n7. Integre o armazenamento para requisições duplicadas e os procedimentos de recuperação de falhas.\n8. Conclua a verificação de segurança das dependências de produção.\n9. Confirme a transferência real e a entrega do conteúdo com o pequeno valor configurado.\n\nO suporte a múltiplas redes não significa suporte a todas as combinações. Verifique em conjunto o escopo de suporte do SDK e do facilitador. A referência é a [documentação de suporte a redes e tokens](https://docs.x402.org/core-concepts/network-and-token-support).","content_html":"\u003cp\u003eO pagamento x402 é implementado incluindo as condições de pagamento na resposta 402 da API. Prepare o Node.js e uma carteira de teste. Primeiro, valide a assinatura e a liquidação v2 na Base Sepolia. Configure o envio da resposta paga somente após o sucesso da liquidação.\u003c/p\u003e\n\u003cp\u003eAs informações de valores e redes seguem a documentação oficial de x402, Base e Circle vinculada nas fontes.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#prepara%C3%A7%C3%A3o-e-instala%C3%A7%C3%A3o-para-a-pr%C3%A1tica\" class=\"anchor\" id=\"preparação-e-instalação-para-a-prática\"\u003e\u003c/a\u003ePreparação e instalação para a prática\u003c/h2\u003e\n\u003cp\u003ePrepare um ambiente de desenvolvimento em que seja possível modificar a API e uma carteira de teste. O exemplo foi elaborado com Node.js 22 e x402 SDK 2.28.0. A estrutura de instalação segue o \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers\"\u003eguia oficial para vendedores\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ePrepare um endereço de carteira EVM para receber os pagamentos.\u003c/li\u003e\n\u003cli\u003ePrepare uma carteira de teste separada para efetuar os pagamentos.\u003c/li\u003e\n\u003cli\u003eObtenha USDC de teste da Base Sepolia para a carteira de pagamento.\u003c/li\u003e\n\u003cli\u003eCrie o projeto de prática com os comandos abaixo.\u003c/li\u003e\n\u003cli\u003eSalve os arquivos TypeScript apresentados a seguir na mesma pasta.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003emkdir\u003c/span\u003e\u003cspan\u003e x402-demo\n\u003c/span\u003e\u003cspan\u003ecd\u003c/span\u003e\u003cspan\u003e x402-demo\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e init\u003c/span\u003e\u003cspan\u003e -y\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e pkg set type=module\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e install\u003c/span\u003e\u003cspan\u003e --save-exact\u003c/span\u003e\u003cspan\u003e express@5.3.0 viem@2.57.12 @x402/core@2.28.0 @x402/express@2.28.0 @x402/evm@2.28.0 @x402/fetch@2.28.0\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e install\u003c/span\u003e\u003cspan\u003e --save-dev --save-exact\u003c/span\u003e\u003cspan\u003e typescript tsx @types/node @types/express\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eO servidor que recebe os pagamentos não precisa da chave privada da carteira recebedora. Configure a chave privada usada para pagar de modo que ela seja lida apenas pelo processo do cliente. O método de assinatura da carteira segue o \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-buyers\"\u003eguia oficial para compradores\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eA validação deste exemplo abrange a checagem de tipos e um fluxo de pagamento simulado. Não é um exemplo em que a transferência real na rede de testes já foi concluída. Confira os resultados on-chain por conta própria nas etapas de execução abaixo.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#compara%C3%A7%C3%A3o-entre-x402-v1-e-v2\" class=\"anchor\" id=\"comparação-entre-x402-v1-e-v2\"\u003e\u003c/a\u003eComparação entre x402 v1 e v2\u003c/h2\u003e\n\u003cp\u003eAo implementar a v2, é preciso adequar tanto os cabeçalhos quanto os campos do corpo. Alterar apenas os nomes dos cabeçalhos deixa a estrutura dos dados incompatível. A tabela a seguir se baseia no \u003ca href=\"https://docs.x402.org/guides/migration-v1-to-v2\"\u003eguia oficial de migração\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eAspecto\u003c/th\u003e\n\u003cth\u003ev1\u003c/th\u003e\n\u003cth\u003ev2\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eVersão do protocolo\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ex402Version: 1\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003ex402Version: 2\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eCondições iniciais de pagamento\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eCorpo JSON da resposta 402\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eCabeçalho de resposta \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eDados de pagamento assinados\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eCabeçalho de requisição \u003ccode\u003eX-PAYMENT\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eCabeçalho de requisição \u003ccode\u003ePAYMENT-SIGNATURE\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eResultado da liquidação\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eCabeçalho de resposta \u003ccode\u003eX-PAYMENT-RESPONSE\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eCabeçalho de resposta \u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eIdentificador da rede principal da Base\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ebase\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eeip155:8453\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eIdentificador da Base Sepolia\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ebase-sepolia\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eCampo de valor nas condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003emaxAmountRequired\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eamount\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eDescrição do recurso\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\n\u003ccode\u003eresource\u003c/code\u003e e outros campos dentro das condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eObjeto \u003ccode\u003eresource\u003c/code\u003e no nível superior\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eCondições no payload de pagamento\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\n\u003ccode\u003escheme\u003c/code\u003e, \u003ccode\u003enetwork\u003c/code\u003e e outros campos no nível superior\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eObjeto \u003ccode\u003eaccepted\u003c/code\u003e com as condições selecionadas\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eExemplo de pacote TypeScript\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ex402-express\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003e@x402/express\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eO local de envio das condições de pagamento na v1 está definido na \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md\"\u003eespecificação HTTP v1\u003c/a\u003e. Na v2, o local padrão é o cabeçalho \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e. A implementação também pode retornar um corpo, mas use o cabeçalho como referência para o processamento.\u003c/p\u003e\n\u003cp\u003eA \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md\"\u003eespecificação HTTP v2\u003c/a\u003e descreve o código de status da seguinte forma.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eO servidor indica que o pagamento é necessário usando o código de status HTTP 402 \"Pagamento necessário\".\u003c/p\u003e\n\u003cp\u003eFonte: especificação HTTP v2 do x402\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eOs cabeçalhos de pagamento da v2 contêm valores JSON codificados em Base64. Base64 não é um método de criptografia. Use HTTPS em serviços externos.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#sequ%C3%AAncia-de-requisi%C3%A7%C3%A3o-http-402-e-pagamento\" class=\"anchor\" id=\"sequência-de-requisição-http-402-e-pagamento\"\u003e\u003c/a\u003eSequência de requisição HTTP 402 e pagamento\u003c/h2\u003e\n\u003cp\u003eEsta prática usa o fluxo básico de autorização do mecanismo EVM \u003ccode\u003eexact\u003c/code\u003e. \u003ccode\u003eexact\u003c/code\u003e é uma forma de pagamento de um valor definido. A sequência segue a \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md\"\u003eespecificação central do x402 v2\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eO cliente faz uma requisição à API paga sem informações de pagamento.\u003c/li\u003e\n\u003cli\u003eO servidor retorna HTTP 402 e \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eO cliente seleciona uma das condições permitidas em \u003ccode\u003eaccepts\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eO SDK assina uma autorização de pagamento compatível com a condição selecionada.\u003c/li\u003e\n\u003cli\u003eO cliente repete a requisição incluindo \u003ccode\u003ePAYMENT-SIGNATURE\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eO servidor valida a autorização por meio de \u003ccode\u003e/verify\u003c/code\u003e do facilitador.\u003c/li\u003e\n\u003cli\u003eSe a validação for aprovada, o servidor executa o processamento do recurso.\u003c/li\u003e\n\u003cli\u003eO servidor solicita a liquidação por meio de \u003ccode\u003e/settle\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eApós o sucesso da liquidação, entrega o corpo pago e \u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eEssa não é uma sequência fixa comum a todos os métodos de pagamento. A v2 também define fluxos com outros momentos de liquidação. O código abaixo permite apenas o fluxo básico \u003ccode\u003eauthorization\u003c/code\u003e.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#pap%C3%A9is-do-servidor-de-recursos-e-do-facilitador\" class=\"anchor\" id=\"papéis-do-servidor-de-recursos-e-do-facilitador\"\u003e\u003c/a\u003ePapéis do servidor de recursos e do facilitador\u003c/h3\u003e\n\u003cp\u003eO servidor de recursos determina o preço e as condições de acesso ao conteúdo. O facilitador é responsável pela validação do pagamento e pela liquidação. A divisão de papéis se baseia na \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md\"\u003edocumentação oficial do facilitador\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eComponente\u003c/th\u003e\n\u003cth\u003eResponsabilidade\u003c/th\u003e\n\u003cth\u003eEstado que não deve ser considerado sucesso\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Componente\"\u003eCliente\u003c/td\u003e\n\u003ctd data-label=\"Responsabilidade\"\u003eSelecionar condições e assinar a autorização de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Estado que não deve ser considerado sucesso\"\u003eApenas a geração da assinatura foi concluída\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Componente\"\u003eServidor de recursos\u003c/td\u003e\n\u003ctd data-label=\"Responsabilidade\"\u003eDeclarar o preço e controlar a resposta paga\u003c/td\u003e\n\u003ctd data-label=\"Estado que não deve ser considerado sucesso\"\u003eO cliente afirma que houve sucesso\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Componente\"\u003eFacilitador \u003ccode\u003e/verify\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"Responsabilidade\"\u003eVerificar a validade da assinatura e das condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Estado que não deve ser considerado sucesso\"\u003eApenas \u003ccode\u003eisValid: true\u003c/code\u003e foi recebido\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Componente\"\u003eFacilitador \u003ccode\u003e/settle\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"Responsabilidade\"\u003eNesta prática, executar o pagamento on-chain e retornar o resultado\u003c/td\u003e\n\u003ctd data-label=\"Estado que não deve ser considerado sucesso\"\u003eA transação foi enviada, mas o resultado não foi confirmado\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003e/verify\u003c/code\u003e é uma verificação que não altera o estado on-chain. Portanto, uma validação bem-sucedida não significa que o recebimento foi concluído. Mesmo após a validação, o saldo ou o estado da autorização pode mudar.\u003c/p\u003e\n\u003cp\u003eSe a validação ou a liquidação falhar, bloqueie o corpo pago. Bloquear quando não é possível confirmar o sucesso é um comportamento chamado fail-closed. Esse comportamento também pode ser observado na \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts\"\u003eimplementação oficial para Express\u003c/a\u003e.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#compara%C3%A7%C3%A3o-entre-a-rede-principal-e-a-rede-de-testes-da-base\" class=\"anchor\" id=\"comparação-entre-a-rede-principal-e-a-rede-de-testes-da-base\"\u003e\u003c/a\u003eComparação entre a rede principal e a rede de testes da Base\u003c/h2\u003e\n\u003cp\u003eNa primeira execução, use apenas a Base Sepolia. A Circle declara que o USDC da rede de testes não tem valor financeiro. Os endereços seguem a \u003ca href=\"https://developers.circle.com/stablecoins/usdc-contract-addresses\"\u003elista de contratos USDC da Circle\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eItem\u003c/th\u003e\n\u003cth\u003eRede principal da Base\u003c/th\u003e\n\u003cth\u003eRede de testes Base Sepolia\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eFinalidade\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003ePagamento com ativos reais\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003eTestes de implementação e tratamento de falhas\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eChain ID\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003e\u003ccode\u003e8453\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003e\u003ccode\u003e84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eRede x402 v2\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003e\u003ccode\u003eeip155:8453\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eContrato USDC\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003e\u003ccode\u003e0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003e\u003ccode\u003e0x036CbD53842c5426634e7929541eC2318f3dCF7e\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eRPC público\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003e\u003ccode\u003ehttps://mainnet.base.org\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003e\u003ccode\u003ehttps://sepolia.base.org\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item\"\u003eValor financeiro do token\u003c/td\u003e\n\u003ctd data-label=\"Rede principal da Base\"\u003eAtivo com valor financeiro real\u003c/td\u003e\n\u003ctd data-label=\"Rede de testes Base Sepolia\"\u003eSem valor financeiro\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eConfira o Chain ID e o RPC na \u003ca href=\"https://docs.base.org/get-started/connect-to-base\"\u003edocumentação de rede da Base\u003c/a\u003e. Mesmo que o endereço da carteira seja o mesmo, os saldos são separados em redes diferentes. Não registre o sucesso na rede de testes como receita real.\u003c/p\u003e\n\u003cp\u003eVocê pode solicitar USDC de teste no \u003ca href=\"https://faucet.circle.com/\"\u003eCircle Testnet Faucet\u003c/a\u003e. Selecione Base Sepolia como rede. No endereço de recebimento, informe o endereço da carteira de teste usada para pagar.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#implementa%C3%A7%C3%A3o-de-uma-api-paga-com-nodejs\" class=\"anchor\" id=\"implementação-de-uma-api-paga-com-nodejs\"\u003e\u003c/a\u003eImplementação de uma API paga com Node.js\u003c/h2\u003e\n\u003cp\u003eConecte \u003ccode\u003epaymentMiddleware\u003c/code\u003e antes da rota paga. O exemplo abaixo exige \u003cstrong\u003e0.001 USDC\u003c/strong\u003e por chamada. O valor usa o preço de exemplo do guia oficial para vendedores. (Valor conferido: 0.001 USDC por chamada · fonte: docs.x402.org · verificado em 2026-10-28)\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#arquivo-do-servidor\" class=\"anchor\" id=\"arquivo-do-servidor\"\u003e\u003c/a\u003eArquivo do servidor\u003c/h3\u003e\n\u003cp\u003eSalve o código a seguir como \u003ccode\u003eserver.ts\u003c/code\u003e. O servidor recebe requisições apenas na interface local. O endereço de recebimento é lido da variável de ambiente \u003ccode\u003ePAY_TO\u003c/code\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport express from \"express\";\n\u003c/span\u003e\u003cspan\u003eimport { getAddress, zeroAddress } from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { paymentMiddleware } from \"@x402/express\";\n\u003c/span\u003e\u003cspan\u003eimport { HTTPFacilitatorClient, x402ResourceServer } from \"@x402/core/server\";\n\u003c/span\u003e\u003cspan\u003eimport { ExactEvmScheme } from \"@x402/evm/exact/server\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst payTo = getAddress(process.env.PAY_TO ?? \"\");\n\u003c/span\u003e\u003cspan\u003eif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\n\u003c/span\u003e\u003cspan\u003econst network = \"eip155:84532\";\n\u003c/span\u003e\u003cspan\u003econst resourceServer = new x402ResourceServer(\n\u003c/span\u003e\u003cspan\u003e  new HTTPFacilitatorClient({ url: \"https://x402.org/facilitator\" }),\n\u003c/span\u003e\u003cspan\u003e).register(network, new ExactEvmScheme());\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst app = express();\n\u003c/span\u003e\u003cspan\u003eapp.use((_req, res, next) =\u0026gt; {\n\u003c/span\u003e\u003cspan\u003e  res.setHeader(\"Cache-Control\", \"private, no-store\");\n\u003c/span\u003e\u003cspan\u003e  next();\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003eapp.use(paymentMiddleware({\n\u003c/span\u003e\u003cspan\u003e  \"GET /paid-data\": {\n\u003c/span\u003e\u003cspan\u003e    accepts: [{ scheme: \"exact\", price: \"$0.001\", network, payTo }],\n\u003c/span\u003e\u003cspan\u003e    description: \"Sample paid JSON\",\n\u003c/span\u003e\u003cspan\u003e    mimeType: \"application/json\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e}, resourceServer));\n\u003c/span\u003e\u003cspan\u003eapp.get(\"/paid-data\", (_req, res) =\u0026gt; {\n\u003c/span\u003e\u003cspan\u003e  res.json({ content: \"Paid sample content\" });\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003eapp.listen(4021, \"127.0.0.1\");\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003ehttps://x402.org/facilitator\u003c/code\u003e é o endereço de teste do guia oficial. Neste exemplo, ele é usado para a liquidação na Base Sepolia. Para escolher um facilitador para produção, consulte o \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet\"\u003eprocedimento para a rede principal no guia para vendedores\u003c/a\u003e.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#exemplo-de-c%C3%A1lculo-do-pre%C3%A7o\" class=\"anchor\" id=\"exemplo-de-cálculo-do-preço\"\u003e\u003c/a\u003eExemplo de cálculo do preço\u003c/h3\u003e\n\u003cp\u003eO preço do exemplo corresponde a \u003ccode\u003e1000\u003c/code\u003e unidades mínimas de USDC. O USDC tem 6 casas decimais. A conversão de preço do SDK se baseia na \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts\"\u003eimplementação do servidor EVM\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003e0.001 USDC × 10^6 = 1000 최소 단위\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eValor a verificar\u003c/th\u003e\n\u003cth\u003eValor esperado neste exemplo\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Valor a verificar\"\u003e\n\u003ccode\u003eprice\u003c/code\u003e na configuração do servidor\u003c/td\u003e\n\u003ctd data-label=\"Valor esperado neste exemplo\"\u003e\u003ccode\u003e\"$0.001\"\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Valor a verificar\"\u003e\n\u003ccode\u003eamount\u003c/code\u003e nas condições de pagamento da resposta 402\u003c/td\u003e\n\u003ctd data-label=\"Valor esperado neste exemplo\"\u003e\u003ccode\u003e\"1000\"\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Valor a verificar\"\u003e\n\u003ccode\u003easset\u003c/code\u003e nas condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Valor esperado neste exemplo\"\u003eContrato USDC da Base Sepolia\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Valor a verificar\"\u003e\n\u003ccode\u003epayTo\u003c/code\u003e nas condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Valor esperado neste exemplo\"\u003eEndereço de recebimento configurado\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Valor a verificar\"\u003e\n\u003ccode\u003enetwork\u003c/code\u003e nas condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Valor esperado neste exemplo\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003eprice\u003c/code\u003e é um valor de configuração do SDK. Nas condições de pagamento efetivas da v2, o campo enviado é \u003ccode\u003eamount\u003c/code\u003e. Compare valores inteiros como strings ou \u003ccode\u003ebigint\u003c/code\u003e.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#execu%C3%A7%C3%A3o-do-servidor-e-verifica%C3%A7%C3%A3o-da-resposta-402\" class=\"anchor\" id=\"execução-do-servidor-e-verificação-da-resposta-402\"\u003e\u003c/a\u003eExecução do servidor e verificação da resposta 402\u003c/h3\u003e\n\u003cp\u003eExecute o servidor no primeiro terminal Bash. O valor informado é o endereço público de recebimento, não uma chave privada. Mantenha esse terminal aberto durante a execução.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e수취 지갑 주소: \u003c/span\u003e\u003cspan\u003e' PAY_TO\n\u003c/span\u003e\u003cspan\u003eexport \u003c/span\u003e\u003cspan\u003ePAY_TO\n\u003c/span\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsx server.ts\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eEnvie uma requisição sem pagamento no segundo terminal. O comando abaixo não assina nenhum pagamento. Ele exibe o status HTTP e as condições de pagamento decodificadas.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enode\u003c/span\u003e\u003cspan\u003e --input-type\u003c/span\u003e\u003cspan\u003e=module \u0026lt;\u0026lt;'\u003c/span\u003e\u003cspan\u003eJS\u003c/span\u003e\u003cspan\u003e'\n\u003c/span\u003e\u003cspan\u003econst response = await fetch(\"http://127.0.0.1:4021/paid-data\");\n\u003c/span\u003e\u003cspan\u003econst header = response.headers.get(\"PAYMENT-REQUIRED\");\n\u003c/span\u003e\u003cspan\u003econsole.log(response.status);\n\u003c/span\u003e\u003cspan\u003econsole.log(header \u0026amp;\u0026amp; JSON.parse(\n\u003c/span\u003e\u003cspan\u003e  Buffer.from(header, \"base64\").toString(\"utf8\")\n\u003c/span\u003e\u003cspan\u003e));\n\u003c/span\u003e\u003cspan\u003eJS\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eA resposta normal sem pagamento é HTTP 402. Compare as condições exibidas com a tabela acima. Se o conteúdo pago for retornado imediatamente, comece corrigindo a configuração de proteção da rota.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#sele%C3%A7%C3%A3o-das-condi%C3%A7%C3%B5es-de-pagamento-e-implementa%C3%A7%C3%A3o-do-cliente\" class=\"anchor\" id=\"seleção-das-condições-de-pagamento-e-implementação-do-cliente\"\u003e\u003c/a\u003eSeleção das condições de pagamento e implementação do cliente\u003c/h2\u003e\n\u003cp\u003eRestrinja o cliente para assinar apenas as condições permitidas. Este exemplo permite somente o preço definido em USDC da Base Sepolia. O filtro de opções de pagamento usa \u003ccode\u003eregisterPolicy\u003c/code\u003e da \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts\"\u003eimplementação oficial de x402Client\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eSalve o código abaixo como \u003ccode\u003eclient.ts\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSalve também o arquivo \u003ccode\u003echeck-transfer.ts\u003c/code\u003e da próxima seção.\u003c/li\u003e\n\u003cli\u003eDepois de preparar os dois arquivos, siga as etapas de execução.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport { writeFile } from \"node:fs/promises\";\n\u003c/span\u003e\u003cspan\u003eimport { getAddress, zeroAddress, type Hex, type Hash } from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { privateKeyToAccount } from \"viem/accounts\";\n\u003c/span\u003e\u003cspan\u003eimport { x402Client, wrapFetchWithPayment } from \"@x402/fetch\";\n\u003c/span\u003e\u003cspan\u003eimport { decodePaymentResponseHeader } from \"@x402/core/http\";\n\u003c/span\u003e\u003cspan\u003eimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\n\u003c/span\u003e\u003cspan\u003eimport { checkTransfer } from \"./check-transfer.js\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst key = process.env.EVM_PRIVATE_KEY ?? \"\";\n\u003c/span\u003e\u003cspan\u003eif (!/^0x[0-9a-fA-F]{64}$/.test(key)) throw new Error(\"Invalid test key\");\n\u003c/span\u003e\u003cspan\u003econst signer = privateKeyToAccount(key as Hex);\n\u003c/span\u003e\u003cspan\u003econst payTo = getAddress(process.env.PAY_TO ?? \"\");\n\u003c/span\u003e\u003cspan\u003eif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\n\u003c/span\u003e\u003cspan\u003econst network = \"eip155:84532\";\n\u003c/span\u003e\u003cspan\u003econst token = \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\";\n\u003c/span\u003e\u003cspan\u003econst client = new x402Client().register(network, new ExactEvmScheme(signer));\n\u003c/span\u003e\u003cspan\u003eclient.registerPolicy((version, options) =\u0026gt; version === 2\n\u003c/span\u003e\u003cspan\u003e  ? options.filter(r =\u0026gt;\n\u003c/span\u003e\u003cspan\u003e      r.scheme === \"exact\" \u0026amp;\u0026amp; r.network === network \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      r.asset.toLowerCase() === token.toLowerCase() \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      r.payTo.toLowerCase() === payTo.toLowerCase() \u0026amp;\u0026amp; r.amount === \"1000\" \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      (!r.extra?.assetTransferMethod || r.extra.assetTransferMethod === \"eip3009\") \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      (!r.extra?.paymentFlow || r.extra.paymentFlow === \"authorization\"))\n\u003c/span\u003e\u003cspan\u003e  : []);\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst paidFetch = wrapFetchWithPayment(fetch, client);\n\u003c/span\u003e\u003cspan\u003econst response = await paidFetch(\"http://127.0.0.1:4021/paid-data\", {\n\u003c/span\u003e\u003cspan\u003e  redirect: \"error\",\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003econst raw = response.headers.get(\"PAYMENT-RESPONSE\");\n\u003c/span\u003e\u003cspan\u003eif (!raw) throw new Error(`No settlement receipt: HTTP ${response.status}`);\n\u003c/span\u003e\u003cspan\u003econst settlement = decodePaymentResponseHeader(raw);\n\u003c/span\u003e\u003cspan\u003eawait writeFile(\"settlement.json\", JSON.stringify(settlement, null, 2));\n\u003c/span\u003e\u003cspan\u003eif (!response.ok || !settlement.success || settlement.network !== network) {\n\u003c/span\u003e\u003cspan\u003e  throw new Error(\"Payment unresolved; inspect settlement.json before retrying\");\n\u003c/span\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003cspan\u003econst evidence = await checkTransfer(\n\u003c/span\u003e\u003cspan\u003e  network, settlement.transaction as Hash, signer.address, payTo, 1000n,\n\u003c/span\u003e\u003cspan\u003e);\n\u003c/span\u003e\u003cspan\u003eawait writeFile(\"transfer.json\", JSON.stringify(evidence, null, 2));\n\u003c/span\u003e\u003cspan\u003econsole.log(await response.text());\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003ewrapFetchWithPayment\u003c/code\u003e cuida do tratamento da resposta 402 e do reenvio da requisição com assinatura. O uso segue o \u003ca href=\"https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch\"\u003eexemplo oficial de fetch\u003c/a\u003e. Se não houver condições de pagamento permitidas, a geração do pagamento é interrompida.\u003c/p\u003e\n\u003cp\u003eEste cliente também pode ser usado por agentes de IA. Porém, o limite de preço por chamada não é um limite de gasto acumulado. Gerencie separadamente o orçamento para chamadas repetidas do agente.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#valida%C3%A7%C3%A3o-do-evento-transfer-de-usdc\" class=\"anchor\" id=\"validação-do-evento-transfer-de-usdc\"\u003e\u003c/a\u003eValidação do evento Transfer de USDC\u003c/h2\u003e\n\u003cp\u003eConfira os logs de transferência de USDC usando o hash da transação retornado no resultado da liquidação. O status de sucesso da transação, por si só, não confirma o destinatário. Os campos de \u003ccode\u003eTransfer\u003c/code\u003e seguem o \u003ca href=\"https://eips.ethereum.org/EIPS/eip-20\"\u003epadrão ERC-20\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eA validação exige os seguintes itens.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eItem de validação\u003c/th\u003e\n\u003cth\u003eReferência para comparação\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003eChain ID do RPC\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003eRede permitida pelo servidor\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003e\n\u003ccode\u003estatus\u003c/code\u003e do recibo da transação\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003eEstado de sucesso\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003eEndereço que emitiu o evento\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003eContrato oficial de USDC nessa rede\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003e\u003ccode\u003eTransfer.from\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003ePagador confirmado\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003e\u003ccode\u003eTransfer.to\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003eEndereço de recebimento definido pelo servidor\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Item de validação\"\u003e\u003ccode\u003eTransfer.value\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Referência para comparação\"\u003eValor em unidades mínimas exigido pelo servidor\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eSalve o código abaixo como \u003ccode\u003echeck-transfer.ts\u003c/code\u003e. A consulta usa \u003ca href=\"https://viem.sh/docs/actions/public/getTransactionReceipt\"\u003egetTransactionReceipt\u003c/a\u003e do viem. A interpretação dos eventos se baseia em \u003ca href=\"https://viem.sh/docs/contract/parseEventLogs\"\u003eparseEventLogs\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport {\n\u003c/span\u003e\u003cspan\u003e  createPublicClient, http, getAddress, parseEventLogs,\n\u003c/span\u003e\u003cspan\u003e  erc20Abi, type Address, type Hash,\n\u003c/span\u003e\u003cspan\u003e} from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { base, baseSepolia } from \"viem/chains\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst configs = {\n\u003c/span\u003e\u003cspan\u003e  \"eip155:84532\": {\n\u003c/span\u003e\u003cspan\u003e    chain: baseSepolia,\n\u003c/span\u003e\u003cspan\u003e    rpc: \"https://sepolia.base.org\",\n\u003c/span\u003e\u003cspan\u003e    token: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e  \"eip155:8453\": {\n\u003c/span\u003e\u003cspan\u003e    chain: base,\n\u003c/span\u003e\u003cspan\u003e    rpc: \"https://mainnet.base.org\",\n\u003c/span\u003e\u003cspan\u003e    token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e} as const;\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003eexport async function checkTransfer(\n\u003c/span\u003e\u003cspan\u003e  network: keyof typeof configs, hash: Hash,\n\u003c/span\u003e\u003cspan\u003e  payer: Address, payTo: Address, amount: bigint,\n\u003c/span\u003e\u003cspan\u003e) {\n\u003c/span\u003e\u003cspan\u003e  const cfg = configs[network];\n\u003c/span\u003e\u003cspan\u003e  const rpc = createPublicClient({ chain: cfg.chain, transport: http(cfg.rpc) });\n\u003c/span\u003e\u003cspan\u003e  if (await rpc.getChainId() !== cfg.chain.id) throw new Error(\"Wrong chain\");\n\u003c/span\u003e\u003cspan\u003e  const receipt = await rpc.getTransactionReceipt({ hash });\n\u003c/span\u003e\u003cspan\u003e  if (receipt.status !== \"success\") throw new Error(\"Transaction failed\");\n\u003c/span\u003e\u003cspan\u003e  const logs = parseEventLogs({\n\u003c/span\u003e\u003cspan\u003e    abi: erc20Abi,\n\u003c/span\u003e\u003cspan\u003e    eventName: \"Transfer\",\n\u003c/span\u003e\u003cspan\u003e    logs: receipt.logs.filter(\n\u003c/span\u003e\u003cspan\u003e      log =\u0026gt; getAddress(log.address) === getAddress(cfg.token),\n\u003c/span\u003e\u003cspan\u003e    ),\n\u003c/span\u003e\u003cspan\u003e    strict: true,\n\u003c/span\u003e\u003cspan\u003e  });\n\u003c/span\u003e\u003cspan\u003e  const transfer = logs.find(log =\u0026gt;\n\u003c/span\u003e\u003cspan\u003e    getAddress(log.args.from) === getAddress(payer) \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e    getAddress(log.args.to) === getAddress(payTo) \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e    log.args.value === amount,\n\u003c/span\u003e\u003cspan\u003e  );\n\u003c/span\u003e\u003cspan\u003e  if (!transfer) throw new Error(\"Matching USDC Transfer not found\");\n\u003c/span\u003e\u003cspan\u003e  return {\n\u003c/span\u003e\u003cspan\u003e    network, transaction: hash, logIndex: transfer.logIndex,\n\u003c/span\u003e\u003cspan\u003e    blockHash: receipt.blockHash, blockNumber: receipt.blockNumber.toString(),\n\u003c/span\u003e\u003cspan\u003e  };\n\u003c/span\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eEssa função confirma que houve uma transferência de USDC na transação em questão. É preciso verificar separadamente se ela está vinculada a um pedido específico da API. No servidor de produção, use as condições do pedido armazenadas como referência para comparação.\u003c/p\u003e\n\u003cp\u003eNão confie no \u003ccode\u003etransfer.json\u003c/code\u003e enviado pelo cliente como prova para autorizar o acesso. O servidor deste exemplo usa os resultados de validação e liquidação do facilitador. Se quiser usar uma consulta independente como condição de autorização de acesso, ela deve ser executada no servidor.\u003c/p\u003e\n\u003cp\u003eUma falha na consulta do recibo não significa necessariamente uma falha no pagamento. Se houver um erro de RPC, consulte novamente o hash da transação armazenado. Defina na política operacional o número de confirmações adicionais e o tratamento de reorganizações da rede.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#execu%C3%A7%C3%A3o-do-pagamento-de-teste-e-verifica%C3%A7%C3%A3o-dos-resultados\" class=\"anchor\" id=\"execução-do-pagamento-de-teste-e-verificação-dos-resultados\"\u003e\u003c/a\u003eExecução do pagamento de teste e verificação dos resultados\u003c/h2\u003e\n\u003cp\u003eDepois de salvar todos os arquivos, execute com a carteira de teste. A checagem de tipos não realiza assinaturas nem transferências. Os comandos abaixo usam as ferramentas TypeScript instaladas anteriormente.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eVerifique os tipos com o comando a seguir.\u003c/li\u003e\n\u003cli\u003eNo segundo terminal, informe o mesmo endereço de recebimento usado no servidor.\u003c/li\u003e\n\u003cli\u003eDigite a chave privada da carteira de pagamento de teste com a entrada oculta.\u003c/li\u003e\n\u003cli\u003eExecute o cliente uma vez.\u003c/li\u003e\n\u003cli\u003eConfira o resultado da liquidação e o log de transferência salvos.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsc\u003c/span\u003e\u003cspan\u003e --noEmit --strict --skipLibCheck --target\u003c/span\u003e\u003cspan\u003e ES2022\u003c/span\u003e\u003cspan\u003e --module\u003c/span\u003e\u003cspan\u003e NodeNext\u003c/span\u003e\u003cspan\u003e --moduleResolution\u003c/span\u003e\u003cspan\u003e NodeNext server.ts client.ts check-transfer.ts\n\u003c/span\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e같은 수취 지갑 주소: \u003c/span\u003e\u003cspan\u003e' PAY_TO\n\u003c/span\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -s -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e테스트 결제 지갑 개인키: \u003c/span\u003e\u003cspan\u003e' EVM_PRIVATE_KEY\n\u003c/span\u003e\u003cspan\u003eexport \u003c/span\u003e\u003cspan\u003ePAY_TO EVM_PRIVATE_KEY\n\u003c/span\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsx client.ts\n\u003c/span\u003e\u003cspan\u003eunset\u003c/span\u003e\u003cspan\u003e EVM_PRIVATE_KEY\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eResultado\u003c/th\u003e\n\u003cth\u003eSignificado\u003c/th\u003e\n\u003cth\u003eO que verificar\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Resultado\"\u003e\u003ccode\u003esettlement.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Significado\"\u003eResultado da liquidação retornado pelo servidor\u003c/td\u003e\n\u003ctd data-label=\"O que verificar\"\u003e\n\u003ccode\u003esuccess\u003c/code\u003e, \u003ccode\u003enetwork\u003c/code\u003e, \u003ccode\u003etransaction\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Resultado\"\u003e\u003ccode\u003etransfer.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Significado\"\u003eRegistro de transferência encontrado na consulta RPC\u003c/td\u003e\n\u003ctd data-label=\"O que verificar\"\u003eRede, hash da transação, posição do log, informações do bloco\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Resultado\"\u003eCorpo pago no console\u003c/td\u003e\n\u003ctd data-label=\"Significado\"\u003eDados exibidos após a validação deste cliente\u003c/td\u003e\n\u003ctd data-label=\"O que verificar\"\u003eVerificar se é o conteúdo solicitado\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eUma nova execução do cliente pode gerar um novo pagamento. Este exemplo mínimo não tem armazenamento para impedir duplicações por pedido. Adicione a funcionalidade de novas tentativas somente depois de atender às condições da próxima seção.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#tratamento-por-condi%C3%A7%C3%A3o-de-falha-de-valida%C3%A7%C3%A3o\" class=\"anchor\" id=\"tratamento-por-condição-de-falha-de-validação\"\u003e\u003c/a\u003eTratamento por condição de falha de validação\u003c/h2\u003e\n\u003cp\u003eNos testes de falha, confirme que o corpo pago não é exposto. Verificar apenas o status HTTP pode deixar passar uma falha no bloqueio. Consulte o \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts\"\u003emiddleware oficial para Express\u003c/a\u003e como referência de comportamento.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eCondição de teste\u003c/th\u003e\n\u003cth\u003eTratamento esperado\u003c/th\u003e\n\u003cth\u003eVerificação adicional\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eAusência do cabeçalho de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eRetornar 402 e as condições de pagamento\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eSem corpo pago\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eApresentação de outro token ou destinatário\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eRejeitar pela política do cliente\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão gerar assinatura\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eAssinatura inválida\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eBloquear por falha de validação\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão executar o manipulador da rota paga\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eSaldo insuficiente\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eBloquear por falha de validação ou liquidação\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão registrar a liquidação como bem-sucedida\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eResultado de liquidação com falha\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eBloquear a resposta paga\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão enviar nem mesmo o corpo já preparado\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eAtraso na resposta do facilitador\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003eManter pendente, sem confirmação de sucesso\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão gerar automaticamente uma nova autorização\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Condição de teste\"\u003eErro na consulta do recibo por RPC\u003c/td\u003e\n\u003ctd data-label=\"Tratamento esperado\"\u003ePreservar o hash da transação e consultar novamente\u003c/td\u003e\n\u003ctd data-label=\"Verificação adicional\"\u003eNão concluir que o pagamento falhou\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eNo fluxo básico de autorização, o manipulador é executado antes da liquidação. Uma falha na liquidação não desfaz operações externas. Comece aplicando a consultas sem efeitos colaterais, como neste exemplo.\u003c/p\u003e\n\u003cp\u003eO envio de e-mails ou a criação de pedidos externos exige um projeto separado. Registre juntos os estados do pagamento e da operação. Defina o que será reexecutado em caso de falha para reduzir operações duplicadas.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#perda-da-resposta-ap%C3%B3s-a-liquida%C3%A7%C3%A3o-e-recupera%C3%A7%C3%A3o-por-reenvio\" class=\"anchor\" id=\"perda-da-resposta-após-a-liquidação-e-recuperação-por-reenvio\"\u003e\u003c/a\u003ePerda da resposta após a liquidação e recuperação por reenvio\u003c/h2\u003e\n\u003cp\u003eArmazene a conclusão do pagamento e a conclusão da entrega do conteúdo como estados separados. O pagamento pode ser concluído, mas a conexão da resposta pode cair. A referência para tratar essa situação é a \u003ca href=\"https://docs.x402.org/extensions/payment-identifier\"\u003edocumentação da extensão Payment-Identifier\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eA propriedade de não duplicar o processamento quando a mesma operação é solicitada novamente se chama idempotência. \u003ccode\u003epayment-identifier\u003c/code\u003e fornece um identificador de pagamento para isso. Não é uma funcionalidade que fica pronta automaticamente apenas com a adição do identificador.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#compara%C3%A7%C3%A3o-entre-pagamento-duplicado-e-reenvio\" class=\"anchor\" id=\"comparação-entre-pagamento-duplicado-e-reenvio\"\u003e\u003c/a\u003eComparação entre pagamento duplicado e reenvio\u003c/h3\u003e\n\u003cp\u003eÉ preciso distinguir a prevenção da reutilização da mesma assinatura da prevenção de pedidos duplicados. EIP-3009 impede a reutilização de um nonce de autorização já usado. Esse comportamento está definido na \u003ca href=\"https://eips.ethereum.org/EIPS/eip-3009\"\u003eespecificação ERC-3009\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSituação\u003c/th\u003e\n\u003cth\u003ePerspectiva da autorização on-chain\u003c/th\u003e\n\u003cth\u003ePerspectiva da operação da API\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situação\"\u003eLiquidar novamente a mesma autorização\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da autorização on-chain\"\u003eSujeita à verificação de nonce já utilizado\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da operação da API\"\u003eÉ necessário consultar o resultado existente\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situação\"\u003eGerar uma nova autorização para o mesmo pedido\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da autorização on-chain\"\u003ePode ser tratada como uma autorização separada\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da operação da API\"\u003eÉ necessário impedir o pagamento duplicado\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situação\"\u003ePerda da resposta após o sucesso da liquidação\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da autorização on-chain\"\u003eA movimentação dos ativos pode estar concluída\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da operação da API\"\u003eÉ necessário entregar o conteúdo novamente\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situação\"\u003eTempo limite após a solicitação de liquidação\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da autorização on-chain\"\u003eO resultado ainda é incerto\u003c/td\u003e\n\u003ctd data-label=\"Perspectiva da operação da API\"\u003eÉ necessário manter um estado pendente e verificar a liquidação\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eO procedimento a seguir é uma proposta de projeto para conectar a extensão oficial ao armazenamento de produção. Ele não está incluído no código mínimo anterior. Para aplicá-lo em produção, adicione armazenamento persistente e controle de requisições simultâneas.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eDeclare no servidor o suporte à extensão \u003ccode\u003epayment-identifier\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003ePreserve no cliente o identificador da requisição lógica.\u003c/li\u003e\n\u003cli\u003eNo servidor, vincule o identificador ao pagador e ao conteúdo da requisição.\u003c/li\u003e\n\u003cli\u003eRegistre atomicamente o estado de processamento para impedir execuções simultâneas.\u003c/li\u003e\n\u003cli\u003eQuando a liquidação tiver sucesso, salve as evidências da transação e o resultado da resposta.\u003c/li\u003e\n\u003cli\u003eSe a autorização e o conteúdo da nova requisição forem os mesmos, retorne o resultado armazenado.\u003c/li\u003e\n\u003cli\u003eSe o resultado da liquidação for incerto, verifique primeiro a autorização existente.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eO identificador de pagamento não é uma senha nem um token de acesso. Não retorne o cache pago para uma requisição que apenas conheça o identificador. Verifique também se ele está sendo reutilizado por outro usuário ou com outro corpo de requisição.\u003c/p\u003e\n\u003cp\u003eNos registros operacionais, armazene juntos a rede, o hash da transação e a posição do log. Vincule esse registro ao pedido para impedir sua reutilização em outros pedidos. A correspondência de \u003ccode\u003eTransfer\u003c/code\u003e, por si só, não comprova o vínculo com o pedido.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#erros-comuns-na-implementa%C3%A7%C3%A3o-de-pagamentos\" class=\"anchor\" id=\"erros-comuns-na-implementação-de-pagamentos\"\u003e\u003c/a\u003eErros comuns na implementação de pagamentos\u003c/h2\u003e\n\u003cp\u003eConfundir campos de versão e sinais de sucesso leva a avaliações incorretas do pagamento. Use a tabela abaixo na revisão antes da implantação. As diferenças entre versões se baseiam no \u003ca href=\"https://docs.x402.org/guides/migration-v1-to-v2\"\u003eguia de migração do x402\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eErro comum\u003c/th\u003e\n\u003cth\u003eCritério correto\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eInterpretar \u003ccode\u003eextra.version: \"2\"\u003c/code\u003e como a versão do x402\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eVerificar a versão do protocolo em \u003ccode\u003ex402Version\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eUsar \u003ccode\u003emaxAmountRequired\u003c/code\u003e na v2\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eUsar \u003ccode\u003eamount\u003c/code\u003e para o valor nas condições de pagamento\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eCriar arbitrariamente o cabeçalho \u003ccode\u003eX-PAYMENT-REQUIRED\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eNa v1, usar o corpo; na v2, usar \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eTratar \u003ccode\u003eisValid: true\u003c/code\u003e como recebimento concluído\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eVerificar separadamente o resultado de \u003ccode\u003e/settle\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eTratar o \u003ccode\u003eto\u003c/code\u003e de nível superior da transação como destinatário do USDC\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eVerificar \u003ccode\u003eTransfer.to\u003c/code\u003e do USDC\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003ePresumir que o signatário é o mesmo que envia a transação\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eComparar o pagador da autorização com \u003ccode\u003eTransfer.from\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eSomar os valores recebidos na rede de testes à receita\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eSeparar os registros da rede principal e da rede de testes\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eGerar um novo pagamento a cada tempo limite\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eRecuperar primeiro o pedido existente e o estado da autorização\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Erro comum\"\u003eEquiparar a versão do pacote SDK à versão do protocolo\u003c/td\u003e\n\u003ctd data-label=\"Critério correto\"\u003eGerenciar separadamente a versão do pacote e \u003ccode\u003ex402Version\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eAs informações de domínio da assinatura do USDC também contêm uma string de versão. Esse valor tem uma finalidade diferente da versão do protocolo x402. Consulte a estrutura do domínio de assinatura na \u003ca href=\"https://eips.ethereum.org/EIPS/eip-3009\"\u003eespecificação ERC-3009\u003c/a\u003e.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#verifica%C3%A7%C3%A3o-de-seguran%C3%A7a-e-limites-de-confian%C3%A7a-em-servi%C3%A7os-externos\" class=\"anchor\" id=\"verificação-de-segurança-e-limites-de-confiança-em-serviços-externos\"\u003e\u003c/a\u003eVerificação de segurança e limites de confiança em serviços externos\u003c/h2\u003e\n\u003cp\u003eControle no servidor a determinação de sucesso do pagamento. A resposta de um facilitador externo também exige uma decisão explícita de confiança. A estrutura que permite operar um facilitador próprio está descrita na \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md\"\u003edocumentação do facilitador\u003c/a\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eNão libere conteúdo com base na mensagem de sucesso do cliente.\u003c/li\u003e\n\u003cli\u003eCompare a rede, o token, o valor e o destinatário declarados pelo servidor.\u003c/li\u003e\n\u003cli\u003eNão registre chaves privadas nem frases-semente nos logs.\u003c/li\u003e\n\u003cli\u003eExclua também as assinaturas completas de autorização dos logs comuns de acesso.\u003c/li\u003e\n\u003cli\u003eLimite o tamanho dos cabeçalhos de pagamento e o tempo de processamento das requisições.\u003c/li\u003e\n\u003cli\u003eVerifique se as respostas pagas não ficam armazenadas em caches compartilhados.\u003c/li\u003e\n\u003cli\u003eSepare os locais de armazenamento das chaves de teste e de produção.\u003c/li\u003e\n\u003cli\u003eNão crie uma rota alternativa sem pagamento quando o facilitador falhar.\u003c/li\u003e\n\u003cli\u003eTeste na prática a expiração das autorizações e as requisições duplicadas.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAs dependências com versões fixadas nesta prática ainda apresentam alertas de verificação de segurança. \u003ccode\u003enpm audit\u003c/code\u003e relatou um aviso relacionado ao zod. Consulte os detalhes no \u003ca href=\"https://github.com/advisories/GHSA-mrhx-c7xc-m3w5\"\u003eaviso de segurança do GitHub\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e audit\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAntes da implantação em produção, verifique a compatibilidade do SDK na versão corrigida. Forçar a troca de uma versão principal pode alterar o comportamento. Não use esta prática como uma configuração de implantação com validação de segurança concluída.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#compara%C3%A7%C3%A3o-entre-servidor-pr%C3%B3prio-e-cloudflare-gateway\" class=\"anchor\" id=\"comparação-entre-servidor-próprio-e-cloudflare-gateway\"\u003e\u003c/a\u003eComparação entre servidor próprio e Cloudflare Gateway\u003c/h3\u003e\n\u003cp\u003eAo usar o Cloudflare Gateway, a forma de validação no servidor de origem muda. A documentação de 30 de setembro de 2026 especifica o uso de x402 v2. A comparação a seguir se baseia na \u003ca href=\"https://developers.cloudflare.com/monetization-gateway/x402/\"\u003edocumentação de x402 da Cloudflare\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eAspecto\u003c/th\u003e\n\u003cth\u003eAbordagem com Express deste artigo\u003c/th\u003e\n\u003cth\u003eCloudflare Monetization Gateway\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eProcessamento do pagamento do cliente\u003c/td\u003e\n\u003ctd data-label=\"Abordagem com Express deste artigo\"\u003eMiddleware Express\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eGateway\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003ePonto de validação no servidor de origem\u003c/td\u003e\n\u003ctd data-label=\"Abordagem com Express deste artigo\"\u003eIntegração com o facilitador escolhido\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eValidação do JWT \u003ccode\u003ePAYMENT-CONTEXT\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eEntrega do resultado da liquidação\u003c/td\u003e\n\u003ctd data-label=\"Abordagem com Express deste artigo\"\u003e\n\u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e do middleware\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eO Gateway gera o recibo de liquidação\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aspecto\"\u003eVerificações adicionais\u003c/td\u003e\n\u003ctd data-label=\"Abordagem com Express deste artigo\"\u003eRedes compatíveis com o facilitador e autenticação\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eValidação da assinatura JWT e proteção do acesso à origem\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003ePAYMENT-CONTEXT\u003c/code\u003e é um cabeçalho entre o Gateway e o servidor de origem. Não é o cabeçalho de assinatura de um cliente x402 comum. Para validar na origem, siga a \u003ca href=\"https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/\"\u003edocumentação Cloudflare Payment validation\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eMesmo quando a requisição passa pelo Gateway, não basta decodificar o JWT. Valide a assinatura com a chave indicada na documentação. Se o cabeçalho estiver ausente ou a validação falhar, bloqueie o conteúdo pago.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#distin%C3%A7%C3%A3o-entre-uso-real-e-registros-de-liquida%C3%A7%C3%A3o\" class=\"anchor\" id=\"distinção-entre-uso-real-e-registros-de-liquidação\"\u003e\u003c/a\u003eDistinção entre uso real e registros de liquidação\u003c/h2\u003e\n\u003cp\u003eA quantidade de transferências on-chain, por si só, não comprova o consumo de conteúdo. Agregue as métricas operacionais vinculando a liquidação à entrega da resposta. Esta é uma proposta de projeto baseada no fluxo de pagamento e no comportamento de reenvio.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eRegistro\u003c/th\u003e\n\u003cth\u003ePergunta que permite responder\u003c/th\u003e\n\u003cth\u003eRegistro adicional necessário\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Registro\"\u003eResposta 402\u003c/td\u003e\n\u003ctd data-label=\"Pergunta que permite responder\"\u003eQuantas vezes as condições de pagamento foram solicitadas\u003c/td\u003e\n\u003ctd data-label=\"Registro adicional necessário\"\u003eSe houve pagamento de fato\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Registro\"\u003eValidação bem-sucedida\u003c/td\u003e\n\u003ctd data-label=\"Pergunta que permite responder\"\u003eSe a autorização era válida\u003c/td\u003e\n\u003ctd data-label=\"Registro adicional necessário\"\u003eResultado da liquidação\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Registro\"\u003eTransferência de USDC\u003c/td\u003e\n\u003ctd data-label=\"Pergunta que permite responder\"\u003eSe houve movimentação de ativos\u003c/td\u003e\n\u003ctd data-label=\"Registro adicional necessário\"\u003eVínculo com o pedido\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Registro\"\u003eLiquidação concluída por pedido\u003c/td\u003e\n\u003ctd data-label=\"Pergunta que permite responder\"\u003eSe a requisição paga foi paga\u003c/td\u003e\n\u003ctd data-label=\"Registro adicional necessário\"\u003eEstado de entrega da resposta\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Registro\"\u003eRegistro de nova entrega\u003c/td\u003e\n\u003ctd data-label=\"Pergunta que permite responder\"\u003eSe uma requisição já paga foi recuperada\u003c/td\u003e\n\u003ctd data-label=\"Registro adicional necessário\"\u003eIdentificador que a distinga de um novo pagamento\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eSepare as requisições de teste na apuração do uso real. Identifique também as novas tentativas do mesmo pedido separadamente. Não apresente o volume de transações, por si só, como demanda pela API ou garantia de receita.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#procedimento-de-migra%C3%A7%C3%A3o-para-a-rede-principal-da-base\" class=\"anchor\" id=\"procedimento-de-migração-para-a-rede-principal-da-base\"\u003e\u003c/a\u003eProcedimento de migração para a rede principal da Base\u003c/h2\u003e\n\u003cp\u003eConsidere a rede principal depois de verificar os caminhos de sucesso e de falha na rede de testes. Alterar apenas a string de rede não conclui a migração. O procedimento de referência segue o \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet\"\u003eguia oficial para vendedores\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eVerifique se o facilitador escolhido oferece suporte à rede principal da Base.\u003c/li\u003e\n\u003cli\u003eEm \u003ccode\u003e/supported\u003c/code\u003e, verifique o suporte a v2, \u003ccode\u003eexact\u003c/code\u003e e \u003ccode\u003eeip155:8453\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eConfigure a autenticação e as condições de uso exigidas pelo provedor.\u003c/li\u003e\n\u003cli\u003eAltere a rede no servidor e no cliente em conjunto.\u003c/li\u003e\n\u003cli\u003eAltere o endereço USDC permitido no cliente para o endereço da rede principal.\u003c/li\u003e\n\u003cli\u003eConfira novamente o valor da resposta 402 e o endereço real de recebimento.\u003c/li\u003e\n\u003cli\u003eIntegre o armazenamento para requisições duplicadas e os procedimentos de recuperação de falhas.\u003c/li\u003e\n\u003cli\u003eConclua a verificação de segurança das dependências de produção.\u003c/li\u003e\n\u003cli\u003eConfirme a transferência real e a entrega do conteúdo com o pequeno valor configurado.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eO suporte a múltiplas redes não significa suporte a todas as combinações. Verifique em conjunto o escopo de suporte do SDK e do facilitador. A referência é a \u003ca href=\"https://docs.x402.org/core-concepts/network-and-token-support\"\u003edocumentação de suporte a redes e tokens\u003c/a\u003e.\u003c/p\u003e\n","tags":["Stablecoin","Agentes de IA","Desenvolvimento de IA","Monetização de conteúdo","Ferramentas de desenvolvimento"],"faqs":[{"question":"Em que o x402 difere da confirmação de um depósito comum em USDC?","answer":"Durante a solicitação HTTP, são enviadas as condições de pagamento, e a solicitação é reenviada com uma autorização de pagamento assinada. Diferentemente do método de conferir os registros de depósito posteriormente, esse processo vincula o procedimento de pagamento à solicitação de um recurso pago."},{"question":"Quais são os cabeçalhos de pagamento do x402 v2?","answer":"As condições de pagamento são enviadas em PAYMENT-REQUIRED, e o payload de pagamento, em PAYMENT-SIGNATURE. O resultado da liquidação é enviado em PAYMENT-RESPONSE."},{"question":"Existe um cabeçalho X-PAYMENT-REQUIRED na v1?","answer":"A especificação oficial HTTP v1 inclui as condições iniciais de pagamento no corpo da resposta JSON. Para o payload de pagamento e o resultado da liquidação, são usados, respectivamente, X-PAYMENT e X-PAYMENT-RESPONSE."},{"question":"Se /verify for bem-sucedido, o pagamento estará concluído?","answer":"O sucesso de /verify significa que a autorização de pagamento é válida. Neste exercício, é necessário verificar separadamente o resultado bem-sucedido de /settle."},{"question":"O USDC de teste da Base Sepolia pode ser considerado receita real?","answer":"A Circle declara que o USDC da rede de testes não tem valor financeiro. Registre as liquidações da rede de testes separadamente das vendas reais."},{"question":"É necessário colocar uma chave privada no servidor recebedor?","answer":"No servidor recebedor deste exemplo, configura-se apenas o endereço público de recebimento. A chave privada usada para autorizar o pagamento é lida pelo cliente de pagamento."},{"question":"Qual é o valor de amount para 0.001 USDC?","answer":"Aplicando as 6 casas decimais do USDC, o valor na menor unidade é 1000. Nas condições de pagamento da v2, use a string \"1000\"."},{"question":"Se o recibo da transação indicar sucesso, o recebimento de USDC também estará confirmado?","answer":"O status de sucesso da transação, por si só, não é suficiente. Confira o pagador, o recebedor e o valor no evento Transfer do contrato oficial do USDC."},{"question":"É seguro reenviar a mesma solicitação de pagamento?","answer":"A prevenção da reutilização do nonce de uma mesma autorização e a prevenção de pedidos duplicados são questões distintas. Antes de tentar novamente, verifique o status do pagamento existente e implemente o tratamento de idempotência por pedido."},{"question":"Se não houver PAYMENT-RESPONSE, basta pagar novamente?","answer":"Se houver perda da resposta ou tempo limite excedido, o resultado da liquidação pode não estar claro. Não comece criando uma nova autorização; verifique o status da liquidação da solicitação existente."},{"question":"O x402 exige o uso do facilitator de uma empresa específica?","answer":"A estrutura oficial permite tanto o uso de um facilitator externo quanto a operação própria. Verifique se a implementação escolhida oferece suporte à versão do protocolo, à forma de pagamento e à blockchain necessárias."},{"question":"Os gastos de um agente de IA também são limitados automaticamente?","answer":"Este exemplo limita apenas as condições de pagamento de cada solicitação. Gerencie os gastos acumulados por chamadas repetidas com uma política de orçamento separada."},{"question":"O PAYMENT-CONTEXT da Cloudflare é um cabeçalho padrão de assinatura de pagamento?","answer":"PAYMENT-CONTEXT é um JWT que o Gateway encaminha ao servidor de origem. Sua finalidade é diferente da do PAYMENT-SIGNATURE do cliente."},{"question":"Posso implantar o exemplo diretamente na rede principal?","answer":"Este código tem uma configuração mínima para testes. Antes da implantação em produção, verifique os alertas de segurança das dependências, o tratamento de solicitações duplicadas, a autenticação do facilitador e a liquidação real."}],"sources":[{"url":"https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md","title":"Especificação do protocolo x402 v2","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md","title":"Transporte HTTP do x402 v1","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md","title":"Transporte HTTP do x402 v2","type":"source"},{"url":"https://docs.x402.org/guides/migration-v1-to-v2","title":"Guia de migração do x402: de V1 para V2","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md","title":"Papel e responsabilidades do facilitador x402","type":"source"},{"url":"https://docs.x402.org/getting-started/quickstart-for-sellers","title":"Guia de início rápido do x402 para vendedores","type":"source"},{"url":"https://docs.x402.org/getting-started/quickstart-for-buyers","title":"Guia de início rápido do x402 para compradores","type":"source"},{"url":"https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch","title":"Exemplo oficial de cliente fetch do x402 em TypeScript","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts","title":"Implementação de middleware Express para x402","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts","title":"Seleção de condições de pagamento e implementação de políticas no x402Client","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts","title":"Implementação da conversão de preços no servidor x402 ExactEvmScheme","type":"source"},{"url":"https://developers.circle.com/stablecoins/usdc-contract-addresses","title":"Endereço do contrato USDC da Circle","type":"data_point"},{"url":"https://docs.base.org/get-started/connect-to-base","title":"Informações sobre a rede principal Base e a rede Base Sepolia","type":"data_point"},{"url":"https://faucet.circle.com/","title":"Faucet da rede de testes da Circle","type":"source"},{"url":"https://viem.sh/docs/actions/public/getTransactionReceipt","title":"viem getTransactionReceipt","type":"source"},{"url":"https://viem.sh/docs/contract/parseEventLogs","title":"viem parseEventLogs","type":"source"},{"url":"https://eips.ethereum.org/EIPS/eip-20","title":"Padrão de token ERC-20","type":"source"},{"url":"https://eips.ethereum.org/EIPS/eip-3009","title":"ERC-3009 Transferência com autorização","type":"source"},{"url":"https://docs.x402.org/extensions/payment-identifier","title":"Extensão de idempotência Payment-Identifier do x402","type":"source"},{"url":"https://developers.cloudflare.com/monetization-gateway/x402/","title":"Protocolo x402 do Cloudflare Monetization Gateway","type":"source"},{"url":"https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/","title":"Validação de pagamentos do Cloudflare Monetization Gateway","type":"source"},{"url":"https://docs.x402.org/core-concepts/network-and-token-support","title":"Redes e suporte a tokens do x402","type":"source"},{"url":"https://github.com/advisories/GHSA-mrhx-c7xc-m3w5","title":"Alerta de segurança do GitHub: esgotamento de memória devido à validação de grandes coleções pelo Zod","type":"source"}],"images":[{"id":2199,"url":"https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MDcsInB1ciI6ImJsb2JfaWQifX0=--49c502fd8da16158a617c3586dfa81ced4bc95df/ai-f0ae2b5c.webp","is_representative":true,"generation_method":"ai_photo","license":"ai_generated","mime_type":"image/webp","width":1536,"height":1024,"translations":{"ko":{"alt":"짙은 회색 스웨터를 입은 남성이 서버 랙 선반에 놓인 태블릿 화면을 살펴보고 있다.","caption":"메인넷으로 전환하기 전에 테스트 환경에서 x402 결제 연동을 검증하세요.","description":null},"en":{"alt":"A man in a dark gray sweater examines a tablet resting on a server rack shelf.","caption":"Validate the x402 payment integration in a test environment before switching to mainnet.","description":null},"ja":{"alt":"濃いグレーのセーターを着た男性が、サーバーラックの棚に置かれたタブレットを確認している。","caption":"メインネットへ移行する前に、テスト環境でx402の決済連携を検証しましょう。","description":null},"es":{"alt":"Un hombre con un suéter gris oscuro revisa una tableta sobre la bandeja de un rack de servidores.","caption":"Valida la integración de pagos x402 en un entorno de prueba antes de pasar a la red principal.","description":null},"id":{"alt":"Seorang pria bersweater abu-abu gelap memeriksa tablet di atas ambalan rak server.","caption":"Validasi integrasi pembayaran x402 di lingkungan uji sebelum beralih ke mainnet.","description":null},"pt":{"alt":"Um homem de suéter cinza-escuro examina um tablet apoiado na prateleira de um rack de servidores.","caption":"Valide a integração de pagamentos x402 em um ambiente de teste antes de migrar para a rede principal.","description":null},"zh-hant":{"alt":"一名穿著深灰色毛衣的男子正在查看伺服器機架層板上的平板電腦。","caption":"切換至主網前，先在測試環境中驗證 x402 支付整合。","description":null},"de":{"alt":"Ein Mann im dunkelgrauen Pullover prüft ein Tablet auf der Ablage eines Serverracks.","caption":"Prüfen Sie die x402-Zahlungsintegration in einer Testumgebung, bevor Sie ins Mainnet wechseln.","description":null}}},{"id":2200,"url":"https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MTMsInB1ciI6ImJsb2JfaWQifX0=--4e70727f132519277c68d1c6279d95585a936549/ai-3dbd1c62.webp","is_representative":false,"generation_method":"ai_semi","license":"ai_generated","mime_type":"image/webp","width":1536,"height":1024,"translations":{"ko":{"alt":"창가에서 여성이 평평하게 펼친 노트북으로 입력하고 있으며, 화면에는 목록과 두 경로가 합쳐지는 흐름도가 보인다.","caption":"중복 요청 복구를 시험해 결제 재시도가 이중 정산으로 이어지지 않는지 확인하세요.","description":null},"en":{"alt":"A woman types on a laptop opened flat, with a list and two paths converging on one endpoint on its screen.","caption":"Test duplicate-request recovery to ensure payment retries do not cause a second settlement.","description":null},"ja":{"alt":"窓辺で女性が平らに開いたノートパソコンを操作し、画面には一覧と2本の経路が合流するフロー図が表示されている。","caption":"重複リクエストの復旧をテストし、決済の再試行で二重精算が起きないことを確認しましょう。","description":null},"es":{"alt":"Una mujer teclea en un portátil abierto en plano; la pantalla muestra una lista y dos rutas que convergen.","caption":"Prueba la recuperación de solicitudes duplicadas para evitar una segunda liquidación al reintentar el pago.","description":null},"id":{"alt":"Seorang perempuan mengetik di laptop yang dibuka rata, dengan daftar dan diagram dua jalur yang menyatu di layar.","caption":"Uji pemulihan permintaan duplikat untuk memastikan percobaan ulang pembayaran tidak memicu penyelesaian ganda.","description":null},"pt":{"alt":"Uma mulher digita num notebook aberto na horizontal, com uma lista e duas rotas convergentes na tela.","caption":"Teste a recuperação de solicitações duplicadas para garantir que novas tentativas de pagamento não gerem liquidação dupla.","description":null},"zh-hant":{"alt":"一名女子在窗邊操作完全攤平的筆記型電腦，螢幕顯示清單及兩條路徑匯合的流程圖。","caption":"測試重複請求的復原流程，確認付款重試不會造成重複結算。","description":null},"de":{"alt":"Eine Frau tippt auf einem flach aufgeklappten Laptop; das Display zeigt eine Liste und zwei zusammenlaufende Pfade.","caption":"Testen Sie die Wiederherstellung bei doppelten Anfragen, damit Zahlungswiederholungen keine zweite Abrechnung auslösen.","description":null}}}],"published_at":"2026-10-28T19:20:55+09:00","updated_at":"2026-10-28T19:20:55+09:00","license":"cc_by","translation_status":"reviewed","available_locales":["ko","en","ja","es"],"data_locales":["ko","en","ja","es","id","pt","zh-hant","de"],"url":"https://injoys.com/en/articles/x402-payments-2026-v2-base-usdc-settlement-guide"}