> ## 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.

# Apps Demo e Exemplos

> Implementações de exemplo e exemplos de integração

## Visão Geral

Explore nossa coleção de aplicações de demonstração e exemplos de código para acelerar sua integração com a API KillB.

## Aplicações de Exemplo

<CardGroup cols={2}>
  <Card title="Demo On-Ramp" icon="arrow-up" href="#demo-on-ramp">
    Fluxo completo de on-ramp de fiat para cripto
  </Card>

  <Card title="Demo Off-Ramp" icon="arrow-down" href="#demo-off-ramp">
    Converta cripto de volta para moeda fiat local
  </Card>

  <Card title="Painel de Poupança" icon="chart-line" href="#demo-poupanca">
    Interface de conta poupança custodial
  </Card>

  <Card title="Ouvinte de Webhook" icon="bell" href="#demo-webhook">
    Lide com notificações de eventos em tempo real
  </Card>
</CardGroup>

## Demo On-Ramp

Uma implementação completa do fluxo de on-ramp (COP/MXN → USDC).

### Recursos

* Criação de usuário e KYC
* Exibição de cotação em tempo real
* Integração de pagamento PSE/SPEI
* Rastreamento de status da transação
* Tratamento de webhook

### Exemplo de Código

<CodeGroup>
  ```javascript React theme={null}
  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();
      // Redirecionar para URL de pagamento PSE
      window.location.href = ramp.paymentInfo[0].url;
    };

    return (
      <div>
        <input
          type="number"
          value={amount}
          onChange={(e) => setAmount(e.target.value)}
          placeholder="Valor em COP"
        />
        <button onClick={getQuote}>Obter Cotação</button>
        
        {quote && (
          <div>
            <p>Você receberá: {quote.toAmount} USDC</p>
            <p>Taxa: {quote.rate}</p>
            <button onClick={createRamp}>Continuar para Pagamento</button>
          </div>
        )}
      </div>
    );
  }
  ```

  ```python Flask theme={null}
  from flask import Flask, request, jsonify
  import requests

  app = Flask(__name__)

  @app.route('/create-onramp', methods=['POST'])
  def create_onramp():
      data = request.json
      
      # Obter cotação
      quote_response = requests.post(
          'https://sandbox.killb.app/api/v2/quotations',
          headers={
              'Authorization': f'Bearer {access_token}',
              'Content-Type': 'application/json'
          },
          json={
              'fromCurrency': 'COP',
              'toCurrency': 'USDC',
              'amount': data['amount'],
              'amountIsToCurrency': False,
              'cashInMethod': 'PSE',
              'cashOutMethod': 'POLYGON'
          }
      )
      quote = quote_response.json()
      
      # Criar ramp
      ramp_response = requests.post(
          'https://sandbox.killb.app/api/v2/ramps',
          headers={
              'Authorization': f'Bearer {access_token}',
              'Content-Type': 'application/json'
          },
          json={
              'quotationId': quote['id'],
              'userId': data['userId'],
              'accountId': data['accountId']
          }
      )
      ramp = ramp_response.json()
      
      return jsonify({
          'rampId': ramp['id'],
          'paymentUrl': ramp['paymentInfo'][0]['url'],
          'status': ramp['status']
      })

  if __name__ == '__main__':
      app.run(debug=True)
  ```
</CodeGroup>

## Demo Off-Ramp

Converta criptomoeda de volta para moeda fiat local.

### Recursos

* Verificação de saldo da carteira
* Cálculo de cotação
* Validação de conta bancária
* Monitoramento de transação
* Geração de recibo

### Exemplo de Código

<CodeGroup>
  ```javascript Next.js theme={null}
  export default function OffRampPage() {
    const createOffRamp = async (formData) => {
      // Passo 1: Obter cotação
      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();

      // Passo 2: Criar 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();

      // Passo 3: Mostrar instruções de pagamento
      return ramp;
    };

    return (
      <form onSubmit={(e) => {
        e.preventDefault();
        createOffRamp(formData);
      }}>
        {/* Campos do formulário */}
      </form>
    );
  }
  ```

  ```python Django theme={null}
  from django.http import JsonResponse
  from django.views.decorators.http import require_http_methods
  import requests

  @require_http_methods(["POST"])
  def create_offramp(request):
      data = json.loads(request.body)
      base_url = 'https://sandbox.killb.app'
      token = request.headers.get('Authorization')
      
      # Criar cotação
      quote_response = requests.post(
          f'{base_url}/api/v2/quotations',
          headers={'Authorization': token},
          json={
              'fromCurrency': 'USDC',
              'toCurrency': 'COP',
              'amount': data['amount'],
              'amountIsToCurrency': False,
              'cashInMethod': 'POLYGON',
              'cashOutMethod': 'PSE'
          }
      )
      quote = quote_response.json()
      
      # Criar ramp
      ramp_response = requests.post(
          f'{base_url}/api/v2/ramps',
          headers={'Authorization': token},
          json={
              'quotationId': quote['id'],
              'userId': data['userId'],
              'accountId': data['bankAccountId']
          }
      )
      ramp = ramp_response.json()
      
      return JsonResponse(ramp)
  ```
