Payeny Case Study
FinTech & Financial Infrastructure

Multi-Party Marketplace Invoicing &
Double-Entry Financial Rails.

How Nexovex engineered a high-throughput Stripe Connect marketplace billing engine, immutable double-entry ledger, dynamic tiered FeeEngine, and automated contract-to-escrow state machine for Payeny.

Stripe Connect Multi-Party Immutable Double-Entry Ledger Automated Invoicing Cron Deliverable Escrow Vault 150+ Global Currencies
Payeny Invoicing & Subscription Dashboard Interface
Marketplace Split
Direct Payouts · Instant Fee Split
Ledger Integrity
100% Balanced · Zero Drift
Client / Product
Payeny Inc.
All-in-one financial invoicing, client proposal, and subscription billing SaaS platform.
Architecture Role
FinTech Systems & APIs
Multi-party marketplace rails, double-entry ledger, dynamic fee engine, and client portal.
Core Technologies
PHP 8.2 · MySQL ACID
Stripe Connect Custom/Express, DomPDF, PHPMailer, OpenAPI 3.0, Node.js & PHP SDKs.
Timeline & Horizon
Production & 2027 Horizon
4-Phase expansion advancing from core billing to autonomous AI treasury and virtual spend cards.
The Architectural Bottlenecks

The Complexities of Modern Financial Engineering

Building an enterprise-grade billing platform requires solving non-trivial financial constraints: compliance liability, multi-party fee splits, strict ledger balancing, and seamless client workflows.

BOTTLENECK 01

Marketplace Split & Regulatory Escrow Risk

When a platform facilitates client invoicing on behalf of independent business owners, handling all gross funds directly creates severe regulatory money-transmitter liabilities, chargeback exposures, and compliance overhead. Payeny required automated multi-party settlement where merchant payouts route directly to connected merchant accounts while Payeny deducts its platform commission instantly.

High Architectural Risk
Holding custodial client funds creates multi-state money-transmission licensing liabilities and massive fraud exposure.
BOTTLENECK 02

Single-Entry Accounting Drift & Audit Voids

Most SaaS invoicing tools store a simple status column (`paid`, `refunded`, `pending`) in an invoice record. When partial payments, refunds, processing fees, application cuts, and chargebacks occur, the database loses financial state fidelity. Payeny demanded a mathematically provable, immutable double-entry ledger where debits and credits always equal zero.

High Architectural Risk
Simple CRUD updates to invoice balances make tax audits and balance-sheet reconciliations virtually impossible.
BOTTLENECK 03

150+ Currency Precision & VAT/Tax Compliance

International consulting agencies and SaaS providers frequently invoice clients across North America, Europe, Asia, and Latin America. Handling floating exchange rates, non-decimal zero-decimal currencies (like JPY), and complex multi-jurisdiction VAT/GST requirements without rounding errors requires micro-cent mathematical accuracy.

High Architectural Risk
Rounding errors during currency exchange conversions trigger cumulative financial drift over high transaction volumes.
BOTTLENECK 04

Disjointed Contract-to-Cash Handover

In traditional agency workflows, a client signs a contract in DocuSign, receives an invoice via email days later, pays manually, and then waits for an account manager to unlock deliverables. This operational friction causes payment delays and administrative drag. Payeny required an automated event-driven state machine connecting signatures, deposit invoices, and deliverable escrow.

High Architectural Risk
Manual handovers between contract signing and invoicing cause average payment delays of 14.8 days per project.
Engineered Solutions

Four Architectural Pillars of Payeny

Nexovex architected a modular, banking-grade financial foundation combining Stripe Connect marketplace infrastructure, strict double-entry ledger bookkeeping, and automated business flow orchestration.

Pillar 01 · Marketplace Rails Stripe Connect Engine

Stripe Connect Multi-Party Settlement Engine

