+
+
+ Confirm Split Payment
+
+
+ Review distribution rules and recipient allocations before executing payment.
+
+
+
+ {/* Rules Validation Section */}
+
+
+ Rule Validations
+
+
+ {rules.map((rule, idx) => (
+
+ {rule.description}
+
+ {rule.passed ? 'Passed' : 'Failed'}
+
+
+ ))}
+
+
+
+ {/* Recipient Distribution Table */}
+
+
+
+
+ | Recipient |
+ Share |
+ Net Amount |
+ {result && Status | }
+
+
+
+ {derivedLines.map((line, idx) => {
+ const res = result?.recipientResults.find((r) => r.address === line.address);
+ return (
+
+ |
+ {line.address}
+ |
+ {line.sharePercent}% |
+
+ {line.netAmount.toFixed(7)} {request.assetCode}
+ |
+ {result && (
+
+
+ {res?.status ?? 'Pending'}
+
+ |
+ )}
+
+ );
+ })}
+
+
+
+
+ {/* Totals Summary */}
+
+
+ Gross Total
+
+ {totalGross.toFixed(7)} {request.assetCode}
+
+
+
+ Tax Withheld
+
+ {totalTax.toFixed(7)} {request.assetCode}
+
+
+
+ Fees
+
+ {totalFees.toFixed(7)} {request.assetCode}
+
+
+
+ Net Distributed
+
+ {totalNet.toFixed(7)} {request.assetCode}
+
+
+
+
+ {/* Status / Results Notification */}
+ {status === 'completed' && (
+
+ All {result?.successCount} recipient payments distributed successfully!
+
+ )}
+
+ {status === 'partial_failure' && (
+
+ {result?.error}
+
+ )}
+
+ {status === 'failed' && (
+
+ {result?.error || 'Split payment failed to execute.'}
+
+ )}
+
+ {/* Action Buttons */}
+
+ {status === 'completed' || status === 'partial_failure' || status === 'failed' ? (
+
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+ );
+};
diff --git a/src/hooks/useSplitPayment.ts b/src/hooks/useSplitPayment.ts
new file mode 100644
index 00000000..eac729b4
--- /dev/null
+++ b/src/hooks/useSplitPayment.ts
@@ -0,0 +1,200 @@
+'use client';
+
+import { useState, useCallback } from 'react';
+import {
+ buildSplitConfirmation,
+ executeSplitPayment,
+ generateSplitPaymentId,
+} from '@/lib/splitPayment';
+import type {
+ SplitPaymentState,
+ SplitPaymentRequest,
+ SplitPaymentConfirmation,
+ SplitPaymentResult,
+ PaymentExecutor,
+ SplitRuleConfig,
+ RecipientPaymentResult,
+} from '@/types/splitPayment';
+import type { RecipientLine } from '@/hooks/useSplitCalculator';
+
+const INITIAL_STATE: SplitPaymentState = {
+ status: 'pending',
+ confirmation: null,
+ result: null,
+ isExecuting: false,
+ error: null,
+};
+
+export interface UseSplitPaymentOptions {
+ /** Payment executor function — abstracted for testability */
+ executor: PaymentExecutor;
+ /** Rule configuration overrides */
+ ruleConfig?: Partial