Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot finalize newly created invoice #173

Open
adrianlungu opened this issue Jan 27, 2021 · 3 comments
Open

Cannot finalize newly created invoice #173

adrianlungu opened this issue Jan 27, 2021 · 3 comments

Comments

@adrianlungu
Copy link

Hello,

In this specific flow, the finalize seems to be behaving slightly different than what Stripe is doing:

  1. Create invoice items for a specific customer: stripeClient.InvoiceItems.New(params)
  2. Create the new invoice for the customer: stripeClient.Invoices.New(params)
  3. Finalize the invoice in order for Stripe to attempt payment:
        finalizeParams := &stripe.InvoiceFinalizeParams{}
	finalizeParams.AddExpand("payment_intent")
	invoice, err := stripeClient.Invoices.FinalizeInvoice(newInvoice.ID, finalizeParams)

These are the logs outlining the described steps:

localstripe_1  | ::ffff:172.23.0.5 [27/Jan/2021:20:14:54 +0000] "POST /v1/invoiceitems HTTP/1.1" 200 635 "-" "Stripe/v1 GoBindings/69.3.0"
localstripe_1  | ::ffff:172.23.0.5 [27/Jan/2021:20:14:54 +0000] "POST /v1/invoices HTTP/1.1" 200 3156 "-" "Stripe/v1 GoBindings/69.3.0"
localstripe_1  | ::ffff:172.23.0.5 [27/Jan/2021:20:28:34 +0000] "POST /v1/invoices/in_83vIseHK26CYkd/finalize HTTP/1.1" 404 172 "-" "Stripe/v1 GoBindings/69.3.0"
backend_1      | 2021/01/27 20:14:54 logger.go:34: create proration invoice error:  Couldn't deserialize JSON (response status: 404, body sample: '404: Not Found'): invalid character ':' after top-level value
localstripe_1  | ::ffff:172.23.0.5 [27/Jan/2021:20:28:34 +0000] "POST /v1/invoices/in_83vIseHK26CYkd/void HTTP/1.1" 400 253 "-" "Stripe/v1 GoBindings/69.3.0"

We attempt to void the invoice in case anything goes wrong, but that also returns a 404.

Am I understanding correctly that localstripe currently finalizes the invoice during the creation process ? I.e. in POST /v1/invoices ?

Thanks!

@H--o-l
Copy link
Collaborator

H--o-l commented Jan 28, 2021

Hey @adrianlungu !

Thanks for using localstripe!

From the 404 you see on /invoice/id/finalize I'd say it's because the route doesn't exist.
You can see existing routes for invoices here and here:

for cls in (Charge, Coupon, Customer, Event, Invoice, InvoiceItem,
PaymentIntent, PaymentMethod, Plan, Product, Refund, SetupIntent,
Source, Subscription, SubscriptionItem, TaxRate, Token):
for method, url, func in (
('POST', '/v1/' + cls.object + 's', api_create),
('GET', '/v1/' + cls.object + 's/{id}', api_retrieve),
('POST', '/v1/' + cls.object + 's/{id}', api_update),
('DELETE', '/v1/' + cls.object + 's/{id}', api_delete),
('GET', '/v1/' + cls.object + 's', api_list_all)):
app.router.add_route(method, url, func(cls, url))

extra_apis.extend((
('GET', '/v1/invoices/upcoming', Invoice._api_upcoming_invoice),
('POST', '/v1/invoices/{id}/pay', Invoice._api_pay_invoice),
('POST', '/v1/invoices/{id}/void', Invoice._api_void_invoice),
('GET', '/v1/invoices/{id}/lines', Invoice._api_list_lines)))

The /invoice/id/void route does exist so that is probably another issue.

To add a new route to localstripe, contributions are welcomed ;-).
If you want to contribute you can start here:
https://github.com/adrienverge/localstripe/tree/591f3b5a62eccfbe86ac24a2b937dc047a46095a#hacking-and-contributing

About when localstripe changes invoice state, the best I can tell you is to go and try to look here:

@property
def status(self):
if self._draft:
return 'draft'
elif self._voided:
return 'void'
elif self.total <= 0:
return 'paid'
elif self.payment_intent:
pi = PaymentIntent._api_retrieve(self.payment_intent)
if pi.status == 'succeeded':
return 'paid'
elif pi.status == 'canceled':
return 'void'
return 'open'

Two quick things about localstripe:

  • Features exist only thanks to the contributions of peoples that needed them.
  • There is no documentation, but we carefully code and review PR with the goal to have a self-explanatory code. If you need an implementation detail, reading the code is the best place.

@adrianlungu
Copy link
Author

Hey @H--o-l ,

Thanks for the quick reply and the insight into the project.

I took a look but it seems this might be a bigger change than I anticipated initially.

I'm not sure if I'm reading the code properly here:

return cls._get_next_invoice(

But it seems that the current flow of invoice creation is tied to subscriptions, there's no way to create a one-off invoice similar to how Stripe supports this.

Please let me know if I'm wrong.

@H--o-l
Copy link
Collaborator

H--o-l commented Jan 28, 2021

But it seems that the current flow of invoice creation is tied to subscriptions, there's no way to create a one-off invoice similar to how Stripe supports this.

I haven't look inside this code for a while so I don't want to be too affirmative on it, but it is also what I think.

If it's true, and it seems it is, maybe it's still possible to adapt the code to handle one-time invoices but what will require some work indeed.
At least objects can be re-use so maybe it's a reasonable workload. I let you see if you think it's doable or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants