Saltar al contenido principal

Visión General

Explora nuestra colección de aplicaciones de demostración y ejemplos de código para acelerar tu integración con la API de KillB.

Aplicaciones de Ejemplo

Demo On-Ramp

Una implementación completa del flujo de on-ramp (COP/MXN → USDC).

Características

  • Creación de usuario y KYC
  • Visualización de cotización en tiempo real
  • Integración de pago PSE/SPEI
  • Seguimiento del estado de la transacción
  • Manejo de webhook

Ejemplo de Código

import { useState } from 'react';

function OnRampWidget() {
  const [quote, setQuote] = useState(null);
  const [amount, setAmount] = useState('');

  const getQuote = async () => {
    const response = await fetch('/api/v2/quotations', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        fromCurrency: 'COP',
        toCurrency: 'USDC',
        amount: parseFloat(amount),
        amountIsToCurrency: false,
        cashInMethod: 'PSE',
        cashOutMethod: 'POLYGON'
      })
    });
    
    const data = await response.json();
    setQuote(data);
  };

  const createRamp = async () => {
    const response = await fetch('/api/v2/ramps', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        quotationId: quote.id,
        userId: currentUser.id,
        accountId: walletAccount.id
      })
    });
    
    const ramp = await response.json();
    // Redirigir a URL de pago PSE
    window.location.href = ramp.paymentInfo[0].url;
  };

  return (
    <div>
      <input
        type="number"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Monto en COP"
      />
      <button onClick={getQuote}>Obtener Cotización</button>
      
      {quote && (
        <div>
          <p>Recibirás: {quote.toAmount} USDC</p>
          <p>Tasa: {quote.rate}</p>
          <button onClick={createRamp}>Continuar al Pago</button>
        </div>
      )}
    </div>
  );
}

Ver Demo Completa

Ve la aplicación de demostración completa de on-ramp en GitHub

Demo Off-Ramp

Convierte criptomoneda de vuelta a moneda fiat local.

Características

  • Verificación de saldo de billetera
  • Cálculo de cotización
  • Validación de cuenta bancaria
  • Monitoreo de transacción
  • Generación de recibo

Ejemplo de Código

export default function OffRampPage() {
  const createOffRamp = async (formData) => {
    // Paso 1: Obtener cotización
    const quoteRes = await fetch('/api/v2/quotations', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        fromCurrency: 'USDC',
        toCurrency: 'COP',
        amount: formData.amount,
        amountIsToCurrency: false,
        cashInMethod: 'POLYGON',
        cashOutMethod: 'PSE'
      })
    });
    const quote = await quoteRes.json();

    // Paso 2: Crear ramp
    const rampRes = await fetch('/api/v2/ramps', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        quotationId: quote.id,
        userId: formData.userId,
        accountId: formData.bankAccountId
      })
    });
    const ramp = await rampRes.json();

    // Paso 3: Mostrar instrucciones de pago
    return ramp;
  };

  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      createOffRamp(formData);
    }}>
      {/* Campos del formulario */}
    </form>
  );
}

Demo Ahorros

Implementa una interfaz de cuenta de ahorros custodial.

Ejemplo de Código

// Crear cuenta de ahorros
const createSavingsAccount = async (userId) => {
  const response = await fetch('/api/v2/savings', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      userId: userId,
      acceptedTermsAndConditions: true
    })
  });
  
  return await response.json();
};

// Obtener saldo
const getBalance = async (savingsAccountId) => {
  const response = await fetch(
    `/api/v2/savings/${savingsAccountId}/balance`,
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );
  
  return await response.json();
};

// Obtener instrucciones de depósito
const getDepositInstructions = async (savingsAccountId, type) => {
  const response = await fetch(
    `/api/v2/savings/${savingsAccountId}/deposit-instructions/${type}`,
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );
  
  return await response.json();
};

Demo Escuchador de Webhook

Maneja eventos de webhook en tiempo real de KillB.

Ejemplo de Código

const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

