#mxd
1 messages · Page 1 of 1 (latest)
What's the exact code that's throwing the error?
could be this: ```@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
try:
prices = stripe.Price.list(
lookup_keys=[request.form['lookup_key']],
expand=['data.product']
)
checkout_session = stripe.checkout.Session.create(
line_items=[
{
'price': prices.data[0].id,
'quantity': 1,
},
],
mode='subscription',
success_url=YOUR_DOMAIN +
'/success.html?session_id={CHECKOUT_SESSION_ID}',
cancel_url=YOUR_DOMAIN + '/cancel.html',
)
return redirect(checkout_session.url, code=303)
except Exception as e:
print(e)
return "Server error", 500```
I suspect you're on an older version of Stripe Python library. Are you able to check which version you're using and upgrade if applicable?
That's usually the case, but *I believe * Prices were a new product that didn't exist in that version. You will need to upgrade in order for that request to work
to what version?
ill experience breaking changes since im required to use particular version of flask
I would recommend upgrading to the newest version, but if that's not possible, then this is the version that added Prices as a resource: https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md#2470---2020-04-29
I can't guarantee that will be compatible with all the snippets in our docs though, so that's why I recommend doing a full upgrade.
im not sure which version
stripe==2.60.0?
tried 2.6, still not working
i think its just a miscommunication with this: 'price': prices.data[0].id,
Are you getting the same error?
i think its just a miscommunication with this: 'price': prices.data[0].id,
Are you able to step through the code to see what that variable is? If not, can you do aprint()statement at each step to make sure the variable contains the correct thing?
would it be wrong if I did this? ``` checkout_session = stripe.checkout.Session.create(
line_items=[
{
#'price': prices.data[0].id,
#'quantity': 1,
'price': 'price_1LzibnLXb2BpINMF2FrTyY7B',
'quantity': 1,
},
],
Hard-coding is always an option
i tried it
Does it work?
no
should it be something like: checkout_session = stripe.checkout.Session.create( line_items=[ { #'price': prices.data[0].id, #'quantity': 1, 'price': price['price_1LzibnLXb2BpINMF2FrTyY7B'], 'quantity': 1, }, ],?
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
The docs give an example of how to create a Checkout Session using python and they specify the required parameters
yeah I did it correctly then, what about this part? lookup_keys=[request.form['lookup_key']],
<!-- Add a hidden field with the lookup_key of your price-->
<input type="hidden" name="lookup_key" value="price_1LzibnLXb2BpINMF2FrTyY7B" />
<button id="checkout-and-portal-button" type="submit">Checkout</button>
</form>```
do i need to do something about 'lookup_key'?
I don't know what that is. Where does that code come from?
same issue, so im just going to abandon it, and use a payment link or the pricing-tables, those seem to work, the problem is I cant see what is going on in the code in order to store subscription data to a mysql database with pricing-tables and payment-link because its all done behind the scenes
I'm happy to help you sort this out if you want to keep at it, but I'm going to need you to share a little more debugging detail about what you're seeing and the exact issues/errors
This, in particular, should have worked, and I am curious why it did not work for you.
im abandoning the single-subscription checkout, it doesnt work
i wanted to use it because I can control the session and stuff which I need to store user info to provision access to paid features
can i do that with payment-link and pricing-table with a webhook? if so... how and I doing that (not much documentation on stripe for it)
def webhook():
event = None
payload = request.data
sig_header = request.headers['STRIPE_SIGNATURE']
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
raise e
except stripe.error.SignatureVerificationError as e:
# Invalid signature
raise e
# Handle the event
if event['type'] == 'customer.subscription.created':
subscription = event['data']['object']
# ... handle other event types
# how to flip a boolean field to 1
elif event['type'] == 'customer.subscription.deleted':
subscription = event['data']['object']
# ... handle other event types
# how to flip a boolean field to 0
elif event['type'] == 'customer.subscription.updated':
subscription = event['data']['object']
# ... handle other event types
# how to flip a boolean field to 1
else:
print('Unhandled event type {}'.format(event['type']))
return jsonify(success=True)
You can use payment links and pricing tables for creating subscriptions, yes. What exactly are you trying to do with the webhook?
provision access to paid features, after the human subscribes, they are redirected to members page, when customer.subscription.created , i need a way to flip a boolean to true for the active subscriber, and flip a boolean to true for the product they subscribed to so when the new subscriber is on the members page I have logic that shows them what they can see ```{if users and subscriber.status=="active" }
<p><a href="">Modify Your subscription</a></p>
<p> add your first post</p>
<form></form>
{% endif %}
You can use customer.subscription.created if you like, and examine the items on the subscription
Note that the customer redirect and the webhook are separate things
If you're trying to show something to a customer on a success page, you'll need to retrieve information from the backend
Using checkout, you can do something like this to get the session ID in the success url, which you can then retrieve from your server: https://stripe.com/docs/payments/checkout/custom-success-page#modify-success-url
like this???
def webhook_received():
webhook_secret = 'whsec_...'
request_data = json.loads(request.data)
if webhook_secret:
signature = request.headers.get('stripe-signature')
try:
event = stripe.Webhook.construct_event(
payload=request.data, sig_header=signature, secret=webhook_secret)
data = event['data']
except Exception as e:
return e
event_type = event['type']
else:
data = request_data['data']
event_type = request_data['type']
data_object = data['object']
print('event ' + event_type)
if event_type == 'checkout.session.completed':
print('Payment succeeded!')
elif event_type == 'customer.subscription.created':
print('Subscription created %s', event.id)
# like this?? looook HERE!!!!!
session = stripe.checkout.Session.retrieve(request.args.get('session_id'))
customer = stripe.Customer.retrieve(session.customer)
elif event_type == 'customer.subscription.updated':
print('Subscription created %s', event.id)
elif event_type == 'customer.subscription.deleted':
# handle subscription canceled automatically based
# upon your subscription settings. Or if the user cancels it.
print('Subscription canceled: %s', event.id)
return jsonify({'status': 'success'})
You seem to be mixing up your webhook endpoint and your success page for the customer
those are separate things
the webhook endpoint is a server endpoint that just handles webhook requests from Stripe
the success page is a page for a customer to go to after checkout etc
i dont get a custom success page when using payment-link and price-table , its a no-code and the only option i get is which page the customer lands on after checking out which is members in this case
i thought I could use webhooks to modify data in the database
def webhook_received():
webhook_secret = {{'STRIPE_WEBHOOK_SECRET'}}
request_data = json.loads(request.data)
if webhook_secret:
# Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
signature = request.headers.get('stripe-signature')
try:
event = stripe.Webhook.construct_event(
payload=request.data, sig_header=signature, secret=webhook_secret)
data = event['data']
except Exception as e:
return e
# Get the type of webhook event sent - used to check the status of PaymentIntents.
event_type = event['type']
else:
data = request_data['data']
event_type = request_data['type']
data_object = data['object']
if event_type == 'checkout.session.completed':
# Payment is successful and the subscription is created.
# You should provision the subscription and save the customer ID to your database.
print(data)
elif event_type == 'invoice.paid':
# Continue to provision the subscription as payments continue to be made.
# Store the status in your database and check when a user accesses your service.
# This approach helps you avoid hitting rate limits.
print(data)
elif event_type == 'invoice.payment_failed':
# The payment failed or the customer does not have a valid payment method.
# The subscription becomes past_due. Notify your customer and send them to the
# customer portal to update their payment information.
print(data)
else:
print('Unhandled event type {}'.format(event_type))
return jsonify({'status': 'success'})```
Payment is successful and the subscription is created.
# You should provision the subscription and save the customer ID to your database.
You certainly can, but this line had me concerned you are assuming there would be a session id in the request args (as you might expect on the success page redirect)
session = stripe.checkout.Session.retrieve(request.args.get('session_id'))