Skip to Content
Crypto OperationsOfframp (Sell Crypto)

Offramp - Sell Cryptocurrency

Convert cryptocurrency to fiat currency in your virtual account.

What is OFFRAMP?

OFFRAMP allows you to sell cryptocurrency and receive fiat funds in your virtual account.

Use cases:

  • Convert crypto holdings to fiat
  • Realize crypto gains
  • Prepare fiat for operations
  • Accept crypto payments and convert to fiat

Deals vs Orders

Important: OFFRAMP operations use the /deals endpoint, not /orders. A deal represents the intent to sell crypto and must be paid completely (no partial payments). The deal creates orders that execute the sale.

Key differences from ONRAMP:

  • Deal: The crypto sale intent (must be funded completely)
  • Order: The actual execution of the sale (created automatically by the deal)
  • No partial payments: OFFRAMP deals must be paid in full, unlike ONRAMP
  • Destination: Deals only need the destination virtual account

Quick Example

// Sell 10 USDC for COP // 1. Get quote (network required!) const quote = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`, { type: 'OFFRAMP', originCurrencySymbol: 'USDC', destinationCurrencySymbol: 'COP', amountIn: 10, // 10 USDC network: 'ETHEREUM' // Required for crypto quotes }, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('Will receive:', quote.data.amountOut, 'COP'); // e.g., 39,500 COP console.log('Quote valid for:', quote.data.validFor || '10-15', 'seconds'); // 2. Create deal (not order!) const deal = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/deals`, { destinationAccountId: 'va_cop_12345', // Your COP virtual account quoteId: quote.data.id }, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('Deal created:', deal.data.id); console.log('Deal must be paid completely'); // Funds will be credited to COP virtual account after confirmation

Complete Payment Required: Unlike ONRAMP, OFFRAMP deals must be funded completely. Partial payments are not supported.


Step-by-Step Integration

Step 1: Get Quote

const quote = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`, { type: 'OFFRAMP', originCurrencySymbol: 'USDC', destinationCurrencySymbol: 'COP', amountIn: 10, network: 'ETHEREUM' // Required for crypto quotes }, { headers: { 'Authorization': `Bearer ${token}` } } ); // Display to user console.log('Selling:', quote.data.amountIn, 'USDC'); console.log('Will receive:', quote.data.amountOut, 'COP'); console.log('Exchange rate:', quote.data.exchangeRate); console.log('Fee:', quote.data.koyweFee, 'COP'); console.log('Quote expires in:', quote.data.validFor || '10-15', 'seconds');

Step 2: Create Deal

const deal = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/deals`, { type: 'OFFRAMP', destinationAccountId: 'va_cop_12345', // Only need destination virtual account quoteId: quote.data.id, externalId: `offramp-${Date.now()}` }, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('Deal created:', deal.data.id); console.log('Status:', deal.data.status); // "PENDING" console.log('Deposit address:', deal.data.depositAddress); // Where to send crypto

Simplified Request: Deals only need the destinationAccountId (virtual account) and quoteId. The crypto amount and currencies are already defined in the quote.

Step 3: Send Cryptocurrency

After creating the deal, send the cryptocurrency to the provided deposit address:

const dealDetails = await axios.get( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/deals/${deal.data.id}`, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('Send crypto to:', dealDetails.data.depositAddress); console.log('Amount to send:', dealDetails.data.amountIn, dealDetails.data.originCurrencySymbol); console.log('Network:', dealDetails.data.network); console.log('Must send complete amount - partial payments not allowed');

Step 4: Wait for Confirmation

app.post('/webhooks/koywe', (req, res) => { const event = JSON.parse(req.body); if (event.type === 'order.paid' && event.data.type === 'OFFRAMP') { console.log('Crypto received and confirmed!'); } if (event.type === 'order.completed' && event.data.type === 'OFFRAMP') { console.log('Fiat credited to virtual account!'); console.log('Amount:', event.data.amountOut, event.data.destinationCurrencySymbol); } res.status(200).send('OK'); });

Order Flow


Complete Example

async function sellUSDC(amount) { try { const token = await authenticate(); // 1. Get quote const quote = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`, { type: 'OFFRAMP', originCurrencySymbol: 'USDC', destinationCurrencySymbol: 'COP', amountIn: amount }, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log(`Selling ${amount} USDC for ${quote.data.amountOut} COP`); console.log(`Rate: 1 USDC = ${quote.data.exchangeRate} COP`); // 2. Create offramp order const order = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/orders`, { type: 'OFFRAMP', originCurrencySymbol: 'USDC', destinationCurrencySymbol: 'COP', amountIn: amount, quoteId: quote.data.id }, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('✓ Offramp order created:', order.data.id); console.log('📍 Send USDC to:', order.data.depositAddress); console.log('💰 Amount:', order.data.amountIn, 'USDC'); console.log('🌐 Network:', order.data.network || 'Ethereum'); return { orderId: order.data.id, depositAddress: order.data.depositAddress, amount: order.data.amountIn, currency: order.data.originCurrencySymbol }; } catch (error) { console.error('Error:', error.response?.data || error.message); throw error; } } // Usage const offramp = await sellUSDC(10); console.log('Send your USDC to the deposit address above');

Important Notes

Blockchain Confirmations: OFFRAMP orders require blockchain confirmations. Settlement time varies by network:

  • Ethereum: 12-15 minutes (12 confirmations)
  • Polygon: 2-5 minutes (128 confirmations)
  • BSC: 3-5 minutes (15 confirmations)
  • Bitcoin: 30-60 minutes (3 confirmations)

One-time Address: Each OFFRAMP order generates a unique deposit address. Don’t reuse addresses from previous orders.


Next Steps

Last updated on