Cartão de Crédito

Trabalhamos em parceria com a Tuna para processar nossas transações de cartão de crédito. Para sua total segurança, a Tuna possui certificação PCI, garantindo o mais alto padrão de proteção de dados.

Este guia descreve o fluxo completo para criação de um pedido com pagamento via cartão de crédito, desde a busca de passagens até o processamento do pagamento e criação final do pedido. Todas as APIs mencionadas estão documentadas na seção API Reference.

Fluxo de Integração

1. Busca de passagens por origem/destino

Descrição: Lista de viagens encontradas por rota (origem e destino) e data.

Endpoint: GET https://platform-bff-partners.stg.clickbus.net/partners/api/v5/trips

ℹ️

Consulte o tópico "Buscar por rota e data" na seção API Reference.

GET /trips?from=sao-paulo-tiete-sp&to=tres-pontas-mg-via-varginha&departureDate=2025-09-30&returnDate=2025-10-10&clientId=2
2. Selecionar e bloquear assento

Descrição: Bloquear um ou mais assentos para garantir a reserva antes da finalização do pedido.

Endpoint: POST https://platform-bff-partners.stg.clickbus.net/partners/api/v4/trips/{id}/seats

ℹ️

Consulte o tópico "Bloquear um ou mais assentos" na seção API Reference.

{
  "seats": [
    {
      "label": "25",
      "isLowFare": false,
      "discount": {},
      "passengerData": {
        "name": "Tamires Silva",
        "documentType": "CPF",
        "documentNumber": "12345678900"
      }
    }
  ]
}
3. Consultar meios de pagamento

Descrição: Consulta métodos de pagamento disponíveis para processar pedidos. Esta etapa não realiza o pagamento, apenas retorna as opções habilitadas para exibição no checkout.

Endpoint: POST https://platform-bff-partners.stg.clickbus.net/partners/api/v4/payments

ℹ️

Consulte o tópico "Consultar métodos de pagamento" na seção API Reference.

{
  "items": [
    {
      "type": "seat",
      "insurance": false,
      "itemDetails": {
        "id": "{{seatId}}",
        "type": "seat",
        "price": 190.09
      }
    }
  ],
  "useClub": false,
  "roundTripTravel": true,
  "beginCheckout": true,
  "pixInstallmentActive": true
}
4. Criar sessão de pagamento

Descrição: Cria uma nova sessão de pagamento que será usada para tokenização e processamento do cartão.

Endpoint: POST https://platform-bff-partners.stg.clickbus.net/partners/api/v4/payments/session

ℹ️

Consulte o tópico "Criar sessão de pagamento" na seção API Reference.

{
  "customer": {
    "email": "ana*****@email.com"
  }
}
5. Tokenizar cartão de crédito

Descrição: É possível tokenizar cartões via plugin Javascript: (https://dev.tuna.uy/plugins/javascript)

Exemplo usando o plugin JS

        <head>
            <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/tuna-statics/components.min.css">
        </head>
    <script src="https://js.tuna.uy/tuna-essentials.js"></script>
    <script src="https://storage.googleapis.com/tuna-statics/tuna-v2.js"></script>

    <script>
        const statusElement = document.getElementById('status');
        const urlBase = 'https://platform-bff-partners.stg.clickbus.net/partners';
        const ACCESS_TOKEN_URL = urlBase + '/api/oauth/basic-token';
        const PAYMENT_SESSION_URL = urlBase + '/api/v4/payments/session';
        let tunaInstance = null;
        /**
         * Obtém o Access Token usando as credenciais Basic.
         */
        async function createAccessToken() {
            try {
                const response = await fetch(ACCESS_TOKEN_URL, {
                    method: 'POST',
                    headers: {
                        // CORREÇÃO AQUI: Formato URL-encoded para o corpo
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'Authorization': 'Basic dm95b246JDJhJDEwJHlncFlMYVVUdFFubE1wMW1lRnBId09FZERiVTNLU004Ri9UUzQ1aHhUQnVZRGhVcTZXckQy'    
                    },
                    body: 'grant_type=client_credentials'
                });
                
                if (!response.ok) {
                    throw new Error(`Erro ${response.status} ao obter Access Token.`);
                }
                
                const data = await response.json();
                console.log('Access Token Obtido: ', data.access_token);
                return data.access_token;
            } catch (error) {
                console.error('Falha em createAccessToken:', error);
                return null;
            }
        }

        /**
         * Cria uma nova sessão de pagamento usando o token obtido.
         */
        async function createPaymentSession() {
            
            statusElement.textContent = 'Obtendo Access Token...';
            
            const sessionElement = document.getElementById('session-id-container').querySelector('strong');
            
            const accessToken = await createAccessToken();

            if (!accessToken) {
                statusElement.textContent = 'Falha ao obter Access Token.';
                return;
            } else {
                statusElement.textContent = 'Acess Token Criado com Sucesso!';
                document.getElementById('access-token-container').querySelector('strong').textContent = accessToken;
            }

            const params = new URLSearchParams({
                clientId: '59999'
            });

            const PAYMENT_SESSION_URL_WITH_PARAMS = PAYMENT_SESSION_URL + '?' + params.toString();
            console.log('URL de Criação de Sessão:', PAYMENT_SESSION_URL_WITH_PARAMS);

            const customer = { email: '[email protected]' };            
            const requestBody = { customer: customer };

            statusElement.textContent = 'Criando Sessão de Pagamento...';

            try {
                const response = await fetch(PAYMENT_SESSION_URL_WITH_PARAMS, {
                    method: 'POST', 
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + accessToken 
                    },
                    body: JSON.stringify(requestBody) 
                });

                if (!response.ok) {
                    // Tenta ler o corpo da resposta para mais detalhes do erro
                    const errorDetails = await response.text(); 
                    console.error('Detalhes do Erro da Sessão:', errorDetails);
                    throw new Error(`Erro ${response.status} ao criar sessão.`);
                }

                const sessionData = await response.json();
                
                statusElement.textContent = 'Sessão de Pagamento criada com sucesso!';
                sessionElement.textContent = sessionData.sessionId;

                return sessionData;

            } catch (error) {
                console.error('Falha em createPaymentSession:', error);
                statusElement.textContent = 'Falha na Criação da Sessão. Verifique o Console.';
                return null;
            }  
        }

        async function generateCardTokenTuna() {
            const sessionData = await createPaymentSession();

            statusElement.textContent = 'Gerando Token do Cartão...';

            const cardTokenElement = document.getElementById('card-token-container').querySelector('strong');

            const creditCard = {
                cardHolderName: 'Authorized',
                cardNumber: '4716992200743495',
                expirationMonth: 1,
                expirationYear: 2027,
                cvv: '222',
                singleUse: true
            };


            if (sessionData) {
                const session = sessionData.sessionId;
                
                tunaInstance = Tuna(session);
                const tokenizador = await tunaInstance.tokenizator();
                const cardToken = await tokenizador.generate(creditCard);
                
                console.log('Token Gerado:', cardToken.token);
                
                statusElement.textContent = 'Token Gerado com Sucesso!';
                cardTokenElement.textContent = cardToken.token;

                return cardToken.token;
            }
        }

        // Inicia o fluxo
        generateCardTokenTuna();
    </script>
6. Fingerprints (Análise antifraude)

Descrição: Implementação de análise de comportamento para prevenção de fraudes através da integração com Koin.

A integração de fingerprints deve seguir a documentação oficial da Koin, garantindo conformidade com os padrões de segurança PCI.

7. Criar pedido

Descrição: Cria um novo pedido com pagamento via Cartão de Crédito, incluindo validação, antifraude e processamento do pagamento.

Endpoint: POST https://platform-bff-partners.stg.clickbus.net/partners/api/v4/orders

ℹ️

Consulte o tópico "Criar novo pedido com Cartão de Crédito" na seção API Reference.

{
  "tokenPixInstallmentId": "eyJ0eXAiOiJ*******IUzI1NiJ9...",
  "orderFinancialChannelId": 2,
  "totalAmount": 354.83,
  "payment": {
    "amount": 354.83,
    "installments": "3",
    "currency": "BRL",
    "type": "credit_card",
    "paymentDetails": {
      "meta": {
        "tunaClearSaleSessionId": "14b71ac4-8db******5-0125296dc886",
        "tunaSessionId": "yetuWPPQDbp*****gdY/0SiugxDSmyPFM..."
      },
      "creditCard": {
        "brand": "visa",
        "expirationMonth": "12",
        "expirationYear": "2028",
        "cardholderName": "INSTITUTO ******",
        "tokens": {
          "tuna": "ct_OThmN2QzY********LWE5ODQtYWIxOGE3MDhiNTUx0"
        }
      }
    }
  },
  "user": {
    "name": "Paulo ******",
    "email": "com*****@email.com"
  }
}