There may be a slight error in the documentation. The documentation on creating stripe payment subscriptions implies that you can refer to a plan by name e.g.
however that gives an error and I have found that you need to refer to a plan by its id e.g. “222” or 222 (both integers and strings seems to work ok). You may want to update the doco?
Issue 2 - stripe customer creation
Is it possible to access the raw stripe package library rather than the Anvil version? When using the raw stripe package from stripe.com (not the Anvil version stripe.checkout ) you must associate a subscription with a stripe Customer id, whereas Anvil’s stripe.checkout does not seem to allow a customer to be specified at all. In fact it seems that Anvil creates a brand new customer object for you every time a subscription is created.
This behaviour by Anvil is helpful but may be limiting e.g. I cannot add a subscription to an existing stripe customer, and how do I look up an existing Customer to check their subscription status - the Anvil stripe result objects give me a subscription_id but not a customer_id? Thus being able to access the raw official stripe library would make these advanced usages possible. They both have the same package name stripe - so that’s a bit of a name clash though…
Issue 2: I’ve been working with Stripe subscriptions for the past couple of days. Stripe has made it’s subscription model very flexible which places subscription management very much on the devs shoulder.
To get to the full Stripe api, you can call it from a ServerModule. Make sure the customer isn’t already subscribed if you only allow for one subscription. Stripe allows for multiple subscriptions (e.g. multiple web host accounts at $9.99 per month)
# only do this if we're not subscribed
subscription_response = stripe.checkout.subscribe(plan="weekly_ballet",
title="Subscribe",
customer = self.customer,
description="Weekly ballet class")
# todo: check for success or failure
# unfortunately the subscription response does not contain the customer id!
# so we take the long road to get it
user = anvil.users.get_user()
full_subscription = anvil.server.call('retrieve_subscription',subscription_response['subscription_id'])
anvil.server.call('update_student', user, full_subscription['customer'])
The next big challenge is to handle pausing a subscription!
Thanks for navigating the corners of this with us! stripe.checkout.subscribe() is pretty limited. If you want to do more advanced things, I would suggest calling stripe.checkout.get_token(). This returns a tuple of the Stripe token and a dictionary of user information (by default it’s just the email address, but other billing info also turns up here). Eg:
You then have a choice of two approaches. First, you can use Anvil’s server-side Stripe utilities, which are available in the anvil.stripe package:
new_customer = anvil.stripe.new_customer(email_address, token)
print new_customer['id'] # You can read any of the JSON keys in a Stripe Customer object
sub = new_customer.new_subscription("my-plan-id")
# You can also retrieve customers, and get either full subscription
# objects or just a list of plan IDs they are subscribed to
existing_customer = anvil.stripe.get_customer("cust-id-XXXXXX")
if "my_plan" in existing_customer.get_subscription_ids():
print "You are subscribed to my_plan!"
Alternatively, you can use this token with the standard server-side stripe package (in the Full Python 2.7 and 3.6 runtimes). (You may need to pass raw=True to get_token() to get a token that is directly associated with your account rather than with Anvil.)
I’ve just re-upped our TODO list item for “improve our Stripe documentation”! Thankfully, it is at least all in the autocompleter.
Does this mean that client side usage (with ‘import stripe.checkout’ in the form) of stripe.checkout.get_token with raw=True is the only change that is require to get and use tokens that are directly associated (as in not associated with Anvil’s stripe account and thus not subject to an additional 2% processing fee)?
for instance, will the following code, on the client side, suffice to obtain appropriate tokens?
if so, will the obtained tokens (stored at user[‘stripe_customer_id’]) work on the server side with an ‘import anvil.stripe’ statement and the following code:
InternalError: Internal server error: 5fc676bf0afc
at /downlink/anvil/_threaded_server.py, line 435
called from /downlink/anvil/_server.py, line 42
called from ServerModule1, line 26
called from account_page, line 21
I gave stripe.checkout.subscribe a try and that was telling me there is “no such plan”. However, I have created a product on strip and am referencing their price id. I also tried the product ID, but that didn’t work either. Am I missing something on what the plan id is?
You should probably start a new topic with your issue, since the post you replied to is several years old. In that new topic, include the full error message from the app log, the client and server code, and identify what line 26 in the server module is.
That internal server code might give Anvil folks some extra insight.