logo Home / gs-payment-ecommercev1.0 / Integração Ecommerce Carteiras Digitais

Integração Ecommerce Carteiras Digitais

#🔹 1. Visão geral

O gs-payment aceita pagamento de cartão por carteira digital: Google Pay, Apple Pay (web e app iOS) e Samsung Pay. O contrato é o mesmo para as três: o cliente paga na carteira, a carteira entrega um token cifrado, e você repassa esse token sem modificação no bloco card.wallet da autorização de cartão que já usa hoje. O gs-payment descriptografa o token, extrai os dados do cartão (cartão tokenizado da bandeira, criptograma e validade) e segue o fluxo normal de autorização no adquirente.

  • Nem o seu front-end nem o seu back-end veem dados de cartão: o token chega cifrado e só o gs-payment o abre.

  • Muda apenas o type (GOOGLE_PAY, APPLE_PAY ou SAMSUNG_PAY) e a origem do token.

  • Cada carteira tem um passo de habilitação feito uma única vez, com o time de implantação GSURF (seção 2).


#🔹 2. Habilitação por carteira (uma vez)

#Google Pay

Há dois modelos. O corpo da chamada à API é idêntico nos dois; muda só a configuração do front-end e quem detém as chaves de descriptografia. A escolha é registrada no cadastro do parceiro no gs-payment.

Modelo

Quem tem as chaves

tokenizationSpecification

Quando usar

GATEWAY (recomendado)

O gs-payment (registrado no Google como gateway). Você não gera chave nenhuma

type: "PAYMENT_GATEWAY" + gateway + gatewayMerchantId, fornecidos pela GSURF

Você quer usar o gs-payment como gateway, sem gerenciar chaves

DIRECT

Você gera o par EC P-256, registra a chave pública no Google e entrega a privada à GSURF

type: "DIRECT" + protocolVersion: "ECv2" + publicKey

Você já tem (ou quer ter) integração DIRECT própria com o Google

Modelo GATEWAY:

const tokenizationSpecification = {
  type: "PAYMENT_GATEWAY",
  parameters: {
    gateway: "<fornecido pela GSURF>",
    gatewayMerchantId: "<fornecido pela GSURF>"
  }
};

const cardPaymentMethod = {
  type: "CARD",
  parameters: {
    allowedAuthMethods: ["CRYPTOGRAM_3DS"],
    allowedCardNetworks: ["MASTERCARD", "VISA"]
  },
  tokenizationSpecification
};

Modelo DIRECT: gere a chave privada em PEM/PKCS#8 e a pública no formato que o Google espera, registre a pública no Google Pay & Wallet Console (integração DIRECT, ECv2) e envie à GSURF, por canal seguro, a(s) chave(s) privada(s) e o seu merchantId Google. É possível cadastrar mais de uma chave privada, para rotação.

# chave privada EC P-256 em PKCS#8 (PEM) -> enviar à GSURF por canal seguro
openssl ecparam -name prime256v1 -genkey -noout -out gpay-private-key.pem
openssl pkcs8 -topk8 -nocrypt -in gpay-private-key.pem -out gpay-private-key-pkcs8.pem

# chave pública em base64 -> registrar no Google como publicKey
openssl ec -in gpay-private-key-pkcs8.pem -pubout -outform DER | openssl base64 -A

O gatewayMerchantId e o merchantId Google são usados só no front-end/Google; não são enviados à API do gs-payment. O parceiro é identificado na API pela autenticação GMAC.

#Apple Pay na web (checkout no seu domínio)

Você não precisa de conta Apple Developer, certificado nem Merchant ID próprio: o gs-payment opera como integrador da Apple. O que você faz é hospedar o arquivo de verificação de domínio, e a GSURF registra o domínio na Apple.

  1. Receba da GSURF o arquivo de verificação de domínio.

  2. Publique-o em https://<seu-dominio>/.well-known/apple-developer-merchantid-domain-association. Ele precisa responder HTTP 200 direto, sem redirecionamento, sem autenticação e sem bloqueio de WAF/geolocalização (a Apple valida a partir dos IPs dela). Com Cloudflare ou CDN semelhante, deixe esse caminho sem proxy de TLS.

  3. Repita para cada domínio e subdomínio do checkout: loja.com.br e www.loja.com.br são domínios diferentes para a Apple.

  4. Informe à GSURF os domínios publicados; a GSURF faz o registro e avisa quando estiver ativo.

  5. Integre a merchant session (seção 4).

