Pular para conteúdo

Extensão de mandatos AP2

Visão geral

A extensão AP2 Mandates permite a troca segura de intenções do usuário e autorizações usando Credenciais Digitais Verificáveis. Ele estende o capacidade padrão do Shopping Service Checkout para oferecer suporte ao Protocolo AP2.

Quando esta capacidade é negociada e ativa, ela transforma um padrão sessão de checkout em um contrato vinculado criptograficamente:

  • As empresas DEVEM incorporar uma assinatura criptográfica na finalização da compra respostas, provando que os termos (preço, itens de linha) são autênticos.
  • Plataformas DEVEM fornecer provas assinadas criptograficamente (Mandatos) durante a operação complete, comprovando que o usuário autorizou explicitamente a estado de checkout específico e transferência de fundos.

Security Binding: Depois que esta extensão for negociada no recurso intersecção, a sessão será Segurança Bloqueada. Nenhuma das partes poderá voltar a um fluxo de checkout padrão (desprotegido).

Diagrama de sequência de fluxo AP2 de alto nível

Projeto

Todos os campos específicos do AP2 estão aninhados em um objeto ap2 nas solicitações e respostas. Este projeto fornece:

  • Modularidade do esquema — O esquema de checkout básico permanece limpo; AP2 adiciona um campo contendo todos os seus dados.
  • Canonização consistente — Uma regra: excluir ap2 do negócio cálculo de assinatura. Os campos AP2 futuros são tratados automaticamente.
  • Coexistência de extensões — Várias extensões de segurança podem coexistir sem colisões de namespace.
  • Sinal de capacidade — A presença do objeto ap2 indica claramente AP2 está ativo.

Descoberta e Negociação

Esta extensão segue o protocolo de negociação padrão do BCP. Está ativado somente quando aparece na Interseção de capacidade de ambos os negócios e a plataforma.

Anúncio do perfil da empresa

As empresas declaram apoio adicionando br.dev.bcp.shopping.ap2_mandate aos seus Lista capabilities em /.well-known/ucp.

Exemplo de perfil comercial:json { "ucp": { "version": "2026-07-14", "services": {}, "capabilities": { "br.dev.bcp.shopping.checkout": [ { "version": "2026-07-14", "spec": "https://bcp.dev.br/2026-07-14/specification/checkout", "schema": "https://bcp.dev.br/2026-07-14/schemas/shopping/checkout.json" } ], "br.dev.bcp.shopping.ap2_mandate": [ { "version": "2026-07-14", "spec": "https://bcp.dev.br/2026-07-14/specification/ap2-mandates", "schema": "https://bcp.dev.br/2026-07-14/schemas/shopping/ap2_mandate.json", "extends": "br.dev.bcp.shopping.checkout", "config": { "vp_formats_supported": { "dc+sd-jwt": { } } } } ] }, "payment_handlers": {} } }### Anúncio do perfil da plataforma

As plataformas declaram apoio em seu perfil. Se a plataforma estiver operando sob modelo de provedor de plataforma confiável, a plataforma DEVE fornecer pelo menos um digite a matriz keys de nível superior em seu perfil.

Ativação e bloqueio de sessão

  1. A plataforma anuncia seu URI de perfil (mecanismo específico de transporte).
  2. A empresa busca o perfil e calcula a interseção.
  3. Se br.dev.bcp.shopping.ap2_mandate estiver presente na intersecção:
    • O negócio DEVE incluir ap2.merchant_authorization em todos respostas de checkout.
    • A empresa NÃO DEVE aceitar uma solicitação complete_checkout que não possui ap2.checkout_mandate.
    • A plataforma DEVE verificar a assinatura da empresa antes de apresentar o checkout para o usuário.

Requisitos-chave de assinatura

Para utilizar esta extensão, uma chave de assinatura pública DEVE estar disponível para o empresa para verificar a assinatura do mandato.

  • Fluxo do Provedor da Plataforma: Chave fornecida no keys do perfil da plataforma.
  • Fluxo de credencial do usuário: Chave vinculada à credencial de pagamento digital.

Se uma chave pública não puder ser resolvida ou se a assinatura for inválida, a empresa DEVE retornar um erro.

Requisitos criptográficos

Esta extensão usa as primitivas criptográficas definidas no Especificação de Assinaturas de mensagens:

  • Algoritmo: de acordo com a regra de assinatura JWT do Checkout do AP2 — o AP2 v0.2 requer ECDSA (ES256/ES384/ES512); veja a nota abaixo.
  • Canonização: JCS (RFC 8785)
  • Formato chave: JWK (RFC 7517)
  • Chave Descoberta: keys[] em /.well-known/ucp (consulte Descoberta de chave)

Consulte Assinaturas de mensagens para formato e rotação de chaves.

Nota (requisito de algoritmo). AP2 vincula a Mandação de Pagamento ao Finalização de compra via hash(checkout_jwt); a propriedade de segurança subjacente é imprevisibilidade por sessão dos bytes assinados - qual é o único do BCP Checkout por sessão id fornece estruturalmente. AP2 v0.2 é internamente inconsistente sobre como exigir isso: specification.md declara um regra de classe de algoritmo (apenas não determinística, por exemplo, ECDSA), enquanto o Considerações de segurança e privacidade estabelecem uma regra de entropia satisfeita por qualquer algoritmo com entropia de carga útil suficiente. AP2 #268 trilhas convergindo para a formulação da entropia. Siga pela AP2 para regra autoritária; sob a leitura de entropia, um JWT de checkout BCP pode ser assinado com qualquer algoritmo (incluindo Ed25519), deixando uma chave servir a ambos Assinatura de mandato AP2 e Web Bot Auth.

Autorização Comercial

As empresas DEVEM incorporar sua assinatura no corpo da resposta de checkout em ap2.merchant_authorization usando formato JWS Detached Content (RFC 7515 Apêndice F).

Resposta de checkout com assinatura incorporada:json { "ucp": { ... }, "id": "chk_abc123", "status": "ready_for_complete", "currency": "USD", "line_items": [ ... ], "totals": [ ... ], "links": [ ... ], "ap2": { "merchant_authorization": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im1lcmNoYW50XzIwMjUifQ..<signature>" } }O valor merchant_authorization é um JWS com payload desanexado no formato <header>..<signature>. O ponto duplo (..) indica que a carga útil está transmitido separadamente (como o próprio corpo do checkout).

Reivindicações de cabeçalho JWS:

Reivindicação Tipo Obrigatório Descrição
alg corda Sim Algoritmo de assinatura aceito pelo AP2 (ex. ES256)
kid corda Sim ID da chave referenciando o keys do negócio

Cálculo de assinatura:

A assinatura DEVE abranger tanto o cabeçalho JWS quanto a carga útil do checkout. Isto evita ataques de substituição de algoritmo onde um invasor modifica o alg reivindicação sem invalidar a assinatura.```text sign_checkout(checkout, private_key, kid, alg="ES256"): // Extract payload (checkout minus ap2) payload = checkout without "ap2" field

// Canonicalize using JCS (RFC 8785)
canonical_bytes = jcs_canonicalize(payload)

// Create protected header
header = {"alg": alg, "kid": kid}
encoded_header = base64url_encode(json_encode(header))

// Sign header + payload per JWS
signing_input = encoded_header + "." + base64url_encode(canonical_bytes)
signature = sign(signing_input, private_key, alg)

// Return detached JWS (header..signature, no payload)
checkout.ap2.merchant_authorization = encoded_header + ".." + base64url_encode(signature)
return checkout

```### Estrutura do Mandato

Os mandatos são credenciais SD-JWT com Key Binding (+kb). A plataforma DEVE produzir dois artefatos de mandato distintos:

Mandato Colocação BCP Finalidade
checkout_mandate ap2.checkout_mandate Prova vinculada aos termos de checkout protege os negócios
mandato_pagamento payment.instruments[*].credential.token Comprovante vinculado à autorização de pagamento protege fundos

O mandato de checkout DEVE conter a resposta de checkout completa, incluindo o Campo ap2.merchant_authorization. Isso cria uma ligação criptográfica aninhada onde a assinatura da plataforma cobre a assinatura da empresa.

Limite de especificação: Esta extensão define onde os mandatos são colocados nas solicitações e respostas do BCP. A estrutura de credenciais do mandato (reivindicações, divulgação seletiva, vinculação de chave) é definida pelo Especificação do Protocolo AP2.

Canonização

Todas as cargas JSON DEVEM ser canonizadas usando Canonização JSON Esquema (JCS) de acordo com RFC 8785.

Por que JCS para Mandatos? As assinaturas de solicitação BCP usam Content-Digest (bruto bytes) sem canonização — a solicitação é assinada e verificada imediatamente pela mesma conexão HTTP. Os mandatos são diferentes:

  • Durabilidade — Os mandatos são armazenados como prova do consentimento do usuário. Eles podem ser recuperados e verificados dias ou meses depois.
  • Transmissão entre sistemas — Os mandatos passam por vários sistemas (plataforma → negócio → PSP → rede de cartões) que pode serializar novamente o JSON.
  • Reprodutibilidade — Qualquer parte deve reconstruir os bytes assinados exatos do conteúdo JSON lógico, independentemente das diferenças de serialização.

JCS garante que JSON semanticamente idêntico produza saída idêntica em bytes, tornando as assinaturas reproduzíveis entre implementações e tempo.

Regra Específica do AP2: Ao calcular o merchant_authorization do negócio assinatura, exclua totalmente o campo ap2. Isso garante futuros campos AP2 são tratados automaticamente.

O Fluxo do Mandato

Uma vez negociada a capacidade br.dev.bcp.shopping.ap2_mandate, a sessão está bloqueado no fluxo a seguir. Ambas as partes DEVEM seguir estas etapas para garantir a integridade criptográfica; qualquer tentativa de ignorar essas etapas ou enviar uma solicitação de conclusão sem mandatos DEVE resultar em uma falha de sessão.

Etapa 1: Criação e assinatura do checkout

A plataforma inicia a sessão. O negócio retorna o objeto Checkout com ap2.merchant_authorization embutido no corpo da resposta.

Checkout extended with AP2 mandate support.

Name Type Required Description
ucp any Yes UCP metadata for checkout responses.
id string Yes Unique identifier of the checkout session.
line_items Array[object] Yes List of line items being checked out.
buyer object No Representation of the buyer.
context object No Provisional buyer signals for relevance and localization—not authoritative data. Businesses SHOULD use these values when verified inputs (e.g., shipping address) are absent, and MAY ignore or down-rank them if inconsistent with higher-confidence signals (authenticated account, risk detection) or regulatory constraints (export controls). Eligibility and policy enforcement MUST occur at checkout time using binding transaction data. Context SHOULD be non-identifying and can be disclosed progressively—coarse signals early, finer resolution as the session progresses. Higher-resolution data (shipping address, billing address) supersedes context.
signals object No Environment data provided by the platform to support authorization and abuse prevention. Values MUST NOT be buyer-asserted claims — platforms provide signals based on direct observation or independently verifiable third-party attestations. All signal keys MUST use reverse-domain naming to ensure provenance and prevent collisions when multiple extensions contribute to the shared namespace.
attribution object No Platform-emitted referral and conversion-event context — campaign identifiers, click IDs, source/medium markers, etc. The same parameters platforms communicate via URL query parameters in browser-based flows.
status string Yes Checkout state indicating the current phase and required action. See Checkout Status lifecycle documentation for state transition details.
Enum: incomplete, requires_escalation, ready_for_complete, complete_in_progress, completed, canceled
currency string Yes ISO 4217 currency code reflecting the merchant's market determination. Derived from address, context, and geo IP—buyers provide signals, merchants determine currency.
totals Array[Total] Yes Different cart totals.
messages Array[object] No List of messages with error and info about the checkout session state.
links Array[object] Yes Links to be displayed by the platform (Privacy Policy, TOS). Mandatory for legal compliance.
expires_at string No RFC 3339 expiry timestamp. Default TTL is 6 hours from creation if not sent.
continue_url string No URL for checkout handoff and session recovery. MUST be provided when status is requires_escalation. See specification for format and availability requirements.
payment object No Payment configuration containing handlers.
order object No Details about an order created for this checkout session.
ap2 any No

Exemplo de resposta:json { "ucp": { ... }, "id": "chk_abc123", "status": "ready_for_complete", "currency": "USD", "line_items": [ { "id": "li_1", "item": {"id": "item_123", "title": "Widget", "price": 2500}, "quantity": 2, "totals": [ {"type": "subtotal", "amount": 5000}, {"type": "total", "amount": 5000} ] } ], "totals": [ {"type": "subtotal", "amount": 5000}, {"type": "tax", "amount": 400}, {"type": "total", "amount": 5400} ], "links": [ ... ], "ap2": { "merchant_authorization": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im1lcmNoYW50XzIwMjUifQ..<signature>" } }A plataforma DEVE verificar a assinatura:```text verify_merchant_authorization(checkout, merchant_profile): // Parse detached JWS (header..signature) jws = checkout.ap2.merchant_authorization [encoded_header, empty, encoded_signature] = jws.split(".")

// Decode and validate header
header = json_decode(base64url_decode(encoded_header))
assert header.alg in ap2_accepted_algorithms  // ES256/ES384/ES512 per AP2 v0.2

// Reconstruct signed payload (checkout minus ap2)
payload = checkout without "ap2" field
canonical_bytes = jcs_canonicalize(payload)

// Reconstruct signing input (header + payload)
signing_input = encoded_header + "." + base64url_encode(canonical_bytes)

// Get business's public key and verify
public_key = get_key_by_kid(merchant_profile.keys, header.kid)
return verify(encoded_signature, signing_input, public_key, header.alg)

```### Etapa 2: Consentimento do usuário e geração de mandato

Quando o usuário confirma a compra, a plataforma DEVE facilitar a geração de mandatos verificáveis criptograficamente.

Opção 1: Provedor de plataforma confiável

Um provedor de plataforma confiável atua em nome do usuário para gerar o credenciais de mandato. O provedor da plataforma DEVE garantir que os mandatos não são criados sem o consentimento explícito do usuário de fontes confiáveis e determinísticas canais.

Mediante consentimento do usuário, a plataforma assina os mandatos usando seu servidor chave. A empresa confia que a assinatura da plataforma implica o consentimento do usuário.

Opção 2: credencial de pagamento digital

Neste modelo, o usuário possui um VDC emitido por uma fonte confiável para a empresa (por exemplo: uma credencial de pagamento digital emitida por um banco ou rede).

A plataforma solicita uma apresentação através de um protocolo como OpenID4VP. O usuário A Wallet (ou equivalente) processa a solicitação e assina os mandatos usando o chave privada associada à sua credencial de pagamento.

A empresa confia no Emissor da Credencial (Banco) e verifica a Chave do usuário Assinatura de ligação (+kb).

Etapa 3: Envio (complete_checkout)

Uma vez gerados os mandatos, a plataforma os submete no preenchimento solicitar:

AP2 extension data including checkout mandate.

Name Type Required Description
checkout_mandate string No SD-JWT+kb proving user authorized this checkout.
{
"payment": {
"instruments": [
{
"id": "instr_1",
"handler_id": "gpay_1234",
"type": "card",
"selected": true,
"display": {
"description": "Visa •••• 1234"
},
"billing_address": {
"street_address": "123 Main St",
"address_locality": "Anytown",
"address_region": "CA",
"address_country": "US",
"postal_code": "12345"
},
"credential": {
"type": "PAYMENT_GATEWAY",
"token": "examplePaymentMethodToken"
}
}
]
},
"ap2": {
"checkout_mandate": "eyJhbGciOiJFUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9..." // The User-Signed SD-JWT+kb / platform provider signed SD-JWT / delegated SD-JWT-KB
}
}
``*ap2.checkout_mandate`: O mandato de checkout SD-JWT+kb contendo o
checkout completo (com ap2.merchant_authorization)
* payment.instruments[*].credential.token: Contém a ordem de pagamento (token composto)

Verificação e processamento

Verificação comercial

Ao receber a solicitação complete, a empresa DEVE:

  1. Aplicar Negociação: Se o AP2 foi negociado, rejeite a solicitação com Código de erro mandate_required se ap2.checkout_mandate estiver faltando.

Verificação de mandato (conforme especificação AP2):

  1. Verificar Mandato: Decodifique e verifique a assinatura SD-JWT, ligação de chave, e expiração de acordo com o Especificação do Protocolo AP2.
  2. Extrair Checkout Incorporado: Extraia o objeto checkout do reivindicações de mandato verificadas.

Verificação BCP:

  1. Verifique a autorização comercial: Confirme ap2.merchant_authorization no checkout incorporado está a assinatura válida da própria empresa:```text jws = embedded_checkout.ap2.merchant_authorization [encoded_header, _, encoded_signature] = jws.split(".") header = json_decode(base64url_decode(encoded_header))

    payload = embedded_checkout without "ap2" field signing_input = encoded_header + "." + base64url_encode(jcs_canonicalize(payload))

    my_key = get_key_by_kid(my_keys, header.kid) verify(encoded_signature, signing_input, my_key, header.alg) ```2. Verificar a correspondência dos termos: Confirme se os termos de checkout incorporados correspondem aos estado atual da sessão (id, totais, itens de linha).

Verificação PSP

A empresa passa o token (objeto composto) para seu Pagamento Manipulador / PSP. O PSP verifica o payment_mandate conforme o Especificação do Protocolo AP2, incluindo validação de assinatura, expiração e correlação com o check-out.

Esquema

Autorização comercial

JWS Detached Content signature (RFC 7515 Appendix F) over the checkout response body (excluding ap2 field). Format: <base64url-header>..<base64url-signature>. The header MUST contain 'alg' (ES256/ES384/ES512) and 'kid' claims. The signature covers both the header and JCS-canonicalized checkout payload.

Pattern: ^[A-Za-z0-9_-]+\.\.[A-Za-z0-9_-]+$

Resposta de check-out do AP2

O objeto ap2 incluído nas respostas de checkout.

AP2 extension data including merchant authorization.

Name Type Required Description
merchant_authorization string No Merchant's signature proving checkout terms are authentic.

Mandato de check-out

SD-JWT+kb credential in ap2.checkout_mandate. Proving user authorization for the checkout. Contains the full checkout including ap2.merchant_authorization.

Pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+(~[A-Za-z0-9_-]+)*$

Solicitação completa de AP2

O objeto ap2 incluído nas solicitações de checkout COMPLETE.

AP2 extension data including checkout mandate.

Name Type Required Description
checkout_mandate string No SD-JWT+kb proving user authorized this checkout.

Códigos de erro

Error codes specific to AP2 mandate verification.

Enum: mandate_required, agent_missing_key, mandate_invalid_signature, mandate_expired, mandate_scope_mismatch, merchant_authorization_invalid, merchant_authorization_missing

Código de erro Descrição
mandate_required AP2 foi negociado, mas falta ap2.checkout_mandate na solicitação.
agent_missing_key O perfil da plataforma não possui uma entrada keys válida.
mandate_invalid_signature A assinatura do mandato não pode ser verificada.
mandate_expired O carimbo de data/hora do mandato exp passou.
mandate_scope_mismatch O mandato está vinculado a uma verificação diferente.
merchant_authorization_invalid A assinatura da autorização comercial não pôde ser verificada.
merchant_authorization_missing A resposta de checkout omite ap2.merchant_authorization.