#ninjajinja_code
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/1299363296964644898
đ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- ninjajinja_code, 1 hour ago, 8 messages
- ninjajinja_code, 1 day ago, 16 messages
- ninjajinja_code, 3 days ago, 15 messages
subscription Id
sub_1QDhj5GA5TYWMni87Fk83tt1
complete function
``
const stripeSubscription = await stripe.subscriptions.retrieve(
dbSubscription.subscriptionId as string
);
if (newNfts.length > 0) {
const chargeAmount = newNfts.length * 9500;
await stripe.invoiceItems.create({
customer: stripeSubscription.customer as string,
amount: chargeAmount,
currency: "usd",
description: `Charge for ${newNfts.length} new NFT(s)`,
});
const invoice = await stripe.invoices.create({
customer: stripeSubscription.customer as string,
auto_advance: true,
collection_method: "charge_automatically",
});
await stripe.invoices.pay(invoice.id);
}
const { updatedSubscription, priceId, quantity } =
await updateStripeSubscriptionQuantity(stripeSubscription, nfts);
const subscriptionSchedule = await isSubscriptionScheduleCreated(
updatedSubscription.schedule as string
);
await updateStripeSubscriptionSchedule(
subscriptionSchedule.id,
subscriptionSchedule.phases[0]?.start_date,
priceId,
quantity
);
await handlePaymentMethodUpdate(stripeSubscription.id, setupIntentId);
const updatedSub = await updateLocalSubscriptionStatus(
subscriptionId,
updatedSubscription.status,
nfts
);
return {
success: true,
message: "Subscription updated successfully",
subscription: updatedSub,
};
}```
Can you explain more about what the unexpected thing happening here is?
amount due should be 190 but comes out to be $379.91
since they have aready paid 190 $
next moth they should be paying 190$
why they are being charged 379.91
its bit confusing
Recommend reading: https://docs.stripe.com/billing/subscriptions/prorations
By default when you update a subscription, we prorate the update, and prorations are charged on the next invoice
but we set prorations to none
scheduleId: string,
scheduleStartDate: number,
price: string,
quantity: number
): Promise<Stripe.SubscriptionSchedule> {
const now = new Date();
const currentQuarterEnd = endOfQuarter(now);
const nextQuarterStart = addDays(currentQuarterEnd, 1);
// Get the next quarter start date as a Unix timestamp (in seconds)
const endDateInSeconds = getUnixTime(nextQuarterStart);
return stripe.subscriptionSchedules.update(scheduleId, {
phases: [
{
start_date: scheduleStartDate,
end_date: endDateInSeconds,
items: [
{
price,
quantity, // Ensure correct quantity is set
},
],
proration_behavior: "none",
},
{
billing_cycle_anchor: "phase_start",
items: [
{
price,
quantity, // Set quantity for the next phase as well
},
],
proration_behavior: "none",
},
],
});
}```
while creatng Sub
stripeCustomerId: string,
priceId: string,
nfts: number[],
dbSubscriptionId: string,
dbUserId: string
) {
return stripe.subscriptions.create({
customer: stripeCustomerId,
items: [{ price: priceId, quantity: nfts.length }],
payment_settings: {
payment_method_types: ["card", "paypal"],
save_default_payment_method: "on_subscription",
},
payment_behavior: "default_incomplete",
expand: ["latest_invoice.payment_intent", "schedule"],
metadata: {
userId: dbUserId,
subscriptionId: dbSubscriptionId,
nfts: JSON.stringify(nfts),
},
proration_behavior: "none",
collection_method: "charge_automatically",
});
}
```\
Prorations aren't set globally
They're set on a per-request basis
You didn't set it on the update request
So, the default behavior of create prorations is used
* Updates the quantity and metadata of a Stripe subscription
*
* @param stripeSubscription - The Stripe subscription object to update
* @param nfts - Array of NFT IDs to be included in the subscription
* @throws {ServiceError} If price ID or quantity is missing from the updated subscription
* @returns {Promise<{
* updatedSubscription: Stripe.Subscription,
* priceId: string,
* quantity: number
* }>} Updated subscription details
*/
export async function updateStripeSubscriptionQuantity(
stripeSubscription: Stripe.Subscription,
nfts: number[]
) {
const updatedItemParams = stripeSubscription.items.data.map((item) => ({
id: item.id,
quantity: nfts.length,
metadata: { nfts: JSON.stringify(nfts) },
}));
const updatedSubscription = await stripe.subscriptions.update(
stripeSubscription.id,
{ items: updatedItemParams }
);
const { priceId, quantity } = getSubscriptionDetails(updatedSubscription);
if (!priceId || !quantity) {
Logger.error(
`Missing price ID or quantity for subscription ${updatedSubscription.id}`
);
throw new ServiceError({
code: "PriceId_Or_Quantity_Missing",
message: "subscription price id or quantity missing",
});
}
return { updatedSubscription, priceId, quantity };
}```
so here as well I would need to set prorations to none? @lethal cloak
If the behavior you're trying to achieve is to disable prorations, then yeah
But I recommend reading that doc I sent you before doing anything else
So you understand what you're building
I will run you through it
we have a cut off date if a user want to add some more seat before that date we create a invoice charge so eg if a seat is 15 $ and they add 2 more we would charge them 30 $ and then the next cycle would charge them 45 $\
Please read the doc though
It's not good to build a subscription integration if you don't understand how our prorations work
That's how you end up in trouble with unexpected behavior you didn't anticipate
But to achieve what you want, it sounds like you need to disable prorations
And charge them an extra 30 in an invoice outside of the subscription
Because if you set proration_behavior to always_invoice, it will immediately charge you a prorated amount for those 2 extra seats
Again, recomend reading the doc so you understand