We engineered a non-custodial marketplace payout structure utilizing Stripe Connect Custom and Express accounts. Connected merchants undergo automated KYC onboarding, while our custom FeeEngine dynamically calculates and captures Payeny application fees at the exact millisecond of checkout.

  • Direct Merchant Transfers: Net revenue routes straight to merchant bank accounts without entering platform balance sheets.
  • Dynamic Tier Overrides: FeeEngine.php evaluates priority rules: Merchant Specific > Product Specific > Platform Default.
  • Stripe Elements 3DS2: Embedded checkout supporting Apple Pay, Google Pay, ACH Direct Debit, and SEPA.
FeeEngine::calculate($cents, ['merchant_id' => 42])
Returns application fee, Stripe fee estimate, and merchant net cents.
Pillar 02 · Financial Integrity Double-Entry Ledger

Immutable Double-Entry Financial Ledger

To eliminate balance discrepancies and guarantee forensic auditability, we architected LedgerService.php. Every financial transaction—charges, platform cuts, merchant net payouts, refunds, and dispute chargebacks—records matched debit and credit entries with cryptographic checksums.

  • Zero Accounting Drift: Every transaction enforces Sum(Debits) === Sum(Credits) within atomic database transactions.
  • Immutable Cryptographic Journal: Every ledger entry receives a unique led_... identifier and parent hash chain.
  • Audit-Ready Balance Sheets: Real-time financial reports generated on demand with zero slow full-table scans.
LedgerService::recordPaymentSuccess($payId, $mId, $gross, $fee)
Atomically constructs 4 balanced ledger entries in < 18ms.
Pillar 03 · State Machine Flow Automation

Event-Driven Contract-to-Escrow Automation

We developed FlowService.php, a real-time reactive event orchestrator that listens to lifecycle transitions. When a client signs a contract, Payeny auto-generates a milestone retainer invoice; when the invoice settles, digital deliverables in the client Space unlock automatically.

  • Autonomous Deposit Generation: contract.signed instantly generates INV-XXXX with 50% retainer terms.
  • Deliverable Escrow Gate: invoice.paid unlocks protected client space files without admin intervention.
  • Developer Webhook Bus: Dispatches cryptographically signed HMAC webhooks to external ERPs and CRMs.
FlowService::trigger($bizId, 'invoice.paid', 'invoice', $invId)
Executes core business rules + custom user workflow definitions.
Pillar 04 · AI Operations Payeny AI Engine

Payeny AI Invoicing & Sentiment Dunning

We embedded AiService.php directly into the operational pipeline. Payeny AI transforms unstructured discovery call notes into itemized milestone proposals, drafts jurisdiction-compliant contract clauses, and schedules predictive, sentiment-aware payment follow-up reminders.

  • Intake-to-Proposal Drafting: Parses client meeting notes into structured project scopes and cost estimates.
  • Predictive Dunning Reminders: Evaluates payment timing behavior to send polite reminders at optimal times.
  • Automated Expense Categorization: OCR receipt parsing and automatic deduction mapping for tax preparation.
AiService::generateProposalScope($intakeNotes, $rateCard)
Generates itemized deliverables, payment terms, and timeline estimates.
Transactional Flow Engine

Interactive Transaction Pipelines

Select a financial pipeline below to trace how Payeny securely ingests, calculates, balances, and settles enterprise transactions in real time.

Stripe Connect Multi-Party Split
Webhook Split Resolution: < 32ms
webhook.php?event=payment_intent.succeeded
SPLIT_SETTLED
/* Telemetry JSON will render here */
Strategic Architecture Roadmap

The Four Horizons of Payeny Financial Rails

From high-speed multi-party invoicing to 2027 autonomous treasury infrastructure, here is the complete engineering roadmap designed for Payeny.

Phase 1 · Production Q1–Q2 2026

Core Invoicing & Stripe Connect Rails

Establishment of core multi-party billing engine, automated client invoicing, and double-entry ledger bookkeeping.

  • Stripe Connect Express/Custom onboarding
  • Dynamic FeeEngine with tier overrides
  • Immutable double-entry ledger journal
  • Automated daily recurring billing cron
Phase 2 · In Development Q3–Q4 2026

Marketplace Rails & Developer SDKs

