import { getAlbyService } from './alby' import { calculateArticleSplit, calculateReviewSplit } from './platformCommissions' import type { AlbyInvoice } from '@/types/alby' /** * Payment split service * Handles automatic commission splitting for platform payments * * Since WebLN doesn't support BOLT12, we use a two-step approach: * 1. Platform creates invoice for full amount * 2. Platform automatically forwards author/reviewer portion after payment * * This ensures commissions are always collected and tracked. */ export class PaymentSplitService { /** * Create invoice with commission split for article payment * Returns invoice for full amount (800 sats) that will be split after payment */ async createArticleInvoiceWithSplit( _authorLightningAddress: string, articleTitle: string ): Promise<{ invoice: AlbyInvoice split: { author: number; platform: number; total: number } }> { const split = calculateArticleSplit() const alby = getAlbyService() await alby.enable() const invoice = await alby.createInvoice({ amount: split.total, description: `Article payment: ${articleTitle} (${split.author} sats to author, ${split.platform} sats commission)`, expiry: 86400, // 24 hours }) return { invoice, split, } } /** * Create invoice with commission split for review reward * Returns invoice for full amount (70 sats) that will be split after payment */ async createReviewRewardInvoiceWithSplit( _reviewerLightningAddress: string, reviewId: string ): Promise<{ invoice: AlbyInvoice split: { reviewer: number; platform: number; total: number } }> { const split = calculateReviewSplit() const alby = getAlbyService() await alby.enable() const invoice = await alby.createInvoice({ amount: split.total, description: `Review reward: ${reviewId} (${split.reviewer} sats to reviewer, ${split.platform} sats commission)`, expiry: 3600, // 1 hour }) return { invoice, split, } } /** * Verify that payment amount matches expected split */ verifyPaymentSplit( type: 'article' | 'review', paidAmount: number, expectedSplit: { author?: number; reviewer?: number; platform: number; total: number } ): boolean { if (paidAmount !== expectedSplit.total) { return false } // Verify split amounts match expected commission structure if (type === 'article') { const articleSplit = calculateArticleSplit() return ( expectedSplit.author === articleSplit.author && expectedSplit.platform === articleSplit.platform ) } if (type === 'review') { const reviewSplit = calculateReviewSplit() return ( expectedSplit.reviewer === reviewSplit.reviewer && expectedSplit.platform === reviewSplit.platform ) } return false } } export const paymentSplitService = new PaymentSplitService()