Skip to main content

Basic Transaction Operations

List All Transactions

import { Moflay } from "@moflay/sdk";

const moflay = new Moflay({
  token: process.env.MOFLAY_API_KEY,
});

async function listAllTransactions() {
  try {
    const transactions = await moflay.transactions.list({});
    
    for await (const page of transactions) {
      console.log("Transactions page:", page);
    }
  } catch (error) {
    console.error("Failed to list transactions:", error);
    throw error;
  }
}

Get a Specific Transaction

async function getTransaction(transactionId: string) {
  try {
    const transaction = await moflay.transactions.getOne({
      id: transactionId,
    });

    console.log("Transaction details:", transaction);
    return transaction;
  } catch (error) {
    console.error("Failed to get transaction:", error);
    throw error;
  }
}

Filter Transactions by Date Range

async function getTransactionsByDateRange(startDate: Date, endDate: Date) {
  try {
    const transactions = await moflay.transactions.list({
      start: startDate,
      end: endDate,
    });
    
    for await (const page of transactions) {
      console.log("Transactions in date range:", page);
    }
  } catch (error) {
    console.error("Failed to filter transactions by date:", error);
    throw error;
  }
}

// Get transactions from the last 7 days
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const now = new Date();
getTransactionsByDateRange(sevenDaysAgo, now);

Search Transactions

async function searchTransactions(query: string) {
  try {
    const transactions = await moflay.transactions.list({
      q: query,
    });
    
    for await (const page of transactions) {
      console.log("Search results:", page);
    }
  } catch (error) {
    console.error("Failed to search transactions:", error);
    throw error;
  }
}

// Search by customer name
searchTransactions("John Doe");

// Search by transaction ID
searchTransactions("TXN-123456");

Filter by Transaction Status

async function getTransactionsByStatus(status: string) {
  try {
    const transactions = await moflay.transactions.list({
      q: `status:${status}`,
    });
    
    for await (const page of transactions) {
      console.log(`Transactions with status ${status}:`, page);
    }
  } catch (error) {
    console.error("Failed to filter transactions by status:", error);
    throw error;
  }
}

// Get completed transactions
getTransactionsByStatus("completed");

// Get failed transactions
getTransactionsByStatus("failed");

Transaction Analytics and Reporting

Transaction Summary

async function getTransactionSummary() {
  try {
    const allTransactions = await moflay.transactions.list({});
    let totalAmount = 0;
    let completedCount = 0;
    let failedCount = 0;
    let pendingCount = 0;
    const transactionsByDay: Record<string, number> = {};

    for await (const page of allTransactions) {
      page.data.forEach(transaction => {
        totalAmount += transaction.amount || 0;
        
        const status = transaction.status?.toLowerCase();
        if (status === "completed") {
          completedCount++;
        } else if (status === "failed") {
          failedCount++;
        } else {
          pendingCount++;
        }

        const createdAt = new Date(transaction.createdAt);
        const dayKey = createdAt.toISOString().split('T')[0];
        transactionsByDay[dayKey] = (transactionsByDay[dayKey] || 0) + 1;
      });
    }

    console.log("Transaction Summary:");
    console.log(`Total amount: ${totalAmount}`);
    console.log(`Completed: ${completedCount}`);
    console.log(`Failed: ${failedCount}`);
    console.log(`Pending: ${pendingCount}`);
    console.log("Transactions by day:", transactionsByDay);

    return {
      totalAmount,
      completedCount,
      failedCount,
      pendingCount,
      transactionsByDay,
    };
  } catch (error) {
    console.error("Failed to get transaction summary:", error);
    throw error;
  }
}

Daily Transaction Report

