- Correction toutes erreurs TypeScript : - Variables non utilisées supprimées - Types optionnels corrigés (exactOptionalPropertyTypes) - Imports corrigés (PLATFORM_BITCOIN_ADDRESS depuis platformConfig) - Gestion correcte des propriétés optionnelles - Suppression fichiers obsolètes : - code-cleanup-summary.md (redondant) - todo-implementation*.md (todos obsolètes) - corrections-completed.md, fallbacks-found.md (corrections faites) - implementation-summary.md (redondant) - documentation-plan.md (plan, pas documentation) - Suppression scripts temporaires : - add-ssh-key.sh - add-ssh-key-plink.sh - Réorganisation documentation dans docs/ : - architecture.md (nouveau) - commissions.md (nouveau) - implementation-summary.md - remaining-tasks.md - split-and-transfer.md - commission-system.md - commission-implementation.md - content-delivery-verification.md Toutes erreurs TypeScript corrigées, documentation centralisée.
104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
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()
|