#Apple Pay no app iOS

  1. Tenha uma conta Apple Developer própria: o Merchant ID e o app precisam estar na sua conta.

  2. Crie o Merchant ID (ex.: merchant.com.suaempresa.loja) em Certificates, Identifiers & Profiles.

  3. Peça à GSURF o CSR (.certSigningRequest) gerado para esse Merchant ID. Não gere um CSR próprio: certificado emitido com CSR seu produz tokens que o gs-payment não consegue decifrar. Um CSR por Merchant ID.

  4. No Merchant ID, crie o Apple Pay Payment Processing Certificate com o CSR da GSURF (certificado ECC; responda que será usado por um payment provider) e baixe o .cer.

  5. Envie o .cer à GSURF (é público, não contém segredo) e aguarde a confirmação de ativação antes de testar; sem ela a autorização retorna InvalidApplePayToken.

  6. No Xcode, adicione a capability Apple Pay com o Merchant ID. O merchantIdentifier do PKPaymentRequest precisa ser o mesmo do entitlement, com merchantCapabilities = .capability3DS.

No app não há merchant validation: a identidade vem do entitlement. O certificado expira a cada 25 meses; a renovação segue o mesmo fluxo (novo CSR da GSURF).

Se o portal da Apple responder "The uploaded CSR file has already been used to generate another certificate", peça um CSR novo à GSURF para este Merchant ID.

#Samsung Pay

Use o modelo *direct / network token* da SDK do Samsung Pay (o *encrypted network token bundle*); o modelo indireto via Samsung-PG não é usado. As chaves de descriptografia são combinadas com o time de implantação GSURF. Samsung Pay é sempre transação de carteira, com criptograma.


#🔹 3. Autorização com carteira

O fluxo é o mesmo do cartão: criar a transação com POST /payments/card (recebe o gti) e autorizar com POST /payments/card/{gti}, enviando o token em transaction_data.card.wallet:

{
  "transaction_data": {
    "card": {
      "wallet": {
        "type": "APPLE_PAY",
        "token": "{\"data\":\"...\",\"signature\":\"...\",\"header\":{...},\"version\":\"EC_v1\"}"
      }
    }
  }
}

Campo

Tipo

Obrigatório

Descrição

wallet.type

string

✅

GOOGLE_PAY, APPLE_PAY ou SAMSUNG_PAY

wallet.token

string

✅

Token cifrado exatamente como a carteira entregou (máx. 10000 caracteres)

  • O card aceita exatamente uma forma de entrada: wallet, ou token, ou number+expiry_date, ou click_to_pay_token. Enviar wallet junto de outra forma retorna 400.

  • Com wallet, não envie number, expiry_date nem security_code: os dados vêm do token.

  • O bloco wallet aceita apenas type e token.

  • Os demais blocos da autorização (anti_fraud_data, payer, acquirer_additional_data) continuam funcionando junto da carteira.

  • Envie o token logo após receber da carteira: ele tem validade curta e token velho é recusado.

#De onde tirar o token

Carteira

Valor a enviar em wallet.token

Formato

Google Pay

paymentData.paymentMethodData.tokenizationData.token (a string, sem parse)

ECv2

Apple Pay (web)

JSON.stringify(event.payment.token.paymentData) no onpaymentauthorized

EC_v1

Apple Pay (app iOS)

String(data: payment.token.paymentData, encoding: .utf8) no didAuthorizePayment

EC_v1

Samsung Pay

O JWE compacto entregue pela SDK

JWE

O token precisa chegar intacto: não re-encode, não reordene e não remova campos no caminho (front-end → seu back-end → gs-payment). Qualquer alteração quebra a verificação de assinatura.


#🔹 4. Apple Pay na web: merchant session

Antes de abrir a payment sheet na web, a Apple exige a *merchant validation*. O gs-payment faz essa etapa por você em POST /wallets/apple/session. Como o endpoint é autenticado por GMAC, chame-o a partir do seu back-end (nunca exponha as credenciais GMAC no navegador):