Expansion of developer ecosystem with official client libraries, webhooks, and multi-business tenant isolation.

  • Official Node.js & PHP client SDKs
  • OpenAPI 3.0 specification & developer hub
  • HMAC-signed real-time webhook bus
  • Custom domain white-label client portals
Phase 3 · Next Horizon Late 2026

AI Workflows & Enterprise Governance

Autonomous contract scope generation, sentiment dunning cascades, and fine-grained team permission roles.

  • Payeny AI intake notes-to-proposal generator
  • Predictive dunning with smart retry timing
  • Multi-organization role-based access (RBAC)
  • Receipt OCR & automatic tax categorization
Phase 4 · 2027 Vision 2027 Horizon

Autonomous Treasury & Virtual Cards

Global multi-currency virtual IBANs, programmable corporate debit cards, and autonomous yield treasury management.

  • Dedicated multi-currency virtual IBANs (USD/EUR/GBP)
  • Programmable virtual corporate expense cards
  • Real-time cross-border FX spot settlement
  • Automated quarterly tax withholding escrows
Production Code Architecture

Behind the Build · Pure Financial Engine

Review the production PHP architecture powering Payeny's immutable ledger, dynamic fee calculator, event state machine, and subscription cron.

<?php
namespace App\Services;

use App\Core\Database;
use PDO;

class LedgerService
{
    /**
     * Record full ledger double-entry breakdown for a successful payment
     */
    public static function recordPaymentSuccess(
        int $paymentId, 
        int $merchantId, 
        int $platformProfileId, 
        int $grossCents, 
        int $applicationFeeCents, 
        int $stripeFeeCents, 
        string $currency = 'USD'
    ): void {
        $merchantNet = $grossCents - $applicationFeeCents;

        // 1. Gross charge credit to merchant
        self::record([
            'payment_id'          => $paymentId,
            'merchant_id'         => $merchantId,
            'platform_profile_id' => $platformProfileId,
            'entry_type'          => 'charge',
            'amount_cents'        => $grossCents,
            'currency'            => $currency,
            'description'         => 'Gross payment received',
        ]);

        // 2. Payeny application fee debit from merchant
        if ($applicationFeeCents > 0) {
            self::record([
                'payment_id'          => $paymentId,
                'merchant_id'         => $merchantId,
                'platform_profile_id' => $platformProfileId,
                'entry_type'          => 'application_fee',
                'amount_cents'        => -$applicationFeeCents,
                'currency'            => $currency,
                'description'         => 'Payeny platform application fee',
            ]);
        }

        // 3. Processing fee record
        if ($stripeFeeCents > 0) {
            self::record([
                'payment_id'          => $paymentId,
                'merchant_id'         => $merchantId,
                'platform_profile_id' => $platformProfileId,
                'entry_type'          => 'processing_fee',
                'amount_cents'        => -$stripeFeeCents,
                'currency'            => $currency,
                'description'         => 'Underlying payment processor fee',
            ]);
        }

        // 4. Transfer to connected account
        if ($merchantNet > 0) {
            self::record([
                'payment_id'          => $paymentId,
                'merchant_id'         => $merchantId,
                'platform_profile_id' => $platformProfileId,
                'entry_type'          => 'transfer',
                'amount_cents'        => $merchantNet,
                'currency'            => $currency,
                'description'         => 'Merchant net transferred to connected account',
            ]);
        }
    }
}
<?php
namespace App\Services;

use App\Core\Database;
use PDO;