app.post('/webhooks/killb', (req, res) => {
  // Verificar firma del webhook
  const signature = req.headers['x-signature-sha256'];
  const payload = JSON.stringify(req.body);
  
  const expectedSignature = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');
  
  if (signature !== expectedSignature) {
    return res.status(401).json({ error: 'Firma inválida' });
  }
  
  // Procesar evento webhook
  const { event, data } = req.body;
  
  switch(event) {
    case 'ramp.completed':
      handleRampCompleted(data);
      break;
    case 'ramp.failed':
      handleRampFailed(data);
      break;
    case 'user.kyc_updated':
      handleKYCUpdate(data);
      break;
  }
  
  res.status(200).json({ received: true });
});

app.listen(3000);

Aprende Más

Lee la guía completa de seguridad de webhook

Fragmentos de Código

Gestión de Usuarios

const createUser = async (userData) => {
  const response = await fetch('/api/v2/users', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      type: 'PERSON',
      externalId: userData.externalId,
      data: {
        firstName: userData.firstName,
        lastName: userData.lastName,
        email: userData.email,
        phone: userData.phone,
        dateOfBirth: userData.dateOfBirth,
        address: userData.address,
        document: userData.document
      }
    })
  });
  
  return await response.json();
};

Creación de Cuenta

const createWalletAccount = async (userId, walletAddress) => {
  const response = await fetch('/api/v2/accounts', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      type: 'WALLET',
      userId: userId,
      externalId: `wallet-${userId}`,
      data: {
        firstName: 'Juan',
        lastName: 'Pérez',
        email: '[email protected]',
        phone: '+573001234567',
        currency: 'USDC',
        network: 'POLYGON',
        address: walletAddress,
        countryCode: 'CO',
        document: {
          type: 'PASSPORT',
          number: 'AB123456',
          issuedCountryCode: 'CO'
        }
      }
    })
  });
  
  return await response.json();
};

Creación de Ramp

const executeRamp = async (userId, accountId, amount, direction) => {
  try {
    // 1. Crear cotización
    const quote = await fetch('/api/v2/quotations', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        fromCurrency: direction === 'ON' ? 'COP' : 'USDC',
        toCurrency: direction === 'ON' ? 'USDC' : 'COP',
        amount: amount,
        amountIsToCurrency: false,
        cashInMethod: direction === 'ON' ? 'PSE' : 'POLYGON',
        cashOutMethod: direction === 'ON' ? 'POLYGON' : 'PSE'
      })
    }).then(r => r.json());

    console.log('Cotización:', quote);

    // 2. Crear ramp
    const ramp = await fetch('/api/v2/ramps', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        quotationId: quote.id,
        userId: userId,
        accountId: accountId
      })
    }).then(r => r.json());

    console.log('Ramp:', ramp);
    
    return ramp;
  } catch (error) {
    console.error('Fallo en la creación del ramp:', error);
    throw error;
  }
};

Probando en Sandbox

Usa estas funciones auxiliares para probar tu integración:

Simular Cash-In

curl --request POST \
  --url https://teste-94u93qnn.uc.gateway.dev/api/v2/faker/cash-in \
  --header 'Authorization: Bearer TU_TOKEN_DE_ACCESO' \
  --header 'Content-Type: application/json' \
  --data '{
    "rampId": "ramp-id-aqui"
  }'

Simular Finalización de Cash-Out

curl --request POST \
  --url https://teste-94u93qnn.uc.gateway.dev/api/v2/faker/cash-out \
  --header 'Authorization: Bearer TU_TOKEN_DE_ACCESO' \
  --header 'Content-Type: application/json' \
  --data '{
    "rampId": "ramp-id-aqui"
  }'
Los endpoints Faker solo funcionan en el ambiente sandbox y se usan con fines de prueba.

Lista de Verificación de Integración

1

Configurar Autenticación

Implementar lógica de inicio de sesión y actualización de token
2

Crear Gestión de Usuarios

Construir flujos de creación de usuario y envío de KYC
3

Implementar Creación de Cuenta

Agregar gestión de cuenta bancaria y billetera
4

Construir UI de Cotización

Mostrar precios en tiempo real a los usuarios
5

Manejar Flujo de Ramp

Crear y monitorear transacciones ramp
6

Configurar Webhooks

Recibir actualizaciones de estado en tiempo real
7

Agregar Manejo de Errores

Implementar manejo de errores adecuado y lógica de reintento
8

Probar Exhaustivamente

Usar ambiente sandbox para pruebas de extremo a extremo

Recursos Adicionales

¿Tienes una app demo para compartir? Contáctanos en [email protected] para que sea destacada!