11import 'server-only'
22
3+ import { z } from 'zod'
34import { SUPABASE_AUTH_HEADERS } from '@/configs/api'
45import type {
56 AddOnOrderConfirmResponse ,
@@ -8,8 +9,10 @@ import type {
89 CustomerPortalResponse ,
910 Invoice ,
1011 PaymentMethodsCustomerSession ,
12+ PaymentMethodsSetupSession ,
1113 TeamItems ,
1214 UsageResponse ,
15+ VerificationPaymentResponse ,
1316} from '@/core/modules/billing/models'
1417import { repoErrorFromHttp } from '@/core/shared/errors'
1518import type { TeamRequestScope } from '@/core/shared/repository-scope'
@@ -35,12 +38,24 @@ export interface BillingRepository {
3538 createOrder ( itemId : string ) : Promise < RepoResult < AddOnOrderCreateResponse > >
3639 confirmOrder ( orderId : string ) : Promise < RepoResult < AddOnOrderConfirmResponse > >
3740 getCustomerSession ( ) : Promise < RepoResult < PaymentMethodsCustomerSession > >
41+ createPaymentMethodsSession ( ) : Promise < RepoResult < PaymentMethodsSetupSession > >
42+ createVerificationPayment ( ) : Promise < RepoResult < VerificationPaymentResponse > >
3843}
3944
4045async function parseText ( response : Response ) : Promise < string > {
4146 return ( await response . text ( ) ) || 'Request failed'
4247}
4348
49+ const PaymentMethodsSessionResponseSchema = z . object ( {
50+ client_secret : z . string ( ) . min ( 1 ) ,
51+ setup_intent_client_secret : z . string ( ) . min ( 1 ) ,
52+ } )
53+
54+ const VerificationPaymentResponseSchema = z . object ( {
55+ client_secret : z . string ( ) . min ( 1 ) ,
56+ amount_due_cents : z . number ( ) . int ( ) . positive ( ) ,
57+ } )
58+
4459export function createBillingRepository (
4560 scope : BillingScope ,
4661 deps : BillingRepositoryDeps = {
@@ -249,7 +264,7 @@ export function createBillingRepository(
249264 } ,
250265 async getCustomerSession ( ) {
251266 const res = await fetch (
252- `${ deps . billingApiUrl } /teams/${ scope . teamId } /payment-methods/customer -session` ,
267+ `${ deps . billingApiUrl } /teams/${ scope . teamId } /payment-methods-session` ,
253268 {
254269 method : 'POST' ,
255270 headers : {
@@ -265,5 +280,61 @@ export function createBillingRepository(
265280
266281 return ok ( ( await res . json ( ) ) as PaymentMethodsCustomerSession )
267282 } ,
283+ async createPaymentMethodsSession ( ) {
284+ const res = await fetch (
285+ `${ deps . billingApiUrl } /teams/${ scope . teamId } /payment-methods-session?include_setup_intent=true` ,
286+ {
287+ method : 'POST' ,
288+ headers : {
289+ 'Content-Type' : 'application/json' ,
290+ ...SUPABASE_AUTH_HEADERS ( scope . accessToken , scope . teamId ) ,
291+ } ,
292+ }
293+ )
294+
295+ if ( ! res . ok ) {
296+ return err ( repoErrorFromHttp ( res . status , await parseText ( res ) ) )
297+ }
298+
299+ const parseResult = PaymentMethodsSessionResponseSchema . safeParse (
300+ await res . json ( )
301+ )
302+
303+ if ( ! parseResult . success ) {
304+ return err (
305+ repoErrorFromHttp ( 500 , 'Invalid payment methods session response' )
306+ )
307+ }
308+
309+ return ok ( parseResult . data )
310+ } ,
311+ async createVerificationPayment ( ) {
312+ const res = await fetch (
313+ `${ deps . billingApiUrl } /teams/${ scope . teamId } /verification-payment` ,
314+ {
315+ method : 'POST' ,
316+ headers : {
317+ 'Content-Type' : 'application/json' ,
318+ ...SUPABASE_AUTH_HEADERS ( scope . accessToken , scope . teamId ) ,
319+ } ,
320+ }
321+ )
322+
323+ if ( ! res . ok ) {
324+ return err ( repoErrorFromHttp ( res . status , await parseText ( res ) ) )
325+ }
326+
327+ const parseResult = VerificationPaymentResponseSchema . safeParse (
328+ await res . json ( )
329+ )
330+
331+ if ( ! parseResult . success ) {
332+ return err (
333+ repoErrorFromHttp ( 500 , 'Invalid verification payment response' )
334+ )
335+ }
336+
337+ return ok ( parseResult . data )
338+ } ,
268339 }
269340}
0 commit comments