Created
April 11, 2024 11:29
-
-
Save proton0210/beb322f0cd0c15a6bc2f92c12022678c to your computer and use it in GitHub Desktop.
Stripe Check out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Stripe from "stripe"; | |
import { NextResponse } from "next/server"; | |
import { auth } from "@clerk/nextjs"; | |
export async function POST(request: Request) { | |
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY; | |
if (!STRIPE_SECRET_KEY) { | |
throw new Error("Please add STRIPE_SECRET_KEY to .env"); | |
} | |
const stripe = new Stripe(STRIPE_SECRET_KEY); | |
// Get the request body | |
const data = await request.json(); | |
console.log("Request data:", data); | |
// Extract the priceId and clerkId from the request body | |
const { userId } = auth(); | |
const { priceId } = data; | |
const currentUrl = request.headers.get("origin") || null; | |
const session = await stripe.checkout.sessions.create({ | |
line_items: [ | |
{ | |
price: priceId, | |
quantity: 1, | |
}, | |
], | |
mode: "payment", | |
success_url: `${currentUrl}/product`, // Use the current URL for success_url | |
cancel_url: `${currentUrl}/product`, | |
metadata: { | |
userId, | |
}, | |
}); | |
console.log("Created Stripe checkout session:", session); | |
console.log("Session metadata:", session.metadata); | |
return NextResponse.json(session.url); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// route.config.ts | |
import { NextRequest, NextResponse } from "next/server"; | |
export const config = { | |
runtime: "edge", | |
bodyParser: false, | |
}; | |
export async function middleware(request: NextRequest) { | |
return NextResponse.next(); | |
} | |
// route.ts | |
import { clerkClient } from "@clerk/nextjs"; | |
import { NextRequest, NextResponse } from "next/server"; | |
import Stripe from "stripe"; | |
import { DynamoDBClient, UpdateItemCommand, UpdateItemCommandInput } from "@aws-sdk/client-dynamodb"; | |
const dynamodb = new DynamoDBClient({ | |
region: process.env.AWS_REGION!, | |
credentials: { | |
accessKeyId: process.env.AWS_ACCESS_KEY_ID!, | |
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, | |
}, | |
}); | |
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, { | |
apiVersion: "2023-10-16", | |
}); | |
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET as string; | |
export async function POST(req: NextRequest) { | |
if (req === null) | |
throw new Error(`Missing userId or request`, { cause: { req } }); | |
const stripeSignature = req.headers.get("stripe-signature"); | |
if (stripeSignature === null) throw new Error("stripeSignature is null"); | |
let event; | |
try { | |
event = stripe.webhooks.constructEvent( | |
await req.text(), | |
stripeSignature, | |
webhookSecret | |
); | |
} catch (error) { | |
if (error instanceof Error) | |
return NextResponse.json( | |
{ | |
error: error.message, | |
}, | |
{ | |
status: 400, | |
} | |
); | |
} | |
if (event === undefined) throw new Error(`event is undefined`); | |
switch (event.type) { | |
case "checkout.session.completed": | |
const session = event.data.object; | |
console.log(`Payment successful for session ID: ${session.id}`); | |
clerkClient.users.updateUserMetadata( | |
event.data.object.metadata?.userId as string, | |
{ | |
publicMetadata: { | |
stripe: { | |
status: session.status, | |
payment: session.payment_status, | |
}, | |
}, | |
} | |
); | |
const customerId = session.metadata!.userId as string; | |
const amount = session.amount_total || 0; | |
await updateUserCredits(customerId, amount); | |
break; | |
default: | |
console.warn(`Unhandled event type: ${event.type}`); | |
} | |
return NextResponse.json({ status: 200, message: "success" }); | |
} | |
async function updateUserCredits(customerId: string, amount: number): Promise<void> { | |
let modifiedAmount = amount / 100; | |
console.log("Amount: ", modifiedAmount); | |
const amountMapping: { [key: string]: number } = { | |
"5": 5, | |
"25": 40, | |
"49": 99, | |
}; | |
const credits = amountMapping[modifiedAmount.toString()] || 0; // Ensure credits fallbacks to 0 if not found | |
console.log(credits); | |
const params: UpdateItemCommandInput = { | |
TableName: "Users", | |
Key: { | |
ClerkID: { S: customerId }, | |
}, | |
UpdateExpression: "SET Credits = Credits + :val", | |
ExpressionAttributeValues: { | |
":val": { N: credits.toString() }, | |
}, | |
ReturnValues: "UPDATED_NEW", | |
}; | |
try { | |
const command = new UpdateItemCommand(params); | |
const result = await dynamodb.send(command); | |
console.log("Credits updated successfully:", result); | |
} catch (error) { | |
console.error("Error updating credits:", error); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://docs.stripe.com/testing#international-cards |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment