#devangbhuva97-invoice
1 messages ยท Page 1 of 1 (latest)
having a look
I think it's because you're creating the Invoice too soon, like you call the Invoice create API before the InvoiceItem create API has finished. Are you doing this in parallel with threads or something?
this ~shoudn't happen if you do the creation in sequence like
await stripe.invoiceItems.create({
...
});
let invoice = await stripe.invoices.create({
...
});
``` where you only start the API call for create the Invoice after the invoice create call is finished
Not doing in parallel. But as per time show in logs, invoice create request is after invoice create item!
Not sure when 1st request was completed. Maybe as your guess, it's not completed & next request started!
yeah that 's what I think at least, the firs one hadn't finished
thanks @cloud schooner for looking into this
but that shouldn't happen since you shouldn't have gotten an API response before it completed so you couldn't have started the create Invoice call. I think unfortunately it can happen sometimes
the better way to do this is to use exclude behaviour (https://stripe.com/docs/api/invoices/create#create_invoice-pending_invoice_items_behavior) and then add the invoice items to the draft invoice itself using https://stripe.com/docs/api/invoiceitems/create#create_invoiceitem-invoice , it avoids this whole problem with pending items having to be created first
in the latest API version that is the default since it works better, but the docs are not updated properly yet
I'm closing this thread, but if there are additional questions or anything else that we can assist with, then please let us know in #dev-help. ๐
@twilit scaffold
Yesterday I raised one issue. Today I have some data points for that
api_version:Aug 27, 2020 @ 05:30:00.000 account:acct_1Ihw53CScnf89tZo idempotency_key:stripe-node-retry-1befb0f9-0b5b-4812-b34f-ed9956c915fe method:POST path:/v1/invoiceitems status:200 request_id:req_8vt7LU7uBp5Cq4 elapsed:367 request_start_time:1,661,502,663,631 request_end_time:1,661,502,663,998 namespace:stripe action:api_response timestamp:Aug 26, 2022 @ 14:01:03.998 _id:jwlG2YIBLP4p6pEjrSVR _type:_doc _index:payments-logs-2022-08-26 _score: -
api_version:Aug 27, 2020 @ 05:30:00.000 account:acct_1Ihw53CScnf89tZo idempotency_key:stripe-node-retry-ee716ed6-eacd-49e1-a3aa-ee42cafc879b method:POST path:/v1/invoices status:400 request_id:req_DbZnx9kOB56EWL elapsed:279 request_start_time:1,661,502,664,011 request_end_time:1,661,502,664,290 namespace:stripe action:api_response timestamp:Aug 26, 2022 @ 14:01:04.290 _id:zP9G2YIBch4dH3Qkrld2 _type:_doc _index:payments-logs-2022-08-26 _score: -
Invoice create request started after first request completed but still getting error
Can you share your code which invokes those API calls?
secretKey: string,
params: Stripe.InvoiceItemCreateParams,
options?: Stripe.RequestOptions
): Promise<Stripe.InvoiceItem> {
this.logStripeInfo(params, options, 'createInvoiceItems')
try {
const invoiceItems = await this.stripe(secretKey).invoiceItems.create(params, options)
return invoiceItems
} catch (error) {
this.logStripeError(error, 'createInvoiceItems')
throw error
}
}
async createInvoiceLink() {
const location_currency = location.country ? currencyCode[location.country] : 'USD'
await Promise.all(
body.items.map((item) => {
const itemPrice = amountInSmallestCurrency(Number(item.price), location_currency)
totalInvoiceAmount = currencyJS(totalInvoiceAmount).add(itemPrice).value
const data = {
customer,
currency: location_currency,
description: item.name,
unit_amount_decimal: itemPrice.toString()
}
return this.createInvoiceItems(secretKey, data, stripeOptions)
})
)
const invoice = await this.createInvoice(secretKey, data, stripeOptions)
}```
this is part of our code
I suspect your code isn't executing as you expect it is, the createInvoice seemingly isn't waiting for your Promise.all to resolve. I think you need to make your .map async:
await Promise.all(
body.items.map(async (item) => {
const itemPrice = amountInSmallestCurrency(Number(item.price), location_currency)
totalInvoiceAmount = currencyJS(totalInvoiceAmount).add(itemPrice).value
const data = {
customer,
currency: location_currency,
description: item.name,
unit_amount_decimal: itemPrice.toString()
}
return await this.createInvoiceItems(secretKey, data, stripeOptions)
})
)
but logically it should works.... because map will return array of promise & promise.all will resolve it
& as per logs, it is executing right as well
can you check above logs which I shared
In this quick example, we'll learn how to use Promise.all() with Async/Await in JavaScript
You need to make your .map async
Please try it ๐
Ok.. let me check it
Thanks
Hey @tardy tinsel
Reason for not getting expected result in blog is await
If you will add await in Promise.all, you will get expected result
it means - our code should working fine
so can you please check below details
req_8vt7LU7uBp5Cq4 -> completed on 1,661,502,663,998 &
req_DbZnx9kOB56EWL -> started on 1,661,502,664,011
as per stripe logs
Those aren't timestamps returned by our API, its just the time your function call ended. It doesn't really mean anything
Did you try making .map async?
this issue is not for every time.. I won't able to test by doing that code change
Is there only 1 invoice item in this example? Or are you expecting multiple?
yes.. there is only 1 invoice item in example
Even if you see, yesterday we removed async await in map... after discussed with your team member. I had doubt that it's require return.. but still this issue is not fixed
as I said yesterday the best solution is going to be not using the pending invoice item behaviour and using the new draft invoice and adding items to that
the pending invoice item integration has lots and lots of problems and what you're seeing(a race condition) is not uncommon, it's why we built a new integration since we had a lot of problems with it
yes.. that I agree but we can not immediate migrate everything... even I raised couple of race conditions for previous approach & that time this new API was not exist!
cool, well that's the solution anyway
if you want to just make small changes to existing code all I can really suggest is doing something hacky like sleeping the code for e.g. 3 seconds before creating the invoice after creating the items.
๐
What is guarantee that new flow will work fine? Because there is also race condition..
After creating invoice, if I will create multiple invoice items & after that I will finalize invoice. So is there any chance that any invoice item missed in invoice?
Because same issue we are facing right now... even after successfully request completed, your system won't able to get invoice item
it should work
Really I didn't expect that - stripe team will provide this type of solution ๐ - migrate in to new api without checking anything