Server side stripe payments

I followed the documentation to implement stripe payments on the server side.
I managed to make it work but I’m still struggling to parse the stripe response.

Unlike the client side, just printing the result of the charge call doesn’t give me a usable dict. Instead, I just get ‘Anvil LiveObject’.

I did a pprint(vars(result)) and I see a dictionary of information but it doesn’t contain the url or result.

Can I assume if there’s a transaction ID that the transaction is a success? Sorry if I overlook the documentation somewhere.

Also on this page: https://anvil.works/docs/integrations/stripe/payments-and-subscriptions
I think the server-side code for add_card has an error. In the case of a new customer, the customer already has a token so the last line will try to add it again and cause a internal server error. I think the last line should be indented with the else block.

Hi @shopinthewoods,

Calling stripe_customer.charge on the server side returns a dictionary similar to the Stripe Charge object. Charges are identified by a unique, random ID, and you can access attributes of the Charge object as you would a normal dict. The status attribute tells you if the transaction has succeeded, and will return either succeeded , pending , or failed. For example:

# In a Server Module:
@anvil.server.callable
def charge_user(token, email):
  stripe_customer = anvil.stripe.new_customer(email, token)
  charge = stripe_customer.charge(amount=999, currency="USD")
  print("ID: {}, Status: {}".format(charge['id'], charge['status']))

This will print out the charge id and status for each payment taken on the server.

2 Likes

Thanks for this but I’m still confused. I saw charge object documentation on Stripe’s site but it doesn’t match the object that I’m getting back from Anvil. For example, the link you sent lists a ‘receipt_url’ property of the dict but that doesn’t appear to be in the dict.

I had the same experience. And I found a clue.

In https://anvil.works/docs/server/packages, the Stripe package is version 2.15.0. On the Python Package Index, the current Stripe package version is 2.35.1.

That’s minor 20 versions in less than a year, during which Stripe has been regularly adding features. Odds are, receipt_url is one of those later features.

So far, I haven’t needed the receipt_url. If it turns out to be something vital, I can always install Stripe’s latest-and-greatest at my “home office”, and use that to get the receipt_url, e.g., on a nightly run, and update my Anvil records that way.

Ok, that’s interesting.
Is there a way to reliably dump the full contents of the stripe charge object to a string?

If I do, as Bridget suggested;

print("ID: {}, Status: {}".format(charge['id'], charge['status']))
I get this showing the status correctly:

ID: ch_1FC5BPJNsq6p0T6Be8mAgjOZ, Status: succeeded

But if I do
pprint(vars(charge))

I get this result which doesn’t show the status

{‘_spec’: {‘backend’: ‘anvil.stripe.Charge’,
‘id’: ‘[“ch_1FC5BPJNsq6p0T6Be8mAgjOZ”]’,
‘itemCache’: {‘id’: ‘ch_1FC5BPJNsq6p0T6Be8mAgjOZ’},
‘mac’: ‘f0ba9dc8a65c6dd3f6ab209890341b908d25cf15b0dca2d816c6a0cbaf0afd89’,
‘methods’: [‘getitem’],
‘path’: [‘response’],
‘permissions’: ,
‘type’: [‘LiveObject’]}}
{‘_spec’: {‘backend’: ‘anvil.stripe.Charge’,
‘id’: ‘[“ch_1FC5BPJNsq6p0T6Be8mAgjOZ”]’,
‘itemCache’: {‘id’: ‘ch_1FC5BPJNsq6p0T6Be8mAgjOZ’},
‘mac’: ‘f0ba9dc8a65c6dd3f6ab209890341b908d25cf15b0dca2d816c6a0cbaf0afd89’,
‘methods’: [‘getitem’],
‘path’: [‘response’],
‘permissions’: ,
‘type’: [‘LiveObject’]}}

I haven’t found any obvious way to do it. The presence of getitem suggests that Anvil has implemented its own subscripting routine for objects of this type. So it is their member function getitem that is returning the value from charge[your string here]

As this may be a security measure, I’ve been reluctant to try poking in any further.

As a Stripe user, I can independently, at our home office, use the latest Stripe library, to get the URL, if I must, using the provided ID.

Hi both,

To clarify, the stripe.customer.charge function returns a dictionary similar to the Stripe Charge Object.

The reason this dict differs slightly from the documentation here is that we use the stripe-java client library behind the scenes. This means that the Charge object only contains the attributes implemented explicitly in this library. This is the version we use right now, hence why receipt_url is not available (it was added more recently).

As Ian mentioned in response to your previous post, @p.colbert, we’ll be upgrading this very soon as part of a wider Stripe update.

I agree it would be useful to have access to the full list of attributes of the Charge object - moving this to feature requests.

Awesome. Thanks Bridget. That would be great. Then I could just store the string of the result and it would be relatively future proof if the content details change.

@bridget, you’re right, I could have mentioned it here. Somehow, I got that post mixed up with another, private message; then erred on the side of caution in not repeating anything from a private message.

Hi @shopinthewoods - I’m coming very late to the party but in case you didn’t spot it already, or in case someone else reading this finds it useful, the transaction url is simply:

"https://dashboard.stripe.com/test/payments/" + charge['id']

And I haven’t checked because I’m still learning and testing, but would assume you just remove /test for live transactions.

I’ve also asked @hannah to bump the task of updating Stripe and its Anvil documentation on another thread.

All the best,
Peter

1 Like