def clean(self): super(DirectContributionForm, self).clean() if not self._errors and not self.campaign.is_free: # # ---- IMPORTANT ----- # # Ideally, we would verify the CC here and post the transaction # later in save(). However, there isn't an efficient way to merely # verify a credit card without actually posting the CC transaction; # All that the ``CreditCardField`` validates that the CC number # abides by the Luhn-checksum but this could still not be a # legitimately issued CC number. # # Therefore, post the transaction here and produce validation errors # based on what the transaction processor returns. # # The end result is that if this method succeeds, the transaction has # already been posted. # # Save ``UserProfile`` and ``User`` fields to the database # because ``TransactionData`` needs to extract the payer's # name and address from the user instance. UserProfileForm.save(self, commit=True) data = TransactionData() data.user = self.user_profile.user payment = Payment() data.payment = payment payment.invoice_num = make_invoice_num(self.campaign, data.user) payment.total_amount = '%s' % self.campaign.contribution_amount * self.qty payment.cc_num = self.cleaned_data['cc_num'] payment.expiration_date = self.cleaned_data['expiration_date'] payment.ccv = self.cleaned_data['ccv'] self.payment_processor = PaymentProcessor() extra = dict(x_description=self.campaign.title) self.payment_processor.prepare_data(data, extra_dict=extra) is_success, code, text = self.payment_processor.process() if not is_success: raise forms.ValidationError(escape(text)) return self.cleaned_data
class DirectContributionForm(_ContributionFormBase): """Collect payment data and user profile data required by a campaign. Payment mode is direct via credit card. """ def __init__(self, campaign, user_profile, *args, **kwargs): _ContributionFormBase.__init__(self, 'direct', campaign, user_profile, *args, **kwargs) self.payment_processor = None self.fields['first_name'].help_text = _('First name') self.fields['last_name'].help_text = _('Last name. It may include middle initial and suffix. For example, if your name is John M. Smith Jr., the last name would be entered as "M. Smith Jr."') if campaign.address_required or not campaign.is_free: self.fields['address1'].help_text = _('The billing address for your credit card.') if not campaign.is_free: # Add payment fields self.fields['cc_num'] = CreditCardField(label=_('Credit Card #'), help_text=_('All major credit cards are supported. To safeguard your privacy, we will discard your credit card information after this transaction has been completed.')) if not self.qty_shown: h = self.fields['cc_num'].help_text self.fields['cc_num'].help_text = ' '.join([h, _('Your credit card will be charged for $%.2f.' % campaign.contribution_amount)]) self.fields['expiration_date'] = CreditCardExpiryDateField(label=_('Expiration Date')) self.fields['ccv'] = CreditCardCCVField(label=_('Verification Code')) def clean(self): super(DirectContributionForm, self).clean() if not self._errors and not self.campaign.is_free: # # ---- IMPORTANT ----- # # Ideally, we would verify the CC here and post the transaction # later in save(). However, there isn't an efficient way to merely # verify a credit card without actually posting the CC transaction; # All that the ``CreditCardField`` validates that the CC number # abides by the Luhn-checksum but this could still not be a # legitimately issued CC number. # # Therefore, post the transaction here and produce validation errors # based on what the transaction processor returns. # # The end result is that if this method succeeds, the transaction has # already been posted. # # Save ``UserProfile`` and ``User`` fields to the database # because ``TransactionData`` needs to extract the payer's # name and address from the user instance. UserProfileForm.save(self, commit=True) data = TransactionData() data.user = self.user_profile.user payment = Payment() data.payment = payment payment.invoice_num = make_invoice_num(self.campaign, data.user) payment.total_amount = '%s' % self.campaign.contribution_amount * self.qty payment.cc_num = self.cleaned_data['cc_num'] payment.expiration_date = self.cleaned_data['expiration_date'] payment.ccv = self.cleaned_data['ccv'] self.payment_processor = PaymentProcessor() extra = dict(x_description=self.campaign.title) self.payment_processor.prepare_data(data, extra_dict=extra) is_success, code, text = self.payment_processor.process() if not is_success: raise forms.ValidationError(escape(text)) return self.cleaned_data def save(self, commit=True): if not self.campaign.is_free: is_success, code, text = self.payment_processor.result if not is_success: raise PaymentError(_('There was a system error in processing your payment.')) amount = D(self.payment_processor.transaction_data.payment.total_amount) else: amount = 0 UserProfileForm.save(self, commit=commit) if not self.campaign.is_free: tx_id = self.payment_processor.transaction_data.payment.invoice_num else: tx_id = make_invoice_num(self.campaign, self.user_profile.user) c = Contribution(campaign=self.campaign, contributor=self.user_profile.user, amount=amount, qty=self.qty, paid_on=datetime.now(), payment_mode='direct', transaction_id=tx_id) if commit: c.save() return c
class DirectContributionForm(_ContributionFormBase): """Collect payment data and user profile data required by a campaign. Payment mode is direct via credit card. """ def __init__(self, campaign, user_profile, *args, **kwargs): _ContributionFormBase.__init__(self, 'direct', campaign, user_profile, *args, **kwargs) self.payment_processor = None self.fields['first_name'].help_text = _('First name') self.fields['last_name'].help_text = _( 'Last name. It may include middle initial and suffix. For example, if your name is John M. Smith Jr., the last name would be entered as "M. Smith Jr."' ) if campaign.address_required or not campaign.is_free: self.fields['address1'].help_text = _( 'The billing address for your credit card.') if not campaign.is_free: # Add payment fields self.fields['cc_num'] = CreditCardField( label=_('Credit Card #'), help_text= _('All major credit cards are supported. To safeguard your privacy, we will discard your credit card information after this transaction has been completed.' )) if not self.qty_shown: h = self.fields['cc_num'].help_text self.fields['cc_num'].help_text = ' '.join([ h, _('Your credit card will be charged for $%.2f.' % campaign.contribution_amount) ]) self.fields['expiration_date'] = CreditCardExpiryDateField( label=_('Expiration Date')) self.fields['ccv'] = CreditCardCCVField( label=_('Verification Code')) def clean(self): super(DirectContributionForm, self).clean() if not self._errors and not self.campaign.is_free: # # ---- IMPORTANT ----- # # Ideally, we would verify the CC here and post the transaction # later in save(). However, there isn't an efficient way to merely # verify a credit card without actually posting the CC transaction; # All that the ``CreditCardField`` validates that the CC number # abides by the Luhn-checksum but this could still not be a # legitimately issued CC number. # # Therefore, post the transaction here and produce validation errors # based on what the transaction processor returns. # # The end result is that if this method succeeds, the transaction has # already been posted. # # Save ``UserProfile`` and ``User`` fields to the database # because ``TransactionData`` needs to extract the payer's # name and address from the user instance. UserProfileForm.save(self, commit=True) data = TransactionData() data.user = self.user_profile.user payment = Payment() data.payment = payment payment.invoice_num = make_invoice_num(self.campaign, data.user) payment.total_amount = '%s' % self.campaign.contribution_amount * self.qty payment.cc_num = self.cleaned_data['cc_num'] payment.expiration_date = self.cleaned_data['expiration_date'] payment.ccv = self.cleaned_data['ccv'] self.payment_processor = PaymentProcessor() extra = dict(x_description=self.campaign.title) self.payment_processor.prepare_data(data, extra_dict=extra) is_success, code, text = self.payment_processor.process() if not is_success: raise forms.ValidationError(escape(text)) return self.cleaned_data def save(self, commit=True): if not self.campaign.is_free: is_success, code, text = self.payment_processor.result if not is_success: raise PaymentError( _('There was a system error in processing your payment.')) amount = D( self.payment_processor.transaction_data.payment.total_amount) else: amount = 0 UserProfileForm.save(self, commit=commit) if not self.campaign.is_free: tx_id = self.payment_processor.transaction_data.payment.invoice_num else: tx_id = make_invoice_num(self.campaign, self.user_profile.user) c = Contribution(campaign=self.campaign, contributor=self.user_profile.user, amount=amount, qty=self.qty, paid_on=datetime.now(), payment_mode='direct', transaction_id=tx_id) if commit: c.save() return c