Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ export declare const internal: FilterApi<
>;

export declare const components: {
stripe: import("@convex/stripe/_generated/component.js").ComponentApi<"stripe">;
stripe: import("@convex-dev/stripe/_generated/component.js").ComponentApi<"stripe">;
};
2 changes: 1 addition & 1 deletion example/convex/convex.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineApp } from "convex/server";
import stripe from "@convex/stripe/convex.config.js";
import stripe from "@convex-dev/stripe/convex.config.js";

const app = defineApp();
app.use(stripe);
Expand Down
15 changes: 4 additions & 11 deletions example/convex/http.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { httpRouter } from "convex/server";
import type Stripe from "stripe";
import { components } from "./_generated/api";
import { registerRoutes } from "@convex/stripe";
import { registerRoutes } from "@convex-dev/stripe";

const http = httpRouter();

Expand All @@ -10,10 +9,7 @@ const http = httpRouter();
registerRoutes(http, components.stripe, {
webhookPath: "/stripe/webhook",
events: {
"customer.subscription.updated": async (
ctx: any,
event: Stripe.CustomerSubscriptionUpdatedEvent
) => {
"customer.subscription.updated": async (ctx, event) => {
// Example custom handler: Log subscription updates
const subscription = event.data.object;
console.log("🔔 Custom handler: Subscription updated!", {
Expand All @@ -24,10 +20,7 @@ registerRoutes(http, components.stripe, {
// You can run additional logic here after the default database sync
// For example, send a notification, update other tables, etc.
},
"payment_intent.succeeded": async (
ctx: any,
event: Stripe.PaymentIntentSucceededEvent
) => {
"payment_intent.succeeded": async (ctx, event) => {
// Example custom handler: Log successful one-time payments
const paymentIntent = event.data.object;
console.log("💰 Custom handler: Payment succeeded!", {
Expand All @@ -36,7 +29,7 @@ registerRoutes(http, components.stripe, {
});
},
},
onEvent: async (ctx: any, event: Stripe.Event) => {
onEvent: async (ctx, event) => {
// Log all events for monitoring/debugging
console.log(`📊 Event received: ${event.type}`, {
id: event.id,
Expand Down
6 changes: 3 additions & 3 deletions example/convex/stripe.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* Benji's Store - Stripe Integration
*
* This file demonstrates how to use the @convex/stripe component
*
* This file demonstrates how to use the @convex-dev/stripe component
* for handling payments and subscriptions with Clerk authentication.
*/

import { action, mutation, query } from "./_generated/server";
import { components } from "./_generated/api";
import { StripeSubscriptions } from "@convex/stripe";
import { StripeSubscriptions } from "@convex-dev/stripe";
import { v } from "convex/values";

const stripeClient = new StripeSubscriptions(components.stripe, {});
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@convex/stripe",
"name": "@convex-dev/stripe",
"description": "A stripe component for Convex.",
"repository": "github:michaelshimeles",
"homepage": "https://github.com/michaelshimeles#readme",
"repository": "github:get-convex/stripe",
"homepage": "https://github.com/get-convex/stripe#readme",
"bugs": {
"url": "https://github.com/michaelshimeles/issues"
"url": "https://github.com/get-convex/stripe/issues"
},
"version": "0.1.0",
"license": "Apache-2.0",
Expand Down
4 changes: 2 additions & 2 deletions src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,10 @@
* export default http;
* ```
*/
export function registerRoutes(
export function registerRoutes<Ctx extends ActionCtx = ActionCtx>(
http: HttpRouter,
component: ComponentApi,
config?: RegisterRoutesConfig
config?: RegisterRoutesConfig<Ctx>,
) {
const webhookPath = config?.webhookPath ?? "/stripe/webhook";
const eventHandlers = config?.events ?? {};
Expand Down Expand Up @@ -394,7 +394,7 @@

// Call generic event handler if provided
if (config?.onEvent) {
await config.onEvent(ctx, event);

Check failure on line 397 in src/client/index.ts

View workflow job for this annotation

GitHub Actions / Test and lint

Argument of type 'GenericActionCtx<GenericDataModel>' is not assignable to parameter of type 'Ctx'.
}

// Call custom event handler if provided
Expand Down
138 changes: 69 additions & 69 deletions src/client/types.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,78 @@
import type {
HttpRouter,
GenericActionCtx,
GenericMutationCtx,
GenericDataModel,
GenericQueryCtx,
} from "convex/server";
import type Stripe from "stripe";

// Type utils follow

export type QueryCtx = Pick<GenericQueryCtx<GenericDataModel>, "runQuery">;
export type MutationCtx = Pick<
GenericMutationCtx<GenericDataModel>,
"runQuery" | "runMutation"
>;
export type ActionCtx = Pick<
GenericActionCtx<GenericDataModel>,
"runQuery" | "runMutation" | "runAction"
>;

// Webhook Event Handler Types

HttpRouter,
GenericActionCtx,
GenericMutationCtx,
GenericDataModel,
GenericQueryCtx,
} from "convex/server";
import type Stripe from "stripe";

// Type utils follow

export type QueryCtx = Pick<GenericQueryCtx<GenericDataModel>, "runQuery">;
export type MutationCtx = Pick<
GenericMutationCtx<GenericDataModel>,
"runQuery" | "runMutation"
>;
export type ActionCtx = Pick<
GenericActionCtx<GenericDataModel>,
"runQuery" | "runMutation" | "runAction"
>;

// Webhook Event Handler Types

/**
* Handler function for a specific Stripe webhook event.
* Receives the mutation context and the full Stripe event object.
*/
export type StripeEventHandler<
Ctx extends ActionCtx = ActionCtx,
T extends Stripe.Event.Type = Stripe.Event.Type,
> = (ctx: Ctx, event: Stripe.Event & { type: T }) => Promise<void>;

/**
* Map of event types to their handlers.
* Users can provide handlers for any Stripe webhook event type.
*/
export type StripeEventHandlers<Ctx extends ActionCtx = ActionCtx> = {
[K in Stripe.Event.Type]?: StripeEventHandler<Ctx, K>;
};

/**
* Configuration for webhook registration.
*/
export type RegisterRoutesConfig<Ctx extends ActionCtx = ActionCtx> = {
/**
* Handler function for a specific Stripe webhook event.
* Receives the mutation context and the full Stripe event object.
* Optional webhook path. Defaults to "/stripe/webhook"
*/
export type StripeEventHandler<
T extends Stripe.Event.Type = Stripe.Event.Type,
> = (ctx: ActionCtx, event: Stripe.Event & { type: T }) => Promise<void>;

webhookPath?: string;

/**
* Map of event types to their handlers.
* Users can provide handlers for any Stripe webhook event type.
* Optional event handlers that run after default processing.
* The component will handle database syncing automatically,
* and then call your custom handlers.
*/
export type StripeEventHandlers = {
[K in Stripe.Event.Type]?: StripeEventHandler<K>;
};

events?: StripeEventHandlers;

/**
* Configuration for webhook registration.
* Optional generic event handler that runs for all events.
* This runs after default processing and before specific event handlers.
*/
export type RegisterRoutesConfig = {
/**
* Optional webhook path. Defaults to "/stripe/webhook"
*/
webhookPath?: string;

/**
* Optional event handlers that run after default processing.
* The component will handle database syncing automatically,
* and then call your custom handlers.
*/
events?: StripeEventHandlers;

/**
* Optional generic event handler that runs for all events.
* This runs after default processing and before specific event handlers.
*/
onEvent?: StripeEventHandler;
/**
* Stripe webhook secret for signature verification.
* Defaults to process.env.STRIPE_WEBHOOK_SECRET
*/
STRIPE_WEBHOOK_SECRET?: string;

/**
* Stripe secret key for API calls.
* Defaults to process.env.STRIPE_SECRET_KEY
*/
STRIPE_SECRET_KEY?: string;
};

onEvent?: StripeEventHandler<Ctx>;
/**
* Type for the HttpRouter to be used in registerRoutes
* Stripe webhook secret for signature verification.
* Defaults to process.env.STRIPE_WEBHOOK_SECRET
*/
export type { HttpRouter };

STRIPE_WEBHOOK_SECRET?: string;

/**
* Stripe secret key for API calls.
* Defaults to process.env.STRIPE_SECRET_KEY
*/
STRIPE_SECRET_KEY?: string;
};

/**
* Type for the HttpRouter to be used in registerRoutes
*/
export type { HttpRouter };
Loading