-
Notifications
You must be signed in to change notification settings - Fork 432
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
How to delete a price using API #658
Comments
@moskrc The Price API does not support deletion today. You should instead set |
@remi-stripe On this topic, if you don't delete a price, which has been added to a product, you get an error deleting the product.
Should we just be setting products to inactive too, rather than deleting them? |
Yes we recommend keeping your object so that it can help with future reconciliations. |
@remi-stripe It doesn't make any sense to be able to delete an unused product and not be able to delete an unused price. It's also not logical that we can delete a price in the Stripe panel but not through the API. You should enable this at least in the development mode where we are adding a lot of dummy data and want to clear some of it after testing. The only option here is to delete all test data from the Stripe panel. |
@sasokovacic I agree but in the future we want to remove the ability to delete object and instead default to marking them as inactive and make them hidden. The Prices API is a newer API and replaces the Plans API. Plans could be deleted though so we had to support deletion in the Dashboard for backwards compatibility. If we had removed it, we'd have broken thousands of integrations that expect this flow to works in the Dashboard. Overall though, we are moving away from it and will, in the (far) future, disable this feature. For newer integrations, deleting a Price is something we don't want to directly support which is why you can't do it in the API |
@remi-stripe I know this is OT for stripe-python but IMO Stripe should consider allowing deletion of prices that haven't been used anywhere. Especially for users doing most of their business directly from the dashboard (eg. using Stripe purely as an invoicing platform), mistakenly creating prices can happen and if no related invoice has been issued, it ought to be fine to delete. |
@jleclanche It's really confusing when an API fails in almost all cases though. Being able to delete a Price never used but not delete another Price is a pit of failure for a developer to discover. And FWIW We do allow this in the Dashboard already for that reason. |
@remi-stripe what is the reasoning behind this decision? What is so problematic about deleting unused records? It's the most basic functionality in any application. When I build apps for businesses, I always implement soft deletion, but they are also able to hard delete data that doesn't have any value in the system. This is how you enable users to clean up the database frequently and consistently. |
@sasokovacic It's related to what I mentioned. You would think you can delete all prices but later discover you can only delete unused prices for example. And if you support price deletion, then in the API you get a truncated version of the object that only returns the |
I've just stumbled across this issue as I'm working on the "product and price" creation bit of a Stripe integration for someone right now (JS SDK in Node.js but applies just the same, and this issue came up top in Google search). It really makes no sense to me why the "..." menu against a price in the dashboard (the web UI) allows users to "Delete price" but I cannot do the same from the API. Also, loosely related, I was surprised I could create products and specify the product Something definitely doesn't sit right here. I was expecting consistency and parity from Stripe across all levels of the UX/DX, given how focussed you are on API / developer first (or at least as far as I understood you were). It just feels a bit curiously incongruous. 🤷 Developers just learning your platform will be thrashing about, in both test and production environments, so I think it's only natural to be able to fix our mistakes by deleting unused and misconfigured objects while we experiment... especially when those experiments are programs / scripts that we're writing to "initialise" our Stripe environments. |
@remi-stripe from my experience deletion/soft-deletion is the most basic and most common functionality these days. Also, there is a difference between archived, soft-deleted, and hard-deleted status. IMO Stripe should have at least the first two available through its API. As for truncated objects, you don't have to return them. There is no need for this. You only return active objects by default. Archived and soft-deleted objects can be retrieved explicitly using some parameter or different URI. In the end, it's your decision. I'm just sharing my experiences building many business apps. Some businesses require hard deletion, but most of them require soft-deletion which means these records are not visible anywhere in the app except in some special view for troubleshooting purposes. |
I will second the comments from Quintin and sasokovacic. I just ran into this myself when attempting to use the API to completely automate some testing our accounting team is doing --- in the test area! Lo and behold I can't use the API to clean up a bunch of test prices, and, well, that really stinks. I see zero reason why deleting prices via the API should be blocked from the test environment. Second, I even feel that in the production area, it should be allowed as well via API. First, it's the end user's data, and if they make a mistake and want it GONE, that should be their choice. Since people (and especially accountants -- haha!) make mistakes a lot, and since there are numbers involved and the potential for fat-fingering, a good UX for an API-centric product like Stripe is supposed to be would allow this --- or at least give the user the ability to enable such a 'feature' themselves. It's fine if Stripe wants to think that they need to hold everyone's hand on everything, but you don't. If you want to have a default mode where it is disabled, fine, but give us the ability to enable it and use it if we know what we're doing. And we do. Just food for thought. Thanks for reading. |
One reason is that if we didn't block it, you'd build your entire integration thinking it will just work in Live mode only to discover you're down the day you deploy to production. Consistency between Test mode and Live mode is quite crucial for patterns like this and we do our best to approach it this way when we can As for the second part of your comment, I don't disagree conceptually but we used to support deletion on the Plan API and I have helped countless developers over the years try to recover from deleting the wrong Plan, re-creating a new Plan with the same id and then being thoroughly confused why 2 subscriptions on the "same plan id" had a different amount charged, etc. There is a lot more to it than just deleting to suppress a mistake and over the years as business grows there is a higher cost than you would expect to supporting real deletion in the API. |
@remi-stripe thats why I suggested soft-deletion. This is how you prevent users from doing hard-deletion mistakes and they can do a recovery when they soft-delete something. This is what businesses mostly require from my experiences. Soft-delete should be the default behaviour. As for hard-delete, I agree with pm-bc. Users should be able to remove all their content from the platform if they want. But it should be done explicitely which means you should send some extra parameter in the request or use different URI. |
@remi-stripe If you monitoring feedback, please, check these real-world examples.
The main reason of all problems like that is that you do not use your soft by yourselves in real world and do not want to notice the obvious things that make working with your application very difficult. |
@kg69design Thanks for the feedback, we'll see if we can make improvements to the Dashboard to make those flows better. |
Looks like you should read up on db constraints @remi-stripe. Things that are unused should be deletable, things that are in use can only be made inactive. It's worked for relational DBs since the 60s. I know you don't care, you just want to make one of your pain points be someone else's pain point and you have succeeded in doing exactly that. |
Also, whenever you want to test a certain product during development, you might want to delete it later on so it doesn't clutter everything up. I run into a lot of situations were I quickly create a new product to test the integration of my API with stripe, then have to manually delete it later. |
Addendum about Price object usage. It's not just the usage in active Subscriptions which will make it undeletable. I noticed creating new Invoices from within the dashboard will create a "one-time" interval Price object. Also you can accidentally create the same price value twice in two objects (if you manually enter the value amount rather than select from dropdown in Product selection). Once this price_id gets used in a finalized Invoice, now it's basically undeletable because it is used in 1 transaction. As invoices can never be removed, and now it's part of that transaction history. Can only archive and ignore clutter in Dashboard. Not part of any active Subscriptions at all. I fully understand the necessity to keep these objects around for the transaction history of an invoice (which is meant to be eternal). Hoping we can get a more ignore/soft delete type feature, as long as the Price object is removed from any active transactions and its only existence is in old invoices like these. As sometimes we literally do not need the Price object anymore (and possibly created in err or in testing), and the only thing it does is clutter lists in Dashboard as archived and requires being filtered out in list calls to API as well (even though that is fairly simple to handle as well, by default it would be listed though). |
Would not mind a truncate feature for all the data in test mode
…On Thu, Sep 23, 2021 at 2:21 PM Nicholas Schell ***@***.***> wrote:
Addendum about Price object usage. It's not just the usage in active
Subscriptions which will make it undeletable. I noticed creating new
Invoices from within the dashboard will create a "one-time" interval Price
object. Also you can accidentally create the same price value twice in two
objects (if you manually enter the value amount rather than select from
dropdown in Product selection). Once this price_id gets used in a finalized
Invoice, now it's basically undeletable because it is used in 1
transaction. As invoices can never be removed, and now it's part of that
transaction history. Can only archive and ignore clutter in Dashboard. Not
part of any active Subscriptions at all.
I fully understand the necessity to keep these objects around for the
transaction history of an invoice (which is meant to be eternal). Hoping we
can get a more ignore/soft delete type feature, as long as the Price object
is removed from any active transactions and its only existence is in old
invoices like these. As sometimes we literally do not need the Price object
anymore (and possibly created in err or in testing), and the only thing it
does is clutter lists in Dashboard as archived and requires being filtered
out in list calls to API as well (even though that is fairly simple to
handle as well, by default it would be listed though).
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#658 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AENX3UMFOMAGVHLB5CXNGDLUDN42RANCNFSM4NKC4RLQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Truncate test data or bulk deletion/update active state would be very helpful |
Deleting a price should be in any environment. There are many reasons a delete should be implemented. If users want to delete them, allow it, it's their choice if they want to delete or archive them. |
If deletion of prices is impossible, perhaps then listing all prices should by default be However, I can see how such a change in the API could break applications that use archived prices differently than me, so perhaps developers that do not want to see archived prices in lists should just always use active=true in their API requests to filter out inactive prices. |
In my case, I just wanted to migrate form Because you seem to force setting Now, please force that kindly on us developers, you ask "how?", well, like whenever we call |
I think @top-master you have been fooled into thinking they care, based on the way this is STILL broken after a full year, it is obvious, they don't |
@boatcoder that's a pretty surprising comment. We do care, we listen to feedback, we explain our thought process and we also try to clarify why we do things a certain way. We've built dozens of features based on feedback from developers here, on public mailing list, on our Discord server or to support. We won't be able to build everything though and we don't always agree that something should be built or designed in a certain way. For example we disagree that deleting should not delete and subtly marked it as inactive but still existing. It's not wrong, but it's also not how deletion has worked historically in our API. That definitely doesn't mean we don't care and that we don't listen. |
So if you do care, why can I not delete a price that hasn't been used by
anything? Why can I not delete a product (that has never been used)
because it has a price I can't use? I could see preventing this deletion
because of FK references, but even in my DB, I can remove all the things
that reference something or pass CASCADE to the deletion to make things go
away for real.
The fact that someone else had a problem after they deleted their prices
prevents me from deleting test prices (that are unused) seems ludicrous at
best.
If you truly want to make it easier for developers, maybe you shouldn't
handcuff so tightly. Enforce consistency just like SQL has been doing
since the 60s, everyone should understand that model if they are a
developer. These jagged edges that exist in the stripe test mode world are
pain points for us and more than a year after this has been reported and
echoed by lots of people, it's still busted.
That's what I call neglect, not care.
…On Thu, Apr 7, 2022 at 9:52 PM remi-stripe ***@***.***> wrote:
@boatcoder <https://github.com/boatcoder> that's a pretty surprising
comment. We do care, we listen to feedback, we explain our thought process
and we also try to clarify why we do things a certain way. We've built
dozens of features based on feedback from developers here, on public
mailing list, on our Discord server or to support.
We won't be able to build everything though and we don't always agree that
something should be built or designed in a certain way. For example we
disagree that deleting should *not delete and subtly marked it as
inactive but still existing*. It's not wrong, but it's also not how
deletion has worked historically in our API.
That definitely doesn't mean we don't care and that we don't listen.
—
Reply to this email directly, view it on GitHub
<#658 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AENX3UOWVIOVZYDYWCCOT3LVD6NOJANCNFSM4NKC4RLQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Yes. With an appropriately worded error message, and a note in the documentation, I find it extremely unlikely that any developer capable of using the Stripe APIs would be confused by this. For example: "Prices can only be deleted if they have not been used by any payments." On the other hand, here in this thread, we have dozens of developers who have already been confused by the fact that you can't delete a price.
Well clearly we already have lots of developers here who have thought to use this in production, actually written code to use Price.delete(), and already discovered the hard way that it doesn't work. There are a lucky few who have stumbled upon this thread, but likely many others who are just left confused as to why Product has a delete method, but Price doesn't. I really don't see how making it only work in test mode, or in both test and production mode but only when the price object has not been used, could make the situation any more confusing or irritating than it currently is. |
I'm sorry, but the absence of a Price Delete API means no one can go to production thinking it exists and discover the hard way it doesn't. On the other hand, if the method did exist but had the limitation you're all discussing, then the majority of developers would discover this the hard way in production when suddenly deletion (which they thought would just work) errors. I understand the frustration, and I don't disagree with the ask to simply support real deletion (whether the Price is used or not). I disagree though that just supporting this in the API with a clear error is a good developer experience. |
No problem, since Stripe doesn't seem to care to listen to feedback from its own customers, I have decided to switch my integration to PayPal and Square Payments over the long term, so this won't be an issue for me. |
^ What Matt said. It is, well, insane that Stripe can't do something
crazy-obvious here, as so many of us have alluded to.
The simplest answer of all would be to add either an "Opt-in" to the
ability to delete via API - for all environments - or an "Opt-out", as the
case may be.
To hamstring developers like Stripe is doing is uncalled for.
But Stripe hasn't listened to us up to now, so I doubt they will in the
future. It's also why I refuse to ever work for 'big' companies ever again
and have thrown myself into the startup world and am loving it. We don't do
inexplicable things like this in the startup world.
…On Mon, Feb 13, 2023 at 3:27 PM Matthew Lloyd ***@***.***> wrote:
No problem, since Stripe doesn't seem to care to listen to feedback from
its own customers, I have decided to switch my integration to PayPal and
Square Payments over the long term, so this won't be an issue for me.
—
Reply to this email directly, view it on GitHub
<#658 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APSDRV53OCVPR4ZKHQIVUQTWXKKJTANCNFSM4NKC4RLQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@remi-stripe You must be getting as frustrated with this discussion as the folks running into the issue are given it’s been active for two years now apparently. My take (that no one asked for):
I have a feeling that implementing the second point would alleviate the concerns of the majority of the folks here (including me; I just ran into this issue myself, leading me to this thread) while also meeting the needs you’ve articulated in the thread. Regardless, hope everyone’s having a good start to the week and let’s try not to gang up on Remi, folks. It can’t be fun for them either. |
@aral |
Not ideal, but one imperfect workaround to this issue – especially if your needs are simple – is to only ever create one price for any given currency and subscription period with a unit cost of 1. Then you can adjust the unit amount to whatever you like and never have to edit the price. I just remembered that I’m actually using this approach for our donation widget at Small Technology Foundation and it works great for our needs there. (We’re only using whole numbers there but I guess you could use it for any amount by setting the price to 0.01.) Again, not perfect and not useful for every use case but sharing it here since (a) I’m using it in production on at least one project and (b) it might help someone else out. I might actually end up using this technique for Domain also since people will be able to change the price of the subscription from their dashboards and I don’t want it to create an endless stream of prices and have to manage whether they’re active or not. |
Exactly the kind of unhelpful comment we don’t need, Robert. C’mon, now. Put yourself in their place and read your comment. How does it make you feel? |
@aral do you really think that all the comments after 2 years here helped anything to solve it? |
That's an idea and why some of exceptions are allowed in the Dashboard. The risk is that it's easy to think you can delete a Price after something like this and not realize it only works with unused Prices. But that's something we're considering.
It's a lot less common nowadays but years ago it was how many integrations were built when everything was still on the |
I just created hundreds of test prices by error in test mode and wanted to delete them after, only to get an error message and finding this issue. Not being able to delete TEST data is counter productive and insanely frustrating. I tried archiving the related products, but it does not archive the related prices and they still come up when I search for prices with stripe.Price.search(), even though their related products are archived. Guess I'm going to loop over all these prices objects now to set active = false on them :/ My point is, this is a TEST mode. I made an error, and I'm trying to fix it, but I can't and it's frustrating. |
This really should not even be a continuing conversation - and I'd refrained from posting recently, but that post above from TheBeardedRaspberry irked my dander once again. On that note, if the folks at Stripe would slap themselves on their collective heads a few times and realize that ... it's friggin' test mode for goodness' sake! Let developers develop... it's TEST mode because you expect them to mess around and make mistakes, and it's COMMON-FRIGGIN-SENSE that you need to let us wipe prices to start with a clean slate. Unreal! |
With full respect to Stripe developers (I got plenty of help from them through Discord) I landed on this ticket because I was surprised to learn that I cannot remove prices created by our unit tests. The consequence of this is that the amount of test data increases with each run of our test suite which makes using the dashboard to debug our integration increasingly difficult. Just to say I am supportive of removing everything in test mode. |
+1 on making this feature a reality. Would be a huge time and cost saver if we could do this programmatically instead of through the dashboard. |
I've created an automation script that simplifies the process of deleting archived products on the Stripe dashboard. This script uses Selenium in the background to perform the task seamlessly, saving valuable time during development and testing. To use this solution, follow these steps:
The script will log in to your Stripe account and take care of deleting archived products. Enjoy the time saved! |
Should have a price and product delete in the test API. |
With that current, first version, I deleted hundreds of my products that had multiple prices. |
I believe its possible to refactor your test setup so that you can simply archive and unarchive products and price objects. Try:
This should mean you dont continue adding to the 'archived' storage, and just archive/unarchive data already stored. NOTE: I have not yet tried this, but it is the direction I'm going to try and take |
Yet another developer here who just stumbled on this issue after creating a whole lot of test products/prices. Very frustrating. I don't understand why it's such a problem to give us a soft delete in the API, with an option to include these inactive records in queries, if we so choose. Then Stripe can keep the data for eternity, and developers won't be bothered by it. |
Following, the same issues above, I also wondered for a while "Would it be safe to launch this bulk creation, how can I clean up everything?" then I did it... and apparently I was wrong :( anyway in my case I don't have thousands of prices/products, still... frustrating |
We are now in 2023, actually I can delete one product with its price through the dashboard but using the API when I try to remove the Product it says that there is a price related to it so it is not possible to erase it. It is necessary that exists a consistency between the API and what we can do using the Dashboard. I think that if using the Dashboard delete option I can delete one product I must have the same possibility using the API, please fix this as soon as possible, or give some consistency in the behavior of both API and Dashboard. |
It's 2024, and you cannot delete price from the api yet? I am using python and I am still getting the error "stripe._error.InvalidRequestError: Request req_fn450vi6oyjYpH: This product cannot be deleted because it has one or more user-created prices." |
I tried to delete the seed data mistakenly created in test mode. |
Please add this feature. If I can seed thousands of prices in an instant, I should be able to delete them just as fast. "Archived" should be reserved for unused novel prices, not the numerous clones that I have erroneously generated. Thanks |
This is a must. I have been tasked with cleaning up a Stripe account that got compromised. Clicking the "..." -> "Delete Product" -> "Delete Product" 230,000 times is not going to cut it. Also saying nothing should be deleted for "historical purposes" is not a great response either when it was all created by bad actors. Even a soft delete would be fine. |
This is pretty disappointing, while I'm developing my workflow has been: 1. create my db 2. reseed it with some test data, 3. run tests and fix until I break something really bad 4. wipe the db and goto step 1. To do step 2 I have to make calls to my stripe dev sandbox to get the keys for the products and prices I create, as a result I have created dozens if not hundreds of prices and products on a test connected account (which is no big deal really), but what is the recommended workflow? What's the point of not being able to trivially wipe a test environment? |
Will this feature request ever be implemented? |
Hello,
I want to delete a price inside a product, I can do it in the Stripe dashboard, but I can’t do this using API
Code:
Result:
Thanks
The text was updated successfully, but these errors were encountered: