11'use strict' ;
22
3- const Stripe = require ( '../../lib/stripe-client' ) ;
3+ const createStripeClient = require ( '../../lib/stripe-client' ) ;
44const db = require ( '../../lib/db' ) ;
55const { requireAdminAuth } = require ( './_auth' ) ;
66
7+ function asServiceUnavailable ( res , status , error ) {
8+ return res . status ( 503 ) . json ( { ok : false , status, error } ) ;
9+ }
10+
11+ function asConflict ( res , status , error ) {
12+ return res . status ( 409 ) . json ( { ok : false , status, error } ) ;
13+ }
14+
715module . exports = async function handler ( req , res ) {
816 res . setHeader ( 'Content-Type' , 'application/json; charset=utf-8' ) ;
917 res . setHeader ( 'Cache-Control' , 'no-store' ) ;
@@ -14,25 +22,35 @@ module.exports = async function handler(req, res) {
1422 }
1523 if ( ! requireAdminAuth ( req , res ) ) return ;
1624
17- if ( ! process . env . STRIPE_SECRET_KEY ) {
18- return res . status ( 503 ) . json ( { ok : false , status : 'STRIPE_NOT_CONFIGURED' } ) ;
19- }
20-
2125 const body = req . body || { } ;
2226 const claimId = typeof body . claimId === 'string' ? body . claimId . trim ( ) : '' ;
2327 if ( ! claimId ) return res . status ( 400 ) . json ( { ok : false , status : 'INVALID_CLAIM_ID' } ) ;
2428
29+ let stripe ;
30+ try {
31+ stripe = createStripeClient ( process . env . STRIPE_SECRET_KEY ) ;
32+ } catch ( error ) {
33+ if ( error ?. code === 'STRIPE_NOT_CONFIGURED' ) {
34+ return asServiceUnavailable ( res , 'STRIPE_NOT_CONFIGURED' , 'Stripe secret key is not configured.' ) ;
35+ }
36+ if ( error ?. code === 'STRIPE_SECRET_KEY_INVALID' ) {
37+ return asServiceUnavailable ( res , 'STRIPE_SECRET_KEY_INVALID' , error . message ) ;
38+ }
39+ console . error ( 'ADMIN_CREATE_CHECKOUT_STRIPE_INIT_FAILED' , { message : error ?. message , code : error ?. code , claimId } ) ;
40+ return asServiceUnavailable ( res , 'STRIPE_NOT_CONFIGURED' , 'Stripe secret key is not configured.' ) ;
41+ }
42+
2543 try {
2644 const claims = db . normalizeRows ( await db . query ( 'select * from claim_requests where claim_id = $1 limit 1' , [ claimId ] ) ) ;
27- if ( ! claims . length ) return res . status ( 404 ) . json ( { ok : false , status : 'CLAIM_NOT_FOUND' } ) ;
45+ if ( ! claims . length ) return res . status ( 404 ) . json ( { ok : false , status : 'CLAIM_NOT_FOUND' , error : 'Claim not found.' } ) ;
2846
2947 const claim = claims [ 0 ] ;
3048 if ( claim . status === 'paid' || claim . payment_status === 'paid' ) {
31- return res . status ( 409 ) . json ( { ok : false , status : 'PAYMENT_ALREADY_COMPLETED' } ) ;
49+ return asConflict ( res , 'PAYMENT_ALREADY_COMPLETED' , 'Payment is already completed for this claim.' ) ;
3250 }
3351
3452 if ( ! [ 'cards_published' , 'payment_pending' ] . includes ( claim . status ) ) {
35- return res . status ( 409 ) . json ( { ok : false , status : 'CLAIM_NOT_READY_FOR_PAYMENT' } ) ;
53+ return asConflict ( res , 'CLAIM_NOT_READY_FOR_PAYMENT' , 'Claim must be cards_published before creating checkout.' ) ;
3654 }
3755
3856 if ( claim . status === 'payment_pending' && claim . stripe_checkout_session_id ) {
@@ -45,38 +63,53 @@ module.exports = async function handler(req, res) {
4563 } ) ;
4664 }
4765
48- const stripe = new Stripe ( process . env . STRIPE_SECRET_KEY ) ;
49- const priceCents = Number . parseInt ( process . env . STRIPE_FOUNDING_PRICE_CENTS || '2000' , 10 ) || 2000 ;
5066 const siteUrl = process . env . COMMANDLAYER_SITE_URL || 'https://www.commandlayer.org' ;
5167 const successUrl = `${ siteUrl } /claim/status.html?claimId=${ encodeURIComponent ( claimId ) } &payment=success` ;
5268 const cancelUrl = `${ siteUrl } /claim/status.html?claimId=${ encodeURIComponent ( claimId ) } &payment=cancelled` ;
5369
54- const session = await stripe . checkout . sessions . create ( {
55- mode : 'payment' ,
56- success_url : successUrl ,
57- cancel_url : cancelUrl ,
58- line_items : [ {
59- quantity : 1 ,
60- price_data : {
61- currency : 'usd' ,
62- unit_amount : priceCents ,
63- product_data : { name : 'Founding Activation' }
70+ let session ;
71+ try {
72+ session = await stripe . checkout . sessions . create ( {
73+ mode : 'payment' ,
74+ success_url : successUrl ,
75+ cancel_url : cancelUrl ,
76+ line_items : [ {
77+ quantity : 1 ,
78+ price_data : {
79+ currency : 'usd' ,
80+ unit_amount : 2000 ,
81+ product_data : {
82+ name : 'CommandLayer Founding Activation' ,
83+ description : '10 Trust Verification agent namespaces'
84+ }
85+ }
86+ } ] ,
87+ metadata : {
88+ claimId,
89+ tenant : claim . tenant || '' ,
90+ packId : claim . pack_id || '' ,
91+ product : 'founding_activation'
6492 }
65- } ] ,
66- metadata : {
67- claimId,
68- tenant : claim . tenant || '' ,
69- packId : claim . pack_id || '' ,
70- product : 'founding_activation'
93+ } ) ;
94+ } catch ( error ) {
95+ console . error ( 'ADMIN_CREATE_CHECKOUT_SESSION_FAILED' , { message : error ?. message , code : error ?. code , claimId } ) ;
96+ const payload = {
97+ ok : false ,
98+ status : 'CHECKOUT_SESSION_CREATE_FAILED' ,
99+ error : 'Unable to create Stripe checkout session.'
100+ } ;
101+ if ( process . env . NODE_ENV !== 'production' ) {
102+ payload . debug = { message : error ?. message || 'Unknown Stripe error' , code : error ?. code || null } ;
71103 }
72- } ) ;
104+ return res . status ( 502 ) . json ( payload ) ;
105+ }
73106
74107 await db . query (
75108 `insert into claim_payments (claim_id, provider, stripe_checkout_session_id, amount_cents, currency, status, metadata_json)
76109 values ($1, 'stripe', $2, $3, 'usd', 'pending', $4::jsonb)
77110 on conflict (stripe_checkout_session_id)
78111 do update set status = excluded.status, metadata_json = excluded.metadata_json, updated_at = now()` ,
79- [ claimId , session . id , priceCents , JSON . stringify ( { checkoutUrl : session . url || null } ) ]
112+ [ claimId , session . id , 2000 , JSON . stringify ( { checkoutUrl : session . url || null } ) ]
80113 ) ;
81114
82115 const fromStatus = claim . status ;
@@ -88,7 +121,7 @@ module.exports = async function handler(req, res) {
88121 payment_currency = 'usd',
89122 stripe_checkout_session_id = $3
90123 where claim_id = $1` ,
91- [ claimId , priceCents , session . id ]
124+ [ claimId , 2000 , session . id ]
92125 ) ;
93126
94127 await db . query (
@@ -107,7 +140,7 @@ module.exports = async function handler(req, res) {
107140
108141 return res . status ( 200 ) . json ( { ok : true , status : 'CHECKOUT_SESSION_CREATED' , claimId, checkoutUrl : session . url || null , sessionId : session . id } ) ;
109142 } catch ( error ) {
110- console . error ( 'ADMIN_CREATE_CHECKOUT_SESSION_FAILED ' , { message : error . message , code : error . code } ) ;
143+ console . error ( 'ADMIN_CREATE_CHECKOUT_SESSION_UNEXPECTED ' , { message : error ? .message , code : error ? .code , claimId } ) ;
111144 return res . status ( 500 ) . json ( { ok : false , status : 'ADMIN_CREATE_CHECKOUT_SESSION_FAILED' , error : 'Failed to create checkout session.' } ) ;
112145 }
113146} ;
0 commit comments