I am creating a stripe checkout session in my development mode, that is successfully sending information to my webhook, and when I print out my session details, it successfully prints out all the information from the session. The weird part is though, that when I try to access an individual piece of information so I can save it in my backend with prisma, it says the information is undefined when i console.log it out. It’s so weird I can see the whole thing, but not the individual information. What am I doing wrong and how can I access the individual lines in my Next.js program?
Here is my webhook code
import Stripe from "stripe";
import { stripe } from "@/lib/stripe";
import { headers } from "next/headers";
import { NextResponse } from "next/server";
import prisma from "@/lib/db/prisma";
import { OrderItem } from "@prisma/client";
import { createCart, getCart } from "@/lib/db/cart";
import { revalidatePath } from "next/cache";
export async function POST(req: Request) {
const cart = (await getCart()) ?? (await createCart());
const body = await req.text();
const signature = headers().get("Stripe-Signature") as string;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!,
);
} catch (error) {
return new NextResponse("Invalid signature", { status: 400 });
}
const session = event.data.object as Stripe.Checkout.Session;
if (event.type === "charge.succeeded") {
console.log("*********************************************************");
console.log(session.shipping_details?.address?.state);
console.log("*********************************************************");
const paymentIntent = event.data.object;
const userId = paymentIntent.metadata.userId;
const {
name,
address,
aptNumber,
city,
state,
zipCode,
country,
paymentMethod,
totalInCents,
taxInCents,
cartItems,
} = paymentIntent.metadata;
try {
await prisma.$transaction(async (prisma) => {
// Create the order
const order = await prisma.order.create({
data: {
userId,
name,
address,
aptNumber,
city,
state,
zipCode,
country,
paymentMethod,
totalInCents: parseInt(totalInCents),
taxInCents: parseInt(taxInCents),
},
});
// Create order items
const orderItems = JSON.parse(cartItems).map((item: OrderItem) => ({
productId: item.productId,
productName: item.productName,
price: item.price,
quantity: item.quantity,
orderId: order.id,
}));
await prisma.orderItem.createMany({
data: orderItems,
});
// Empty the user's cart
await prisma.cartItem.deleteMany({
where: {
cart: {
userId: userId,
},
},
});
await prisma.cart.update({
where: { id: cart.id },
data: {},
});
revalidatePath("/", "layout");
});
} catch (error) {
console.error("Error handling checkout session:", error);
}
}
return new NextResponse("ok", { status: 200 });
}
and here is what is printed out when I console.log the whole session.
{
id: *the id is here*,
object: 'charge',
amount: 1499,
amount_captured: 1499,
amount_refunded: 0,
application: null,
application_fee: null,
application_fee_amount: null,
balance_transaction: null,
billing_details: {
address: {
city: 'Austin',
country: 'US',
line1: '3186 Brentwood Drive',
line2: null,
postal_code: '78746',
state: 'TX'
},
email: '[email protected]',
name: 'John Doe',
phone: null
},
calculated_statement_descriptor: 'JOHN DOE',
captured: true,
created: 1722718453,
currency: 'usd',
customer: null,
description: null,
destination: null,
dispute: null,
disputed: false,
failure_balance_transaction: null,
failure_code: null,
failure_message: null,
fraud_details: {},
invoice: null,
livemode: false,
metadata: {},
on_behalf_of: null,
order: null,
outcome: {
network_status: 'approved_by_network',
reason: null,
risk_level: 'normal',
risk_score: 35,
seller_message: 'Payment complete.',
type: 'authorized'
},
paid: true,
payment_intent: 'pi_3PjoxtRu5CVeMm6U0PoyXjnC',
payment_method: 'pm_1PjoxsRu5CVeMm6UvlsVXLbb',
payment_method_details: {
card: {
amount_authorized: 1499,
authorization_code: null,
brand: 'visa',
checks: [Object],
country: 'US',
exp_month: 11,
exp_year: 2042,
extended_authorization: [Object],
fingerprint: '08eKoYQiOE8pTlLD',
funding: 'credit',
incremental_authorization: [Object],
installments: null,
last4: '4242',
mandate: null,
multicapture: [Object],
network: 'visa',
network_token: [Object],
overcapture: [Object],
three_d_secure: null,
wallet: null
},
type: 'card'
},
radar_options: {},
receipt_email: null,
receipt_number: null,
receipt_url: 'https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xUGZDT1pSdTVDVmVNbTZVKPaxurUGMgYiOLShtJk6LBZH4IQkJ4DUUBK9TzBeAOdnf8adJI3SNgJhlihMuQHs9e8IDacRGL5vePD12-',
refunded: false,
review: null,
shipping: {
address: {
city: 'AUSTIN',
country: 'US',
line1: '3186 Brentwood Drive',
line2: null,
postal_code: '78746',
state: 'TX'
},
carrier: null,
name: 'John Doe',
phone: null,
tracking_number: null
},
source: null,
source_transfer: null,
statement_descriptor: null,
statement_descriptor_suffix: null,
status: 'succeeded',
transfer_data: null,
transfer_group: null
}
and when I check an individual item such as
console.log(session.shipping_details?.address?.state);
it just prints out undefined, which is weird.
ALSO, you may have noticed, and I find it really weird too, but when I am trying to access the information in session, and try to do a session.”autocomplete” to get the available keys to choose from, it does not give me just basic shipping. only shipping_details, which is really weird as well. I can seem to access top level keys, such as session.created, but deeper keys value pairs don’t seem to work. I have never dealt with this before so I am very confused.
I have console.logged about every possible way I can think about. I have looked through the documentation, but it mostly just shows me how the session object is structured, but nothing that might make me understand why it is not working.