#sugam1469_api
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/1267764446516875358
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi, could you provide a bit more details please? What are you referring to by "child" and "parent" here?
parent is the existing customer
and he make the new subscription for his new child
this is the part of my code
where i have made seperate invoice each time but if exisiting customer then it will return invoice already paid as response
Are you creating Invoices or Subscriptions?
firstly invoice is created and when the invoice is paid subscription is created
but while creating a new invoice with existing customer i got invoice already paid in response
When you create a Subscription, the first Invoice is created automatically, you don't need to create it manually.
๐ taking over for my colleague. Let me know if there's any follow-up Qs I can answer!
so to make it manually in here what should i do
while manually creating invoice for the existing customer
for the second subscription im getting invoice already paid in response
but im creating seperate invoices but also im getting invoice already paid without paying it
would you mind sharing the subscription ID or the invoice ID to look at it?
give me a second please
since this API version https://docs.stripe.com/upgrades#2022-08-01 (you're using a newer API version) when you create an invoice, it won't include any pending invoice items
const advanceInvoice = await stripePayment.createInvoice(customer.id, {
user_id: user.id,
customer: customer.id,
branch_id: branch_id,
child_id: input.child_id,
});
const advPaymentInvoiceItem = await stripePayment.createInvoiceItem(
customer.id,
admission_fee,
advanceInvoice.id
);
here the second function should be above the first one?
basically you need to do this https://docs.stripe.com/invoicing/integration#:~:text=If you set,API%3A
so that you can add as many invoice items as you want before it gets finalized
createInvoiceItem = async (
customer_id: string,
price: string,
invoice_id: string
) => {
const invoiceItem = await stripe.invoiceItems.create({
customer: customer_id,
price: price,
invoice: invoice_id,
currency: "usd",
});
return invoiceItem;
};
have done this
I meant you need to set auto_advance to false https://docs.stripe.com/api/invoices/create#create_invoice-auto_advance
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
what's the new invoice ID?
in_1PiC9rClpZRGdmb0FoToql4P
taking a look please give me a moment
let's try the following:
- create the invoice items without passing the invoice ID first,
- the create the invoice and set https://docs.stripe.com/api/invoices/create#create_invoice-pending_invoice_items_behavior to 'include'
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
no got same issue
createInvoiceItem = async (
customer_id: string,
price: string,
invoice_id?: string
) => {
const invoiceItem = await stripe.invoiceItems.create({
customer: customer_id,
price: price,
invoice: invoice_id,
currency: "usd",
});
return invoiceItem;
};
createInvoice = async (customer_id: string, metadata: any) => {
const invoice = await stripe.invoices.create({
customer: customer_id,
currency: "usd",
auto_advance: false,
collection_method: "charge_automatically",
metadata: metadata,
pending_invoice_items_behavior: 'include'
});
return invoice;
};
const advPaymentInvoiceItem = await stripePayment.createInvoiceItem(
customer.id,
admission_fee,
// advanceInvoice.id
);
const advanceInvoice = await stripePayment.createInvoice(customer.id, {
user_id: user.id,
customer: customer.id,
branch_id: branch_id,
child_id: input.child_id,
});
customer: customer_id,
price: price,
invoice: invoice_id,
currency: "usd",
});
return invoiceItem;
};```
you shouldn't pass the invoice ID since it hasn't been created yet
const advanceInvoice = await stripePayment.createInvoice(customer.id, { user_id: user.id, customer: customer.id, branch_id: branch_id, child_id: input.child_id, });
when you create this invoice you need to do the same as the first one which means you need to add
pending_invoice_items_behavior: 'include'
btw you don't need auto_advance: false in this scenario since you're already creating all the invoice items before creating the invoice
here user_id is parent id and child_id is child id
a single invoice is generated for both parent and child
child_id is in the metadata of invoice
in_1PiCjUClpZRGdmb04NQqu8tV
when you create the second invoice advanceInvoice you're not including the invoice item advPaymentInvoiceItem
where should i add it
the problem is not about invoice items(those are being included and work as normal), it's because the Customer you're using has a large credit balance that reduces the invoices to $0.
how can i fix it?
use a different/fresh Customer or set the balance of this customer to $0
its same for all customer
in first subscription there will not be customer so it is working fine but in second subscription with the same customer id it is saying invoice already paid
although im creating seperate invoices
then you should check what you're doing that leads to the customers getting large balances like this, I'd suggest you debug carefully using the Dashboard and the docs https://docs.stripe.com/billing/customer/balance
i think its because of proration
createSubscription = (
plans: string[],
metadata: object,
customerId: string,
payment_method_id: string,
coupon_code?: any,
) =>
new Promise(async (resolve, reject) => {
try {
const now = new Date();
const utcYear = now.getUTCFullYear();
const utcMonth = now.getUTCMonth();
// Calculate the Unix timestamp for the 1st day of the current month in UTC
const firstDayOfMonth = new Date(Date.UTC(utcYear, utcMonth, 1));
const billingCycleAnchor = Math.floor(firstDayOfMonth.getTime() / 1000);
const nextMonth = new Date(Date.UTC(utcYear, utcMonth + 1, 1));
const nextbillingCycleAnchor = Math.floor(nextMonth.getTime() / 1000);
const daysInMonth = new Date(utcYear, utcMonth + 1, 0).getDate();
const daysUntilEndOfMonth = (daysInMonth - now.getUTCDate()) + 1;
const pricePromises = plans.map((planId) => stripe.prices.retrieve(planId));
const priceDetails = await Promise.all(pricePromises);
const baseAmount = priceDetails.reduce((total, price) => total + price.unit_amount, 0) / 100;
let discountAmount = 0;
let proratedAmount = 0;
if (coupon_code) {
// Fetch the coupon details from Stripe
const coupon = await stripe.coupons.retrieve(coupon_code);
if (coupon.amount_off) {
discountAmount = coupon.amount_off / 100;
} else if (coupon.percent_off) {
discountAmount = (coupon.percent_off / 100) * baseAmount;
}
proratedAmount = (daysUntilEndOfMonth / daysInMonth) * (baseAmount - discountAmount);
} else {
proratedAmount = (daysUntilEndOfMonth / daysInMonth) * 300;
}
const creditBalance = proratedAmount ? baseAmount - proratedAmount : 0;
here the credit balance of user is calculated and transferred to next month
if(discountAmount){
await stripe.invoiceItems.create({
customer: customerId,
amount: discountAmount * 100,
currency: 'usd',
description: 'Discount Amount',
});
}
const subscriptionItems = {
customer: customerId,
coupon: coupon_code,
items: plans.map((plan) => {
return { price: plan };
}),
metadata: {
...metadata,
credit: creditBalance ? creditBalance.toFixed(2) : 0,
},
default_payment_method: payment_method_id,
billing_cycle_anchor: nextbillingCycleAnchor,
backdate_start_date: billingCycleAnchor,
};
stripe.subscriptions
.create(subscriptionItems)
.then((subscription: any) => {
return stripe.customers.update(customerId, {
balance: -Math.round(creditBalance * 100),
}).then(() => subscription)
})
.then((subscription: any) => {
resolve(subscription);
})
.catch((err: any) => {
reject(err);
});
} catch (e) {
reject(e);
}
});
probably
how can i fix it?
depends what fix you want
like this is the normal default behaviour. I pay you $100 upfront for a subscription, later I change to a cheaper $10 plan, so I get a refund to my credit balance of the difference(the proration), and I can use that balance so that future payments (like the second subscription) are reduced.
if you don't want that, consider options like disabling proration or clearing the balance manually.