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
 def test_tax(self):
     plan = RentalPlan.objects.get(slug="unlimited1")
     self.signup_plan(plan)
     billing_card = BillingCard.objects.all()[0]
     billing_card.county = "Palm Beach"
     billing_card.save()
     mrp = MemberRentalPlan.objects.all()[0]
     fake_now = datetime.datetime.combine(mrp.next_payment_date, datetime.time())
     with patched_context(datetime.datetime, "now", Fake().is_callable().returns(fake_now)):
         call_command("rent", "recurring_billing")
     self.assertEqual(BillingHistory.objects.count(), 2)
     bh = BillingHistory.objects.all()[1]
     self.assertEqual(bh.debit, plan.thereafter_payments_amount)
     self.assertEqual(bh.tax, get_tax_amount(plan.thereafter_payments_amount, state="FL", county="Palm Beach"))
Esempio n. 3
0
    def make_first_payment(self, user, profile, billing_card, customer_ip):
        """
        Being used when we would like to bill user for the first time and he doesn't
        have ``MemberRentalPlan`` associated yet.

        May raise ``PaymentError``.
        """
        billing_data = {
            "first_name": billing_card.first_name,
            "last_name": billing_card.last_name,
            "address1": billing_card.address1,
            "address2": billing_card.address2,
            "city": billing_card.city,
            "state": billing_card.state,
            "county": billing_card.county,
            "zip_code": billing_card.zip,
        }
        billing_card_data = billing_card.data.copy()
        shipping_data = {
            "first_name": user.first_name,
            "last_name": user.last_name,
            "address1": profile.shipping_address1,
            "address2": profile.shipping_address2,
            "city": profile.shipping_city,
            "state": profile.shipping_state,
            "county": profile.shipping_county,
            "zip_code": profile.shipping_zip,
        }
        email = user.email

        first_payment_amount = self.get_next_payment_amount()
        first_payment_type = self.get_next_payment_type()
        tax_amount = get_tax_amount(first_payment_amount, billing_data["state"], billing_data.get("county"))

        billing_history = BillingHistory.objects.create(
            payment_method=get_card_display_number(billing_card_data["number"]),
            debit=Decimal(first_payment_amount),
            reason="rent",
            type=TransactionType.RentPayment,
            card_data=billing_card_data,
            tax=tax_amount,
        )

        invoice_num, description = self.get_first_payment_description(billing_history.pk)
        aim_data = build_aim_data(
            shipping_data, billing_data, billing_card_data, invoice_num, description, email, customer_ip, tax_amount
        )

        aim = create_aim()
        success_status = TransactionStatus.Passed
        if first_payment_type == "AUTH_ONLY":
            aim_response = aim.authorize(first_payment_amount, **aim_data)
            success_status = TransactionStatus.Authorized
        elif first_payment_type == "AUTH_CAPTURE":
            aim_response = aim.capture(first_payment_amount, **aim_data)

        billing_history.description = description
        billing_history.aim_transaction_id = aim_response.transaction_id
        billing_history.aim_response = aim_response._as_dict
        billing_history.message = aim_response.response_reason_text
        if aim_response.response_code == 1:
            billing_history.status = success_status
            billing_history.save()
            return billing_history
        else:
            billing_history.status = TransactionStatus.Declined
            billing_history.save()
            raise PaymentError(aim_response.response_reason_text)