Skip to main content

Visão geral

Com o Apple Pay, o usuário paga com os cartões já cadastrados na Wallet do iPhone, iPad, Mac ou Apple Watch, com autenticação por Face ID/Touch ID, sem digitar número de cartão. O seu app ou site recebe da Apple um token de pagamento criptografado (PKPaymentToken) e o envia para a API da UvviPay, que faz a decriptação e o processamento. Não há tarifa adicional para processar Apple Pay: a precificação é a mesma das demais transações com cartão de crédito da sua conta. Funciona em apps a partir do iOS 10 e na web em Safari, Chrome, Edge e Firefox (ver Navegadores compatíveis). Consulte os dispositivos compatíveis e os bancos participantes na documentação da Apple.
Seu sistema nunca vê os dados do cartão. O token do Apple Pay é cifrado pela Apple diretamente para a UvviPay. O número do cartão não passa pelo seu código nem pelos seus servidores, o que reduz o seu escopo PCI.

Propriedades da forma de pagamento

Recorrência: por enquanto o Apple Pay está disponível apenas para pagamentos avulsos. Cobranças recorrentes com Apple Pay ainda não são suportadas.

Suporte de produto

  • Link de Pagamento: o Apple Pay já aparece automaticamente no checkout dos seus links de pagamento, sem nenhuma configuração (sujeito à habilitação do método para a sua conta). O botão funciona em Safari, Chrome, Edge e Firefox, inclusive em domínio personalizado (white-label).
  • API de Pagamentos: integração própria no seu app iOS ou site, descrita neste guia.

Aceitar Apple Pay

A configuração depende de onde o botão vai aparecer. Escolha o caminho:

App iOS

Merchant ID próprio, certificado criado com o CSR da UvviPay e ativado pela API, capability no Xcode. 5 etapas, 1 vez por app.

Site (web)

Sem conta Apple Developer: registre seus domínios pela API e hospede o arquivo de verificação. O botão roda em Safari, Chrome, Edge e Firefox com o Apple Pay JS SDK.

Configuração no app iOS

Elegibilidade na App Store: a Apple só permite Apple Pay dentro de apps para bens físicos e serviços consumidos fora do app (delivery, transporte, ingressos, e-commerce, pagamento de contas etc.). Conteúdo digital, funcionalidades do app e assinaturas de conteúdo devem usar In-App Purchase, conforme a regra 3.1.1 das App Review Guidelines. Confirme o enquadramento do seu produto antes de integrar.
Faça a configuração 1 vez por app. São 5 etapas: 3 no Apple Developer Portal e na API da UvviPay, 1 só na API e 1 no Xcode. Como funciona: o iOS cifra o token do Apple Pay para o Payment Processing Certificate do seu Merchant ID. A chave privada desse certificado fica na UvviPay. Por isso o CSR (Certificate Signing Request) vem da API da UvviPay, e não de um comando seu. Você só transporta arquivos públicos entre a UvviPay e a Apple.
1

Registre um Apple Merchant ID

No Apple Developer Portal, acesse Certificates, Identifiers & Profiles → Identifiers. No filtro do canto superior direito, selecione Merchant IDs. Crie um novo Merchant ID para o seu app.
  • Description: o nome do seu negócio (ex.: Minha Empresa LTDA)
  • Identifier: um identificador único no formato reverso do seu domínio, prefixado com merchant. (ex.: merchant.com.minhaempresa.app)
Guarde esse identificador. Você vai usá-lo nas etapas 3 e 5.
2

Emita o CSR pela API da UvviPay

Envie o POST /v1/certificates com type: apple_pay_payment_processing:
Emitir CSR
A resposta traz o certificado com status issued:
Resposta (resumida)
Guarde 2 campos:
  • id: você vai usá-lo na URL da etapa 4.
  • signingRequestPem: salve o conteúdo em um arquivo .csr. O JSON traz as quebras de linha como \n. Se você copiou a resposta na mão, converta as quebras antes de salvar. Com jq o arquivo sai pronto:
Salvar o CSR em arquivo
O publicKeyFingerprint é o publicKeyHash que o iOS coloca em todo token cifrado para este certificado. A UvviPay usa esse valor para escolher a chave privada na hora de decriptar.
3

Crie o certificado no Apple Developer Portal

O certificado é criado a partir do Merchant ID, não pelo menu Certificates.
  1. Acesse Identifiers, filtre por Merchant IDs e abra o Merchant ID da etapa 1.
  2. Na seção Apple Pay Payment Processing Certificate, clique em Create Certificate.
  3. Na pergunta “Will payments associated with this Merchant ID be processed exclusively in China mainland?”, responda No e clique em Continue.
  4. Em Choose File, selecione o arquivo .csr da etapa 2 e clique em Continue.
  5. Clique em Download. O arquivo baixado é o apple_pay.cer, em formato DER (binário).
Envie o .csr da etapa 2. Um certificado criado com CSR próprio (openssl req, Keychain Access) falha na etapa 4 com certificate_mismatch, e a UvviPay não consegue decriptar tokens cifrados para ele.
4

Ative o certificado na API da UvviPay

Sem esta etapa o certificado fica em issued e a UvviPay ignora os tokens cifrados para ele. Pagamentos do app falham até a ativação.Envie o .cer em base64, em 1 linha, no POST /v1/certificates/{id}/activate. Use o id da etapa 2:
Ativar certificado
Para usar Postman ou Insomnia, copie o base64 para a área de transferência e cole no body:
Copiar o base64 (macOS)
Body
O endpoint aceita também o certificado em PEM (-----BEGIN CERTIFICATE-----). Não envie o arquivo .cer binário sem converter.A ativação confere, na hora, que o certificado corresponde ao CSR da etapa 2. A resposta traz status: active, a validade em notBefore e notAfter e o hash do Merchant ID em metadata.merchantIdHash. A partir desse momento o certificado vale para as transações, sem contato com o suporte e sem reiniciar nada.Para conferir o .cer antes de ativar, compare a chave pública com o publicKeyFingerprint da etapa 2:
Conferir o .cer (opcional)
5

Habilite o Apple Pay no Xcode

No Xcode, abra o target do seu app em Signing & Capabilities. Adicione a capability Apple Pay e marque o Merchant ID da etapa 1.O app precisa ser assinado pelo mesmo time da Apple que possui o Merchant ID. Com isso o PKPaymentRequest do seu app já pode usar o seu merchantIdentifier.

Status do certificado

Acompanhe seus certificados pelo GET /v1/certificates. O certificado da Apple vale por 25 meses (notAfter). Acompanhe a data e rotacione antes do vencimento.

Rotacionar ou substituir o certificado

Use este procedimento para renovar um certificado perto do vencimento ou para substituir um certificado comprometido. A Apple permite 2 Payment Processing Certificates ativos por Merchant ID ao mesmo tempo. O iOS cifra o token para o certificado ativo mais recente do Merchant ID. Nenhuma atualização do app é necessária. ATENÇÃO: revogue o certificado antigo só depois de confirmar um pagamento com o novo. Um token cifrado para um certificado revogado falha e não pode ser recuperado.
  1. Emita um novo CSR (etapa 2).
  2. Crie o novo certificado no portal da Apple com esse CSR (etapa 3). Não revogue o antigo ainda.
  3. Ative o novo certificado na UvviPay (etapa 4).
  4. Faça 1 pagamento de teste no app e confirme a aprovação.
  5. Revogue o certificado antigo na UvviPay pelo POST /v1/certificates/{id}/revoke.
  6. Revogue o certificado antigo no portal da Apple, na seção Apple Pay Payment Processing Certificate do Merchant ID.
Cada CSR gera exatamente 1 certificado na Apple. Para qualquer troca, comece por um novo POST /v1/certificates.

Configuração na web

Para exibir o botão Apple Pay no seu site você não precisa de conta Apple Developer nem de Merchant ID próprio. A UvviPay registra o seu domínio na Apple e cria a sessão de pagamento. A integração tem 5 partes:
  1. Registrar o domínio na UvviPay e hospedar 1 arquivo de verificação.
  2. Confirmar a verificação do domínio.
  3. Criar 1 endpoint no seu backend para validar a sessão.
  4. Carregar o Apple Pay JS SDK na página do checkout.
  5. Montar o botão no frontend com a Apple Pay JS API.
O uso do Apple Pay na web está sujeito às diretrizes de uso aceitável da Apple para sites. O Apple Pay na web não depende mais do Safari. Com o Apple Pay JS SDK carregado na página, a experiência muda conforme o dispositivo: Nos 3 casos com Apple Pay o seu código é o mesmo: o ApplePaySession dispara os mesmos eventos e entrega o mesmo paymentData. A diferença fica dentro do SDK da Apple. NOTA: sem o SDK, window.ApplePaySession existe só no Safari e no WebKit do iOS. O botão em CSS (-webkit-appearance: -apple-pay-button) também só renderiza nesses navegadores. Use o SDK e o botão <apple-pay-button> para cobrir Chrome, Edge e Firefox.

Quem fala com quem

O fluxo envolve o navegador, o seu backend e a UvviPay. O navegador nunca chama a UvviPay: as credenciais client-id e client-secret ficam só no seu backend. O ApplePaySession dispara 2 eventos, e cada evento gera 1 chamada ao seu backend. Fora do Safari, o begin() abre o modal com código antes do onvalidatemerchant; o restante não muda.

Passo a passo do registro

1

Registre o domínio pela API

Registre cada domínio onde o botão Apple Pay aparece com o POST /v1/payment-method-domains:
Registrar domínio
Resposta
Guarde o id e o verificationFile.content. Você usa os dois nos próximos passos.Regras do domainName:Status possíveis do domínio:
O registro é idempotente. Se você perdeu o verificationFile.content, chame o POST de novo com o mesmo domainName. A resposta devolve o registro existente com o arquivo.
2

Hospede o arquivo de verificação

Publique o verificationFile.content no caminho indicado em verificationFile.path:
Caminho do arquivo
Regras do arquivo:
  • O conteúdo é 1 string hexadecimal. Publique a string como está. Não decodifique, não adicione aspas nem quebra de linha final.
  • O nome do arquivo não tem extensão.
  • A URL responde 200 por HTTPS com certificado válido. Sem redirecionamento, nem de http para https, nem de apex para www.
  • A URL é pública. Sem autenticação, sem bloqueio por WAF, bot protection ou geolocalização.
  • Content-Type: text/plain.
Exemplos de hospedagem:
NOTA: aplicações SPA (React, Vue, Angular) com fallback para index.html respondem 200 com HTML para qualquer rota. A Apple recebe HTML no lugar do arquivo e a verificação falha. Confira o conteúdo da resposta, não só o status.Antes de seguir, confira a URL de fora da sua rede:
Conferir o arquivo
Resultado esperado:
  • Primeira linha HTTP/2 200 (sem 301/302).
  • Header content-type: text/plain.
  • Corpo igual ao verificationFile.content, sem <html no início.
Mantenha o arquivo hospedado permanentemente. A Apple revalida os domínios de forma periódica. Se o arquivo sair do ar, o Apple Pay para de funcionar no seu site.
3

Dispare a verificação

Com o arquivo no ar, chame o POST /v1/payment-method-domains/{id}/validate com o id do registro:
Verificar domínio
A UvviPay registra o domínio na Apple durante a chamada. Os servidores da Apple buscam o arquivo no seu domínio nesse momento. A chamada demora alguns segundos.
Resposta esperada
Erros do validate:O validate em um domínio já verified responde 200 sem chamar a Apple. Use a chamada como conferência a qualquer momento.
4

Remova um domínio que saiu do ar

Túnel de teste, hostname antigo ou domínio que parou de servir o arquivo precisa sair do registro. Liste os domínios, copie o id e chame o DELETE /v1/payment-method-domains/{id}:
Remover domínio
Resposta esperada: HTTP 204 sem corpo.Depois da remoção, o mesmo domainName pode ser registrado de novo.Erros do DELETE:

Criar o endpoint de validação no seu backend

O navegador entrega um validationURL a cada clique no botão. O seu backend repassa essa URL à UvviPay pelo POST /v1/payments/apple-pay/validate-merchant e devolve a resposta ao navegador. O corpo da resposta é a merchant session da Apple. Devolva o JSON sem alterar nenhum campo.
Chamada à UvviPay (seu backend)
Exemplo mínimo em Express:
Express (seu backend)
Respostas da UvviPay: NOTA: proteja o endpoint com a autenticação do seu usuário e com rate limit. Cada chamada gera 1 requisição da UvviPay à Apple.

Carregar o Apple Pay JS SDK

Inclua o SDK oficial da Apple no <head> de toda página que exibe o botão:
HTML (dentro do head)
O que o SDK faz em cada navegador: Regras do SDK:
  • Use a versão 1.latest ou fixe uma versão igual ou superior a 1.2.0. Versões anteriores não abrem o modal com código.
  • Avalie window.ApplePaySession e canMakePayments() depois do evento load do script. Antes disso, fora do Safari, window.ApplePaySession é undefined.
  • Se o script falhar (rede, bloqueio de CSP), não exiba o botão.
  • Renderize o botão com o web component <apple-pay-button>. O botão em CSS só funciona no Safari.
Se a sua página usa Content Security Policy (CSP), libere estas origens:
CSP
Para carregar o SDK em aplicações SPA sem editar o <head>, injete o script em tempo de execução e aguarde o load:
Carregar o SDK 1 vez (SPA)

Fluxo no frontend

Com o domínio verified, o endpoint no ar e o SDK carregado, monte o botão com a Apple Pay JS API. O código abaixo tem 4 pontos críticos, marcados com // [0], // [1], // [2] e // [3].
Botão (HTML)
JavaScript (seu site)
Busque preço, frete e total antes de exibir o botão. O intervalo entre o clique e o completeMerchantValidation tem limite de poucos segundos. NOTA: em React, Vue e frameworks com delegação de eventos, o onClick no <apple-pay-button> não dispara. O web component da Apple chama stopPropagation() e o evento não chega à raiz do documento. Registre o listener com ref e addEventListener no próprio elemento.
React (botão)
Atributos do <apple-pay-button>: Ajuste tamanho e borda com as variáveis CSS --apple-pay-button-height, --apple-pay-button-width, --apple-pay-button-border-radius e --apple-pay-button-padding. Detalhes na documentação da Apple.

Considerações da integração web

  • HTTPS obrigatório em todas as páginas com o botão, inclusive em homologação.
  • Disponibilidade: com o SDK carregado, o Apple Pay funciona em Safari, Chrome, Edge e Firefox (ver Navegadores compatíveis). Fora do Safari, o cliente precisa de 1 iPhone com iOS 18 ou superior para escanear o código. Exiba o botão só quando window.ApplePaySession?.canMakePayments() for true, avaliado depois do load do SDK.
  • Iframes: se o checkout roda em um iframe, o Safari 17+ exige o atributo allow="payment". Registre os 2 domínios: o da página e o do iframe.
  • Domínio da página = domínio registrado: envie window.location.hostname sem alterar. Domínios não registrados recebem 400.
  • Aparência do botão: use o web component <apple-pay-button> do SDK e siga as diretrizes da Apple para botões Apple Pay. O botão em CSS (-webkit-appearance: -apple-pay-button) só renderiza no Safari e no WebKit do iOS.
  • CSP: libere applepay.cdn-apple.com em script-src e smp-paymentservices.apple.com em connect-src.

Testar o Apple Pay na web

NOTA: localhost, IPs e domínios de preview (*.vercel.app, *.netlify.app, túneis) não funcionam. A Apple só cria sessão para domínio verified, e a verificação exige HTTPS público com o arquivo no ar. Teste no Safari:
  1. Confirme status: verified no GET /v1/payment-method-domains.
  2. Abra a página no Safari (macOS ou iOS) com 1 cartão real na Wallet.
  3. Confirme que o botão aparece. Se não aparecer, confira canMakePayments() e o cadastro do cartão na Wallet.
  4. Abra o Web Inspector na aba Network antes de clicar.
  5. Clique no botão. A folha do Apple Pay abre em menos de 1 segundo.
  6. Confira a chamada ao seu endpoint de validação: status 200 e corpo com a merchant session.
  7. Autorize com Touch ID ou Face ID. Confira a chamada de pagamento ao seu backend.
  8. Confira o pagamento no painel ou no GET /v1/payments/{id}.
  9. Estorne o pagamento de teste pelo PUT /v1/payments/{id}/refund.
Teste em Chrome, Edge ou Firefox no desktop (Mac ou Windows):
  1. Tenha em mãos 1 iPhone com iOS 18 ou superior e 1 cartão real na Wallet.
  2. Abra a página e o DevTools na aba Network. Confirme o download de apple-pay-sdk.js com status 200.
  3. Confirme que o botão <apple-pay-button> aparece. Se não aparecer, execute window.ApplePaySession?.canMakePayments() no console. O esperado é true.
  4. Clique no botão. O navegador abre um modal da Apple com 1 código.
  5. Escaneie o código com a câmera do iPhone. O iPhone abre a folha do Apple Pay.
  6. Autorize com Face ID ou Touch ID no iPhone. O modal do navegador fecha sozinho.
  7. Confira a chamada de pagamento ao seu backend e o pagamento no GET /v1/payments/{id}.
  8. Estorne o pagamento de teste.
Teste em Chrome no iPhone: o fluxo é o mesmo do Safari (folha nativa), porque o navegador usa o WebKit. Se a folha fecha com erro logo depois de abrir, leia o corpo da resposta do seu endpoint de validação na aba Network. A mensagem da UvviPay indica a causa exata (domínio não registrado, pending ou failed).

Processando o pagamento

Tanto no app quanto na web, ao receber a autorização do usuário envie o paymentData do token (em base64) no campo applePay do POST /v1/payments, no lugar do bloco card:
O campo applePay.network deve vir de paymentMethod.network do token: a bandeira é informada pela Apple, já que o número tokenizado (DPAN) não passa por validação de BIN convencional.
Envie card ou applePay, nunca os dois na mesma requisição. Com applePay, o próprio token faz o papel de credencial e de autenticação: CVV e 3DS são dispensados.

Testando

  • Use um cartão real. Não é possível salvar cartões de teste comuns na Wallet; a Apple só provisiona cartões emitidos por bancos participantes. Valide o fluxo com uma transação de valor baixo e estorne em seguida (PUT /v1/payments/{id}/refund).
  • Sandbox da Apple: para testar sem cartão real, a Apple oferece o ambiente de sandbox com cartões de teste provisionáveis em contas sandbox. Serve para validar a integração do app/site, mas a autorização financeira de ponta a ponta só acontece com cartão real.
  • Web: siga o checklist em Testar o Apple Pay na web. Só domínio verified em HTTPS público funciona; localhost e previews não abrem a folha. Teste no Safari e em pelo menos 1 navegador de terceiros no desktop (fluxo com código no iPhone).

Boas práticas

  • Chame a API pelo seu backend. O paymentData deve ser encaminhado do app/site para o seu servidor e de lá para a UvviPay. client-id/client-secret nunca devem ser embarcados no app nem expostos no front-end.
  • Envie logo após a autorização. O token do Apple Pay tem janela de validade curta; não o armazene para uso posterior.
  • Trate o resultado na tela de pagamento (payment sheet). Retorne sucesso ou falha (PKPaymentAuthorizationResult / session.completePayment) conforme a resposta da API, para o usuário ver o estado correto na animação do Apple Pay.
  • Verifique a disponibilidade. No iOS, use canMakePayments(usingNetworks:); na web, ApplePaySession.canMakePayments() depois do load do SDK. Só então exiba o botão.
  • Use o botão oficial. No iOS, PKPaymentButton; na web, o web component <apple-pay-button> do SDK, com os estilos das Human Interface Guidelines.

Erros comuns

Veja também