Stripe payments; checking status of subscriptions

The app I am building is a subscription service. I need to
(1) Check if the customer has an account on our Anvil app
if not create an account
get the customers Stripe information/authorization to check subscription status
(2) Check if the user has a Stripe account, and appropriate payment plan.
If not than go to the Stripe ‘Checkout service’ and return
(3) If both accounts exist redirected to the main app form.

Is there a tutorial for doing this?

It seems to me that the first time the customer visits and are redirected to Stripe I need to get a usr/pswrd/token of some kind, store that in the users table on my app, and use it on later visits to check for the status of the stripe account/subscription at Stripe.

I have not found the API documentation for checking the status of the customers’ Stripe subscription status. I did find some docs on getting tokens for one-off payments and getting a customer ID. Is retrieving payment status information part of the anvil.stripe Module? If not where might it be?

In the future I also I will need to send to Stripe information on usage levels for metered billing. Not an immediate need but thought I would mention it in case it is also, or can be, part of the anvil.stripe Module

I realise it is a broad questions, but if anyone has examples or pointers it would be very much appreciated.

You will find tutorials here. One of them is a Stripe tutorial. There are other related writings all over this site.

This site’s built-in Search is definitely your friend here, but you may need to do more than skim the titles to find the information you’re looking for. Any time you’re trying to coordinate the activity of two or more programs (e.g., yours and Stripe’s), you get a somewhat intricate topic. The details you want may be buried in code that illustrates a seemingly unrelated Stripe issue.

Anvil’s Stripe integration uses a wrapper around Stripe’s own API. (A wrapper around a wrapper!) Its documentation delegates a lot of detail (implicitly) to Stripe’s documentation, so it is helpful to first understand Stripe’s view of things (through its API).

This is not as straightforward as it it might be.

  1. Anvil’s wrapper is several versions behind Stripe’s latest API.
  2. Stripe’s own API continues to evolve with little notice.
  3. API documentation in general is too low-level. It assumes that you already understand the big picture – the concepts, architecture, constraints, and naming conventions – and just need some specific details. It can take awhile to reverse-engineer the big picture from the small. Patience, and other sources, can really help.

What I remember that may apply:

  1. To give an Anvil App user a Stripe subscription, you must define that user in Stripe as a Stripe Customer, with payment information. This will return a Stripe ID for that Customer, for use in all further Stripe transactions involving that Customer. You’ll need to keep a copy of that Stripe ID, and associate it with your Anvil App user.
  2. Between Anvil and Stripe, Stripe has the better documentation for Stripe’s Subscriptions model, and examples of how to use it.
  3. Be prepared to use the available Stripe API directly, if Anvil’s high-level API does not expose what you need.
  4. When things get really complex, consider using Stripe’s latest Python API in-house, to accomplish any Stripe-specific subtasks by direct communication with Stripe. That way you have the fewest possible middle-men muddying the process.

@p.colbert Thanks for the extensive reply. Very helpful.

Just a quick update. Not much progress on this. I tried to use Stripe’s Checkout service. Reportedly it allows you to direct to a hosted service on the Stripe servers then direct to the application once payment is made. But as the corporate website from which the first link is made is on a Wix host. The integration was not straightforward and end up not practical with the Wix and Stripe support teams both saying “go talk to the other guys”

Just a quick update. Not much progress on this. I tried to use Stripe’s Checkout service. Reportedly it allows you to direct to a hosted service on the Stripe servers then direct to the application once payment is made. But as the corporate website from which the first link is made is on a Wix host. The integration was not straightforward and end up not practical with the Wix and Stripe support teams both saying “go talk to the other guys”

It seems to me that the functionally is not that complex if more of the Stripe API was available via the anvil.stripe or stripe.checkout modules.

In the Stripe documentation there are reference to calls something like:

stripe.Subscription.create(
customer='cus_4fdAW5ftNQow1a',
  items=[{
      'plan': 'plan_CBXbz9i7AIOTzr',
    }
])

Then when the customer returns to check the subscription is still active. I could do t

stripe.Subscriptions.object  

which is also in the API.

It is not clear to me how to do that in Anvil. Is adding the subscription functions something that need to be requested from Anvil support. Or is there a way to call the APIs by other means.

Thanks again

I haven’t tried Subscriptions myself. With any luck, someone else here will have more clues.

However, in the worst case, you can run Python on one of your local computers, to call Stripe from there, using Stripe’s latest Python library.

To trigger that code from your Anvil App (server-side or client-side code), you would use Anvil’s Uplink library. This lets your local Python script connect to your App via internet, and supply functions that your App can remotely call.

This may not be ideal. Each incoming function call runs in its own thread, so multiple instances of your local function may be running simultaneously, each serving a different user. If these instances share any changeable information at all (e.g., a database connection), then conflicts can occur. The longer it takes for the function to finish, the more likely this will be. Calling out to Stripe will likely be one of those longer-running tasks.

If you decide to go this route, then you’ll want to decouple the incoming call from the actual work to be done. With this approach, the incoming call triggers the work – perhaps it queues it up somewhere – but doesn’t wait for it to finish. Some other Uplink-enabled program can post the result to your App’s database, when complete.

This is a pattern that applies to any non-trivial Uplink-triggered work.