Pular para o conteúdo principal
Nesta página
Método de integração

Tokenize credenciais de pagamento para reutilizá-las com segurança.

Escolha uma experiência Vault hospedada pela DEUNA ou um fluxo de API compatível com PCI, receba um ID de cartão reutilizável e processe pagamentos futuros com segurança.

Interface
Entrada de credenciais hospedada pela DEUNA ou captura do lojista compatível com PCI
Modelo de entrega
Componente SDK ou API de Cards autorizada pelo cliente
Ideal para
Cartões salvos, checkout em um clique e pagamentos recorrentes

Compreenda os limites da credencial#

O card_id retornados por um fluxo de tokenização suportado são referências de pagamento da DEUNA. A sua disponibilidade para um pagamento posterior depende do consentimento do cliente, tipo de token, conta do comerciante, conexão com o provedor, ambiente, país e operação habilitada para esse fluxo.

  • Não assuma que todas as credenciais armazenadas podem ser transferidas entre processadores ou métodos de pagamento.
  • Verifique o comportamento de rede-token, atualização de conta, portabilidade, uso recorrente e exclusão para a conta de destino antes da produção.
  • Mantenha o PAN, CVV, token do provedor e credenciais privadas fora dos seus logs e metadados de aplicação.
  • Armazene o cliente, o propósito do consentimento, o horário da tokenização, o status da credencial e o uso futuro permitido no seu sistema de registro.
  • Suporte à revogação, expiração, substituição e exclusão da credencial sem tratar um token excluído como uma assinatura cancelada automaticamente.

Use a Catálogo de Capacidades do Provedor Para suporte de conexão publicado e confirme o comportamento da credencial específico da conta com o seu Gerente de Contas Técnicas da DEUNA.

Escolha um método de integração#

O Payment Vault oferece suporte aos SDKs da DEUNA e à API de Cards autorizada pelo cliente. Os dois métodos retornam um card_id; escolha o método de acordo com quem controla a experiência de entrada de credenciais e o respectivo escopo do Padrão de Segurança de Dados da Indústria de Cartões de Pagamento (PCI DSS).

Integre com a API de Cards#

Use a API de Cards quando seu aplicativo controlar a experiência de entrada de cartões e estiver preparado para as responsabilidades correspondentes do PCI DSS. Este é um fluxo autorizado pelo cliente: autentique o cliente e depois chame POST /v2/users/{user_id}/cards com o token Bearer desse cliente e o contexto do lojista exigido pelo endpoint para armazenar um cartão.

:::info Rota pública suportada Para novas integrações, use apenas POST /v2/users/{user_id}/cards. A rota sem versão /users/{user_id}/cards preserva um contrato legado de cartão único, enquanto /users/{user_id}/cards/{card_id}/tokens adiciona um token específico do processador a um cartão existente e não é um endpoint de criação de cartão. Nenhuma das rotas faz parte do catálogo atual da API externa. Veja Diferenças da rota POST de Cartão. :::

O /v2 usa um corpo de solicitação que é um array JSON, mesmo quando você armazena apenas um cartão:

curl --request POST \
  --url 'https://api.sandbox.deuna.io/v2/users/USER_ID/cards' \
  --header 'Authorization: Bearer USER_ACCESS_TOKEN' \
  --header 'X-Merchant-ID: MERCHANT_ID' \
  --header 'Content-Type: application/json' \
  --data '[
    {
      "card_holder": "Jane Doe",
      "card_number": "CARD_NUMBER",
      "card_cvv": "CARD_CVV",
      "expiry_month": "12",
      "expiry_year": "2029",
      "is_default": true
    }
  ]'

Uma solicitação bem-sucedida retorna HTTP 201 Created. Armazene o data[].id como o card_id; nunca armazene o PAN ou o CVV enviados.

Cartão criadoJSON
{
  "data": [
    {
      "id": "8b5d0b45-e34f-4fd3-8cb5-79a7041f86ec",
      "company": "visa",
      "last_four": "4242",
      "expiration_date": "12/29"
    }
  ]
}

Após um timeout ou uma resposta ambígua, consulte Listar cartões armazenados antes de reenviar o cartão. O contrato do Gateway não publica um cabeçalho de idempotência para esta operação, portanto os clientes não devem presumir que uma nova tentativa seja idempotente. Os metadados de verificação podem estar ausentes até a DEUNA verificar a credencial; consulte Metadados de verificação do cartão.

Integre com um SDK da DEUNA#

A integração do Payment Vault é feita através dos SDKs da DEUNA.

Em ambientes web, o widget pode ser aberto em um elemento HTML de destino ou exibido como modal.

Escolha sua plataforma SDK:

Recursos

  • O SDK expõe vários retornos de chamada que permitem ao comerciante reagir dinamicamente a eventos importantes dentro do fluxo de pagamento, tais como:
    • Quando o usuário fecha o widget.
    • Quando um cartão ou credencial de pagamento é tokenizado com sucesso.
    • Quando uma tentativa de tokenização falha.
  • O Cofre de Pagamento pode ser renderizado incorporado ou como um modal.

Informações adicionais

Saiba mais sobre a integração do Payment Vault:

  • Verificando o tipo de evento e a marca do cartão: o Vault reconhece marcas de cartões a partir de metadados de eventos.
  • Desconto aplicado caso o cartão seja Mastercard pelo estabelecimento comercial: Se o cartão for Mastercard, será aplicado um desconto de 20% no carrinho de compras atual. Esta ação é executada inteiramente pelo seu aplicativo.
  • Atualização de pedido: Após aplicar um desconto, sua aplicação é responsável por atualizar o pedido usando o endpoint DEUNA Update Order.
  • Notificação ao widget para atualização do pedido e parcelamento: as alterações no status de um pedido são comunicadas usando retornos de chamada do SDK.
  • Exibir uma tag promocionalAlém de atualizar o valor do pedido e do pagamento, você pode aplicar estilos CSS personalizados ao widget ativo usando setCustomStyles(...). Veja o Guia do SDK da Web.

Processar um pagamento com o token retornado card_id

Para processar um pagamento em DEUNA com determinado card_id use o Comprar API.

Exemplo de solicitação curl

JavaScript
const requestBody = {
    payer_info: {
        email: "eposada@deuna.com"
    },
    payment_source: {
        method_type: "credit_card",
        card_info: {
            card_id: "8d369b6e-113a-4640-9e63-dc29957fc86a",
            installment: {
            	plan_option_id: "<uuid que se retorna en el postMessage 'onInstallmentSelected'>"
            }
        }
    },
    // ... Remaining of the request body
};

fetch('https://api.sandbox.deuna.io/v2/merchants/orders/purchase', {
    method: 'POST',
    headers: {
        'x-api-key': '<YOUR_PRIVATE_API_KEY>',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl --location 'https://api.sandbox.deuna.io/v2/merchants/orders/purchase' \
--header 'x-api-key: YOUR_PRIVATE_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "payer_info": {
        "email": "foo@bar.com"
    },
    "payment_source": {
        "method_type": "credit_card",
        "card_info": {
            "card_id": "8d369b6e-113a-4640-9e63-dc29957fc86a"
        }
    },
    "order": {
        "order_id": "testapi-0003",
        "currency": "MXN",
        "items": [
          {
              "id": "216",
              "name": "10 Cellphones",
              "description": "",
              "options": "string option",
              "total_amount": {
                  "original_amount": 2000,
                  "amount": 2000,
                  "currency": "MXN",
                  "currency_symbol": "$"
              },
              "unit_price": {
                  "amount": 200,
                  "currency": "MXN",
                  "currency_symbol": "$"
              },
              "tax_amount": {
                  "amount": 0,
                  "currency": "MXN",
                  "currency_symbol": "$"
              },
              "quantity": 1,
              "uom": "string",
              "upc": "string",
              "sku": "",
              "isbn": "",
              "brand": "",
              "manufacturer": "",
              "category": "",
              "color": "",
              "size": "",
              "weight": {
                  "amount": 0,
                  "unit": "kg"
              },
              "image_url": "https://images-staging.getduna.com/95463fb5-6279-4ec3-8ff9-fe07aacd2142/db5b698c57654116_domicilio_216_750x750_1662162887.png?d=200x200&format=webp",
              "details_url": "",
              "type": "physcal",
              "taxable": true
          }
        ],
        "sub_total": 2000,
        "total_amount": 2000,
        "store_code": "all",
        "billing_address": {
            "address1": "presa angostura 36PH",
            "address2": "",
            "address_type": "home",
            "city": "CDMX",
            "country_code": "MX",
            "email": "foo@bar.com",
            "first_name": "efren",
            "identity_document": "162915134",
            "is_default": true,
            "last_name": "garcia",
            "phone": "+525222222222",
            "state_code": "MX",
            "state_name": "miguel hidalgo",
            "zipcode": "11500"
        }
    }
}'
PHP
$curl = curl_init();

$requestBody = json_encode(array(
    "payer_info" => array(
        "email" => "foo@bar.com"
    ),
    "payment_source" => array(
        "method_type" => "credit_card",
        "card_info" => array(
            "card_id" => "8d369b6e-113a-4640-9e63-dc29957fc86a"
        )
    ),
    // Aquí puedes continuar añadiendo el resto del cuerpo de la solicitud
    "order" => array(
        "order_id" => "testapi-0003",
        "currency" => "MXN",
        "items" => array(
            // Aquí van los detalles de los items
        ),
        // Continúa con el resto de los detalles del pedido
    )
));

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => $requestBody, // Aquí se utiliza la variable
  CURLOPT_HTTPHEADER => array(
    "x-api-key: YOUR_PRIVATE_API_KEY", // Asegúrate de reemplazar con tu API key real
    "Content-Type: application/json"
  ),
));


$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
Ruby
require 'uri'
require 'net/http'
require 'json'

url = URI("https://api.sandbox.deuna.io/v2/merchants/orders/purchase")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request_body = {
    payer_info: {
        email: "foo@bar.com"
    },
    payment_source: {
        method_type: "credit_card",
        card_info: {
            card_id: "8d369b6e-113a-4640-9e63-dc29957fc86a"
        }
    }
    # ... Agrega aquí el resto del cuerpo de la solicitud
}.to_json

request = Net::HTTP::Post.new(url)
request["x-api-key"] = "YOUR_PRIVATE_API_KEY" # Reemplaza con tu API key
request["Content-Type"] = "application/json"
request.body = request_body

response = http.request(request)
puts response.read_body
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import org.json.JSONObject;

public class Main {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        
        JSONObject requestBody = new JSONObject()
            .put("payer_info", new JSONObject().put("email", "foo@bar.com"))
            .put("payment_source", new JSONObject()
                .put("method_type", "credit_card")
                .put("card_info", new JSONObject().put("card_id", "8d369b6e-113a-4640-9e63-dc29957fc86a")))
            // ... Agrega aquí el resto del cuerpo de la solicitud

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.sandbox.deuna.io/v2/merchants/orders/purchase"))
            .header("x-api-key", "YOUR_PRIVATE_API_KEY") // Reemplaza con tu API key
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(requestBody.toString()))
            .build();

        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
            .thenApply(HttpResponse::body)
            .thenAccept(System.out::println)
            .join();
    }
}

Demonstração

Após a integração do Payment Vault, a experiência é semelhante à seguinte demonstração: