-
Couldn't load subscription status.
- Fork 0
Description
Pasting CodeRabbit's review of the widget from another repo.
🐛 Code Quality Issues in Payment Widget Component
Component Source: Request Network Registry (https://ui.request.network)
Installation Method: ShadCN registry via npx shadcn add payment-widget
Discovered in: RequestNetwork/easy-invoice#168
Summary
During integration of the payment widget into our dashboard, automated code review identified 11 issues ranging from critical API bugs to minor documentation inconsistencies. Since this is an external component, we're reporting these upstream for fixes in the registry.
🔴 Critical Issues
1. Missing onComplete Callback Prop
File: src/components/payment-widget/payment-widget.tsx (Line 96)
Severity: Critical
The onComplete prop is defined in PaymentWidgetProps but never destructured or forwarded to the provider, breaking the public API.
Fix:
export function PaymentWidget({
amountInUsd,
recipientWallet,
paymentConfig,
receiptInfo,
onPaymentSuccess,
onPaymentError,
+ onComplete,
uiConfig,
walletAccount,
children,
}: PaymentWidgetProps) {
return (
<Web3Provider walletConnectProjectId={paymentConfig.walletConnectProjectId}>
<PaymentWidgetProvider
amountInUsd={amountInUsd}
recipientWallet={recipientWallet}
walletAccount={walletAccount}
paymentConfig={paymentConfig}
uiConfig={uiConfig}
receiptInfo={receiptInfo}
onPaymentSuccess={onPaymentSuccess}
onPaymentError={onPaymentError}
+ onComplete={onComplete}
>
<PaymentWidgetInner>{children}</PaymentWidgetInner>
</PaymentWidgetProvider>
</Web3Provider>
);
}2. Receipt Number Property Mismatch
File: src/components/payment-widget/components/payment-success.tsx (Line 60)
Severity: Critical
Form registers receiptInfo.invoiceNumber, but code reads receiptInfo.receiptNumber, causing user input to be ignored.
Fix:
- receiptNumber: receiptInfo?.receiptNumber
- ? receiptInfo.receiptNumber
+ receiptNumber: receiptInfo?.invoiceNumber
+ ? receiptInfo.invoiceNumber
: generateReceiptNumber(),Also update ReceiptInfo interface to include invoiceNumber or rename the form field to receiptNumber consistently.
3. Invalid ShadCN Installation Command
File: src/components/payment-widget/README.md (Line 31)
Severity: Critical
Documentation shows npx shadcn add payment-widget, which is not a standard shadcn command. Since this is a custom registry component, the installation instructions should be updated.
Suggested fix: Document the proper registry-based installation or direct import method.
🟠 Major Issues
4. Missing Fetch Timeout
File: src/components/payment-widget/utils/payment.ts (Line 150)
Severity: Major
The fetch call to create payouts has no timeout, which could cause the UI to hang indefinitely if the API is unresponsive.
Fix:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
try {
const response = await fetch(`${RN_API_URL}/v2/payouts`, {
signal: controller.signal,
method: "POST",
headers: {
"x-client-id": rnApiClientId,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: amountInUsd,
payerWallet: payerWallet,
payee: recipientWallet,
invoiceCurrency: "USD",
paymentCurrency: paymentCurrency,
feePercentage: feeInfo?.feePercentage || undefined,
feeAddress: feeInfo?.feeAddress || undefined,
customerInfo: params.customerInfo,
reference,
}),
});
return response;
} catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
throw new Error('Request timeout: API took too long to respond');
}
throw error;
} finally {
clearTimeout(timeoutId);
}5. Empty Transaction Receipts Array Not Handled
File: src/components/payment-widget/components/payment-modal.tsx (Line 67)
Severity: Major
Code assumes transactionReceipts is non-empty when accessing the last element, which will throw if the array is empty.
Fix:
const handlePaymentSuccess = async (
requestId: string,
transactionReceipts: TransactionReceipt[],
) => {
setRequestId(requestId);
- setTxHash(
- transactionReceipts[transactionReceipts.length - 1].transactionHash,
- );
+ if (transactionReceipts.length > 0) {
+ setTxHash(
+ transactionReceipts[transactionReceipts.length - 1].transactionHash,
+ );
+ }
setActiveStep("payment-success");
await onPaymentSuccess?.(requestId, transactionReceipts);
};6. Incorrect Totals Visibility Logic
File: src/components/payment-widget/components/receipt/receipt-template.tsx (Line 156)
Severity: Major
Using .length > 0 on string totals means "0".length > 0 evaluates to true, showing zero values incorrectly.
Fix:
- {receipt.totals.totalDiscount.length > 0 && (
+ {Number.parseFloat(receipt.totals.totalDiscount) > 0 && (
<div className="total-line">
<span>Discount:</span>
<span className="total-amount">
-
{formatCryptoAmount(
receipt.totals.totalDiscount.toString(),
receipt.payment.currency,
)}
</span>
</div>
)}
- {receipt.totals.totalTax.length > 0 && (
+ {Number.parseFloat(receipt.totals.totalTax) > 0 && (
<div className="total-line">
<span>Tax:</span>
<span className="total-amount">
{formatCryptoAmount(
receipt.totals.totalTax.toString(),
receipt.payment.currency,
)}
</span>
</div>
)}🟡 Minor Issues
7. Wallet Override Flag Logic
File: src/components/payment-widget/context/payment-widget-context/payment-widget-provider.tsx (Line 46)
Severity: Minor
isWalletOverride is true if walletAccount exists, even when account.address is undefined.
Fix:
- const isWalletOverride = walletAccount !== undefined;
- const connectedWalletAddress = walletAccount
- ? walletAccount.account?.address
- : address;
+ const overriddenAddress = walletAccount?.account?.address;
+ const isWalletOverride = Boolean(overriddenAddress);
+ const connectedWalletAddress = overriddenAddress ?? address;8. Redundant Console Warning Before Throw
File: src/components/payment-widget/utils/payment.ts (Line 87)
Severity: Minor
console.warn immediately followed by throw makes the warning less useful.
Fix:
- console.warn("Unknown value format, defaulting to 0:", value);
- throw new Error("Unknown value format");
+ throw new Error(`Unknown value format: ${JSON.stringify(value)}`);9. Documentation: Hyphenation
File: src/components/payment-widget/README.md (Line 17)
Severity: Minor
"logged in Viem account" should be "logged-in Viem account" (compound adjective).
10. Documentation: Type Inconsistency in Example
File: src/components/payment-widget/README.md (Line 76)
Severity: Minor
Receipt totals example shows numbers, but the type definition requires strings.
Fix:
totals: {
- total: 100,
- totalUSD: 100.00,
- totalDiscount: 0.00,
- totalTax: 0.00,
+ total: "100.00",
+ totalUSD: "100.00",
+ totalDiscount: "0.00",
+ totalTax: "0.00",
},11. Documentation: Callback Parameter Mismatch
File: src/components/payment-widget/README.md (Line 221)
Severity: Minor
API reference documents onPaymentSuccess(requestId) with one parameter, but the basic usage example passes (requestId, transactionReceipts).
Fix: Either update the type signature to include the second parameter or correct the usage example.
Environment
- Integration repository: RequestNetwork/easy-invoice
- Component version: Latest from https://ui.request.network registry
- Discovery method: Automated code review via CodeRabbit
Impact
These issues affect API completeness, runtime stability, and documentation accuracy. Fixing them would improve the developer experience and prevent potential runtime errors in production applications using this component.
Would you like me to create this as an actual GitHub issue in a specific repository?
Originally posted by @coderabbitai[bot] in RequestNetwork/easy-invoice#168 (comment)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status