Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 0 additions & 92 deletions app/api/analyze-study/route.ts

This file was deleted.

75 changes: 75 additions & 0 deletions app/api/stripe/attach-payment-method/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { NextRequest, NextResponse } from 'next/server';
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || 'sk_test_placeholder', {
apiVersion: '2025-02-24.acacia',
});

export async function POST(request: NextRequest) {
try {
const { subscriptionId, customerId, paymentMethodId } = await request.json();

// Validate inputs
if (!subscriptionId || !customerId || !paymentMethodId) {
return NextResponse.json(
{ error: 'Subscription ID, customer ID, and payment method ID required' },
{ status: 400 }
);
}

console.log(`[Stripe] Attaching payment method ${paymentMethodId} to customer ${customerId} and subscription ${subscriptionId}`);

// Attach payment method to customer
await stripe.paymentMethods.attach(paymentMethodId, {
customer: customerId,
});

console.log(`[Stripe] Payment method attached to customer`);

// Set as default payment method for the customer
await stripe.customers.update(customerId, {
invoice_settings: {
default_payment_method: paymentMethodId,
},
});

console.log(`[Stripe] Set as default payment method for customer`);

// Retrieve the subscription to check for existing discounts
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
console.log(`[Stripe] Retrieved subscription, has ${subscription.discounts?.length || 0} discounts`);

// Update the subscription to use this payment method while preserving discounts
const updateParams: any = {
default_payment_method: paymentMethodId,
};

// Preserve existing discounts if any
if (subscription.discounts && subscription.discounts.length > 0) {
updateParams.discounts = subscription.discounts.map((d: any) => ({
coupon: d.coupon?.id,
promotion_code: d.promotion_code,
})).filter((d: any) => d.coupon || d.promotion_code);
console.log(`[Stripe] Preserving ${updateParams.discounts.length} discounts during update`);
}

await stripe.subscriptions.update(subscriptionId, updateParams);

console.log(`[Stripe] Updated subscription ${subscriptionId} with payment method`);

return NextResponse.json({
success: true,
message: 'Payment method attached successfully',
});
} catch (error: any) {
console.error('Stripe attach payment method error:', error);

return NextResponse.json(
{
error: 'Failed to attach payment method',
details: error.message || 'Unknown error',
},
{ status: 500 }
);
}
}
46 changes: 45 additions & 1 deletion app/api/stripe/create-checkout/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const DAYS_PER_MONTH = 30;

export async function POST(request: NextRequest) {
try {
const { walletAddress } = await request.json();
const { walletAddress, couponCode } = await request.json();

// Validate inputs
if (!walletAddress) {
Expand Down Expand Up @@ -45,6 +45,49 @@ export async function POST(request: NextRequest) {
// Get the base URL for redirect
const origin = request.headers.get('origin') || process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';

// Validate promotion code if provided
let discounts = undefined;
if (couponCode && couponCode.trim()) {
try {
console.log(`[Stripe] Validating promotion code: ${couponCode.trim()}`);
// Search for the promotion code
const promotionCodes = await stripe.promotionCodes.list({
code: couponCode.trim(),
limit: 1,
});

if (promotionCodes.data.length === 0) {
console.log(`[Stripe] Promotion code not found`);
return NextResponse.json(
{ error: 'Invalid promotion code' },
{ status: 400 }
);
}

const promotionCode = promotionCodes.data[0];
console.log(`[Stripe] Promotion code retrieved:`, promotionCode.id);

if (!promotionCode.active) {
console.log(`[Stripe] Promotion code is not active`);
return NextResponse.json(
{ error: 'This promotion code is no longer active' },
{ status: 400 }
);
}

// Apply the promotion code
discounts = [{ promotion_code: promotionCode.id }];
console.log(`[Stripe] Promotion code ${promotionCode.id} will be applied to checkout`);
} catch (error: any) {
// Promotion code lookup failed
console.error(`[Stripe] Error validating promotion code:`, error.message);
return NextResponse.json(
{ error: `Invalid promotion code: ${error.message || 'Not found'}` },
{ status: 400 }
);
}
}

// Create Stripe Checkout Session for subscription
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
Expand All @@ -55,6 +98,7 @@ export async function POST(request: NextRequest) {
quantity: 1,
},
],
discounts,
success_url: `${origin}/payment/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${origin}/payment/cancel`,
metadata: {
Expand Down
Loading
Loading