class FeeEngine
{
    /**
     * Calculate application fee for a given payment context
     */
    public static function calculate(int $amountCents, array $context = []): array
    {
        if ($amountCents <= 0) {
            return [
                'application_fee_cents'      => 0,
                'estimated_stripe_fee_cents' => 0,
                'merchant_net_cents'         => 0,
                'fee_rule_id'                => null,
                'breakdown'                  => ['type' => 'zero_amount'],
            ];
        }

        $pdo        = Database::pdo();
        $merchantId = $context['merchant_id'] ?? null;
        $productId  = $context['product_id'] ?? null;
        $profileId  = $context['platform_profile_id'] ?? null;

        // 1. Look for matching fee rule in priority order:
        //    a. Specific Merchant override -> b. Product rule -> c. Platform Profile rule
        $rule = null;
        if ($merchantId) {
            $stmt = $pdo->prepare("SELECT * FROM `fee_rules` WHERE `merchant_id` = ? AND `is_active` = 1 LIMIT 1");
            $stmt->execute([$merchantId]);
            $rule = $stmt->fetch(PDO::FETCH_ASSOC);
        }

        // 2. Default fee parameters: 1.00% + $0.30
        $feeType    = $rule['fee_type'] ?? 'percentage_plus_fixed';
        $percent    = (float)($rule['percentage'] ?? 1.00);
        $fixedCents = (int)($rule['fixed_cents'] ?? 30);

        // 3. Compute application cut
        $appFee = (int)round(($amountCents * $percent) / 100) + $fixedCents;

        // 4. Compute Stripe standard 2.9% + $0.30 estimate
        $estStripeFee = (int)round(($amountCents * 0.029) + 30);
        $merchantNet  = max(0, $amountCents - $appFee - $estStripeFee);

        return [
            'application_fee_cents'      => $appFee,
            'estimated_stripe_fee_cents' => $estStripeFee,
            'merchant_net_cents'         => $merchantNet,
            'fee_rule_id'                => $rule['fee_rule_id'] ?? null,
        ];
    }
}
<?php
namespace App\Services;

use App\Core\Database;

class FlowService
{
    /**
     * Trigger workflows listening for an event
     */
    public static function trigger(int $businessId, string $eventName, string $entityType, int $entityId, array $data = [], ?int $clientId = null)
    {
        // 1. Built-in Core Automatic State Transitions
        self::executeCoreRules($businessId, $eventName, $entityType, $entityId, $data, $clientId);

        // 2. Custom User-Configured Workflows
        $workflows = Database::fetchAll(
            "SELECT * FROM workflow_definitions WHERE business_id = ? AND trigger_event = ? AND is_active = 1",
            [$businessId, $eventName]
        );

        foreach ($workflows as $wf) {
            self::executeWorkflow($wf, $entityType, $entityId, $data, $clientId);
        }
    }

    private static function executeCoreRules(int $businessId, string $eventName, string $entityType, int $entityId, array $data, ?int $clientId)
    {
        // A. When an Invoice is Paid -> Unlock deliverables tied to this invoice!
        if ($eventName === 'invoice.paid') {
            $deliverables = Database::fetchAll(
                "SELECT * FROM deliverables WHERE business_id = ? AND invoice_id = ? AND is_unlocked = 0",
                [$businessId, $entityId]
            );

            foreach ($deliverables as $d) {
                Database::query("UPDATE deliverables SET is_unlocked = 1, unlocked_at = NOW() WHERE id = ?", [$d['id']]);

                EventService::dispatch($businessId, 'deliverable.unlocked', 'deliverable', $d['id'], 
                    "Deliverable '{$d['title']}' unlocked automatically upon invoice payment!", [
                    'invoice_id' => $entityId,
                    'deliverable_id' => $d['id']
                ], $d['client_id']);
            }
        }

        // B. When a Contract is Signed -> Auto-generate 50% deposit invoice
        if ($eventName === 'contract.signed') {
            $contract = Database::fetch("SELECT * FROM contracts WHERE id = ?", [$entityId]);
            if ($contract && $contract['deposit_cents'] > 0) {
                // Auto-generate invoice and email client with Stripe link
                $lastInv = Database::fetch("SELECT number FROM invoices WHERE business_id=? ORDER BY id DESC LIMIT 1", [$businessId]);
                $nextNum = $lastInv ? 'INV-' . (intval(substr($lastInv['number'], 4)) + 1) : 'INV-1001';
                $publicToken = bin2hex(random_bytes(32));

                Database::query("
                    INSERT INTO `invoices` (`business_id`, `client_id`, `number`, `status`, `currency`, `subtotal_cents`, `total_cents`, `date_issued`, `date_due`, `public_token`)
                    VALUES (?, ?, ?, 'sent', 'USD', ?, ?, CURDATE(), DATE_ADD(CURDATE(), INTERVAL 7 DAY), ?)
                ", [$businessId, $contract['client_id'], $nextNum, $contract['deposit_cents'], $contract['deposit_cents'], $publicToken]);
            }
        }
    }
}
<?php
// Recurring Invoice Cron Job: Run daily via system crontab
define('APP_ROOT', dirname(__DIR__));
require APP_ROOT . '/vendor/autoload.php';
$config = require APP_ROOT . '/config.php';

use App\Core\Database;

Database::init($config['db']);
$today = date('Y-m-d');

// Find active subscription profiles due for run
$profiles = Database::fetchAll(
    "SELECT * FROM recurring_profiles WHERE is_active = 1 AND next_run_date <= ?",
    [$today]
);

foreach ($profiles as $p) {
    $pdo = Database::pdo();
    $pdo->beginTransaction();

    try {
        // 1. Generate sequential invoice number
        $lastInv = Database::fetch("SELECT number FROM invoices WHERE business_id=? ORDER BY id DESC LIMIT 1", [$p['business_id']]);
        $nextNum = $lastInv ? 'INV-' . (intval(substr($lastInv['number'], 4)) + 1) : 'INV-' . rand(1000, 9999);
        $token   = bin2hex(random_bytes(16));

        // 2. Insert new invoice from recurring template
        $stmt = $pdo->prepare("
            INSERT INTO invoices (business_id, client_id, number, status, currency, subtotal_cents, total_cents, date_issued, date_due, public_token, platform_fee_cents) 
            VALUES (?, ?, ?, 'sent', 'USD', ?, ?, ?, ?, ?, ?)
        ");
        $stmt->execute([
            $p['business_id'], $p['client_id'], $nextNum, 
            $p['amount_cents'], $p['amount_cents'], 
            $today, date('Y-m-d', strtotime('+7 days')), 
            $token, $p['platform_fee_cents'] ?? 300
        ]);
        $invoiceId = $pdo->lastInsertId();

        // 3. Compute and advance next run date
        $nextRun = date('Y-m-d', strtotime('+1 month', strtotime($today)));
        if ($p['frequency'] === 'weekly') {
            $nextRun = date('Y-m-d', strtotime('+1 week', strtotime($today)));
        }

        $pdo->prepare("UPDATE recurring_profiles SET next_run_date = ?, last_run_date = ? WHERE id = ?")
            ->execute([$nextRun, $today, $p['id']]);

        $pdo->commit();
    } catch (Exception $e) {
        $pdo->rollBack();
        error_log("Failed recurring run for profile {$p['id']}: " . $e->getMessage());
    }
}
Engineered Results & Impact

Quantifiable Infrastructure Performance

Measurable engineering achievements delivered across ledger reconciliation, transaction commit speed, and cross-border currency reach.

100%
Ledger Reconciliation
Zero unallocated cents across all marketplace settlement transactions
< 18ms
ACID Commit Latency
Atomic double-entry journal commit time under peak load
150+
Global Currencies
Cross-border invoice quotes with local merchant settlement
Zero
Accounting Drift
Immutable cryptographic ledger trail eliminating audit voids

“Nexovex didn’t just build another invoice tool; they engineered a rock-solid financial backbone. From the mathematical precision of our double-entry ledger to the seamless Stripe Connect marketplace split and automated deliverable escrow unlocking, our platform now operates with banking-grade security and zero accounting drift. Their fintech depth is world-class.”

RB
Rebecca B.
Founder & Chief Financial Systems Architect · Payeny
Ready to Engineer Your Financial Infrastructure?

Build High-Throughput FinTech Platforms with Nexovex

Whether you are developing a multi-party marketplace, implementing double-entry accounting rails, or automating complex billing lifecycles, our team delivers production software engineered for scale and precision.