Esempio n. 1
0
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
Esempio n. 2
0
    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
Esempio n. 3
0
    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