stripe: Use context managers for error handling in cgi
[hcoop/portal.git] / stripe / stripe-payment.cgi
CommitLineData
f8b39e09
CE
1#!/usr/bin/env python
2# -*- python -*-
3
4import sys
5sys.path.insert(0, '/afs/hcoop.net/user/h/hc/hcoop/portal3/stripe/stripe-pkg/lib/python2.6/site-packages/')
6
7import stripe, cgi, psycopg2, cgitb, datetime, smtplib
8from email.mime.text import MIMEText
5e6afd1a 9from contextlib import contextmanager
f8b39e09
CE
10
11cgitb.enable()
12
13def notify_payment (charge, member):
14 msg_text = """
15A member has paid us via Stripe. Please visit the portal money
16page at your earliest convenience to process the payment.
17
18 Member : {0}
19 Amount (cents) : {1}
20 Stripe Charge ID: {2}
21""".format (member, charge.amount, charge.id)
22
23 msg = MIMEText(msg_text)
24 msg['Subject'] = 'Stripe payment received from {0}'.format(member)
25 msg['From'] = 'payment@hcoop.net'
26 msg['To'] = 'payment@hcoop.net'
27
28 s = smtplib.SMTP ('mail.hcoop.net')
29 s.sendmail ('payment@hcoop.net', ['payment@hcoop.net'], msg.as_string ())
30 s.quit ()
31
32def stripe_key ():
33 keyfile = open ("/afs/hcoop.net/user/h/hc/hcoop/.portal-private/stripe", "r")
34 keystring = keyfile.read ()
35 keyfile.close ()
36 return keystring
37
5e6afd1a
CE
38
39@contextmanager
40def stripe_error_handling ():
41 try:
42 yield
43 except stripe.error.CardError, e: # The card has been declined
44 print 'Status: 200 OK'
45 print
46 print '<html>'
47 print '<head><title>Transaction Failed</title></head>'
48 print '<body>'
49 print '<h1>Failed</h1><p>Reason: '
50 print e.json_body['error']['message']
51 print '</p>'
52 print '</body>'
53 print '</html>'
54 raise
55
56@contextmanager
57def stripe_refund_on_error (charge):
58 try:
59 yield
60 except:
61 print 'Status: 200 OK'
62 print 'Content-Type: text/html'
63 print ''
64 print '<h1>Something went wrong after accepting payment!</h1>'
65 charge.refund ()
66 print '<p>The charge should be refunded. Please contact payment@hcoop.net if it was not!</p>'
67 raise
68
f8b39e09
CE
69# Set your secret key: remember to change this to your live secret key in production
70# See your keys here https://manage.stripe.com/account
71
72stripe.api_key = stripe_key ()
73
74# Get the credit card details submitted by the form
75
76request_params = cgi.FieldStorage()
77
78token = request_params.getvalue ('stripeToken')
79webuser_id = request_params.getvalue('webuser_id')
80member_name = request_params.getvalue('webuser_name')
81amount = request_params.getvalue('stripeDues')
82
83# Create the charge on Stripe's servers - this will charge the user's card
84
5e6afd1a 85with stripe_error_handling ():
f8b39e09
CE
86 charge = stripe.Charge.create( amount=amount,
87 currency="usd",
88 card=token,
89 description='Payment for member {0}'.format (member_name))
5e6afd1a
CE
90
91with stripe_refund_on_error (charge):
92 with psycopg2.connect ('dbname=hcoop_portal3test user=hcoop host=postgres port=5433') as conn:
93 with conn.cursor () as cur:
94 balance = stripe.BalanceTransaction.retrieve (charge.balance_transaction);
95 cur.execute ('insert into stripe_payment (charge_id, card_name, webuser_id, paid_on, gross, fee) values (%s, %s, %s, %s, %s, %s)',
96 (charge.id, charge.card.name, webuser_id, datetime.date.today (), charge.amount, balance.fee))
97
98notify_payment (charge, member_name)
99print 'Status: 303 See Other'
100print 'Location: /portal/portal?cmd=stripeSuccess'
101print ''
102print '<a href="/portal/portal?cmd=stripeSuccess">Go back to the portal</a>'
103