troubleshooting
Index

Troubleshooting & FAQ

Common issues, troubleshooting guides, and frequently asked questions for Fiatsend integration and usage.


Common Issues

Authentication Errors

401 Unauthorized

Problem: API requests are returning 401 Unauthorized errors.

Solutions:

  1. Check API Key Format

    // Correct format
    const sdk = new FiatsendSDK({
      apiKey: "fs_your_64_character_api_key_here",
      environment: "production"
    });
  2. Verify API Key Validity

    // Test API key
    try {
      const balance = await sdk.wallet.getBalance("0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6");
      console.log("API key is valid");
    } catch (error) {
      if (error.status === 401) {
        console.log("API key is invalid or expired");
      }
    }
  3. Check Environment Configuration

    // Ensure correct environment
    const sdk = new FiatsendSDK({
      apiKey: process.env.FIATSEND_API_KEY,
      environment: process.env.NODE_ENV === 'production' ? 'production' : 'staging'
    });

403 Forbidden

Problem: API requests are returning 403 Forbidden errors.

Solutions:

  1. Check API Key Permissions

    • Ensure your API key has the required permissions
    • Contact support to upgrade permissions if needed
  2. Verify Request Headers

    // Ensure proper headers
    const headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      'X-API-USER': userId,
      'X-API-KEY': apiKey,
      'X-API-PUBKEY': publicKey
    };

Payment Issues

Payment Not Processing

Problem: Payments are not being processed or are stuck in pending status.

Solutions:

  1. Check Payment Parameters

    // Ensure all required parameters are provided
    const payment = await sdk.payment.initiatePayment({
      amount: 100, // Must be a number
      currency: "USDT", // Must be valid currency
      recipient: "+233551234567", // Must be valid phone number
      country: "GH", // Must be valid country code
      description: "Payment description" // Optional but recommended
    });
  2. Verify Recipient Phone Number

    // Check if phone number exists in system
    const exists = await sdk.identity.checkNumberExists("+233551234567");
    if (!exists.exists) {
      console.log("Phone number not found in Fiatsend network");
    }
  3. Check Wallet Balance

    // Ensure sufficient balance
    const balance = await sdk.wallet.getBalance(walletAddress);
    if (balance.balances.USDT < amount) {
      console.log("Insufficient balance");
    }

Mobile Money Payment Failures

Problem: Mobile money payments are failing.

Solutions:

  1. Verify Mobile Money Provider

    // Check supported providers
    const supportedProviders = ['mtn', 'airtel', 'telecel'];
    if (!supportedProviders.includes(provider)) {
      console.log("Unsupported mobile money provider");
    }
  2. Check Phone Number Format

    // Ensure correct phone number format
    const phoneNumber = "0551234567"; // Local format for Ghana
    const fullNumber = "+233551234567"; // International format
  3. Handle Provider-Specific Errors

    try {
      const payment = await sdk.payment.createMTNPayment({
        amount: 100,
        phoneNumber: "0551234567",
        externalRef: "PAY-12345",
        wallet: walletAddress
      });
    } catch (error) {
      if (error.code === 'MTN_SERVICE_UNAVAILABLE') {
        console.log("MTN service temporarily unavailable");
      } else if (error.code === 'INVALID_PHONE_NUMBER') {
        console.log("Invalid phone number format");
      }
    }

Identity Management Issues

Identity NFT Creation Fails

Problem: Unable to create identity NFT for mobile number.

Solutions:

  1. Check Mobile Number Format

    // Ensure E.164 format
    const phoneNumber = "+233551234567"; // Correct format
    const phoneNumber = "0551234567"; // Incorrect format
  2. Verify Wallet Connection

    // Ensure wallet is connected and has sufficient gas
    const hasAccount = await sdk.core.hasAccount(walletAddress);
    if (!hasAccount) {
      console.log("Wallet not connected or insufficient gas");
    }
  3. Check for Existing Identity

    // Check if identity already exists
    const exists = await sdk.identity.checkNumberExists(phoneNumber);
    if (exists.exists) {
      console.log("Identity already exists for this phone number");
    }

Phone Number Resolution Fails

Problem: Unable to resolve phone number to wallet address.

Solutions:

  1. Verify Phone Number Exists

    // Check if phone number is registered
    const exists = await sdk.identity.checkNumberExists(phoneNumber);
    if (!exists.exists) {
      console.log("Phone number not registered in Fiatsend network");
    }
  2. Check Network Connection

    // Ensure stable network connection
    try {
      const resolution = await sdk.identity.resolvePhoneToAddress(phoneNumber);
    } catch (error) {
      if (error.code === 'NETWORK_ERROR') {
        console.log("Network connection issue");
      }
    }

SDK Integration Issues

Module Not Found Errors

Problem: Getting "Module not found" errors when importing SDK.

Solutions:

  1. Check Installation

    npm install @fiatsend/sdk
    # or
    yarn add @fiatsend/sdk
  2. Verify Import Statement

    // Correct import
    import { FiatsendSDK } from "@fiatsend/sdk";
     
    // Incorrect import
    import Fiatsend from "@fiatsend/sdk";
  3. Check Node.js Version

    node --version # Should be 16 or higher

TypeScript Errors

Problem: TypeScript compilation errors with SDK.

Solutions:

  1. Install TypeScript Types

    npm install @types/node
  2. Check TypeScript Configuration

    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "commonjs",
        "lib": ["ES2020"],
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true
      }
    }
  3. Use Proper Type Annotations

    import { FiatsendSDK, PaymentRequest } from "@fiatsend/sdk";
     
    const sdk: FiatsendSDK = new FiatsendSDK({
      apiKey: process.env.FIATSEND_API_KEY!,
      environment: "production"
    });
     
    const payment: PaymentRequest = {
      amount: 100,
      currency: "USDT",
      recipient: "+233551234567",
      country: "GH"
    };

Frequently Asked Questions

General Questions

Q: What is Fiatsend?

A: Fiatsend is a Web3 payment platform designed for Africa that enables instant cross-border payments by connecting traditional finance with blockchain technology. Your mobile number becomes your crypto identity through NFT-based resolution.

Q: Which countries does Fiatsend support?

A: Fiatsend currently supports 7+ African countries including Ghana, Kenya, Nigeria, and others. We're continuously expanding to more countries.

Q: What currencies are supported?

A: Fiatsend supports multiple currencies including:

  • Fiat: GHS (Ghana Cedi), USD (US Dollar)
  • Crypto: USDT (Tether USD), USDC (USD Coin), GHSFIAT (Ghana Fiat Token), FSEND (Fiatsend Token)

Q: How fast are transactions?

A: Fiatsend provides sub-5 second settlement times for most transactions, with real-time processing and instant mobile money delivery.

Q: What are the fees?

A: Fiatsend offers competitive fees starting from 0.1% with no hidden charges. Fees vary based on transaction type and amount.

Technical Questions

Q: How do I get started with the SDK?

A: 1. Sign up at console.fiatsend.network (opens in a new tab) 2. Generate your API key 3. Install the SDK: npm install @fiatsend/sdk 4. Initialize the SDK with your API key 5. Start making payments!

Q: What blockchain networks are supported?

A: Fiatsend supports multiple blockchain networks:

  • Lisk Sepolia (Chain ID: 324) - Testnet
  • Polygon (Chain ID: 137) - Mainnet
  • Ethereum (Chain ID: 1) - Mainnet

Q: How do I handle errors in my application?

A: The SDK provides comprehensive error handling with specific error codes and messages. Always wrap API calls in try-catch blocks and handle different error types appropriately.

Q: Can I use Fiatsend in a React application?

A: Yes! Fiatsend provides React hooks and components for easy integration. Check out our Integration Guides for examples.

Q: How do I test my integration?

A: Fiatsend provides a sandbox environment for testing. Use the staging environment and test API keys to develop and test your integration before going live.

Payment Questions

Q: How do mobile money payments work?

A: Fiatsend integrates directly with African mobile money providers (MTN, AirtelTigo, Telecel, Vodafone). When you send a payment, it's automatically converted and delivered to the recipient's mobile money wallet.

Q: What happens if a payment fails?

A: Failed payments are automatically refunded to the sender's wallet. You'll receive a webhook notification about the failure, and you can retry the payment.

Q: Can I send payments to any phone number?

A: You can send payments to any phone number, but the recipient must have a Fiatsend account and identity NFT to receive the payment.

Q: How do I check payment status?