async function getDailyTransactionReport(date: Date) {
  try {
    const startOfDay = new Date(date);
    startOfDay.setHours(0, 0, 0, 0);
    
    const endOfDay = new Date(date);
    endOfDay.setHours(23, 59, 59, 999);

    const transactions = await moflay.transactions.list({
      start: startOfDay,
      end: endOfDay,
    });

    let totalAmount = 0;
    let completedAmount = 0;
    let failedAmount = 0;
    const transactionsList = [];

    for await (const page of transactions) {
      page.data.forEach(transaction => {
        transactionsList.push(transaction);
        totalAmount += transaction.amount || 0;
        
        if (transaction.status?.toLowerCase() === "completed") {
          completedAmount += transaction.amount || 0;
        } else if (transaction.status?.toLowerCase() === "failed") {
          failedAmount += transaction.amount || 0;
        }
      });
    }

    console.log(`Daily Report for ${date.toDateString()}:`);
    console.log(`Total transactions: ${transactionsList.length}`);
    console.log(`Total amount: ${totalAmount}`);
    console.log(`Completed amount: ${completedAmount}`);
    console.log(`Failed amount: ${failedAmount}`);

    return {
      date: date.toDateString(),
      totalTransactions: transactionsList.length,
      totalAmount,
      completedAmount,
      failedAmount,
      transactions: transactionsList,
    };
  } catch (error) {
    console.error("Failed to get daily transaction report:", error);
    throw error;
  }
}

Monthly Revenue Analysis

async function getMonthlyRevenueAnalysis(year: number, month: number) {
  try {
    const startDate = new Date(year, month - 1, 1);
    const endDate = new Date(year, month, 0, 23, 59, 59, 999);

    const transactions = await moflay.transactions.list({
      start: startDate,
      end: endDate,
    });

    let totalRevenue = 0;
    let completedRevenue = 0;
    const dailyRevenue: Record<number, number> = {};
    const customerRevenue: Record<string, number> = {};

    for await (const page of transactions) {
      page.data.forEach(transaction => {
        const amount = transaction.amount || 0;
        totalRevenue += amount;

        if (transaction.status?.toLowerCase() === "completed") {
          completedRevenue += amount;
        }

        const day = new Date(transaction.createdAt).getDate();
        dailyRevenue[day] = (dailyRevenue[day] || 0) + amount;

        const customerId = transaction.customerId || "unknown";
        customerRevenue[customerId] = (customerRevenue[customerId] || 0) + amount;
      });
    }

    console.log(`Monthly Revenue Analysis for ${year}-${month.toString().padStart(2, '0')}:`);
    console.log(`Total revenue: ${totalRevenue}`);
    console.log(`Completed revenue: ${completedRevenue}`);
    console.log("Daily revenue:", dailyRevenue);

    return {
      year,
      month,
      totalRevenue,
      completedRevenue,
      dailyRevenue,
      customerRevenue,
    };
  } catch (error) {
    console.error("Failed to get monthly revenue analysis:", error);
    throw error;
  }
}

Transaction Monitoring and Alerts

Monitor Failed Transactions

async function monitorFailedTransactions() {
  try {
    const failedTransactions = await moflay.transactions.list({
      q: "status:failed",
    });

    const recentFailures = [];
    const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);

    for await (const page of failedTransactions) {
      page.data.forEach(transaction => {
        const createdAt = new Date(transaction.createdAt);
        if (createdAt > oneHourAgo) {
          recentFailures.push(transaction);
        }
      });
    }

    if (recentFailures.length > 0) {
      console.log(`Alert: ${recentFailures.length} transactions failed in the last hour`);
      recentFailures.forEach(transaction => {
        console.log(`- Transaction ${transaction.id}: ${transaction.amount} from ${transaction.customerName}`);
      });
    }

    return recentFailures;
  } catch (error) {
    console.error("Failed to monitor failed transactions:", error);
    throw error;
  }
}

High-Value Transaction Alert

