def ipn(): """Endpoint that receives Instant Payment Notifications (IPNs) from PayPal. Specifications are available at https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNImplementation/. """ request.parameter_storage_class = ImmutableOrderedMultiDict # Checking if data is legit paypal_url = PAYPAL_URL_PRIMARY if current_app.config[ 'PAYMENT_PRODUCTION'] else PAYPAL_URL_SANDBOX verify_args = chain(IPN_VERIFY_EXTRA_PARAMS, request.form.iteritems()) verify_string = u'&'.join( (u'%s=%s' % (param, value) for param, value in verify_args)) verification_response = requests.post(paypal_url, data=verify_string.encode('utf-8')) # Some payment options don't return payment_status value. if 'payment_status' not in request.form: logging.warn('PayPal IPN: payment_status is missing.') return '', 200 if verification_response.text == 'VERIFIED': Donation.process_paypal_ipn(request.form) return '', 200
def ipn(): """Endpoint that receives Instant Payment Notifications (IPNs) from PayPal. Specifications are available at https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNImplementation/. """ request.parameter_storage_class = ImmutableOrderedMultiDict # Checking if data is legit paypal_url = PAYPAL_URL_PRIMARY if current_app.config['PAYMENT_PRODUCTION'] else PAYPAL_URL_SANDBOX verify_args = chain(IPN_VERIFY_EXTRA_PARAMS, request.form.iteritems()) verify_string = u'&'.join((u'%s=%s' % (param, value) for param, value in verify_args)) verification_response = requests.post(paypal_url, data=verify_string.encode('utf-8')) if verification_response.text == 'VERIFIED': Donation.process_paypal_ipn(request.form) return '', 200
def test_process_paypal_ipn(self): # This is not a complete list: good_form = { 'first_name': u'Tester', 'last_name': u'Testing', 'custom': u'tester', # MusicBrainz username 'payer_email': u'*****@*****.**', 'receiver_email': current_app.config['PAYPAL_PRIMARY_EMAIL'], 'business': u'*****@*****.**', 'address_street': u'1 Main St', 'address_city': u'San Jose', 'address_state': u'CA', 'address_country': u'United States', 'address_zip': u'95131', 'mc_gross': u'42.50', 'mc_fee': u'1', 'txn_id': u'TEST1', 'payment_status': u'Completed', # Additional variables: 'option_name1': u'anonymous', 'option_selection1': u'yes', 'option_name2': u'contact', 'option_selection2': u'yes', } Donation.process_paypal_ipn(good_form) # Donation should be in the DB now self.assertEqual(len(Donation.query.all()), 1) self.assertEqual(Donation.query.all()[0].transaction_id, 'TEST1') relatively_bad_form = good_form relatively_bad_form['txn_id'] = 'TEST2' relatively_bad_form['mc_gross'] = '0.49' Donation.process_paypal_ipn(relatively_bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1) bad_form = good_form relatively_bad_form['txn_id'] = 'TEST3' bad_form['business'] = current_app.config['PAYPAL_BUSINESS'] Donation.process_paypal_ipn(bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1) super_bad_form = good_form relatively_bad_form['txn_id'] = 'TEST4' super_bad_form[ 'payment_status'] = 'Refunded' # What kind of monster would do that?! Donation.process_paypal_ipn(super_bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1)
def test_process_paypal_ipn(self): # This is not a complete list: good_form = { 'first_name': u'Tester', 'last_name': u'Testing', 'custom': u'tester', # MusicBrainz username 'payer_email': u'*****@*****.**', 'receiver_email': current_app.config['PAYPAL_PRIMARY_EMAIL'], 'business': u'*****@*****.**', 'address_street': '1 Main St', 'address_city': u'San Jose', 'address_state': u'CA', 'address_country': u'United States', 'address_zip': u'95131', 'mc_gross': u'42.50', 'mc_fee': u'1', 'txn_id': u'TEST1', 'payment_status': u'Completed', # Additional variables: 'option_name1': u'anonymous', 'option_selection1': u'yes', 'option_name2': u'contact', 'option_selection2': u'yes', } Donation.process_paypal_ipn(good_form) # Donation should be in the DB now self.assertEqual(len(Donation.query.all()), 1) self.assertEqual(Donation.query.all()[0].transaction_id, 'TEST1') relatively_bad_form = good_form relatively_bad_form['txn_id'] = 'TEST2' relatively_bad_form['mc_gross'] = '0.49' Donation.process_paypal_ipn(relatively_bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1) bad_form = good_form relatively_bad_form['txn_id'] = 'TEST3' bad_form['business'] = current_app.config['PAYPAL_BUSINESS'] Donation.process_paypal_ipn(bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1) super_bad_form = good_form relatively_bad_form['txn_id'] = 'TEST4' super_bad_form['payment_status'] = 'Refunded' # What kind of monster would do that?! Donation.process_paypal_ipn(super_bad_form) # There should still be one recorded donation self.assertEqual(len(Donation.query.all()), 1)