const session = new ApplePaySession(3, {
  countryCode: "BR",
  currencyCode: "BRL",
  supportedNetworks: ["visa", "masterCard", "elo"],
  merchantCapabilities: ["supports3DS"],
  total: { label: "Sua Loja", amount: "10.00" }
});

session.onvalidatemerchant = async (event) => {
  // seu back-end chama POST /wallets/apple/session com
  // { validation_url: event.validationURL, domain: location.hostname, display_name: "Sua Loja" }
  const merchantSession = await fetch("/seu-backend/apple-pay/session", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ validation_url: event.validationURL })
  }).then(r => r.json());
  session.completeMerchantValidation(merchantSession); // objeto inteiro, sem alterar
};

session.onpaymentauthorized = async (event) => {
  const token = JSON.stringify(event.payment.token.paymentData);
  // seu back-end autoriza em POST /payments/card/{gti} com card.wallet = { type: "APPLE_PAY", token }
  const ok = await autorizarNoSeuBackend(token);
  session.completePayment(ok ? ApplePaySession.STATUS_SUCCESS : ApplePaySession.STATUS_FAILURE);
};

session.begin();
  • A validation_url deve ser repassada sem alteração; só hosts oficiais da Apple são aceitos.

  • A merchant session é de uso único e expira em 5 minutos: obtenha uma nova a cada abertura da sheet.

  • O Apple Pay na web só funciona em Safari, em dispositivo Apple, com HTTPS válido.


#🔹 5. Onde a carteira é aceita

Fluxo

Aceita carteira?

Autorização de cartão (POST /payments/card/{gti})

✅

Recorrência de cartão (criação/edição)

❌ UnsupportedWalletFlow: use token ou number

Zero dollar (POST /payments/card/0dollar)

❌

A carteira exige que o adquirente receba o criptograma e o ECI num bloco próprio. Hoje isso existe para Cielo e Rede; a transação é recusada no ingresso quando o roteamento aponta para outro adquirente:

Adquirente

Carteira

Bandeiras aceitas em carteira

Cielo

✅

todas

Rede

✅

Visa, Mastercard e Elo; demais bandeiras retornam UnsupportedWalletCardBrand

Demais adquirentes

❌

UnsupportedWalletProvider

#Roteamento específico para carteira

Na criação de um roteamento de cartão, o campo opcional wallet_types restringe a regra às carteiras listadas. Assim dá para mandar carteira para a Cielo e o restante do tráfego para outro adquirente:

{
  "provider_id": "...",
  "transaction_type": "CREDIT",
  "initial_installment": 1,
  "final_installment": 12,
  "card_brand_id": "...",
  "wallet_types": ["APPLE_PAY", "GOOGLE_PAY"]
}
  • Ausente: a regra vale para qualquer transação (comportamento de todos os roteamentos existentes).

  • Preenchido: a regra vale somente para as carteiras listadas; nunca para cartão comum.

  • Lista vazia retorna 400. O campo só pode ser definido na criação: um PUT com wallet_types retorna 400; para corrigir, desative/remova e crie de novo.

  • A regra de carteira precisa apontar para um adquirente com suporte; caso contrário a criação retorna UnsupportedWalletProvider.

  • Dentro do mesmo escopo, regras de carteira têm precedência sobre as indiferentes; entre escopos vale a hierarquia normal (canal > loja > parceiro).


#🔹 6. Resposta

A resposta segue o fluxo normal de autorização de cartão. O campo transaction_data.entry_mode indica a carteira usada (GOOGLE_PAY, APPLE_PAY ou SAMSUNG_PAY), também nos hooks de pagamento. O masked_card exibe o cartão tokenizado da bandeira (DPAN), não o número físico do cartão.

{
  "payment_data": { "gti": "0f8e...c1", "status": "AUTHORIZATION_IN_PROGRESS", "amount_paid": 1000 },
  "transaction_data": {
    "entry_mode": "GOOGLE_PAY",
    "card_data": { "masked_card": "411111******1111", "card_brand": { "description": "Visa", "gsurf_code": 85 } }
  }
}

