CDX Pay para desenvolvedores

Tokenização do cartão

O número do cartão, a validade e o CVV nunca passam pelo seu servidor nem pela API da CDX Pay. O comprador digita o cartão em campos seguros (iframes) que o SDK @malga/tokenization monta na sua página. O SDK devolve um token_id de uso único, e só esse token vai do navegador para o seu servidor e daí para a API.

1. Buscar a configuração em tempo de execução

O seu servidor lê a configuração pública de tokenização em GET /v1/capabilities (permissão payments:read) e repassa o bloco tokenization à página de pagamento.

Não fixe esses valores no código. A chave pública de tokenização é trocada periodicamente. Quem a busca a cada carga da página, ou com um cache curto de alguns minutos, recebe a nova sem mudar nada.

curl -s "$WP_API/v1/capabilities" -H "Authorization: Bearer $WP_KEY"
{
  "ec": "<código do seu estabelecimento>",
  "merchant_status": "enabled",
  "key_environment": "test",
  "capabilities": {
    "version": 1,
    "partial_capture": true,
    "partial_refund": true,
    "max_installments": 18,
    "brands": ["Visa", "Mastercard", "Elo", "Amex", "Hipercard"],
    "preauth_ttl_days": 7,
    "payment_sources": ["token", "card"]
  },
  "tokenization": {
    "provider": "malga",
    "available": true,
    "client_id": "<client_id público>",
    "public_key": "<chave pública>",
    "sandbox": true,
    "sdk": { "package": "@malga/tokenization", "version": "2.3.0" },
    "hosted_fields_origin": "https://hosted-fields-sandbox.malga.io"
  }
}
Campo de tokenization Uso
available false quando o ambiente está sem a configuração de tokenização; aí client_id e public_key vêm null e não dá para tokenizar cartão novo
client_id, public_key credenciais públicas, só servem para tokenizar; podem ir para o navegador
sandbox true em homologação; vai em options.sandbox do SDK
sdk.package, sdk.version o pacote npm e a versão exata suportada; use a mesma versão
hosted_fields_origin a origem dos iframes no ambiente; se a sua página tem CSP, libere-a em frame-src

Com available: false, ofereça só o pagamento com cartão salvo (card_id, em Pagamentos) e avise a CDX Pay.

2. Montar os campos e chamar tokenize()

Instale o SDK na versão de sdk.version e empacote-o no bundle da sua página:

npm install @malga/tokenization@2.3.0

O SDK transforma quatro contêineres, com ids fixos, em iframes:

<form id="pagamento">
  <div id="card-number"></div>
  <div id="card-holder-name"></div>
  <div id="card-expiration-date"></div>
  <div id="card-cvv"></div>
  <button type="submit">Pagar</button>
</form>
import { MalgaTokenization } from '@malga/tokenization'

// `config` é o bloco `tokenization` que o seu servidor leu de GET /v1/capabilities.
const config = await fetch('/minha-loja/config-pagamento').then((r) => r.json())

if (!config.available) {
  // Sem tokenização no ambiente: ofereça só o cartão salvo.
} else {
  const tokenizacao = new MalgaTokenization({
    publicKey: config.public_key,
    clientId: config.client_id,
    options: {
      sandbox: config.sandbox,
      config: {
        fields: {
          cardNumber: { container: 'card-number', placeholder: '0000 0000 0000 0000' },
          cardHolderName: { container: 'card-holder-name', placeholder: 'NOME IMPRESSO' },
          cardExpirationDate: { container: 'card-expiration-date', placeholder: 'MM/AA' },
          cardCvv: { container: 'card-cvv', placeholder: 'CVV' },
        },
      },
    },
  })

  document.getElementById('pagamento').addEventListener('submit', async (event) => {
    event.preventDefault()
    const { tokenId, error } = await tokenizacao.tokenize()
    if (!tokenId) {
      // Dado do cartão inválido: mostre `error?.message` e deixe o comprador corrigir.
      return
    }
    // Envie SÓ o tokenId ao seu servidor, que chama POST /v1/payments.
    await fetch('/minha-loja/pagar', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ tokenId }),
    })
  })
}

Cuidados

Escopo PCI DSS da sua página

Atenção. Como a página que embute o SDK executa o script de tokenização e o sessionStorage dela recebe o que o comprador digita, o site do e-commerce fica no escopo PCI DSS SAQ A-EP, e não no SAQ A. Avalie esse escopo com a sua equipe de segurança e o seu assessor de conformidade.

Se você preferir não ter essa página no seu site, o link de pagamento hospedado pela CDX Pay é uma alternativa: o comprador paga numa página da CDX Pay. Fale com o seu contato comercial.