</CodeGroup>

## Demo Poupança

Implemente uma interface de conta poupança custodial.

### Exemplo de Código

```javascript theme={null}
// Criar conta poupança
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();
};

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

// Obter instruções 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 Ouvinte de Webhook

Lide com eventos de webhook em tempo real da KillB.

### Exemplo de Código

<CodeGroup>
  ```javascript Express.js theme={null}
  const express = require('express');
  const crypto = require('crypto');

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

  app.post('/webhooks/killb', (req, res) => {
    // Verificar assinatura do 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: 'Assinatura inválida' });
    }
    
    // Processar 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);
  ```

  ```python FastAPI theme={null}
  from fastapi import FastAPI, Header, HTTPException, Request
  import hmac
  import hashlib

  app = FastAPI()

  @app.post("/webhooks/killb")
  async def webhook_handler(
      request: Request,
      x_webhook_signature: str = Header(None)
  ):
      # Obter corpo bruto
      body = await request.body()
      
      # Verificar assinatura
      expected_signature = hmac.new(
          WEBHOOK_SECRET.encode(),
          body,
          hashlib.sha256
      ).hexdigest()
      
      if x_webhook_signature != expected_signature:
          raise HTTPException(status_code=401, detail="Assinatura inválida")
      
      # Processar evento
      data = await request.json()
      event = data.get('event')
      
      if event == 'ramp.completed':
          handle_ramp_completed(data['data'])
      elif event == 'ramp.failed':
          handle_ramp_failed(data['data'])
      elif event == 'user.kyc_updated':
          handle_kyc_update(data['data'])
      
      return {"received": True}
  ```
</CodeGroup>

<Card title="Saiba Mais" icon="webhook" href="/pt/guides/webhooks/security">
  Leia o guia completo de segurança de webhook
</Card>

## Trechos de Código

### Gerenciamento de Usuários

<CodeGroup>
  ```javascript Criar Usuário theme={null}
  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();
  };
  ```

  ```python Criar Usuário theme={null}
  def create_user(user_data, access_token):
      response = requests.post(
          'https://sandbox.killb.app/api/v2/users',
          headers={
              'Authorization': f'Bearer {access_token}',
              'Content-Type': 'application/json'
          },
          json={
              'type': 'PERSON',
              'externalId': user_data['external_id'],
              'data': {
                  'firstName': user_data['first_name'],
                  'lastName': user_data['last_name'],
                  'email': user_data['email'],
                  'phone': user_data['phone'],
                  'dateOfBirth': user_data['date_of_birth'],
                  'address': user_data['address'],
                  'document': user_data['document']
              }
          }
      )
      return response.json()
  ```
</CodeGroup>

### Criação de Conta

<CodeGroup>
  ```javascript Criar Conta de Carteira theme={null}
  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: 'João',
          lastName: 'Silva',
          email: 'joao@example.com',
          phone: '+5511987654321',
          currency: 'USDC',
          network: 'POLYGON',
          address: walletAddress,
          countryCode: 'BR',
          document: {
            type: 'PASSPORT',
            number: 'AB123456',
            issuedCountryCode: 'BR'
          }
        }
      })
    });
    
    return await response.json();
  };
  ```

  ```python Criar Conta Bancária theme={null}
  def create_bank_account(user_id, bank_details, access_token):
      response = requests.post(
          'https://sandbox.killb.app/api/v2/accounts',
          headers={
              'Authorization': f'Bearer {access_token}',
              'Content-Type': 'application/json'
          },
          json={
              'type': 'PSE',
              'userId': user_id,
              'externalId': f'bank-{user_id}',
              'data': {
                  'firstName': bank_details['first_name'],
                  'lastName': bank_details['last_name'],
                  'email': bank_details['email'],
                  'phone': bank_details['phone'],
                  'accountNumber': bank_details['account_number'],
                  'bankCode': bank_details['bank_code'],
                  'type': 'savings',
                  'countryCode': 'CO',
                  'document': bank_details['document']
              }
          }
      )
      return response.json()
  ```
</CodeGroup>

### Criação de Ramp

<CodeGroup>
  ```javascript Fluxo Completo de Ramp theme={null}
  const executeRamp = async (userId, accountId, amount, direction) => {
    try {
      // 1. Criar cotação
      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('Cotação:', quote);

      // 2. Criar 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('Falha na criação do ramp:', error);
      throw error;
    }
  };
  ```

  ```python Fluxo Completo de Ramp theme={null}
  def execute_ramp(user_id, account_id, amount, direction, access_token):
      base_url = 'https://sandbox.killb.app'
      headers = {
          'Authorization': f'Bearer {access_token}',
          'Content-Type': 'application/json'
      }
      
      # 1. Criar cotação
      quote_payload = {
          'fromCurrency': 'COP' if direction == 'ON' else 'USDC',
          'toCurrency': 'USDC' if direction == 'ON' else 'COP',
          'amount': amount,
          'amountIsToCurrency': False,
          'cashInMethod': 'PSE' if direction == 'ON' else 'POLYGON',
          'cashOutMethod': 'POLYGON' if direction == 'ON' else 'PSE'
      }
      
      quote_response = requests.post(
          f'{base_url}/api/v2/quotations',
          headers=headers,
          json=quote_payload
      )
      quote = quote_response.json()
      print(f'Cotação criada: {quote}')
      
      # 2. Criar ramp
      ramp_payload = {
          'quotationId': quote['id'],
          'userId': user_id,
          'accountId': account_id
      }
      
      ramp_response = requests.post(
          f'{base_url}/api/v2/ramps',
          headers=headers,
          json=ramp_payload
      )
      ramp = ramp_response.json()
      print(f'Ramp criado: {ramp}')
      
      return ramp
  ```
</CodeGroup>

## Testando no Sandbox

Use estas funções auxiliares para testar sua integração:

### Simular Cash-In

```bash theme={null}
curl --request POST \
  --url https://sandbox.killb.app/api/v2/faker/cash-in \
  --header 'Authorization: Bearer SEU_TOKEN_DE_ACESSO' \
  --header 'Content-Type: application/json' \
  --data '{
    "rampId": "ramp-id-aqui"
  }'
