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"))
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)