#the-soundbridge-team_subscriptions-schedules
1 messages ยท Page 1 of 1 (latest)
๐ 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/1403039671910662145
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Yes
So I've created a second monthly re-occuring price for $0.99/Month on the our Everything Bundle (Monthly) subscription like so on the dashboard.
Figuring out the secret handshake for getting client_secret & subscriptonId for the frontend component is unclear
๐ stepping in here as pgskc needs to step away
hi
So my company is trying to do "Start for $0.99, Continue at $9.99/Month"
So for first month users can start for $0.99, then it should automically do $9.99/Month
I'm getting a try/catch error on my current implementation
You are hitting a specific error?
Okay and have you added logs between each step of your code here?
Have you checked that latestInvoice is the object you expect?
Ah okay
So yeah because you are using a Subscription Schedule the Invoice doesn't finalize immediately on Subscription creation
If you look at that Invoice in your Dashboard you will see it is in draft
So you need to finalize it first (or wait the 1 hour for finalization) to be able to access the PaymentIntent
I'm ChatGPTin' this man, the docs are HUGE ๐
ok, so because I just made this extra price, that's why I'm getting this?
No because you use a Subscription Schedule
As opposed to creating the Subscription directly
ok, so I guess this implementation just won't work correct?
Is there anyway to do simply a trial month on a normal subscription?
PayPal does that so easily
Or do you have to do a schedule like this?
I'm not sure what you mean by "it won't work correct"?
It works just fine.
You just need to finalize the Invoice
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Just so this is clear
We're using the React Component on the frontend
For a normal subscription it pulls up like so ^^^
Are you saying I need one more line of code and from this I can get the client_secret and subscriptionId?
Yes. You need the client secret to render Payment Element. To get the client secret you need the Invoice to be finalized.
So after creating the Subscription Schedule you need to finalize the Invoice that is generated by the new Subscription
ok so something like this: const invoice = await stripe.invoices.finalizeInvoice(fullSub.latest_invoice.id);
Yes
ok I see a payment_intent string code now, but no object with client_secret
Are you expanding the payment_intent?
const invoice = await stripe.invoices.finalizeInvoice(latestInvoice?.id, { expand: ['payment_intent'] }); like this?
Yes
ok, I think we got it!
WOW
lots of low-level stuff ๐
the React component is now firing!
I'm extending everything properly towards the end here and not doing anything redunant right?
You could remove the Subscription retrieval request and expand subscription.latest_invoice in your Subscription Schedule creation request
Otherwise lgtm
ok I can add {expand: ['subscription.latest_invoice.payment_intent']} as a second parameter object on stripe.subscriptionSchedules.create()?
Yes
Will the webhook be the same as normal subscription or is the payment type different?
On normal subscription we do this
"object": "list",
"data": [
{
"id": "sli_10047dCrnLkr8CZ739788f16",
"object": "line_item",
"amount": 99,
"amount_excluding_tax": 99,
"currency": "usd",
"description": "1 ร Everything Bundle (Monthly) (at $0.99 / month)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"invoice": "in_1RtXHtCrnLkr8CZ7rGDzUMdD",
"livemode": true,
"metadata": {},
"parent": {
"invoice_item_details": null,
"subscription_item_details": {
"invoice_item": null,
"proration": false,
"proration_details": {
"credited_items": null
},
"subscription": "sub_1RtXHsCrnLkr8CZ7XoGaIWya",
"subscription_item": "si_SpBfpC31QvffiX"
},
"type": "subscription_item_details"
}, the meta data is empty
we need to set a customID here
const schedule = await stripe.subscriptionSchedules.create({
customer: customer.id,
start_date: 'now',
end_behavior: 'release',
metadata: { custom_id },
phases: [
{
items: [
{
price: introPriceId, // $0.99 intro
quantity: 1,
},
],
iterations: 1, // One billing cycle only
},
{
items: [
{
price: priceId, // $9.99 normal monthly
quantity: 1,
},
],
},
],
});
Im setting a custom_id like so
is this correct?
Yeah that would set metadata on the Subscription Schedule object
But that won't get carried down to the Subscription. You would need to update the Subscription with that metadata after it is created.
if (canGetIntroPricing(userData) && productID === subscriptionProducts[0]) {
const introPriceId = process.env.STRIPE_INTRO_MONTHLY_SUBSCRIPTION_PRICE_ID;
if (!introPriceId) {
return NextResponse.json({ message: 'Missing intro price ID' }, { status: 500 });
}
const schedule = await stripe.subscriptionSchedules.create({
customer: customer.id,
start_date: 'now',
end_behavior: 'release',
metadata: { custom_id },
phases: [
{
items: [
{
price: introPriceId, // $0.99 intro
quantity: 1,
},
],
iterations: 1, // One billing cycle only
},
{
items: [
{
price: priceId, // $9.99 normal monthly
quantity: 1,
},
],
},
],
});
// Retrieve the underlying subscription to get payment intent
const fullSub: any = await stripe.subscriptions.retrieve(
schedule.subscription as string,
{ expand: ['latest_invoice'] },
);
const latestInvoice: any = fullSub.latest_invoice as InvoiceWithPaymentIntent;
console.log('latestInvoice', latestInvoice);
await stripe.subscriptions.update(
latestInvoice.subscription,
{
metadata: {
custom_id,
},
},
);
const invoice: any = await stripe.invoices.finalizeInvoice(latestInvoice?.id, { expand: ['payment_intent'] });
// console.log('INVOICE', invoice);
if (!invoice.payment_intent?.client_secret) {
throw new Error('Failed to retrieve payment intent');
}
return NextResponse.json({
client_secret: invoice.payment_intent.client_secret,
subscriptionId: fullSub.id,
});
} ok like this>?
Instead of just dropping a bunch of code I would recommend testing it out!
From a glance I think it looks good!
Yes sorry, seems to be working now. I removed the Metadata from the Subscription schedule creation too. Can you send an example of simplified extend to reduce my code?
I tried adding an second extends object to the creation function, but that function doesn't take a second parameter
๐ Taking over this thread
I tried adding an second extends object to the creation function, but that function doesn't take a second parameter
Which second extend are you referring to? What function doesn't take a second parameter? Could you share a specific line of code that you're facing the issue?
last guy said "You could remove the Subscription retrieval request and expand subscription.latest_invoice in your Subscription Schedule creation request
Otherwise lgtm" when I asked him if I'm doing anything extra or redunant
I don't see any change in your code from my teammate's advice. I could still see stripe.subscriptions.retrieve is still present in your code. The expand: ['subscription.latest_invoice'] can be placed at stripe.subscriptionSchedules.create() to minimise the additional call to stripe.subscriptions.retrieve.