Protocolo Incorporado (EP)¶
Introdução¶
O Protocolo Incorporado (EP) é uma ligação de transporte BCP que permite que um host incorpore uma interface de empresa em um iframe ou webview e troque estruturado mensagens por esse canal. EP define como comunicar – formato da mensagem, configuração de canal, autenticação, tratamento de erros e restrições de segurança. Isso acontece não definir quais dados existem; isso é responsabilidade de cada capacidade que se liga ao EP.
Cada capacidade implementa métodos EP sob seu próprio prefixo de método. Por exemplo,
checkout usa o prefixo ec.* e carrinho usa o prefixo ep.cart.*. O compartilhado
os padrões descritos neste documento aplicam-se uniformemente a todas as capacidades do PE.
Detalhes específicos da capacidade — descoberta, parâmetros de URL, contratos de delegação, cargas úteis de mensagens e definições de esquema - são definidas no EP de cada recurso especificação vinculativa:
Terminologia e atores¶
Funções comerciais¶
- Negócios: O vendedor que fornece bens ou serviços.
- Comprador: o usuário final que faz uma compra.
Componentes Técnicos¶
- Host: O aplicativo que incorpora a interface da empresa (por exemplo, AI Agent aplicativo, Super App, Navegador). Responsável pela autenticação do usuário e, quando UI nativa delegada para ações como pagamento e seleção de endereço.
- Contexto incorporado: A interface do negócio renderizada em um iframe ou visualização da web. Responsável pelo fluxo específico da capacidade (por exemplo, checkout, construção de carrinho).
Transporte e mensagens¶
Formato da mensagem¶
Todas as mensagens EP DEVEM usar o formato JSON-RPC 2.0 (RFC 7159). Cada mensagem DEVE conter:
jsonrpc: DEVE ser"2.0"method: O nome da mensagem (por exemplo,"ec.start","ep.cart.start")params: carga útil específica da mensagem (pode ser um objeto vazio)id: (Opcional) Presente apenas para solicitações que esperam respostas
Tipos de mensagens¶
Solicitações (com campo id):
- Exigir uma resposta do receptor
- DEVE incluir um campo
idexclusivo - O receptor DEVE responder com
idcorrespondente - A resposta DEVE ser
resultouerror_response - Usado para operações que requerem confirmação ou dados
Notificações (sem campo id):
- Apenas informativo, nenhuma resposta esperada
- NÃO DEVE incluir um campo
id - O destinatário NÃO DEVE enviar uma resposta
- Usado para atualizações de estado e eventos informativos
Tratamento de respostas¶
Para solicitações (mensagens com id), os destinatários DEVERÃO responder com result.
Os resultados de sucesso e erro DEVEM ser retornados por meio do campo result,
consistente com o modelo de erro de duas camadas do BCP. O campo JSON-RPC error é
reservado para falhas no nível de transporte (erros de análise, método não encontrado, inválido
parâmetros). Implementações NÃO DEVEM usar o campo JSON-RPC error para
códigos de erro no nível do aplicativo.
Resposta de sucesso:json
{
"jsonrpc": "2.0",
"id": "req_1",
"result": {
"ucp": { "version": "2026-07-14", "status": "success" }
// ... result fields
}
}Resposta de erro:json
{
"jsonrpc": "2.0",
"id": "...",
"result": {
"ucp": { "version": "2026-07-14", "status": "error" },
"messages": [...]
}
}Em ambos os casos, result.ucp.status serve como discriminador entre sucesso
e resultados de erro — o mesmo padrão usado em todos os transportes BCP.
Erros de transporte¶
Erros de transporte são falhas em nível de protocolo que impedem o processamento de solicitações.
Eles são retornados como JSON-RPC error usando códigos de erro JSON-RPC padrão e
indica que a mensagem em si é inválida ou não pôde ser processada - não que
a lógica de negócios executada produziu um resultado de erro. Veja o
Especificação principal para o código de erro completo
registro.
Por exemplo, se uma solicitação não puder ser processada (método desconhecido, malformado
params), o host DEVE responder com um JSON-RPC error:json
{
"jsonrpc": "2.0",
"id": "req_1",
"error": {
"code": -32601,
"message": "Method not found."
}
}## Canais de comunicação
Hosts baseados na Web¶
Quando o host é uma aplicação web, a comunicação começa usando postMessage
entre o host e a janela do contexto incorporado. O anfitrião DEVE ouvir
postMessage chama da janela incorporada e quando uma mensagem é recebida,
DEVE validar se a origem corresponde ao continue_url usado para iniciar o
sessão.
Após a validação, o host PODE criar um MessageChannel e transferir um dos
suas portas na resposta ready. Quando um host responde com MessagePort,
todas as mensagens subsequentes DEVEM ser enviadas por esse canal. Caso contrário, o anfitrião
e as empresas DEVEM continuar usando postMessage() entre seus window
objetos, incluindo validação de origem.
Hosts nativos¶
Quando o host é um aplicativo nativo, ele DEVE injetar globais no
contexto incorporado que permite a comunicação postMessage entre a web e
ambientes nativos. Cada capacidade define os nomes de seus globais seguindo
o padrão:
window.Embedded{Capability}ProtocolConsumer(preferencial) -window.webkit.messageHandlers.Embedded{Capability}ProtocolConsumer
Este objeto DEVE implementar a seguinte interface:javascript
{
postMessage(message: string): void
}Onde message é uma mensagem JSON-RPC 2.0 com string JSON. O anfitrião DEVE
analise a string JSON antes do processamento.
Para mensagens que viajam do host para o contexto incorporado, o host DEVE
injetar JavaScript no webview que chama
window.Embedded{Capability}Protocol.postMessage() com a mensagem JSON-RPC.
O contexto incorporado DEVE inicializar este objeto global - e começar a ouvir
para chamadas postMessage() — antes que a mensagem ready do recurso seja enviada.
Consulte a ligação EP de cada capacidade para obter os nomes globais específicos:
- Check-out:
EmbeddedCheckoutProtocolConsumer/EmbeddedCheckoutProtocol - Carrinho:
EmbeddedCartProtocolConsumer/EmbeddedCartProtocol
Padrões de mensagens¶
Aperto de mão¶
Após a renderização, o contexto incorporado DEVE transmitir prontidão para o host
usando a mensagem ready do recurso. Esta mensagem inicializa um seguro
canal de comunicação entre o host e o contexto incorporado, comunica qual
delegações foram aceitas e sinaliza se a troca de autorização adicional
é necessário.
Fluxo geral:
- O contexto incorporado envia uma solicitação
readycom uma listadelegatee opcional Solicitaçãoauth - O anfitrião responde com:
- Envelope
ucpconfirmando a versão do protocolo negociado upgradeopcional comMessagePortpara atualização de canalcredentialopcional com dados de autorização solicitados- Estado opcional específico da capacidade (por exemplo, estado de delegação de checkout)
- Envelope
- Se o host incluir um
upgrade, o contexto incorporado DEVE descartar todos outros campos na resposta, mude para o canal atualizado e envie um novo Mensagemreadynesse canal - Se o host responder com um resultado
error_response, a sessão não poderá prossiga - o host DEVE destruir o contexto incorporado e PODE redirecionar o comprador paracontinue_urlse disponível. O contexto incorporado NÃO DEVE enviar mais mensagens após receber um erro de handshake.
Cada capacidade define a especificação completa do método ready, incluindo
parâmetros específicos da capacidade e campos de resultados.
Autenticação¶
O contexto incorporado PODE solicitar autorização do host após o
handshake inicial — por exemplo, para atualizar um token OAuth expirado. Isto
exchange usa o método de autenticação do recurso (por exemplo, ec.auth para checkout,
ep.cart.auth para carrinho).
Solicitação:
- Direção: Contexto incorporado → Host
- Tipo: Solicitação
- Carga útil:
type(string, REQUIRED): O tipo de autorização solicitado (por exemplo,"oauth","api_key","jwt").
Resposta de sucesso:
- Direção: Host → Contexto incorporado
- Tipo: Resposta
- Carga útil do resultado:
ucp(objeto, REQUIRED): metadados do protocolo BCP comstatus: "success".credential(string, REQUIRED): Os dados de autorização solicitados.
Resposta de erro:
O host DEVE responder com um result contendo a autorização
dados ou um error_response.
Exemplo de resposta de sucesso:json
{
"jsonrpc": "2.0",
"id": "auth_1",
"result": {
"ucp": { "version": "2026-07-14", "status": "success" },
"credential": "eyJhbGciOiJSUzI1NiIs..."
}
}Exemplo de resposta de erro:json
{
"jsonrpc": "2.0",
"id": "auth_1",
"result": {
"ucp": { "version": "2026-07-14", "status": "error" },
"messages": [
{
"type": "error",
"code": "timeout_error",
"content": "An internal service timed out when fetching the required authorization data.",
"severity": "recoverable"
}
]
}
}Escalonamento de erros:
Se o erro for transitório (indicado pela gravidade recoverable), o
context PODE reiniciar a solicitação de autenticação. Caso contrário, o contexto incorporado
DEVE emitir uma notificação de erro de sessão (consulte Erro de sessão)
contendo uma resposta de erro unrecoverable. Esta escalada também se aplica quando
o contexto incorporado não é capaz de processar uma credencial fornecida pelo host (por exemplo,
a credencial está corrompida). O erro de sessão DEVE incluir um
continue_url para permitir a transferência do comprador.
Exemplo — falha de autenticação escalonada para erro de sessão:json
{
"jsonrpc": "2.0",
"method": "ec.error",
"params": {
"error": {
"ucp": { "version": "2026-07-14", "status": "error" },
"messages": [
{
"type": "error",
"code": "not_supported_error",
"content": "Requested auth credential type is not supported",
"severity": "unrecoverable"
}
],
"continue_url": "https://merchant.example.com"
}
}
}Quando o host recebe esta notificação, ele DEVE desmontar o arquivo incorporado
contexto e DEVE exibir um estado de erro apropriado. Se continue_url for
presente, o host DEVE usá-lo para entregar o comprador para recuperação da sessão.
Erro de sessão¶
Um erro de sessão sinaliza uma condição fatal não relacionada ao recurso do recurso
— por exemplo, uma falha de autenticação do terminal que impede a sessão de
continuando. Cada recurso define seu próprio método de notificação de erros de sessão
(por exemplo, ec.error para finalização da compra, ep.cart.error para carrinho).
Carga útil de notificação:
error(objeto, REQUIRED): Resposta de erro em nível de sessão.ucp(objeto, REQUIRED): metadados do protocolo BCP.statusDEVE ser"error".messages(array, REQUIRED): Uma ou mais mensagens descrevendo o fracasso.continue_url(string, OPCIONAL): URL para transferência ou sessão do comprador recuperação.
Exemplo:json
{
"jsonrpc": "2.0",
"method": "ec.error",
"params": {
"error": {
"ucp": { "version": "2026-07-14", "status": "error" },
"messages": [
{
"type": "error",
"code": "not_supported_error",
"content": "Requested auth credential type is not supported.",
"severity": "unrecoverable"
}
],
"continue_url": "https://merchant.example.com/checkout/abc123"
}
}
}Manuseio do host:
Quando o host recebe uma notificação de erro de sessão, ele DEVE desmontar o
contexto incorporado e DEVE exibir um estado de erro apropriado para o comprador.
Se continue_url estiver presente, o anfitrião DEVE usá-lo para entregar o comprador para
recuperação da sessão.
Ciclo de vida¶
Cada capacidade define os métodos de notificação start e complete que seguem
um contrato compartilhado:
start: O contexto incorporado notifica o host de que a UI está visível e pronto para interação. A notificação DEVE incluir a informação atual completa estado do recurso do recurso (por exemplo, o objeto checkout ou carrinho).complete: O contexto incorporado notifica o host de que o recurso o fluxo foi concluído com sucesso. A notificação DEVE incluir o final estado do recurso.
Ambas são notificações – o host NÃO DEVE responder.
Exemplo – iniciar notificação (carrinho):json
{
"jsonrpc": "2.0",
"method": "ep.cart.start",
"params": {
"cart": {
"id": "cart_123",
"currency": "USD",
"totals": [ ... ],
"line_items": [ ... ],
"buyer": { ... }
}
}
}Exemplo – notificação completa (checkout):json
{
"jsonrpc": "2.0",
"method": "ec.complete",
"params": {
"checkout": {
"id": "checkout_123",
// ... other checkout fields
"order": {
"id": "ord_99887766",
"permalink_url": "https://merchant.com/orders/ord_99887766"
}
}
}
}### Mudança de Estado
Notificações de mudança de estado informam o host sobre mudanças que já ocorreram no contexto incorporado. Estes são apenas informativos - o contexto incorporado tem já aplicou as alterações e renderizou a UI atualizada. O anfitrião NÃO DEVE responder às notificações de mudança de estado.
Cada capacidade define seu próprio conjunto de métodos de mudança de estado cobrindo o campos de recursos relevantes (por exemplo, itens de linha, informações do comprador, totais). Estado notificações de alteração DEVEM incluir o estado atual completo do recurso recurso, não apenas os campos alterados.
Exemplo — itens de linha alterados (checkout):json
{
"jsonrpc": "2.0",
"method": "ec.line_items.change",
"params": {
"checkout": {
"id": "checkout_123",
"totals": [ ... ],
"line_items": [ ... ]
// ... other checkout fields
}
}
}Exemplo — mensagens alteradas (carrinho):json
{
"jsonrpc": "2.0",
"method": "ep.cart.messages.change",
"params": {
"cart": {
"id": "cart_123",
"line_items": [ ... ],
"messages": [
{
"type": "error",
"code": "invalid_quantity",
"path": "$.line_items[0].quantity",
"content": "Quantity must be at least 1",
"severity": "recoverable"
}
]
// ... other cart fields
}
}
}## Códigos de erro
O Protocolo Incorporado define um conjunto compartilhado de códigos de erro. Capacidades PODE definir códigos de erro adicionais para cenários específicos de capacidade.
| Código | Gravidade | Descrição |
|---|---|---|
abort_error |
recoverable |
O usuário cancelou a interação (por exemplo, fechou a planilha). |
security_error |
unrecoverable |
A validação da origem do host falhou. |
invalid_state_error |
unrecoverable |
O aperto de mão foi tentado fora de ordem. |
not_supported_error |
unrecoverable |
A operação solicitada ou o tipo de autorização não são suportados. |
timeout_error |
recoverable |
Um serviço interno expirou. A operação pode ser repetida. |
Erros DEVERÃO usar apenas as gravidades recoverable e unrecoverable.
recoverable significa que a operação pode ser tentada novamente. unrecoverable significa
a operação não pode ser bem-sucedida na sessão atual.
Segurança¶
Política de Segurança de Conteúdo (CSP)¶
Para garantir a segurança, ambas as partes DEVEM implementar Política de Segurança de Conteúdo (CSP) diretivas:
-
Negócios: DEVE definir
frame-ancestors <host_origin>;para garantir que seja incorporado apenas por hosts confiáveis. -
Anfitrião:
- Incorporação direta: se o host incorporar diretamente a página da empresa,
especificando uma diretiva
frame-srclistando todos os negócios em potencial origem pode ser impraticável, especialmente se houver muitas empresas. Em neste cenário, embora umframe-srcrigoroso seja ideal, outras medidas como aquelas em Iframe Sandbox Attributes e Iframes sem credenciais são críticos. - Iframe intermediário: O host PODE usar um iframe intermediário
(por exemplo, em um subdomínio controlado por host) para incorporar a página da empresa.
Isso oferece melhor controle:
- A página principal do host só precisa permitir a origem do
iframe intermediário em seu
frame-src(por exemplo,frame-src <intermediate_iframe_origin>;). - O iframe intermediário DEVE implementar um
frame-srcestrito política, definida dinamicamente para permitir apenas o específico<merchant_origin>para a sessão incorporada atual (por exemplo,frame-src <merchant_origin>;). Isso pode ser definido por meio de cabeçalhos HTTP ao servir o conteúdo iframe intermediário.
- A página principal do host só precisa permitir a origem do
iframe intermediário em seu
- Incorporação direta: se o host incorporar diretamente a página da empresa,
especificando uma diretiva
Atributos da sandbox do iframe¶
Todos os iframes de negócios DEVEM ser colocados em sandbox para restringir seus recursos. O seguintes atributos de sandbox DEVERÃO ser aplicados, mas um host e um negócio PODE negociar recursos adicionais:```html
```### Iframes sem credenciais
Os hosts DEVERÃO usar o atributo credentialless no iframe para carregá-lo
um contexto novo e efêmero. Isso evita que a empresa correlacione o usuário
atividade entre contextos ou acessando sessões existentes, protegendo o usuário
privacidade.```html
```### Validação estrita de origem
Aplicar validação rigorosa de origin para todas as comunicações postMessage
entre quadros.