Skip to content

Conversation

@dorukozgen
Copy link

@dorukozgen dorukozgen commented Dec 17, 2025

Adds an optional metadata prop to the Checkout link.
This improves flexibility and is especially useful for large and complex projects.

// example code here
import { api } from "../convex/_generated/api";
import { CheckoutLink } from "@convex-dev/polar/react";

<CheckoutLink
  polarApi={api.example}
  productIds={["product_id_123"]}
  metadata={{
    organizationId: "org_456",
    planType: "enterprise"
  }}
  embed={false}
>
  Upgrade Organization Plan
</CheckoutLink>`

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added optional metadata support to CheckoutLink component and checkout session creation, allowing merchants to attach custom key-value information to checkout transactions.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

The changes add an optional metadata field to checkout functionality, introducing it across the CheckoutLink React component, the createCheckoutSession method signature, and the generateCheckoutLink API schema. Metadata is threaded through the call chain without altering core business logic.

Changes

Cohort / File(s) Summary
React Component Layer
README.md, src/react/index.tsx
Added optional metadata prop (Record<string, string>) to CheckoutLink component. Updated documentation and propagated metadata to generateCheckoutLink call; included in useEffect dependency array.
API/Client Layer
src/client/index.ts
Extended createCheckoutSession method signature with optional metadata?: Record<string, string> parameter. Added metadata to generateCheckoutLink args schema validation and forwarded it through the API handler to the internal session creation call.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • All changes follow a consistent parameter-propagation pattern across three files
  • No complex logic or control flow modifications
  • Straightforward optional field additions at each layer

Poem

🐰 Metadata hops through the checkout lane,
A little extra info in each link's chain,
Optional and light, it floats on through,
From React down to client—a smooth rendezvous!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately captures the main change: adding an optional metadata prop to the CheckoutLink component for checkout functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@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: 0

🧹 Nitpick comments (1)
README.md (1)

422-422: Consider adding a usage example for the metadata prop.

The documentation accurately describes the metadata prop, but an example would help users understand how to use it. The PR description includes an example with organizationId and planType that could be incorporated here.

Consider adding an example like:

-- `metadata`: (Optional) Metadata for additional information to the checkout
+- `metadata`: (Optional) Metadata for additional information to the checkout.
+  Example: `metadata={{ organizationId: "org_123", planType: "enterprise" }}`
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1da2d45 and 5107137.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • src/client/index.ts (4 hunks)
  • src/react/index.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/react/index.tsx (1)
src/client/index.ts (1)
  • PolarComponentApi (48-50)
🔇 Additional comments (3)
src/client/index.ts (2)

309-333: LGTM!

The metadata parameter is correctly threaded through the generateCheckoutLink action to createCheckoutSession. The typing and schema validation are consistent with the method signature.


99-161: Verify metadata parameter support in Polar SDK's checkoutsCreate function.

The code passes a metadata parameter to checkoutsCreate from @polar-sh/sdk (v0.41.5), but the available SDK documentation does not explicitly show metadata as a supported field in the CheckoutCreate request object. While customersCreate supports metadata, verify that checkoutsCreate also accepts this parameter to ensure compatibility with the current SDK version.

src/react/index.tsx (1)

37-81: LGTM!

The metadata prop is correctly integrated into the CheckoutLink component:

  • Properly typed as optional Record<string, string>
  • Forwarded to generateCheckoutLink
  • Included in the useEffect dependency array to trigger re-fetch when metadata changes

@dorukozgen
Copy link
Author

A more detailed example of what it can be used for

// convex/http.ts
import { httpRouter } from "convex/server";
import { polar } from "./example";

const http = httpRouter();

polar.registerRoutes(http, {
  path: "/polar/events",
  
  onSubscriptionCreated: async (ctx, event) => {
    const metadata = event.data.metadata;
    
    if (metadata?.organizationId) {
      console.log("New subscription for org:", metadata.organizationId);
    }
  },
  
  onSubscriptionUpdated: async (ctx, event) => {
    const metadata = event.data.metadata;
    
    if (metadata?.organizationId) {
      console.log("Updated subscription for org:", metadata.organizationId);
    }
  },
});

export default http;

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.

1 participant