#sugam1469_api

1 messages ยท Page 1 of 1 (latest)

floral larkBOT
#

๐Ÿ‘‹ 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.

marsh narwhal
#

Hi, could you provide a bit more details please? What are you referring to by "child" and "parent" here?

scarlet mulch
#

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

marsh narwhal
#

Are you creating Invoices or Subscriptions?

scarlet mulch
#

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

marsh narwhal
#

When you create a Subscription, the first Invoice is created automatically, you don't need to create it manually.

floral larkBOT
random tendon
#

๐Ÿ‘‹ taking over for my colleague. Let me know if there's any follow-up Qs I can answer!

scarlet mulch
random tendon
#

what are you trying to achieve please?

#

would you mind describing the use case?

scarlet mulch
#

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

random tendon
#

would you mind sharing the subscription ID or the invoice ID to look at it?

scarlet mulch
#

invoice id: in_1PiBzYClpZRGdmb0cMqlJ2jz

random tendon
#

give me a second please

scarlet mulch
#

in finalizedinvoice before paidinvoice im getting status as paid

#

ok

random tendon
scarlet mulch
#

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?

random tendon
#

so that you can add as many invoice items as you want before it gets finalized

scarlet mulch
#

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

random tendon
scarlet mulch
#

still got same response

#

errors
:
"Invoice is already paid"

random tendon
#

what's the new invoice ID?

scarlet mulch
#

in_1PiC9rClpZRGdmb0FoToql4P

random tendon
#

taking a look please give me a moment

scarlet mulch
#

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,
});
random tendon
#
      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

scarlet mulch
#

didn't work

#

still same issue

random tendon
#

did you add it for both invoices?

#

please share both parent and child invoice IDs

scarlet mulch
#

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

floral larkBOT
scarlet mulch
#

in_1PiCjUClpZRGdmb04NQqu8tV

random tendon
#

when you create the second invoice advanceInvoice you're not including the invoice item advPaymentInvoiceItem

scarlet mulch
#

where should i add it

restive owl
#

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.

scarlet mulch
#

how can i fix it?

restive owl
#

use a different/fresh Customer or set the balance of this customer to $0

scarlet mulch
#

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

restive owl
scarlet mulch
#

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);
  }
});
restive owl
#

probably

scarlet mulch
#

how can i fix it?

restive owl
#

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.