def take_money(user_or_profile, amount, reason, invoice_num_func=None, description=None, take_tax=True, take_credits=True, payment_type="AUTH_CAPTURE"): """ Takes money from user's CC and / or store credits. *Args*: ``amount``: e. g. Decimal('13.95') ``reason``: e. g. 'rent' ``invoice_num_func``: function that takes ``profile`` and ``billing_history``, and returns ``invoice_num`` (e. g. 'RENT_SUBS_1_2') ``description``: e. g. 'Monthly Membership - Nov 5, 2011 - Dec 5, 2011' """ profile = get_profile(user_or_profile) card = profile.billing_card aim_method = { "AUTH_CAPTURE": "capture" }[payment_type] tax_amount = 0 if take_tax: tax_amount = get_tax_amount(amount, card.state, card.county) withdrawed_credits = withdraw_store_credits(profile, amount) logger.debug('Taking $%s store credits...', withdrawed_credits) amount -= withdrawed_credits aim_response = None billing_history = BillingHistory.create( profile.user, profile.get_billing_card_display(), debit=amount, reason=reason, type=TransactionType.RentPayment ) if amount: logger.debug('Taking amount of $%s (+$%s tax)...', amount, tax_amount) aim = create_aim() invoice_num = invoice_num_func(profile, billing_history) aim_data = create_aim_data(amount, invoice_num, description, profile) aim_response = getattr(aim, aim_method)(amount, **aim_data) logger.debug('AIM aim_responseponse code: %s (%s)', aim_response.response_code, aim_response.response_reason_code) _create_billing_history(billing_history, profile, amount, tax_amount, description, withdrawed_credits, aim_response) if amount: if aim_response.response_code != 1: if aim_response.response_code == 3 and aim_response.response_reason_code in [6, 7, 8]: raise PaymentError("Credit card is expired") elif aim_response.response_reason_code in [2, 3, 4]: raise PaymentError("Insufficient funds are available for this transaction.") elif aim_response.avs_response == "U": raise PaymentError("We do not accept prepaid cards.") else: raise PaymentError("We are unable to process you credit card at this time.") send_billing_charge_approved(profile, amount) return aim_response
def clean(self): data = super(CheckoutForm, self).clean(skip_card_verification=True) if not self._errors: request = self.request user = request.user if not user.is_authenticated(): p = Profile.create(request, None, entry_point=ProfileEntryPoint.Buy) else: p = user.get_profile() self.profile = p order_data = { 'card_display_number': self.cached_card['display_number'], 'card_data': self.cached_card['data'], 'card_type': self.cached_card['type'], 'billing_state': self.cached_address['state'], 'billing_county': self.cached_address.get('county'),} self.order = BuyOrder.create(request, order_data, p) wizard = self.request.checkout_wizard f = wizard.get_form(0, self.request.POST) f.is_valid() # it's a long way to get info from here email = user.email if user.is_authenticated() else f.cleaned_data['email'] shipping_address = f.cached_address shipping_address.update(f.cached_name) shipping_address['country'] = 'USA' billing_address = self.cached_address billing_address.update(self.cached_name) billing_address['country'] = 'USA' self.billing_history = BillingHistory.create(user if user.is_authenticated() else None, order_data['card_display_number'], debit=self.order.get_order_total(), description = 'Shop Order #%s' % self.order.get_order_number(), reason='buy', type=TransactionType.BuyCheckout) if self.order.user: invoice_num = 'BUY_%s_%s' % (self.order.user.id, self.billing_history.id) else: invoice_num = 'BUY_%s' % self.billing_history.id card = self.cached_card['data'] aim_data = { 'number': card['number'], 'exp': '/'.join((card['exp_month'], card['exp_year'][-2:])), 'code': card['code'], 'billing': billing_address, 'shipping': shipping_address, 'invoice_num': invoice_num, 'description': self.order.get_aim_description(), 'x_customer_ip': self.request.META.get('REMOTE_ADDR'), 'x_email': email, 'x_po_num': self.order.order_no(), } if p.user: aim_data['x_cust_id'] = p.user.id self.billing_history.tax = self.order.get_tax_amount() self.billing_history.applied_credits = self.order.applied_credits aim_data['x_tax'] = self.billing_history.tax self.billing_history.aim_transaction_id = self.order.take_charge(aim_data) if self.billing_history.aim_transaction_id or not self.order.get_charge_amount(): self.billing_history.card_data = self.cached_card['data'] self.billing_history.save() self.order.payment_transaction = self.billing_history self.order.save() request.cart.empty() else: msg = self.order.message self.order.delete() if p.user: self.billing_history.status = TransactionStatus.Declined self.billing_history.save() else: self.billing_history.delete() raise forms.ValidationError(msg) return data
def clean(self): data = super(ConfirmPlanChangingForm, self).clean() if not self._errors: request = self.request wizard = self.request.rent_wizard f = wizard.get_form(0, self.request.POST) f.is_valid() # it's a long way to get info from here plan = int(f.cleaned_data['plan']) _profile = request.user.get_profile() current_plan = MemberRentalPlan.get_current_plan(_profile.user) self.current_plan = current_plan if current_plan and current_plan.plan == plan: self.rent_plan = None return data card = self.cached_card['data'] card['display_number'] = self.cached_card['display_number'] aim_data = { 'x_customer_ip': self.request.META.get('REMOTE_ADDR'), 'x_cust_id': _profile.user.id, 'x_email': _profile.user.email, } shipping_address = _profile.get_shipping_address_data() shipping_address.update(_profile.get_name_data()) shipping_address['country'] = 'USA' billing_address = _profile.get_billing_data() billing_address['country'] = 'USA' downgrade = current_plan and plan <= current_plan.plan self.downgrade = downgrade if downgrade: return data self.rent_plan = MemberRentalPlan.create(_profile.user, plan, downgrade) self.billing_history = None amount = RentalPlan.get_start_payment_amount(plan) #malcala: changs to capture money #do_capture = False do_capture = True if current_plan: last_payment = current_plan.get_last_payment() if last_payment and last_payment.status == TransactionStatus.Passed: orders = RentOrder.objects.filter( user=current_plan.user, date_rent__gte=current_plan.created ).exclude(status__in=[RentOrderStatus.Prepared, RentOrderStatus.Canceled]) if orders.count(): if last_payment.debit < amount: amount -= (current_plan.next_payment_amount or RentalPlan.get_start_payment_amount(current_plan.plan)) do_capture = True tax = Tax.get_value(billing_address['state'], billing_address['county']) tax_amount = decimal.Decimal('%.2f' % (amount * tax / decimal.Decimal('100.0'))) aim_data['x_tax'] = tax_amount self.billing_history = BillingHistory.create(_profile.user, card['display_number'], debit=amount, reason='rent', type=TransactionType.RentPayment) self.billing_history.tax = tax_amount invoice_num, description = self.rent_plan.get_payment_description(False, self.billing_history.id) self.billing_history.description = description self.billing_history.save() if do_capture: res, aim_response, applied_credits, applied_amount = self.rent_plan.take_money(amount, tax_amount, invoice_num, description, card=card, shipping_data=shipping_address, billing_data=billing_address, aim_data=aim_data, profile=_profile) self.billing_history.applied_credits = applied_credits self.billing_history.status = TransactionStatus.Passed self.billing_history.setted = True else: res, aim_response = self.rent_plan.authorize_money(amount, tax_amount, invoice_num, description, card=card, shipping_data=shipping_address, billing_data=billing_address, aim_data=aim_data) self.billing_history.status = TransactionStatus.Authorized self.billing_history.setted = False if aim_response: self.billing_history.aim_transaction_id = aim_response.transaction_id self.billing_history.aim_response = aim_response._as_dict self.billing_history.message = aim_response.response_reason_text if not res: self.billing_history.status = TransactionStatus.Declined self.billing_history.save() self.rent_plan.delete() raise forms.ValidationError(self.rent_plan.status_message) self.billing_history.card_data = self.cached_card['data'] self.billing_history.save() return data