#sumit_api

1 messages ¡ Page 1 of 1 (latest)

gray quiverBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1408306364576567297

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

rich flume
#

Hi! Can I get the event ID for the invoice.payment_succeeded event?

zinc warren
#

evt_1RylbrBGfO543PPI7otpQ6oD

rich flume
#

Thank you! This event is for sub_1RylbqBGfO543PPIzydB0T2C which has invoice in_1RylbpBGfO543PPIcPUfyxpq generated. This is the object ID for the invoice.payment_succeeded event:evt_1RylbtBGfO543PPISmArlcWD [0]. I see that it includes the subscription_details property. Is there another event where you are not seeing the subscription_details?

[0] https://dashboard.stripe.com/acct_1RHp6rBGfO543PPI/test/events/evt_1RylbtBGfO543PPISmArlcWD

zinc warren
#

see the error log says [ERROR] [API] CRITICAL: No subscription ID found on the retrieved invoice object. {"invoiceId":"in_1RylbpBGfO543PPIcPUfyxpq"}

rich flume
#

Which API call are you doing in the screenshot above?

zinc warren
#

Hi Sam, the API call is stripe.invoices.retrieve from the stripe-node library.

Inside our invoice.payment_succeeded webhook handler, we take the Invoice ID from the event and immediately retrieve the full invoice object like this:

JavaScript

// The invoiceId is 'in_1RylbpBGfO543PPIcPUfyxpq' from the log
const invoice = await stripe.invoices.retrieve(invoiceId, {
expand: ['subscription'],
});
The error occurs because the invoice object returned by this API call has a null or missing subscription property, which is inconsistent with what we see in the Dashboard UI.

rich flume
zinc warren
#

it still not working

#

can i send you my stripe-webhook/route.ts so you can check if i am doing any mistake or its somewhere else

rich flume
#

Can you provide me with the request ID for your GET request? Also can you provide me with your API call?

zinc warren
#

The API call is stripe.invoices.retrieve from the stripe-node library. Here is the exact code being executed inside our invoice.payment_succeeded webhook handler:

JavaScript

const invoiceId = "in_1RynFDBGfO543PPI29Lsi8s7";
const invoice = await stripe.invoices.retrieve(invoiceId, {
expand: ['subscription_details'],
});
2. The Request ID:

The Request ID for that exact API call is: req_XekTpLIcZSzwd1

The API call returns a 200 OK status, but the invoice object it returns has a null or missing subscription_details property, which is inconsistent with what we see in the Dashboard UI.

#

the below is my handlePaymentSucceeded funtion from stripe-webhook/route.ts for your reference

async function handlePaymentSucceeded(event: Stripe.Event) {
const incomingInvoice = event.data.object as Stripe.Invoice;
apiLogger.info("--- Handling Payment Succeeded ---", { invoiceId: incomingInvoice.id });

try {
const invoiceId = incomingInvoice.id;
if (!invoiceId) {
apiLogger.error("CRITICAL: Invoice ID is missing in the webhook event.");
return;
}

// 1. Using the correct expand path with the period
const invoice: ExpandedInvoice = await stripe.invoices.retrieve(invoiceId, {
  expand: ['parent.subscription_details.subscription'],
});

// 2. Using the correct accessor path with the period
let subId: string | undefined;
const subscriptionObject = invoice.parent?.subscription_details?.subscription;

if (typeof subscriptionObject === 'string') {
    subId = subscriptionObject;
} else if (subscriptionObject && typeof subscriptionObject === 'object') {
    subId = subscriptionObject.id;
}

apiLogger.info("Checking for subscription ID in parent.subscription_details...", { subscriptionId: subId });

if (typeof subId === 'string') {
  apiLogger.info("Subscription ID found! Retrieving full subscription object...", { subscriptionId: subId });
  const subscription = await stripe.subscriptions.retrieve(subId);

  await handleSubscriptionEvent({
    ...event,
    type: 'customer.subscription.updated',
    data: { object: subscription },
  } as Stripe.Event);
} else {
  apiLogger.error("CRITICAL: No subscription ID found on the retrieved invoice object.", { 
    invoiceId: invoice.id 
  });
}

} catch (error) {
apiLogger.error("Failed to process payment succeeded event.", { error });
throw error;
}
}

rich flume
#

Can you try this instead: expand: ['parent.subscription_details.subscription']

zinc warren
#

please go through the handlePaymentSucceeded function i shared with you

rich flume
#

So does expand: ['parent.subscription_details.subscription'] work because earlier you provided me with

  expand: ['subscription_details'],
});
zinc warren
#

yes it worked , now i can see subscription id found log, but now i am facing this error

RangeError: Invalid time value
at Date1.toISOString (<anonymous>)
at handleSubscriptionEvent (app\api\stripe-webhook\route.ts:142:75)
at handlePaymentSucceeded (app\api\stripe-webhook\route.ts:220:12)
at async POST (app\api\stripe-webhook\route.ts:46:8)
140 | stripe_customer_id: customerId,
141 | stripe_subscription_id: subscriptionId,

142 | current_period_end: new Date(subscription.current_period_end * 1000).toISOString(),
| ^
143 | status: subscription.status,
144 | plan,
145 | };
[2025-08-22T06:28:41.476Z] [ERROR] [API] [ERROR] Subscription handler failed: {"error":{}}
[2025-08-22T06:28:41.476Z] [ERROR] [API] Failed to process payment succeeded event. {"error":{}}

let me know if somehow you can help me with this

rich flume
#

Can I have the requets ID for this please?