Pagamentos

Gerencie pagamentos e cobranças através do gateway Asaas

Endpoints

GET /api/payments

Lista todos os pagamentos cadastrados.

POST /api/payments

Cria um novo pagamento apenas para BOLETO e PIX.

Importante: Esta rota é destinada exclusivamente para pagamentos via BOLETO e PIX. Para pagamentos com cartão de crédito, utilize a rota /api/payments/secure/credit-card.

GET /api/payments/:id

Obtém detalhes de um pagamento específico.

GET /api/payments/customer/:customerId

Lista pagamentos de um cliente específico.

DELETE /api/payments/:id

Remove um pagamento.

POST /api/payments/:id/refund

Estorna um pagamento.

POST /api/payments/secure/credit-card

Cria um novo pagamento com cartão de crédito usando dados criptografados para maior segurança.

Recomendado: Esta é a rota mais segura para pagamentos com cartão de crédito, pois os dados sensíveis são criptografados.

GET /api/payments/public-key

Obtém a chave pública para criptografia dos dados do cartão de crédito.

Uso: Esta chave deve ser usada para criptografar os dados sensíveis do cartão antes de enviá-los para a rota /api/payments/secure/credit-card.
Tipos de Cobrança e Rotas
BOLETO e PIX
  • POST /api/payments - Rota padrão para BOLETO e PIX
  • Suporta descontos, multas e juros
  • Ideal para cobranças com vencimento
Cartão de Crédito
  • POST /api/payments/secure/credit-card - Rota segura com criptografia
  • Suporta parcelamento
  • Requer dados do titular do cartão
  • Dados sensíveis criptografados
Status de Pagamento
  • PENDING: Aguardando pagamento
  • CONFIRMED: Pagamento confirmado
  • OVERDUE: Pagamento vencido
  • REFUNDED: Pagamento estornado
  • CANCELED: Pagamento cancelado
Boas Práticas
  • BOLETO e PIX: Use a rota POST /api/payments com o campo billingType apropriado
  • Cartão de Crédito: Use POST /api/payments/secure/credit-card para máxima segurança
  • Use o campo externalReference para referência do seu sistema
  • Configure descontos, multas e juros conforme sua política (apenas para BOLETO)
  • Monitore os status dos pagamentos para ações automáticas
  • Mantenha os dados do cliente atualizados para emissão de boletos
  • Para cartão de crédito, sempre informe o remoteIp do cliente
  • Utilize a rota segura para maior proteção dos dados sensíveis do cartão

Implementação de Criptografia

Service para criptografar dados sensíveis do cartão de crédito no frontend

Service de Criptografia (Frontend)
Como usar: Este service deve ser usado no frontend para criptografar os dados sensíveis do cartão (número e CCV) antes de enviar para a API.
// api.ts
const tokenApi = axios.create({
  baseURL: import.meta.env.VITE_GATEWAY_URL,
});

const gatewayApi = axios.create({
  baseURL: import.meta.env.VITE_GATEWAY_URL,
});

export const GATEWAY_ENVIRONMENT = (import.meta.env.VITE_GATEWAY_ENVIRONMENT ||
  "SANDBOX") as "SANDBOX" | "PROD";

gatewayApi.interceptors.request.use(async (config) => {
  const clientId = import.meta.env.VITE_CLIENT_ID;

  const response = await tokenApi.get<{ accessToken: string }>(
    `/access-tokens/client/${clientId}`,
    {
      params: { enviroment: GATEWAY_ENVIRONMENT },
    }
  );

  config.headers["Content-Type"] = "application/json";
  config.headers["access_token"] = response.data.accessToken;
  return config;
});

export { gatewayApi };
                
                
// encrypt-payment.ts
import { gatewayApi } from "./api";

class EncryptionService {
  private publicKey: string | null = null;

  async loadPublicKey(): Promise<void> {
    if (this.publicKey) return;

    try {
      const response = await gatewayApi.get<string>("/payments/public-key");

      if (!response.data) {
        throw new Error("Failed to load public key");
      }

      // Remover cabeçalho e rodapé da chave se existirem
      let key = response.data
        .replace("-----BEGIN PUBLIC KEY-----", "")
        .replace("-----END PUBLIC KEY-----", "")
        .replace(/\s/g, "");

      // Verificar se a chave está em formato base64 válido
      try {
        // Tentar decodificar a chave para verificar se é base64 válido
        this.publicKey = key;
      } catch (e) {
        throw new Error("Invalid public key format");
      }
    } catch (error) {
      console.error("Error loading public key:", error);
      throw error;
    }
  }

  async encrypt(data: string): Promise<string> {
    if (!this.publicKey) {
      await this.loadPublicKey();
    }

    const encoder = new TextEncoder();
    const encodedData = encoder.encode(data);

    try {
      // Importar a chave pública
      const importedKey = await window.crypto.subtle.importKey(
        "spki",
        this.base64ToArrayBuffer(this.publicKey!),
        {
          name: "RSA-OAEP",
          hash: "SHA-256",
        },
        false,
        ["encrypt"]
      );

      // Criptografar os dados
      const encrypted = await window.crypto.subtle.encrypt(
        {
          name: "RSA-OAEP",
        },
        importedKey,
        encodedData
      );

      // Converter para base64
      const result = btoa(String.fromCharCode(...new Uint8Array(encrypted)));
      return result;
    } catch (error) {
      console.error("Erro durante a criptografia:", error);
      throw error;
    }
  }

  private base64ToArrayBuffer(base64: string): ArrayBuffer {
    try {
      const binaryString = atob(base64);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }
      return bytes.buffer;
    } catch (error) {
      console.error("Erro ao converter base64 para ArrayBuffer:", error);
      throw error;
    }
  }
}

export default new EncryptionService();
Exemplo de Uso
// Exemplo de como usar o service
import encryptService from './services/encrypt-payment';

async function processCreditCardPayment(paymentData) {
  try {
    // Dados sensíveis do cartão
    const sensitiveData = {
      number: "4242424242424242",
      ccv: "123"
    };

    // Criptografar dados sensíveis
    const encryptedData = await encryptService.encrypt(
      JSON.stringify(sensitiveData)
    );

    // Preparar payload para a API
    const payload = {
      customer: "cus_000006671674",
      value: 0,
      dueDate: "2025-05-01",
      installmentCount: 2,
      totalValue: 100,
      encryptedCreditCard: {
        encryptedData: encryptedData
      },
      creditCard: {
        holderName: "John Doe",
        expiryMonth: "04",
        expiryYear: "2025"
      },
      creditCardHolderInfo: {
        name: "John Doe",
        email: "john.doe@example.com",
        cpfCnpj: "12345678901",
        postalCode: "12345678",
        addressNumber: "123",
        phone: "11987654321"
      },
      remoteIp: "127.0.0.1"
    };

    // Enviar para a API
    const response = await fetch('/api/payments/secure/credit-card', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'access_token': 'seu_token_aqui'
      },
      body: JSON.stringify(payload)
    });

    return await response.json();
  } catch (error) {
    console.error('Erro no processamento:', error);
    throw error;
  }
}
Boas Práticas de Segurança
  • Sempre use HTTPS em produção para transmissão segura
  • Nunca armazene dados sensíveis do cartão no frontend
  • Criptografe apenas os dados necessários (número e CCV)
  • Valide os dados antes da criptografia
  • Use a chave pública apenas para criptografia, nunca para descriptografia
  • Implemente rate limiting para evitar ataques de força bruta
  • Monitore logs para detectar tentativas de fraude
  • Mantenha as dependências atualizadas para evitar vulnerabilidades