def form_valid(self, form, send_data_to_basket=True): data = form.cleaned_data.copy() if settings.POST_DONATE_NEWSLETTER_URL is not None: # This will send the email address to Mailchimp for Thunderbird only. newsletter_url = settings.POST_DONATE_NEWSLETTER_URL data = parse.urlencode({'EMAIL': data['email']}).encode() res = requests.post(newsletter_url, data=data) if not res.ok: sentry_logger.error('Thunderbird newsletter POST failed', extra={'status': res.status_code}, exc_info=True) elif send_data_to_basket: data['source_url'] = self.request.build_absolute_uri() data['lang'] = self.request.LANGUAGE_CODE queue.enqueue(send_newsletter_subscription_to_basket, data) queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Signup', 'eventAction': 'Submitted the Form', 'eventLabel': 'Email', } ]) return super().form_valid(form)
def form_valid(self, form, send_data_to_basket=True): self.currency = form.cleaned_data['currency'] # Create a customer and payment method for this customer result = gateway.customer.create({ 'payment_method_nonce': form.cleaned_data['braintree_nonce'], 'custom_fields': self.get_custom_fields(form), }) if result.is_success: payment_method = result.customer.payment_methods[0] else: logger.error('Failed to create Braintree customer: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form) # Create a subscription against the payment method start_date = now().date() + relativedelta( months=1) # Start one month from today result = gateway.subscription.create({ 'plan_id': get_plan_id(self.currency), 'merchant_account_id': get_merchant_account_id_for_paypal(self.currency, form.cleaned_data['amount']), 'payment_method_token': payment_method.token, 'first_billing_date': start_date, 'price': form.cleaned_data['amount'], }) if result.is_success: self.queue_ga_transaction(id=result.subscription.id, currency=self.currency, amount=form.cleaned_data['amount'], name='PayPal Donation', category='monthly') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'User Flow', 'eventAction': 'Monthly Upgrade Click', 'eventLabel': 'Yes', } ]) return self.handle_successful_transaction( result, form, send_data_to_basket=False) else: logger.error('Failed Braintree transaction: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form)
def process_monthly_transaction(self, form): # Create a customer and payment method for this customer result = self.create_customer(form) if result.is_success: payment_method = result.customer.payment_methods[0] else: return self.process_braintree_error_result(result, form) # Create a subscription against the payment method result = gateway.subscription.create({ 'plan_id': get_plan_id(self.currency), 'merchant_account_id': get_merchant_account_id_for_card(self.currency), 'payment_method_token': payment_method.token, 'price': form.cleaned_data['amount'], 'first_billing_date': now().date(), }) if result.is_success: self.queue_ga_transaction(id=result.subscription.id, currency=self.currency, amount=form.cleaned_data['amount'], name='Card Donation', category='monthly') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Donation', 'eventAction': 'Card', 'eventLabel': 'Monthly', } ]) # Bypass self.handle_successful_transaction, as this is not a transaction # but a subscription: we won't be posting anything to basket immediately, # instead relying on the webhook over in the 'process_webhook' task. # We still must set the correct session data self.set_session_data( result, form, payment_method=payment_method, transaction_id=result.subscription.id, last_4=payment_method.last_4, ) return HttpResponseRedirect(self.get_success_url()) else: logger.error('Failed to create Braintree subscription: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form)
def process_single_transaction(self, form, send_data_to_basket=True): # Create a customer and payment method for this customer # We vault this customer so that upsell doesn't require further authorization result = self.create_customer(form) if result.is_success: payment_method = result.customer.payment_methods[0] else: return self.process_braintree_error_result(result, form) result = gateway.transaction.sale({ 'amount': form.cleaned_data['amount'], 'merchant_account_id': get_merchant_account_id_for_card(self.currency), 'payment_method_token': payment_method.token, 'options': { 'submit_for_settlement': True }, 'device_data': form.cleaned_data['device_data'], }) if result.is_success: self.queue_ga_transaction(id=result.transaction.id, currency=self.currency, amount=form.cleaned_data['amount'], name='Card Donation', category='one-time') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Donation', 'eventAction': 'Card', 'eventLabel': 'Single', } ]) return self.handle_successful_transaction( result, form, payment_method_token=payment_method.token, transaction_id=result.transaction.id, settlement_amount=result.transaction.disbursement_details. settlement_amount, last_4=result.transaction.credit_card_details.last_4, send_data_to_basket=send_data_to_basket, ) else: logger.error('Failed Braintree transaction: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form)
def form_valid(self, form, send_data_to_basket=True): if send_data_to_basket: data = form.cleaned_data.copy() data['source_url'] = self.request.build_absolute_uri() data['lang'] = self.request.LANGUAGE_CODE queue.enqueue(send_newsletter_subscription_to_basket, data) queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Signup', 'eventAction': 'Submitted the Form', 'eventLabel': 'Email', } ]) return super().form_valid(form)
def process_monthly_transaction(self, form): # Create a customer and payment method for this customer result = self.create_customer(form) if result.is_success: payment_method = result.customer.payment_methods[0] else: return self.process_braintree_error_result(result, form) # Create a subcription against the payment method result = gateway.subscription.create({ 'plan_id': get_plan_id(self.currency), 'merchant_account_id': get_merchant_account_id_for_card(self.currency), 'payment_method_token': payment_method.token, 'price': form.cleaned_data['amount'], 'first_billing_date': now().date(), }) if result.is_success: self.queue_ga_transaction(id=result.subscription.id, currency=self.currency, amount=form.cleaned_data['amount'], name='Card Donation', category='monthly') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Donation', 'eventAction': 'Card', 'eventLabel': 'Monthly', } ]) return self.success( result, form, transaction_id=result.subscription.id, last_4=payment_method.last_4, send_data_to_basket=False, ) else: logger.error('Failed to create Braintree subscription: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form)
def form_valid(self, form): payment_method_token = self.request.session[ 'completed_transaction_details']['payment_method_token'] currency = self.request.session['completed_transaction_details'][ 'currency'] # Create a subcription against the payment method start_date = now().date() + relativedelta( months=1) # Start one month from today result = gateway.subscription.create({ 'plan_id': get_plan_id(currency), 'merchant_account_id': get_merchant_account_id_for_card(currency), 'payment_method_token': payment_method_token, 'first_billing_date': start_date, 'price': form.cleaned_data['amount'], }) if result.is_success: self.queue_ga_transaction(id=result.subscription.id, currency=currency, amount=form.cleaned_data['amount'], name='Card Donation', category='monthly') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'User Flow', 'eventAction': 'Monthly Upgrade Click', 'eventLabel': 'Yes', } ]) return self.success(result, form, currency=currency, send_data_to_basket=False) else: logger.error('Failed to create Braintree subscription: {}'.format( result.message), extra={'result': result}) return self.process_braintree_error_result(result, form)
def process_braintree_error_result(self, result, form): """ Parse an error result object from Braintree, and look for errors that we can report back to the user. If we find any, add these to the form. """ default_error_message = _( 'Sorry there was an error processing your payment. ' 'Please try again later or use a different payment method.') if result.errors.deep_errors: # Validation errors exist - check if they are meaningful to the user try: self.check_for_address_errors(result) except InvalidAddress as e: self.gateway_address_errors = e.errors return self.form_invalid(form) errors_to_report = self.filter_user_card_errors(result) if errors_to_report: for error_msg in errors_to_report: form.add_error(None, error_msg) else: form.add_error(None, default_error_message) else: # Processor decline or some other exception form.add_error(None, default_error_message) queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'User Flow', 'eventAction': 'Card Error', 'eventLabel': result.message, } ]) return self.form_invalid(form)
def queue_ga_transaction(self, id, currency, amount, name, category): queue_ga_event(self.request, [ 'ecommerce:addTransaction', { 'id': id, 'revenue': str(amount), 'currency': currency.upper(), 'affiliation': self.request.session.get('project', ''), } ]) queue_ga_event(self.request, [ 'ecommerce:addItem', { 'id': id, 'name': name, 'sku': name, 'category': category, 'price': str(amount), 'quantity': '1', } ]) queue_ga_event(self.request, ['ecommerce:send'])
def form_valid(self, form, send_data_to_basket=True): self.save_campaign_parameters_to_session(form) self.payment_frequency = form.cleaned_data['frequency'] self.currency = form.cleaned_data['currency'] success_kwargs = {} if self.payment_frequency == constants.FREQUENCY_SINGLE: result = gateway.transaction.sale({ 'amount': form.cleaned_data['amount'], 'merchant_account_id': get_merchant_account_id_for_paypal( self.currency, form.cleaned_data['amount']), 'custom_fields': self.get_custom_fields(form), 'payment_method_nonce': form.cleaned_data['braintree_nonce'], 'options': { 'submit_for_settlement': True } }) if result.is_success: self.queue_ga_transaction(id=result.transaction.id, currency=self.currency, amount=form.cleaned_data['amount'], name='PayPal Donation', category='one-time') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Donation', 'eventAction': 'PayPal', 'eventLabel': 'Single', } ]) else: # Create a customer and payment method for this customer result = gateway.customer.create({ 'payment_method_nonce': form.cleaned_data['braintree_nonce'], 'custom_fields': self.get_custom_fields(form), }) if result.is_success: payment_method = result.customer.payment_methods[0] success_kwargs['payment_method'] = payment_method else: return self.form_invalid(form, result=result) # Create a subcription against the payment method result = gateway.subscription.create({ 'plan_id': get_plan_id(self.currency), 'merchant_account_id': get_merchant_account_id_for_paypal( self.currency, form.cleaned_data['amount']), 'payment_method_token': payment_method.token, 'price': form.cleaned_data['amount'], 'first_billing_date': now().date(), }) send_data_to_basket = False if result.is_success: self.queue_ga_transaction(id=result.subscription.id, currency=self.currency, amount=form.cleaned_data['amount'], name='PayPal Donation', category='monthly') queue_ga_event(self.request, [ 'send', 'event', { 'eventCategory': 'Donation', 'eventAction': 'PayPal', 'eventLabel': 'Monthly', } ]) if result.is_success: return self.handle_successful_transaction( result, form, send_data_to_basket=send_data_to_basket, **success_kwargs) return self.form_invalid(form, result=result)