Stablecoin to Fiat transfers (Off-ramps)

Overview

Send cryptocurrency from your wallet to traditional bank accounts, mobile money services, and other fiat payment rails. This guide covers the complete process including blockchain transaction signing and submission.

Key Features:

  • Multi-network support - Ethereum, Polygon, Tron, and other blockchain networks
  • Global fiat rails - Bank transfers (ACH, SEPA, SWIFT), mobile money, local payment systems
  • Real-time conversion - Live exchange rates with transparent fee breakdown
  • Secure signing - Client-side transaction signing maintains custody control

Step-by-Step Process

1. Get Available Channels

Discover supported crypto-to-fiat combinations

curl -H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id" \
https://api.due.network/v1/channels

Look for channels where:

  • Source channels: type: "deposit" on crypto rails (ethereum, tron, polygon)
  • Destination channels: type: "withdrawal" on fiat rails (sepa, ach, bank_swift)

2. Create Recipient

Set up the bank account or mobile money destination for your payout.

curl -X POST https://api.due.network/v1/recipients \
-H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id" \
-H "Content-Type: application/json" \
-d '{
  "name": "John Smith",
  "details": {
    "schema": "bank_us",
    "bankName": "JPMorgan Chase Bank",
    "accountName": "John Smith",
    "accountNumber": "123456789",
    "routingNumber": "021000021",
    "beneficiaryAddress": {
      "street_line_1": "123 Main Street", 
      "city": "New York",
      "postal_code": "10001",
      "country": "USA",
      "state": "NY"
    }
  },
  "isExternal": true
}'

3. Generate Quote

Get real-time pricing for your crypto-to-fiat conversion.

curl -X POST https://api.due.network/v1/transfers/quote \
-H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id" \
-H "Content-Type: application/json" \
-d '{
  "source": {
    "rail": "ethereum",
    "currency": "USDC",
    "amount": "1000.00"
  },
  "destination": {
    "rail": "ach", 
    "currency": "USD",
    "amount": "0"
  }
}'

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "source": {
    "rail": "ethereum",
    "currency": "USDC", 
    "amount": "1000.00",
    "fee": "0.00"
  },
  "destination": {
    "rail": "ach",
    "currency": "USD",
    "amount": "997.50",
    "fee": "2.50"
  },
  "fxRate": 1.0,
  "fxMarkup": 0,
  "expiresAt": "2024-03-15T10:32:15Z"
}

4. Create Transfer

Initialize the crypto-to-fiat transfer using your quote and recipient.

curl -X POST https://api.due.network/v1/transfers \
-H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id" \
-H "Content-Type: application/json" \
-d '{
  "quote": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "sender": "{wallet_id}",
  "recipient": "{recipient_id}",
  "memo": "Crypto payout - Invoice #12345"
}'

Response:

{
  "id": "{transfer_id}",
  "ownerId": "{owner_id}",
  "status": "awaiting_funds",
  "source": {
    "amount": "1000.00",
    "fee": "0.00", 
    "currency": "USDC",
    "rail": "ethereum",
    "id": "{wallet_id}",
    "label": "My Ethereum Wallet",
    "details": {
      "schema": "evm",
      "address": "0x742d35Cc6665C0532925a3b8D98d0dfBb67B1BF8"
    }
  },
  "destination": {
    "amount": "997.50",
    "fee": "2.50",
    "currency": "USD", 
    "rail": "ach",
    "id": "{recipient_id}",
    "label": "John Smith",
    "details": {
      "schema": "bank_us",
      "bankName": "JPMorgan Chase Bank",
      "accountName": "John Smith",
      "accountNumber": "123456789",
      "routingNumber": "021000021"
    },
    "memo": "Crypto payout - Invoice #12345"
  },
  "fxRate": 1.0,
  "fxMarkup": 0,
  "transferInstructions": {
    "type": "TransferIntent"
  },
  "createdAt": "2024-03-15T10:30:15Z",
  "expiresAt": "2024-03-15T10:35:15Z"
}

Key Response Fields:

  • status: "awaiting_funds" - Transfer is waiting for blockchain transaction
  • transferInstructions.type: "TransferIntent" - Indicates crypto transfer requiring intent creation
  • expiresAt - Transfer expires in 5 minutes if not completed

5. Create Transfer Intent

Generate blockchain transaction data for signing.

curl -X POST https://api.due.network/v1/transfers/{transfer_id}/transfer_intent \
-H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id"

Response:

{
  "token": "intent_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "id": "{intent_id}",
  "sender": "0x742d35Cc6665C0532925a3b8D98d0dfBb67B1BF8",
  "amountIn": "1000000000",
  "to": {
    "0x1234567890123456789012345678901234567890": "1000000000"
  },
  "tokenIn": "USDC",
  "tokenOut": "USDC", 
  "networkIdIn": "ethereum",
  "networkIdOut": "ethereum",
  "gasFee": "21000000000000000",
  "signables": [
    {
      "hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
      "type": "EIP712",
      "data": {
        "types": {
          "Transfer": [
            {"name": "to", "type": "address"},
            {"name": "amount", "type": "uint256"},
            {"name": "nonce", "type": "uint256"}
          ]
        },
        "domain": {
          "name": "DueProtocol",
          "version": "1",
          "chainId": 1
        },
        "message": {
          "to": "0x1234567890123456789012345678901234567890",
          "amount": "1000000000",
          "nonce": "123"
        }
      }
    }
  ],
  "nonce": "0x7b",
  "hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
  "reference": "{transfer_id}_deposit",
  "expiresAt": "2024-03-15T10:40:15Z",
  "createdAt": "2024-03-15T10:30:45Z"
}

Key Response Fields:

  • signables - Array of transactions requiring cryptographic signatures
  • gasFee - Estimated gas cost in wei for transaction execution
  • to - Destination address mapping with amounts to transfer
  • hash - Intent hash for verification and submission

6. Sign Transaction

Use your wallet infrastructure to sign the blockchain transaction data.

Example using ethers.js:

import { ethers } from 'ethers';

// Connect to your wallet
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

// Extract signable data from transfer intent
const signable = transferIntent.signables[0];
const domain = signable.data.domain;
const types = signable.data.types;
const message = signable.data.message;

// Sign the EIP-712 message
const signature = await signer._signTypedData(domain, types, message);

console.log('Transaction signature:', signature);

7. Submit Signed Transaction

Submit the signed transaction to complete the crypto-to-fiat payout.

curl -X POST https://api.due.network/v1/transfer_intents/submit \
-H "Authorization: Bearer your_api_key" \
-H "Due-Account-Id: your_account_id" \
-H "Content-Type: application/json" \
-d '{
  "intentToken": "intent_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "signatures": [
    "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678901c"
  ]
}'

Upon successful submission, the blockchain transaction will be processed. Monitor the transfer status to track progress.