A: Use the getTransactionStatus method to check the current status of any payment:

const status = await sdk.payment.getTransactionStatus(transactionId);
console.log(status.status); // 'pending', 'completed', 'failed'

Q: What is the maximum payment amount?

A: Payment limits vary based on your verification level and the recipient's country. Check your account limits in the dashboard.

Identity Questions

Q: What is an identity NFT?

A: An identity NFT is a soulbound token that links your mobile number to your crypto identity. It enables seamless P2P transfers and identity verification.

Q: How do I create an identity NFT?

A: Use the mintIdentity method to create an identity NFT:

const identity = await sdk.identity.mintIdentity({
  phoneNumber: "+233551234567",
  countryCode: "GH",
  metadata: "User metadata",
  walletAddress: "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6"
});

Q: Can I have multiple identities?

A: No, each mobile number can only have one identity NFT. However, you can update your identity information if needed.

Q: What is KYC verification?

A: KYC (Know Your Customer) verification is a process to verify your identity using official documents. It's required for higher transaction limits and certain features.

API Questions

Q: How do I manage my API keys?

A: You can manage your API keys through the Fiatsend dashboard:

  1. Go to your profile settings
  2. Navigate to the Security tab
  3. Click on API Keys
  4. Create, view, or delete API keys as needed

Q: What are the API rate limits?

A: API rate limits vary by endpoint type:

  • Payment Operations: 100 requests per minute
  • Wallet Operations: 200 requests per minute
  • Identity Operations: 50 requests per minute
  • General API: 1000 requests per minute

Q: How do I handle rate limiting?

A: The SDK automatically handles rate limiting with exponential backoff. You can also check rate limit headers in responses and implement your own retry logic.

Q: Can I use webhooks for real-time updates?

A: Yes! Fiatsend supports webhooks for real-time event notifications. Set up webhook endpoints to receive notifications about payment completions, failures, and other events.

Security Questions

Q: How secure is Fiatsend?

A: Fiatsend uses enterprise-level security with:

  • Multi-signature wallets
  • Encryption at rest and in transit
  • KYC/AML compliance
  • Smart contract audits
  • Regulatory oversight

Q: How do I secure my API keys?

A: Always store API keys securely:

  • Use environment variables
  • Never commit keys to version control
  • Rotate keys regularly
  • Use different keys for different environments

Q: What should I do if my API key is compromised?

A: If your API key is compromised:

  1. Immediately revoke the compromised key
  2. Generate a new API key
  3. Update your application with the new key
  4. Review your transaction history for any unauthorized activity

Getting Help

Documentation

Support Channels

Developer Resources

Status Page


Best Practices

Error Handling

try {
  const payment = await sdk.payment.initiatePayment(paymentData);
} catch (error) {
  if (error.status === 400) {
    // Handle validation errors
    console.error("Invalid request:", error.message);
  } else if (error.status === 401) {
    // Handle authentication errors
    console.error("Authentication failed:", error.message);
  } else if (error.status === 429) {
    // Handle rate limiting
    console.error("Rate limited:", error.message);
  } else {
    // Handle other errors
    console.error("Unexpected error:", error.message);
  }
}

Retry Logic

const retryWithBackoff = async (fn, maxRetries = 3) => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      if (error.status === 429) {
        await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
      } else {
        throw error;
      }
    }
  }
};

Logging

const logger = {
  info: (message, data) => console.log(`[INFO] ${message}`, data),
  error: (message, error) => console.error(`[ERROR] ${message}`, error),
  warn: (message, data) => console.warn(`[WARN] ${message}`, data)
};
 
// Usage
try {
  const payment = await sdk.payment.initiatePayment(paymentData);
  logger.info("Payment initiated", { transactionId: payment.transactionId });
} catch (error) {
  logger.error("Payment failed", error);
}

Monitoring

const monitor = {
  startTimer: (operation) => {
    const start = Date.now();
    return {
      end: () => {
        const duration = Date.now() - start;
        console.log(`${operation} took ${duration}ms`);
        return duration;
      }
    };
  }
};
 
// Usage
const timer = monitor.startTimer("Payment Initiation");
try {
  const payment = await sdk.payment.initiatePayment(paymentData);
  timer.end();
} catch (error) {
  timer.end();
  throw error;
}