Here's some code that I use... hopefully should get you started.
def __create_stripe_session(item_name='', amount_cents=0, success_url='', cancel_url='', item_description='', customer_email=None):
"""
Creates a Stripe session (with a payment intent id), valid for 24 hrs, which we can then submit later.
"""
import stripe
stripe.api_key = 'stripe_key_secret'
stripe_session = stripe.checkout.Session.create(
payment_method_types=['card'],
customer_email = customer_email, # prepopulates, but readonly - user can't change it.
line_items=[{
'name': item_name,
'description': item_description,
'amount': amount_cents,
'currency': 'cad',
'quantity': 1,
}],
success_url = success_url,
cancel_url = cancel_url,
)
return stripe_session
def make_donation():
"""
display page with form to enter amount.
"""
# display form.
form = SQLFORM.factory(Field('amount', type='string', label='Donation Amount'))
if form.process().accepted:
# create a Stripe session
stripe_session = __create_stripe_session(
item_name = 'Donation',
amount_cents = int(round(float(form.vars.amount),2)*100),
success_url = '
http://localhost:8055/donations/done?action=payment_complete', # stripe redirects here on success.
cancel_url = '
http://localhost:8055/donations/done?action=cancelled' # stripe redirects here if cancelled.
)
# Save record so can compare with stripe returned event...
# Store the PI in the description temporarily and overwrite when transaction is sucessful.
db.donations.insert(user_id = session.user_id, description=stripe_session.payment_intent, amount=round(float(form.vars.amount),2))
# Now submit to Stripe for execution.
context = dict(public_key = '<your stripe public key here>', stripe_session_id =
stripe_session.id)
return response.render('donations/do_stripe_payment.html', context)
elif form.errors:
response.error = form.errors.amount
return dict(form = form)
@request.restful()
def my_stripe_webhook():
"""
On event, Stripe POSTs this json `webhook` via http.
We need to respond with simple 200-ok or it will attempt to resend a few more times.
"""
import stripe
def POST(*args, **vars):
# Alternatively can take the `id` from the POST info and turn it into a stripe object that can be used and queried.
# e.g. See
https://stripe.com/docs/api/python#retrieve_event for details of the object.
if
request.vars.id == 'evt_00000000000000': # Test event from Stripe - can't query it with api...silly as that seems.
log.warning("dummy Stripe event evt_00000000000000 received. Not processing further.")
return "Ok, thanks. (dummy/test event received)."
else:
# Set the secret key.
stripe.api_key =
'stripe_key_secret'
# see:
https://stripe.com/docs/api/events/object event = stripe.Event.retrieve(
request.vars.id)
log.info(f"Stripe event received. id: {
event.id} type: {event.type}")
if event.type == 'charge.succeeded':
# Check if donation.
rec = db(db.donations.description == event.data.object.payment_intent).select().first()
if rec:
log.info(f"Donation made by user: {rec.user_id}")
# Overwrite the PI code in the description with actual action/message visible to user.
# This is final step and confirms money has been received.
rec.update_record(description = "Funds received, thank you!")
else:
log.error(f"Unknown payment received, see: {event.data.object.payment_intent}")
elif event.type == 'charge.refunded':
# Refund processing here...
elif event.type == 'checkout.session.completed':
return "Ok, thanks"
else:
# process other possible other event types.
return "Thanks again"
return locals()