11import type { FastifyRequest , FastifyReply } from "fastify" ;
22import * as Sentry from "@sentry/bun" ;
33import { ZodError } from "zod" ;
4- import { onboardingCronSchema } from "../../../zod/internals.ts" ;
4+ import DodoPayments from "dodopayments" ;
5+ import { onboardingSchema } from "../../../zod/internals.ts" ;
56import {
67 createWideEventBuilder ,
78 generateRequestId ,
89} from "../../../context/requestContext.ts" ;
910import { logger } from "../../../errors/logger.ts" ;
10- import { AuthError } from "../../../errors/auth.ts " ;
11+ import { AuthError } from "../../../errors/auth" ;
1112import { authenticateHttpApiKey } from "../../../utils/authenticateHttpApiKey.ts" ;
1213import {
1314 upsertMetadata ,
@@ -18,7 +19,7 @@ import { clearClients } from "../../gRPC/payment/paymentProvider.ts";
1819export async function handleOnboarding (
1920 request : FastifyRequest ,
2021 reply : FastifyReply
21- ) : Promise < { crons : string [ ] } > {
22+ ) : Promise < Record < string , never > > {
2223 const builder = createWideEventBuilder (
2324 generateRequestId ( ) ,
2425 request . method ,
@@ -30,14 +31,65 @@ export async function handleOnboarding(
3031 await authenticateHttpApiKey ( authHeader ) ;
3132
3233 const body = await request . body ;
33- const validated = onboardingCronSchema . parse ( body ) ;
34+ const validated = onboardingSchema . parse ( body ) ;
35+
36+ const appUrl = process . env . APP_URL ;
37+ if ( ! appUrl ) {
38+ builder . setError ( 500 , {
39+ type : "ConfigError" ,
40+ message : "APP_URL environment variable is not set" ,
41+ } ) ;
42+ reply . code ( 500 ) ;
43+ return { } ;
44+ }
45+
46+ const liveClient = new DodoPayments ( {
47+ bearerToken : validated . dodoLiveApiKey ,
48+ environment : "live_mode" ,
49+ } ) ;
50+ const testClient = new DodoPayments ( {
51+ bearerToken : validated . dodoTestApiKey ,
52+ environment : "test_mode" ,
53+ } ) ;
54+
55+ let liveSecret : string ;
56+ let testSecret : string ;
57+ try {
58+ const liveWebhook = await liveClient . webhooks . create ( {
59+ url : `${ appUrl } /webhooks/payment/createdCheckout?mode=production` ,
60+ description : "Scrawn live payment webhook" ,
61+ filter_types : [ "payment.succeeded" , "payment.failed" ] ,
62+ } ) ;
63+ liveSecret = ( await liveClient . webhooks . retrieveSecret ( liveWebhook . id ) )
64+ . secret ;
65+
66+ const testWebhook = await testClient . webhooks . create ( {
67+ url : `${ appUrl } /webhooks/payment/createdCheckout?mode=test` ,
68+ description : "Scrawn test payment webhook" ,
69+ filter_types : [ "payment.succeeded" , "payment.failed" ] ,
70+ } ) ;
71+ testSecret = ( await testClient . webhooks . retrieveSecret ( testWebhook . id ) )
72+ . secret ;
73+ } catch ( error ) {
74+ const errMsg = error instanceof Error ? error . message : String ( error ) ;
75+ Sentry . captureException ( error , {
76+ extra : { context : "dodo webhook registration during onboarding" } ,
77+ } ) ;
78+ builder . setError ( 400 , {
79+ type : "DodoApiError" ,
80+ message : `Failed to register webhook with Dodo: ${ errMsg } ` ,
81+ } ) ;
82+ reply . code ( 400 ) ;
83+ return { } ;
84+ }
3485
3586 await upsertMetadata ( {
3687 dodo_live_api_key : validated . dodoLiveApiKey ,
3788 dodo_test_api_key : validated . dodoTestApiKey ,
3889 dodo_live_product_id : validated . dodoLiveProductId ,
3990 dodo_test_product_id : validated . dodoTestProductId ,
40- dodo_webhook_secret : validated . dodoWebhookSecret ,
91+ dodo_live_webhook_secret : liveSecret ,
92+ dodo_test_webhook_secret : testSecret ,
4193 currency : validated . currency ,
4294 redirect_url : validated . redirectUrl ,
4395 } ) ;
@@ -47,7 +99,7 @@ export async function handleOnboarding(
4799 builder . setSuccess ( 200 ) ;
48100
49101 reply . code ( 201 ) ;
50- return { crons : validated . crons } ;
102+ return { } ;
51103 } catch ( error ) {
52104 Sentry . captureException ( error , {
53105 extra : { context : "onboarding route handler" } ,
@@ -59,7 +111,7 @@ export async function handleOnboarding(
59111 message : error . message ,
60112 } ) ;
61113 reply . code ( 401 ) ;
62- return { crons : [ ] } ;
114+ return { } ;
63115 }
64116
65117 if ( error instanceof ZodError ) {
@@ -71,7 +123,7 @@ export async function handleOnboarding(
71123 message : issues ,
72124 } ) ;
73125 reply . code ( 400 ) ;
74- return { crons : [ ] } ;
126+ return { } ;
75127 }
76128
77129 const err = error instanceof Error ? error : new Error ( String ( error ) ) ;
@@ -80,7 +132,7 @@ export async function handleOnboarding(
80132 message : err . message ,
81133 } ) ;
82134 reply . code ( 500 ) ;
83- return { crons : [ ] } ;
135+ return { } ;
84136 } finally {
85137 logger . emit ( builder . build ( ) ) ;
86138 }
@@ -122,7 +174,8 @@ export async function handleGetConfig(
122174 dodo_test_api_key : maskApiKey ( metadata . dodo_test_api_key ) ,
123175 dodo_live_product_id : metadata . dodo_live_product_id ,
124176 dodo_test_product_id : metadata . dodo_test_product_id ,
125- dodo_webhook_secret : maskApiKey ( metadata . dodo_webhook_secret ) ,
177+ dodo_live_webhook_secret : maskApiKey ( metadata . dodo_live_webhook_secret ) ,
178+ dodo_test_webhook_secret : maskApiKey ( metadata . dodo_test_webhook_secret ) ,
126179 currency : metadata . currency ,
127180 redirect_url : metadata . redirect_url ,
128181 } ;
0 commit comments