1+ import Stripe from 'stripe' ;
2+ import { getRedisClient } from './lib/redis.js' ;
3+ import { customAlphabet } from 'nanoid' ;
4+
5+ const stripe = new Stripe ( process . env . STRIPE_SECRET_KEY ) ;
6+ const generateApiKey = customAlphabet ( '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' , 32 ) ;
7+
8+ export default async function handler ( req , res ) {
9+ if ( req . method !== 'POST' ) {
10+ return res . status ( 405 ) . json ( { error : 'Method not allowed' } ) ;
11+ }
12+
13+ try {
14+ const { sessionId } = req . body ;
15+
16+ if ( ! sessionId ) {
17+ return res . status ( 400 ) . json ( { error : 'Session ID is required' } ) ;
18+ }
19+
20+ // Retrieve the session from Stripe
21+ const session = await stripe . checkout . sessions . retrieve ( sessionId ) ;
22+
23+ if ( session . payment_status !== 'paid' ) {
24+ return res . status ( 400 ) . json ( { error : 'Payment not completed' } ) ;
25+ }
26+
27+ const email = session . customer_email || session . customer_details ?. email ;
28+ if ( ! email ) {
29+ return res . status ( 400 ) . json ( { error : 'No email found in session' } ) ;
30+ }
31+
32+ const redis = getRedisClient ( ) ;
33+
34+ // Check if API key already exists for this email
35+ let apiKey = await redis . get ( `api_key:email:${ email } ` ) ;
36+
37+ if ( ! apiKey ) {
38+ // Generate new API key
39+ apiKey = `ak_${ generateApiKey ( ) } ` ;
40+
41+ // Store the API key mappings (never expire)
42+ await redis . set ( `api_key:email:${ email } ` , apiKey ) ;
43+ await redis . set ( `api_key:${ apiKey } ` , JSON . stringify ( {
44+ email,
45+ created : new Date ( ) . toISOString ( ) ,
46+ stripeSessionId : sessionId
47+ } ) ) ;
48+ }
49+
50+ // If there was attestation data in the metadata, create the short URL
51+ let shortUrl = null ;
52+ if ( session . metadata ?. attestationData ) {
53+ try {
54+ const attestationData = JSON . parse ( session . metadata . attestationData ) ;
55+ const dataUrl = `data:application/json;base64,${ btoa ( JSON . stringify ( attestationData ) ) } ` ;
56+
57+ // Generate short ID
58+ const shortIdGenerator = customAlphabet ( '1234567890abcdefghijklmnopqrstuvwxyz' , 8 ) ;
59+ let shortId ;
60+ let exists = true ;
61+
62+ while ( exists ) {
63+ shortId = shortIdGenerator ( ) ;
64+ exists = await redis . exists ( `url:${ shortId } ` ) ;
65+ }
66+
67+ // Store permanently (no expiration)
68+ await redis . set ( `url:${ shortId } ` , dataUrl ) ;
69+ await redis . set ( `url:${ shortId } :owner` , email ) ;
70+
71+ shortUrl = `${ process . env . VERCEL_URL || 'https://attest.ink' } /s/${ shortId } ` ;
72+ } catch ( error ) {
73+ console . error ( 'Error creating short URL from attestation data:' , error ) ;
74+ }
75+ }
76+
77+ res . status ( 200 ) . json ( {
78+ success : true ,
79+ apiKey,
80+ email,
81+ shortUrl
82+ } ) ;
83+ } catch ( error ) {
84+ console . error ( 'Error verifying payment:' , error ) ;
85+ res . status ( 500 ) . json ( { error : 'Failed to verify payment' } ) ;
86+ }
87+ }
0 commit comments