Skip to content

Conversation

bassgeta
Copy link
Contributor

@bassgeta bassgeta commented Oct 2, 2025

Problem

There was no way for users to test our checkout without implementing the widget themselves

Solution

Add an option to input a custom client id before the checkout happens.

Changes

  • added a new env variable for the easy invoice URL
  • added an input for a custom client id in the payment step
  • added links to easy invoice in the new input and the existing client id input on the playground

Resolves #33

Summary by CodeRabbit

  • New Features
    • Optional “Custom client ID” and “Payment reference” fields in payment flow and Playground.
    • New onComplete callback after successful payment closure.
  • Improvements
    • More reliable receipt PDF download.
    • Streamlined completion flow and minor UI spacing tweaks.
    • EasyInvoice link and guidance added in relevant screens.
  • Documentation
    • Updated PaymentWidget docs: onSuccess → onPaymentSuccess, onError → onPaymentError; added onComplete and paymentConfig.reference.
  • Chores
    • Added EASY_INVOICE_URL environment variable and adjusted .env example.
    • Dependency updates (including PDF generation libraries).

Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Walkthrough

Broad update across the payment widget and integration: introduces a reference field through config and execution, renames event callbacks, adds an onComplete callback, restructures context into separate provider/hook, updates receipt PDF generation (html2canvas-pro + jsPDF), adds EasyInvoice guidance and optional client ID input, and adjusts env/constants.

Changes

Cohort / File(s) Summary
Environment & constants
\.env.example, src/lib/constants.ts
Quote API URL in example env; add NEXT_PUBLIC_EASY_INVOICE_URL and exported EASY_INVOICE_URL fallback to https://easyinvoice.request.network.
Dependencies
package.json
Minor bumps for react-query, react-hook-form, viem, wagmi; add html2canvas-pro and jspdf.
Demo payment step
src/components/PaymentStep.tsx
Add custom Client ID input and EasyInvoice link; pass rnApiClientId from custom or env; add paymentConfig.reference; update widget handlers to onPaymentSuccess, onPaymentError, and onComplete; adjust navigation flow.
Playground UI & schema
src/components/Playground/blocks/customize.tsx, src/components/Playground/index.tsx, src/lib/validation.ts
Add EasyInvoice guidance link; add optional paymentConfig.reference; rename handlers in preview/generated code; extend validation schema with optional reference.
Payment widget public API & docs
src/components/payment-widget/payment-widget.types.ts, src/components/payment-widget/payment-widget.tsx, src/components/payment-widget/README.md
Add PaymentConfig.reference; rename onSuccessonPaymentSuccess, onErroronPaymentError; add onComplete; update provider wiring and documentation.
Context restructure
src/components/payment-widget/context/payment-widget-context/index.ts, .../payment-widget-provider.tsx, .../use-payment-widget-context.ts
Introduce typed PaymentWidgetContextValue and PaymentWidgetContext; move consumer hook to its own file; provider now uses onPaymentSuccess, onPaymentError, onComplete and exposes paymentConfig.reference; remove old usePaymentWidgetContext export from provider file.
Widget components
src/components/payment-widget/components/currency-select.tsx, .../payment-confirmation.tsx, .../payment-modal.tsx, .../payment-success.tsx, .../receipt/styles.css
Update context import paths; propagate reference in execute payload; rename callbacks in usage; call onComplete on modal close after success; switch receipt PDF generation to html2canvas-pro + jspdf; minor style padding update.
Widget utils & constants
src/components/payment-widget/utils/payment.ts, .../utils/wagmi.ts, src/components/payment-widget/constants.ts, src/components/payment-widget/hooks/use-payment.ts
Add reference to payment params and pass through to API; tighten types (unknown for error, typed connectors); guard RN_API_URL for non-Node environments; forward reference in usePayment.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant PS as PaymentStep
  participant PW as PaymentWidget
  participant Ctx as PaymentWidgetContext
  participant Hook as usePayment/executePayment
  participant API as Request API

  U->>PS: Enter amount, optional Client ID, optional reference
  PS->>PW: Render with paymentConfig { rnApiClientId, reference, ... }<br/>and callbacks { onPaymentSuccess, onPaymentError, onComplete }
  PW->>Ctx: Provide context (config, ui, callbacks)
  U->>PW: Confirm payment
  PW->>Hook: executePayment({ ..., reference })
  Hook->>API: create payout/payment request
  alt Success
    API-->>Hook: requestId, receipts
    Hook-->>PW: success payload
    PW->>Ctx: invoke onPaymentSuccess(requestId, receipts)
    U->>PW: Close success modal
    PW->>Ctx: invoke onComplete()
  else Error
    API-->>Hook: error
    Hook-->>PW: error
    PW->>Ctx: invoke onPaymentError(error)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • rodrigopavezi
  • MantisClone
  • sstefdev

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning This pull request includes extensive refactoring of the PaymentWidget internals—renaming callbacks, introducing a new context API, adding PDF generation with html2canvas-pro and jspdf, and dependency upgrades—that go beyond the scope of enabling a custom client ID and guidance links defined in issue #33. Please separate the unrelated PaymentWidget API refactor, PDF receipt enhancements, and dependency updates into dedicated pull requests and limit this PR to the custom client ID input and EasyInvoice guidance additions.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the two main changes—adding a link to EasyInvoice for client ID generation and providing an option for a custom client ID in checkout—and directly reflects the core functionality introduced in the pull request.
Linked Issues Check ✅ Passed The implementation adds a custom client ID input on the Demo Page and inserts EasyInvoice guidance links on both the Demo and Playground pages via the new NEXT_PUBLIC_EASY_INVOICE_URL environment variable, thereby satisfying both linked issue objectives for #33.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/33-custom-client-id

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/Playground/index.tsx (1)

