| 1 | #!/usr/bin/env python |
| 2 | # -*- python -*- |
| 3 | |
| 4 | import sys |
| 5 | sys.path.insert(0, '/afs/hcoop.net/user/h/hc/hcoop/portal3/stripe/stripe-pkg/lib/python2.6/site-packages/') |
| 6 | |
| 7 | import stripe, cgi, psycopg2, cgitb, datetime, smtplib |
| 8 | from email.mime.text import MIMEText |
| 9 | from contextlib import contextmanager |
| 10 | |
| 11 | cgitb.enable() |
| 12 | |
| 13 | def notify_payment (charge, member): |
| 14 | msg_text = """ |
| 15 | A member has paid us via Stripe. Please visit the portal money |
| 16 | page 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 | |
| 32 | def 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 | |
| 38 | |
| 39 | @contextmanager |
| 40 | def 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 |
| 57 | def 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 | |
| 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 | |
| 72 | stripe.api_key = stripe_key () |
| 73 | |
| 74 | # Get the credit card details submitted by the form |
| 75 | |
| 76 | request_params = cgi.FieldStorage() |
| 77 | |
| 78 | token = request_params.getvalue ('stripeToken') |
| 79 | webuser_id = request_params.getvalue('webuser_id') |
| 80 | member_name = request_params.getvalue('webuser_name') |
| 81 | amount = request_params.getvalue('stripeDues') |
| 82 | |
| 83 | # Create the charge on Stripe's servers - this will charge the user's card |
| 84 | |
| 85 | with stripe_error_handling (): |
| 86 | charge = stripe.Charge.create( amount=amount, |
| 87 | currency="usd", |
| 88 | card=token, |
| 89 | description='Payment for member {0}'.format (member_name)) |
| 90 | |
| 91 | with 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 | |
| 98 | notify_payment (charge, member_name) |
| 99 | print 'Status: 303 See Other' |
| 100 | print 'Location: /portal/portal?cmd=stripeSuccess' |
| 101 | print '' |
| 102 | print '<a href="/portal/portal?cmd=stripeSuccess">Go back to the portal</a>' |
| 103 | |