async function alertHighValueTransactions(threshold: number) {
  try {
    const allTransactions = await moflay.transactions.list({});
    const highValueTransactions = [];

    for await (const page of allTransactions) {
      page.data.forEach(transaction => {
        if ((transaction.amount || 0) >= threshold) {
          highValueTransactions.push(transaction);
        }
      });
    }

    if (highValueTransactions.length > 0) {
      console.log(`Alert: ${highValueTransactions.length} high-value transactions found (>= ${threshold})`);
      highValueTransactions.forEach(transaction => {
        console.log(`- ${transaction.id}: ${transaction.amount} from ${transaction.customerName}`);
      });
    }

    return highValueTransactions;
  } catch (error) {
    console.error("Failed to check high-value transactions:", error);
    throw error;
  }
}

// Alert for transactions >= 100,000
alertHighValueTransactions(100000);

Transaction Reconciliation

Reconcile Transactions with External System

interface ExternalTransaction {
  id: string;
  amount: number;
  status: string;
  timestamp: Date;
}

async function reconcileTransactions(externalTransactions: ExternalTransaction[]) {
  try {
    const moflayTransactions = await moflay.transactions.list({});
    const moflayTransactionMap = new Map();

    // Create a map of Moflay transactions
    for await (const page of moflayTransactions) {
      page.data.forEach(transaction => {
        moflayTransactionMap.set(transaction.id, transaction);
      });
    }

    const reconciliation = {
      matched: [],
      missingInMoflay: [],
      missingInExternal: [],
      discrepancies: [],
    };

    // Check external transactions against Moflay
    externalTransactions.forEach(externalTxn => {
      const moflayTxn = moflayTransactionMap.get(externalTxn.id);
      
      if (!moflayTxn) {
        reconciliation.missingInMoflay.push(externalTxn);
      } else if (moflayTxn.amount !== externalTxn.amount || moflayTxn.status !== externalTxn.status) {
        reconciliation.discrepancies.push({
          id: externalTxn.id,
          external: externalTxn,
          moflay: moflayTxn,
        });
      } else {
        reconciliation.matched.push(externalTxn);
      }
    });

    // Check for Moflay transactions not in external system
    moflayTransactionMap.forEach((moflayTxn, id) => {
      const externalTxn = externalTransactions.find(t => t.id === id);
      if (!externalTxn) {
        reconciliation.missingInExternal.push(moflayTxn);
      }
    });

    console.log("Reconciliation Results:");
    console.log(`Matched: ${reconciliation.matched.length}`);
    console.log(`Missing in Moflay: ${reconciliation.missingInMoflay.length}`);
    console.log(`Missing in External: ${reconciliation.missingInExternal.length}`);
    console.log(`Discrepancies: ${reconciliation.discrepancies.length}`);

    return reconciliation;
  } catch (error) {
    console.error("Failed to reconcile transactions:", error);
    throw error;
  }
}

Error Handling for Transaction Operations

import * as errors from "@moflay/sdk/models/errors";

async function handleTransactionOperations() {
  try {
    const transactions = await moflay.transactions.list({});
    
    for await (const page of transactions) {
      console.log("Transactions:", page);
    }
  } catch (error) {
    if (error instanceof errors.NotFoundError) {
      console.error("Transaction not found");
    } else if (error instanceof errors.ValidationError) {
      console.error("Validation error:", error.data$);
    } else if (error instanceof errors.RateLimitExceededError) {
      console.error("Rate limit exceeded, please try again later");
    } else if (error instanceof errors.MoflayError) {
      console.error("Transaction operation error:", error.message);
    } else {
      console.error("Unexpected error:", error);
    }
    
    throw error;
  }
}

Integration with Express Payments

async function makePaymentAndTrackTransaction(paymentData: any) {
  try {
    // Make the payment
    const payment = await moflay.express.pay(paymentData);
    console.log("Payment initiated:", payment);

    // Wait a moment for the transaction to be processed
    await new Promise(resolve => setTimeout(resolve, 2000));

    // Get the transaction details
    const transaction = await moflay.transactions.getOne({
      id: payment.id,
    });

    console.log("Transaction details:", transaction);
    return { payment, transaction };
  } catch (error) {
    console.error("Failed to make payment and track transaction:", error);
    throw error;
  }
}