#🔹 7. Google Pay: CRYPTOGRAM_3DS e PAN_ONLY

  • CRYPTOGRAM_3DS é o fluxo de carteira propriamente dito: o token traz criptograma e o gs-payment envia o bloco de carteira ao adquirente.

  • PAN_ONLY é um cartão apenas salvo na conta Google, sem autenticação. O gs-payment aceita, mas processa como cartão comum (sem criptograma e sem ECI), sem os benefícios da carteira. Também não casa roteamentos com wallet_types.

  • Para garantir que só transações autenticadas cheguem, configure allowedAuthMethods: ["CRYPTOGRAM_3DS"] no front-end.


#🔹 8. Erros

Os erros seguem o envelope padrão da API (error_code, message, category):

HTTP

error_code

Quando ocorre

O que fazer

400

UnsupportedWalletProvider

O adquirente roteado não aceita carteira

Ajustar o roteamento para Cielo ou Rede

400

UnsupportedWalletCardBrand

Bandeira não aceita em carteira pelo adquirente (Rede: só Visa, Mastercard e Elo)

Rotear a bandeira para um adquirente que a aceite

400

UnsupportedWalletFlow

Carteira enviada em recorrência

Usar token ou number na recorrência

400

InvalidGooglePayToken

Token Google Pay alterado, malformado ou que não decifra com as chaves cadastradas

Enviar a string original do Google; no DIRECT, conferir se a chave pública registrada corresponde à privada entregue

400

ExpiredGooglePayToken

Token Google Pay vencido

Obter um token novo e enviar sem demora

400

UnsupportedGooglePayAuthMethod

authMethod diferente de CRYPTOGRAM_3DS/PAN_ONLY

Configurar allowedAuthMethods: ["CRYPTOGRAM_3DS"]

400

InvalidApplePayToken

Token Apple Pay alterado, assinatura inválida ou (app iOS) certificado do Merchant ID não ativado ou emitido com CSR errado

Repassar o paymentData intacto; no app, confirmar a ativação com a GSURF

400

ExpiredApplePayToken

Assinatura do token fora da janela de validade

Processar logo após a autorização na sheet

400

InvalidSamsungPayToken

Token Samsung Pay alterado, malformado ou que não decifra

Enviar o JWE exatamente como a SDK entregou

400

InvalidApplePayValidationUrl

validation_url da merchant session não é host oficial da Apple

Repassar a validationURL do onvalidatemerchant sem alteração

404 / 500

GooglePayKeyNotFound, ApplePayKeyNotFound, SamsungPayKeyNotFound, ApplePayMerchantIdentityNotConfigured, GooglePayMerchantNotConfigured, GooglePayGatewayNotConfigured

Carteira ainda não habilitada para o parceiro no gs-payment

Acionar o time de implantação GSURF

500

ApplePayMerchantValidationFailed

A Apple recusou a merchant validation; causa mais comum: domínio não registrado ou ainda não propagado

Conferir o arquivo de domínio e o registro com a GSURF

500

GooglePayRootKeysUnavailable

Indisponibilidade temporária ao validar as chaves do Google

Repetir a requisição


#🔹 9. Testes

  • Google Pay: use o ambiente TEST do Google Pay junto do ambiente de homologação do gs-payment.

  • Apple Pay: o sandbox da Apple não cobre o Brasil. O caminho recomendado é testar em dispositivo físico, com cartão real e valor baixo, desfazendo a transação em seguida pelo fluxo de desfazimento que a sua integração já usa. No app iOS, a payment sheet não funciona no simulador.

  • Antes do teste, confirme com a GSURF que a carteira está habilitada para o seu cadastro (domínio registrado, certificado ativado ou chaves provisionadas).


#🔹 10. Checklist

  1. Carteira habilitada com a GSURF (seção 2): modelo do Google Pay definido, domínio Apple registrado, certificado do app ativado ou chaves Samsung provisionadas.

  2. Roteamento do parceiro apontando carteira para Cielo ou Rede (se preciso, com wallet_types).

  3. Front-end extraindo o token correto de cada carteira (seção 3), sem alteração.

  4. Apple Pay web: back-end chamando POST /wallets/apple/session no onvalidatemerchant.

  5. Autorização em POST /payments/card/{gti} com transaction_data.card.wallet.

  6. Tratamento dos erros da seção 8, especialmente token expirado (obter um novo).