#mxd

1 messages · Page 1 of 1 (latest)

fossil axleBOT
opaque river
#

What's the exact code that's throwing the error?

loud jay
#

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```
opaque river
#

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?

loud jay
#

stripe==2.0.1

#

was told by a stripe developer theres always backwards compatibility

opaque river
#

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

loud jay
#

to what version?

#

ill experience breaking changes since im required to use particular version of flask

opaque river
loud jay
#

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,

opaque river
#

Are you getting the same error?

loud jay
#

yeah

#

and i upgraded to a version with all the pricing changes

opaque river
#

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 a print() statement at each step to make sure the variable contains the correct thing?

loud jay
#

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,
},
],

opaque river
#

Hard-coding is always an option

loud jay
#

i tried it

opaque river
#

Does it work?

loud jay
#

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, }, ],?

opaque river
#

The docs give an example of how to create a Checkout Session using python and they specify the required parameters

loud jay
#

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'?

opaque river
#

I don't know what that is. Where does that code come from?

loud jay
#

from quickstart

opaque river
#

Does adding the Price in lookup_key work?

#

What happens when you run?

loud jay
#

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

lone tendon
#

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

lone tendon
loud jay
#

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)
lone tendon
#

You can use payment links and pricing tables for creating subscriptions, yes. What exactly are you trying to do with the webhook?

loud jay
#

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 %}

lone tendon
#

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

loud jay
#

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'})
lone tendon
#

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

loud jay
#

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

loud jay
#
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.
lone tendon
loud jay
lone tendon
#

That does not look like a valid line for a webhook endpoint

#

You can of course retrieve the checkout session by ID, but you wouldn't get that from request.args.get('session_id') (in a webhook handler)