145-150: Update generated integration code to match new callback names.

The generated integration code still uses the old callback names onSuccess and onError, but the preview widget (lines 196-198) correctly uses the new names onPaymentSuccess and onPaymentError. This inconsistency will mislead developers copying the integration code.

Apply this diff to update the generated code:

-  onSuccess={() => {
+  onPaymentSuccess={(requestId, transactionReceipts) => {
     console.log('Payment successful');
   }}
-  onError={(error) => {
+  onPaymentError={(error) => {
     console.error('Payment failed:', error);
   }}

Consider also adding the new onComplete callback to the generated example for completeness:

   onPaymentError={(error) => {
     console.error('Payment failed:', error);
   }}
+  onComplete={() => {
+    console.log('Payment process completed');
+  }}
src/components/payment-widget/README.md (1)

23-25: Update dependency docs to match implementation.

The widget now imports html2canvas-pro and jspdf, but the README still tells consumers to install html2pdf.js. Please replace the installation instructions and dependency list with the packages actually used by PaymentSuccess, otherwise downstream users will miss required deps.

Also applies to: 375-385

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8babce and 3dab4bd.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (22)
  • .env.example (1 hunks)
  • package.json (1 hunks)
  • src/components/PaymentStep.tsx (4 hunks)
  • src/components/Playground/blocks/customize.tsx (3 hunks)
  • src/components/Playground/index.tsx (2 hunks)
  • src/components/payment-widget/README.md (5 hunks)
  • src/components/payment-widget/components/currency-select.tsx (1 hunks)
  • src/components/payment-widget/components/payment-confirmation.tsx (4 hunks)
  • src/components/payment-widget/components/payment-modal.tsx (4 hunks)
  • src/components/payment-widget/components/payment-success.tsx (4 hunks)
  • src/components/payment-widget/components/receipt/styles.css (1 hunks)
  • src/components/payment-widget/constants.ts (1 hunks)
  • src/components/payment-widget/context/payment-widget-context/index.ts (1 hunks)
  • src/components/payment-widget/context/payment-widget-context/payment-widget-provider.tsx (6 hunks)
  • src/components/payment-widget/context/payment-widget-context/use-payment-widget-context.ts (1 hunks)
  • src/components/payment-widget/hooks/use-payment.ts (1 hunks)
  • src/components/payment-widget/payment-widget.tsx (3 hunks)
  • src/components/payment-widget/payment-widget.types.ts (2 hunks)
  • src/components/payment-widget/utils/payment.ts (6 hunks)
  • src/components/payment-widget/utils/wagmi.ts (3 hunks)
  • src/lib/constants.ts (1 hunks)
  • src/lib/validation.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-07T02:52:54.845Z
Learnt from: MantisClone
PR: RequestNetwork/rn-checkout#17
File: src/components/ui/tabs.tsx:85-94
Timestamp: 2024-11-07T02:52:54.845Z
Learning: In the playground component (`src/components/ui/tabs.tsx`), ARIA attributes are not necessary; focus on adding them to the payment widget instead.

Applied to files:

  • src/components/Playground/index.tsx
🧬 Code graph analysis (7)
src/components/payment-widget/utils/payment.ts (1)
src/components/payment-widget/types/index.ts (1)
  • PaymentError (8-11)
src/components/PaymentStep.tsx (3)
src/store/ticketStore.ts (1)
  • useTicketStore (26-69)
src/lib/constants.ts (1)
  • EASY_INVOICE_URL (44-44)
src/components/payment-widget/payment-widget.tsx (1)
  • PaymentWidget (87-114)
src/components/payment-widget/payment-widget.types.ts (1)
src/components/payment-widget/types/index.ts (1)
  • PaymentError (8-11)
src/components/payment-widget/context/payment-widget-context/use-payment-widget-context.ts (1)
src/components/payment-widget/context/payment-widget-context/index.ts (2)
  • PaymentWidgetContextValue (5-33)
  • PaymentWidgetContext (35-36)
src/components/payment-widget/context/payment-widget-context/payment-widget-provider.tsx (1)
src/components/payment-widget/types/index.ts (1)
  • PaymentError (8-11)
src/components/payment-widget/context/payment-widget-context/index.ts (1)
src/components/payment-widget/types/index.ts (3)
  • FeeInfo (1-4)
  • ReceiptInfo (67-73)
  • PaymentError (8-11)
src/components/Playground/blocks/customize.tsx (1)
src/lib/constants.ts (1)
  • EASY_INVOICE_URL (44-44)
🪛 dotenv-linter (3.3.0)
.env.example

[warning] 9-9: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 9-9: [UnorderedKey] The NEXT_PUBLIC_REQUEST_API_URL key should go before the NEXT_PUBLIC_RN_API_CLIENT_ID key

(UnorderedKey)


[warning] 10-10: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 10-10: [UnorderedKey] The NEXT_PUBLIC_EASY_INVOICE_URL key should go before the NEXT_PUBLIC_GTM_ID key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (21)
src/components/payment-widget/components/receipt/styles.css (1)

3-3: LGTM!

The padding increase improves visual spacing within the receipt container.

src/components/payment-widget/utils/wagmi.ts (3)

1-1: LGTM!

Adding the CreateConnectorFn type import improves type safety.


19-19: LGTM!

Typing the connectors array with CreateConnectorFn[] improves type safety and removes the need for unsafe casts.


41-41: LGTM!

Removing the as any cast is a good type safety improvement enabled by the properly typed connectors array.

src/components/payment-widget/context/payment-widget-context/index.ts (2)

5-33: LGTM!

The PaymentWidgetContextValue interface is well-structured with:

  • Clear separation of concerns (wallet, payment config, UI config, receipt info, callbacks)
  • Proper optional fields (reference, callbacks, wallet details)
  • Support for both sync and async callback patterns

35-36: LGTM!

Context initialization with null is appropriate and enforces usage within a provider via the hook validation.

src/components/payment-widget/context/payment-widget-context/use-payment-widget-context.ts (1)

4-14: LGTM!

The hook follows the standard React context pattern with proper validation and a clear error message for misuse.

src/components/payment-widget/components/currency-select.tsx (1)

13-13: LGTM!

The import path update aligns with the context refactoring to use the centralized module.

src/components/payment-widget/context/payment-widget-context/payment-widget-provider.tsx (2)

21-26: Note the API surface change.

The callback props have been renamed:

  • onSuccessonPaymentSuccess
  • onErroronPaymentError
  • Added: onComplete

This is a breaking change for existing consumers. Ensure migration guidance is provided in documentation or release notes.

Do you want me to help draft migration guidance or a deprecation notice for the renamed callbacks?


48-87: LGTM!

The context value correctly includes:

  • The new reference field from paymentConfig
  • The renamed callbacks (onPaymentSuccess, onPaymentError, onComplete)
  • All dependencies properly tracked in the useMemo deps array
src/components/payment-widget/hooks/use-payment.ts (1)

103-103: LGTM!

The reference field is correctly forwarded to executePayment, ensuring the payment request includes the custom reference when provided.

src/components/payment-widget/constants.ts (1)

1-3: LGTM! Environment guard improves cross-runtime compatibility.

The typeof process !== "undefined" check protects against reference errors in browser and edge environments where process is not defined, making the widget more robust across different runtime contexts.

src/components/Playground/blocks/customize.tsx (2)

14-14: LGTM! EasyInvoice guidance added as per PR objectives.

The import and link provide clear guidance on obtaining a Client ID from EasyInvoice, directly addressing the PR objective to help users understand where to get their credentials.

Also applies to: 130-140


151-157: LGTM! Custom payment reference input correctly implemented.

The optional input field is properly bound to paymentConfig.reference and aligns with the validation schema and type definitions introduced elsewhere in the PR.

src/lib/validation.ts (1)

13-13: LGTM! Optional reference field correctly added to validation schema.

The field is appropriately marked as optional and typed as a string, consistent with the PaymentConfig type changes and the free-form nature of payment references.

src/lib/constants.ts (1)

43-44: LGTM! EASY_INVOICE_URL constant properly defined.

The constant follows the established pattern for environment-based configuration and provides a sensible production fallback URL.

src/components/payment-widget/components/payment-modal.tsx (2)

19-19: LGTM! Context hook import and usage updated correctly.

The import path change aligns with the context restructuring, and the destructured callbacks (onPaymentSuccess, onComplete) match the new API surface.

Also applies to: 30-30


66-66: LGTM! Callback invocations are correct.

Both callbacks are properly invoked with optional chaining:

  • onPaymentSuccess receives requestId and transactionReceipts at payment success
  • onComplete is called when the modal closes from the success step after reset

Also applies to: 83-83

src/components/payment-widget/utils/payment.ts (3)

10-10: LGTM! Optional reference field correctly implemented and propagated.

The reference field is properly:

  • Typed as optional in PaymentParams
  • Destructured in createPayout
  • Passed to the API request body

This enables custom payment references as per the PR objectives.

Also applies to: 130-130, 148-148


56-63: LGTM! Improved type safety in error guard.

Changing the parameter type from any to unknown and adding a null check improves type safety and prevents potential runtime errors when checking error properties.


180-180: LGTM! Simplified error handling.

The anonymous catch clause is cleaner since the error variable was not being used in the catch block.

Comment on lines +9 to +10
NEXT_PUBLIC_REQUEST_API_URL="https://api.stage.request.network"
NEXT_PUBLIC_EASY_INVOICE_URL=https://easyinvoice.request.network
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix quote inconsistency and add EOF blank line.

Issues identified:

  • Line 9 has quotes around the URL value, but line 10 does not
  • Missing blank line at end of file

For consistency and to address linter warnings, either remove quotes from line 9 or add them to line 10, and add a blank line at EOF.

Apply this diff:

-NEXT_PUBLIC_REQUEST_API_URL="https://api.stage.request.network"
-NEXT_PUBLIC_EASY_INVOICE_URL=https://easyinvoice.request.network
+NEXT_PUBLIC_REQUEST_API_URL=https://api.stage.request.network
+NEXT_PUBLIC_EASY_INVOICE_URL=https://easyinvoice.request.network
+

Based on learnings

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
NEXT_PUBLIC_REQUEST_API_URL="https://api.stage.request.network"
NEXT_PUBLIC_EASY_INVOICE_URL=https://easyinvoice.request.network
NEXT_PUBLIC_REQUEST_API_URL=https://api.stage.request.network
NEXT_PUBLIC_EASY_INVOICE_URL=https://easyinvoice.request.network
🧰 Tools
🪛 dotenv-linter (3.3.0)

[warning] 9-9: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 9-9: [UnorderedKey] The NEXT_PUBLIC_REQUEST_API_URL key should go before the NEXT_PUBLIC_RN_API_CLIENT_ID key

(UnorderedKey)


[warning] 10-10: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 10-10: [UnorderedKey] The NEXT_PUBLIC_EASY_INVOICE_URL key should go before the NEXT_PUBLIC_GTM_ID key

(UnorderedKey)

🤖 Prompt for AI Agents
In .env.example around lines 9-10, the URL values are inconsistent (line 9 is
quoted, line 10 is not) and the file lacks a trailing newline; make them
consistent by adding matching double quotes around NEXT_PUBLIC_EASY_INVOICE_URL
so both lines use the same quoting style, and ensure the file ends with a single
blank line (newline at EOF).

Comment on lines +72 to +102
const html2canvas = (await import("html2canvas-pro")).default;
const jsPDF = (await import("jspdf")).default;

html2pdf()
.set({
margin: 1,
filename: `receipt-${receiptParams.metadata?.receiptNumber || "payment"}.pdf`,
image: { type: "jpeg", quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: "in", format: "a4", orientation: "portrait" },
})
.from(element)
.save();
const canvas = await html2canvas(element, {
scale: 2,
useCORS: true,
backgroundColor: "#ffffff",
width: element.scrollWidth,
height: element.scrollHeight,
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight,
});

const pdf = new jsPDF("p", "mm", "a4");
const imgData = canvas.toDataURL("image/png");

const pageWidth = 210;
const pageHeight = 297;
const margin = 10;
let imgWidth = pageWidth - margin * 2;
let imgHeight = (canvas.height * imgWidth) / canvas.width;
const maxHeight = pageHeight - margin * 2;
if (imgHeight > maxHeight) {
const ratio = maxHeight / imgHeight;
imgWidth = imgWidth * ratio;
imgHeight = imgHeight * ratio;
}
pdf.addImage(imgData, "PNG", margin, margin, imgWidth, imgHeight);
pdf.save(
`receipt-${receiptParams.metadata?.receiptNumber || "payment"}.pdf`,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Ensure html2canvas-pro/jspdf are installed and bundled.

The new receipt export path dynamically imports html2canvas-pro and jspdf, but the project previously relied on html2pdf.js. Unless html2canvas-pro and jspdf are added to the runtime dependencies, this import will throw (“Cannot find module ‘html2canvas-pro’”) the first time a user downloads a receipt. Please add both packages (or switch back to an existing dependency) and update the install docs accordingly.

🤖 Prompt for AI Agents
In src/components/payment-widget/components/payment-success.tsx around lines 72
to 102, the dynamic imports of "html2canvas-pro" and "jspdf" will fail at
runtime if those packages are not included in runtime dependencies or bundled;
add both packages to package.json "dependencies" (not just devDependencies) and
run install/build so they are available in production, or alternatively revert
to the previously used bundle (e.g., html2pdf.js or html2canvas) that is already
shipped; finally update the project install/README to list these new runtime
dependencies and confirm CI/build config includes them in the production bundle.

Comment on lines +92 to +93
onPaymentSuccess,
onPaymentError,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify onComplete prop is defined and forwarded.

The props have been renamed from onSuccess/onError to onPaymentSuccess/onPaymentError, but the new onComplete callback mentioned in the AI summary and used in the modal (src/components/payment-widget/components/payment-modal.tsx:30) is not visible in this component's props or forwarding logic.

Run the following script to verify the PaymentWidgetProps type includes onComplete and that it's being forwarded:

Also applies to: 107-108


🏁 Script executed:

#!/bin/bash
# Description: Verify onComplete is defined in PaymentWidgetProps and forwarded to provider

# Search for PaymentWidgetProps type definition
echo "=== PaymentWidgetProps definition ==="
ast-grep --pattern $'export interface PaymentWidgetProps {
  $$$
}'

# Search for onComplete in PaymentWidget component
echo "=== onComplete usage in PaymentWidget ==="
rg -A5 -B5 'onComplete' src/components/payment-widget/payment-widget.tsx

# Search for onComplete in PaymentWidgetProvider
echo "=== onComplete in PaymentWidgetProvider ==="
rg -A5 -B5 'onComplete' src/components/payment-widget/context/payment-widget-context/

Length of output: 6120


Expose and forward onComplete in PaymentWidget
Add onComplete to PaymentWidgetProps and include it in the prop destructuring (around lines 92–93 of src/components/payment-widget/payment-widget.tsx), then pass it through to PaymentWidgetProvider.

🤖 Prompt for AI Agents
In src/components/payment-widget/payment-widget.tsx around lines 92 to 93, the
PaymentWidget is not exposing the onComplete prop; update the PaymentWidgetProps
type to include onComplete, add onComplete to the component props destructuring
alongside onPaymentSuccess and onPaymentError, and forward that onComplete prop
into the PaymentWidgetProvider props so the provider receives and can call it.

Copy link
Member

@rodrigopavezi rodrigopavezi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Review Report

📋 Summary

This PR introduces significant enhancements to the payment widget including improved PDF receipt generation, API interface improvements, and new configuration options. The changes maintain backward compatibility while adding valuable new features.

✅ What's Good

🔧 Dependency Updates

  • Updated core dependencies to latest stable versions:
    • @tanstack/react-query: ^5.90.2 (improved query management)
    • react-hook-form: ^7.63.0 (latest form handling)
    • viem: ^2.37.11 & wagmi: ^2.17.5 (latest Web3 tooling)

📄 Enhanced PDF Generation

  • Replaced html2pdf.js with html2canvas-pro + jsPDF - Better performance and reliability
  • Improved PDF styling with proper dimensions and margins
  • Better error handling for PDF generation failures
  • Optimized rendering with proper scaling and background settings

🔌 API Improvements

  • Clearer prop naming: onSuccessonPaymentSuccess, onErroronPaymentError
  • New onComplete callback for post-payment cleanup/navigation
  • Added reference field to PaymentConfig for tracking purposes
  • Improved error handling with null checks in isPaymentError

🎨 Enhanced Configuration

  • Custom Client ID input with helpful link to EasyInvoice
  • Environment variable support for Easy Invoice URL
  • Better form validation with optional reference field
  • Improved context management with cleaner separation of concerns

⚠️ Areas for Attention

🔄 Breaking Changes (Well Handled)

  • Prop renames are breaking changes but well documented in README
  • Migration path is clear - simple rename operations
  • Backward compatibility maintained through optional fields

🛡️ Security & Robustness

  • Environment variable fallback properly implemented in constants.ts
  • Process undefined check added for better SSR compatibility
  • Error boundaries maintained throughout payment flow

📚 Documentation

  • README thoroughly updated with new prop names and examples
  • Type definitions properly updated to match implementation
  • Clear migration examples provided for breaking changes

🎯 Technical Quality

Code Quality

  • Consistent error handling patterns maintained
  • Proper TypeScript usage with updated interfaces
  • Clean separation of concerns in context management
  • Good use of React patterns (hooks, context, refs)

Performance

  • Lazy loading of PDF generation libraries
  • Optimized canvas rendering settings
  • Proper memory management in PDF generation

Testing Considerations

  • Error handling paths are well covered
  • Fallback values properly implemented
  • Type safety maintained throughout

🚀 Recommendations

Ready to Merge

This PR is well-structured and ready for production:

  1. Breaking changes are minimal and well-documented
  2. New features add significant value (better PDF generation, tracking)
  3. Code quality is high with proper error handling
  4. Documentation is comprehensive and up-to-date

📋 Post-Merge Actions

  1. Update integration guides to reflect new prop names
  2. Consider deprecation warnings for old prop names in future versions
  3. Monitor PDF generation performance in production
  4. Validate Easy Invoice integration works as expected

🏆 Overall Assessment

APPROVED

This is a high-quality PR that significantly improves the payment widget while maintaining excellent backward compatibility practices. The enhanced PDF generation, clearer API design, and improved configuration options make this a valuable addition to the codebase.

Key Strengths:

  • Thoughtful API design improvements
  • Robust error handling
  • Comprehensive documentation updates
  • Clean implementation of new features
  • Proper handling of breaking changes

Impact: Medium-High (New features + API improvements)
Risk: Low (Well-tested, good fallbacks, clear migration path)


📝 Detailed Change Analysis

Dependencies Added/Updated

{
  "@tanstack/react-query": "^5.90.2",
  "html2canvas-pro": "^1.5.11",
  "jspdf": "^3.0.3",
  "react-hook-form": "^7.63.0",
  "viem": "^2.37.11",
  "wagmi": "^2.17.5"
}

API Changes

// Before
interface PaymentWidgetProps {
  onSuccess?: (requestId: string, receipts: TransactionReceipt[]) => void;
  onError?: (error: PaymentError) => void;
}

// After
interface PaymentWidgetProps {
  onPaymentSuccess?: (requestId: string, receipts: TransactionReceipt[]) => void;
  onPaymentError?: (error: PaymentError) => void;
  onComplete?: () => void; // NEW
}

interface PaymentConfig {
  reference?: string; // NEW
  // ... existing fields
}

New Features

  1. Enhanced PDF Generation: Replaced html2pdf.js with html2canvas-pro + jsPDF
  2. Payment Reference Tracking: Added optional reference field for internal tracking
  3. Custom Client ID Configuration: UI for configuring EasyInvoice client ID
  4. Improved Error Handling: Better null checks and error boundaries
  5. Environment Configuration: Support for EASY_INVOICE_URL environment variable

Migration Guide

// Update your PaymentWidget usage:
<PaymentWidget
  // Rename these props:
  onPaymentSuccess={handleSuccess} // was: onSuccess
  onPaymentError={handleError}     // was: onError
  
  // Optional new props:
  onComplete={handleComplete}      // NEW: called when widget closes from success
  paymentConfig={{
    // ... existing config
    reference: "invoice-123"       // NEW: optional tracking reference
  }}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Checkout - Allow EasyInvoice Client ID on Demo Page, Improve Client ID guidance on Playground page
3 participants