> ## Documentation Index
> Fetch the complete documentation index at: https://docs.killb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Implementación On-Ramp

> Convierte moneda fiat a criptomoneda

## Visión General

Un on-ramp convierte moneda fiat (COP, MXN, USD) en criptomoneda (USDC, USDT). Los usuarios pagan con métodos de pago locales y reciben cripto en su billetera.

## Flujo Completo de On-Ramp

<Steps>
  <Step title="Crear Usuario y Billetera">
    Configura perfil de usuario y billetera de destino
  </Step>

  <Step title="Obtener Cotización">
    Solicita cotización de precio para conversión
  </Step>

  <Step title="Crear Ramp">
    Ejecuta ramp con ID de cotización
  </Step>

  <Step title="Usuario Paga">
    Usuario completa pago vía PSE/SPEI/etc
  </Step>

  <Step title="Conversión">
    KillB convierte fiat a cripto
  </Step>

  <Step title="Cripto Entregado">
    USDC/USDT enviado a billetera del usuario
  </Step>
</Steps>

## Ejemplo de Implementación

<CodeGroup>
  ```javascript Flujo Completo theme={null}
  const executeOnRamp = async (userId, walletAddress, amount) => {
    try {
      // 1. Crear cuenta de billetera si es necesario
      let wallet = await findWalletAccount(userId, 'POLYGON', 'USDC');
      
      if (!wallet) {
        wallet = await createWalletAccount(userId, walletAddress, 'USDC', 'POLYGON');
      }
      
      // 2. Obtener cotización
      const quote = await fetch('/api/v2/quotations', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          fromCurrency: 'COP',
          toCurrency: 'USDC',
          amount: amount,
          amountIsToCurrency: false,
          cashInMethod: 'PSE',
          cashOutMethod: 'POLYGON'
        })
      }).then(r => r.json());
      
      console.log(`Recibirás: ${quote.toAmount} USDC`);
      
      // 3. 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: wallet.id,
          externalId: `onramp-${Date.now()}`
        })
      }).then(r => r.json());
      
      // 4. Redirigir a pago
      return {
        rampId: ramp.id,
        paymentUrl: ramp.paymentInfo[0].url,
        expectedAmount: quote.toAmount
      };
      
    } catch (error) {
      console.error('On-ramp falló:', error);
      throw error;
    }
  };

  // Uso
  const result = await executeOnRamp('user-id', '0x742d35...', 100000);
  window.location.href = result.paymentUrl;
  ```

  ```python Flujo Completo theme={null}
  def execute_onramp(user_id, wallet_address, amount, access_token):
      """Ejecuta flujo completo de on-ramp"""
      base_url = 'https://sandbox.killb.app'
      headers = {
          'Authorization': f'Bearer {access_token}',
          'Content-Type': 'application/json'
      }
      
      # 1. Crear cuenta de billetera
      wallet_response = requests.post(
          f'{base_url}/api/v2/accounts',
          headers=headers,
          json={
              'type': 'WALLET',
              'userId': user_id,
              'externalId': f'{user_id}-wallet',
              'data': {
                  # ... datos de billetera
                  'currency': 'USDC',
                  'network': 'POLYGON',
                  'address': wallet_address
              }
          }
      )
      wallet = wallet_response.json()
      
      # 2. Obtener cotización
      quote_response = requests.post(
          f'{base_url}/api/v2/quotations',
          headers=headers,
          json={
              'fromCurrency': 'COP',
              'toCurrency': 'USDC',
              'amount': amount,
              'amountIsToCurrency': False,
              'cashInMethod': 'PSE',
              'cashOutMethod': 'POLYGON'
          }
      )
      quote = quote_response.json()
      
      # 3. Crear ramp
      ramp_response = requests.post(
          f'{base_url}/api/v2/ramps',
          headers=headers,
          json={
              'quotationId': quote['id'],
              'userId': user_id,
              'accountId': wallet['id']
          }
      )
      ramp = ramp_response.json()
      
      return {
          'ramp_id': ramp['id'],
          'payment_url': ramp['paymentInfo'][0]['url'],
          'expected_amount': quote['toAmount']
      }
  ```
</CodeGroup>

## Métodos de Pago

<Tabs>
  <Tab title="PSE (Colombia)">
    Usuario redirigido a checkout PSE:

    ```javascript theme={null}
    // Respuesta del ramp incluye URL de pago
    const paymentUrl = ramp.paymentInfo[0].url;

    // Redirigir usuario
    window.location.href = paymentUrl;

    // Usuario completa pago en PSE
    // Webhook notifica cuando pago confirmado
    ```

    **Flujo:**

    1. Redirigir a URL PSE
    2. Usuario selecciona banco
    3. Usuario autentica
    4. Usuario confirma pago
    5. Webhook recibido
  </Tab>

  <Tab title="SPEI (México)">
    Usuario transfiere a CLABE proporcionada:

    ```javascript theme={null}
    const paymentInfo = ramp.paymentInfo[0];

    // Mostrar al usuario:
    console.log('Banco:', paymentInfo.Bank);
    console.log('CLABE:', paymentInfo.CLABE);
    console.log('Beneficiario:', paymentInfo.Beneficiary);
    console.log('Referencia:', paymentInfo.concepto);

    // Usuario completa transferencia SPEI con referencia
    ```

    **Importante:** Usuario DEBE incluir `concepto` como referencia de pago
  </Tab>
</Tabs>

## Monitoreando Progreso

```javascript theme={null}
const monitorRamp = async (rampId) => {
  const pollInterval = setInterval(async () => {
    const ramp = await fetch(`/api/v2/ramps/${rampId}`, {
      headers: { 'Authorization': `Bearer ${token}` }
    }).then(r => r.json());
    
    console.log('Estado:', ramp.status);
    
    if (ramp.status === 'COMPLETED') {
      console.log('¡Cripto entregado!');
      console.log('Transacción:', ramp.transferProof);
      clearInterval(pollInterval);
    } else if (['FAILED', 'CANCELED'].includes(ramp.status)) {
      console.error('Ramp falló:', ramp.details);
      clearInterval(pollInterval);
    }
  }, 10000); // Verificar cada 10 segundos
};
```

<Tip>
  Usa webhooks como método de notificación primario, con polling como respaldo.
</Tip>

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Guía Off-Ramp" icon="arrow-down" href="/es/guides/ramps/off-ramp">
    Implementa conversión cripto a fiat
  </Card>

  <Card title="Seguimiento de Estado" icon="chart-line" href="/es/guides/ramps/ramp-status">
    Monitorea el progreso del ramp
  </Card>
</CardGroup>
