Skip to content

Commit

Permalink
Support custom return urls (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
qianl15 authored Dec 5, 2024
1 parent 9189539 commit 1b862ff
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 34 deletions.
43 changes: 21 additions & 22 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"typescript": "^5.2.2"
},
"dependencies": {
"@dbos-inc/dbos-sdk": "^1.23.8",
"@dbos-inc/dbos-sdk": "^1.28.6",
"axios": "^1.7.4",
"jwks-rsa": "^3.1.0",
"koa-jwt": "^4.0.4",
Expand Down
8 changes: 6 additions & 2 deletions src/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export class CloudSubscription {
const auth0UserID = ctxt.authenticatedUser;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const userEmail = ctxt.koaContext.state.user["https://dbos.dev/email"] as string;
const sessionURL = await ctxt.invokeWorkflow(Utils).createSubscription(auth0UserID, userEmail);
const body = ctxt.request.body as {success_url: string, cancel_url: string};
const successUrl = body.success_url ?? 'https://console.dbos.dev';
const cancelUrl = body.cancel_url ?? 'https://www.dbos.dev/pricing';
const sessionURL = await ctxt.invokeWorkflow(Utils).createSubscription(auth0UserID, userEmail, successUrl, cancelUrl);
if (!sessionURL) {
throw new DBOSResponseError("Failed to create a checkout session!", 500);
}
Expand All @@ -57,7 +60,8 @@ export class CloudSubscription {
@PostApi('/create-customer-portal')
static async createCustomerPortal(ctxt: HandlerContext) {
const auth0User = ctxt.authenticatedUser;
const sessionURL = await ctxt.invokeWorkflow(Utils).createStripeCustomerPortal(auth0User);
const returnUrl = (ctxt.request.body as {return_url: string}).return_url ?? 'https://www.dbos.dev/pricing';
const sessionURL = await ctxt.invokeWorkflow(Utils).createStripeCustomerPortal(auth0User, returnUrl);
if (!sessionURL) {
throw new DBOSResponseError("Failed to create customer portal!", 500);
}
Expand Down
18 changes: 9 additions & 9 deletions src/subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Utils {

// Workflow to create a Stripe checkout session
@Workflow()
static async createSubscription(ctxt: WorkflowContext, auth0UserID: string, userEmail: string): Promise<string|null> {
static async createSubscription(ctxt: WorkflowContext, auth0UserID: string, userEmail: string, successUrl: string, cancelUrl: string): Promise<string|null> {
// First, look up the customer from the accounts table
let stripeCustomerID = await ctxt.invoke(Utils).findStripeCustomerID(auth0UserID);

Expand All @@ -55,19 +55,19 @@ export class Utils {
}

// Finally, create a Stripe checkout session.
const res = await ctxt.invoke(Utils).createStripeCheckout(stripeCustomerID);
const res = await ctxt.invoke(Utils).createStripeCheckout(stripeCustomerID, successUrl, cancelUrl);
return res;
}

// Workflow to create a Stripe customer portal
@Workflow()
static async createStripeCustomerPortal(ctxt: WorkflowContext, auth0UserID: string): Promise<string|null> {
static async createStripeCustomerPortal(ctxt: WorkflowContext, auth0UserID: string, returnUrl: string): Promise<string|null> {
const stripeCustomerID = await ctxt.invoke(Utils).findStripeCustomerID(auth0UserID);
if (!stripeCustomerID) {
ctxt.logger.error(`Cannot find stripe customer for user ${auth0UserID}`);
return null;
}
const sessionURL = await ctxt.invoke(Utils).createStripeBillingPortal(stripeCustomerID);
const sessionURL = await ctxt.invoke(Utils).createStripeBillingPortal(stripeCustomerID, returnUrl);
return sessionURL;
}

Expand Down Expand Up @@ -113,17 +113,17 @@ export class Utils {

// Create a Stripe billing portal for a customer
@Communicator({intervalSeconds: 10, maxAttempts: 2})
static async createStripeBillingPortal(_ctxt: CommunicatorContext, customerID: string): Promise<string|null> {
static async createStripeBillingPortal(_ctxt: CommunicatorContext, customerID: string, returnUrl: string): Promise<string|null> {
const session = await stripe.billingPortal.sessions.create({
customer: customerID,
return_url: 'https://www.dbos.dev/pricing'
return_url: returnUrl,
});
return session.url;
}

// Create a Stripe checkout session for a customer
@Communicator({intervalSeconds: 10, maxAttempts: 2})
static async createStripeCheckout(_ctxt: CommunicatorContext, stripeCustomerID: string): Promise<string|null> {
static async createStripeCheckout(_ctxt: CommunicatorContext, stripeCustomerID: string, successUrl: string, cancelUrl: string): Promise<string|null> {
const session = await stripe.checkout.sessions.create({
customer: stripeCustomerID,
billing_address_collection: 'auto',
Expand All @@ -134,8 +134,8 @@ export class Utils {
},
],
mode: 'subscription',
success_url: `https://docs.dbos.dev`,
cancel_url: `https://www.dbos.dev/pricing`,
success_url: successUrl,
cancel_url: cancelUrl,
allow_promotion_codes: true,
});
return session.url;
Expand Down

0 comments on commit 1b862ff

Please sign in to comment.