```

### Simular Conclusão de Cash-Out

```bash theme={null}
curl --request POST \
  --url https://sandbox.killb.app/api/v2/faker/cash-out \
  --header 'Authorization: Bearer SEU_TOKEN_DE_ACESSO' \
  --header 'Content-Type: application/json' \
  --data '{
    "rampId": "ramp-id-aqui"
  }'
```

<Warning>
  Endpoints Faker só funcionam no **ambiente sandbox** e são usados para fins de teste.
</Warning>

## Lista de Verificação de Integração

<Steps>
  <Step title="Configurar Autenticação">
    Implementar lógica de login e atualização de token
  </Step>

  <Step title="Criar Gerenciamento de Usuários">
    Construir fluxos de criação de usuário e submissão de KYC
  </Step>

  <Step title="Implementar Criação de Conta">
    Adicionar gerenciamento de conta bancária e carteira
  </Step>

  <Step title="Construir UI de Cotação">
    Mostrar preços em tempo real para usuários
  </Step>

  <Step title="Lidar com Fluxo de Ramp">
    Criar e monitorar transações ramp
  </Step>

  <Step title="Configurar Webhooks">
    Receber atualizações de status em tempo real
  </Step>

  <Step title="Adicionar Tratamento de Erros">
    Implementar tratamento de erros adequado e lógica de retry
  </Step>

  <Step title="Testar Completamente">
    Usar ambiente sandbox para testes de ponta a ponta
  </Step>
</Steps>

## Recursos Adicionais

<CardGroup cols={2}>
  <Card title="Referência da API" icon="book" href="/api-reference/introduction">
    Documentação completa da API
  </Card>

  <Card title="Guia de Webhooks" icon="bell" href="/pt/guides/webhooks/overview">
    Configure notificações em tempo real
  </Card>

  <Card title="Tratamento de Erros" icon="triangle-exclamation" href="/pt/resources/error-handling">
    Melhores práticas para gerenciamento de erros
  </Card>

  <Card title="Melhores Práticas" icon="star" href="/pt/resources/best-practices">
    Dicas para integração pronta para produção
  </Card>
</CardGroup>

<Info>
  Tem um app demo para compartilhar? Entre em contato conosco em [developers@killb.com](mailto:developers@killb.com) para ter destaque!
</Info>
