def charge(db, route, amount, return_url, billing_address=None): """Charge the given credit card (`route`). Amount should be the nominal amount. We'll compute fees below this function and add it to amount to end up with charge_amount. """ assert isinstance(amount, (Decimal, Money)), type(amount) assert route assert route.network == 'mango-cc' participant = route.participant amount = Money(amount, 'EUR') if isinstance(amount, Decimal) else amount charge_amount, fee, vat = upcharge_card(amount) amount = charge_amount - fee wallet = participant.get_current_wallet(amount.currency, create=True) e_id = record_exchange(db, route, amount, fee, vat, participant, 'pre').id payin = DirectPayIn() payin.AuthorId = participant.mangopay_user_id if billing_address: payin.Billing = {'Address': billing_address} payin.CreditedWalletId = wallet.remote_id payin.DebitedFunds = Money_to_cents(charge_amount) payin.CardId = route.address payin.SecureMode = 'FORCE' payin.SecureModeReturnURL = return_url payin.Fees = Money_to_cents(fee) payin.Tag = str(e_id) try: test_hook() payin.save() except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, '', 'failed', error, participant) if payin.SecureModeRedirectURL: raise Redirect(payin.SecureModeRedirectURL) return record_exchange_result( db, e_id, payin.Id, payin.Status.lower(), repr_error(payin), participant )
def test_upcharge_at_min_minus_one_cent(self): actual = upcharge_card(PAYIN_CARD_MIN['EUR'] - EUR('0.01')) expected = upcharge_card(PAYIN_CARD_MIN['EUR']) assert actual == expected
def test_upcharge_at_one_cent(self): actual = upcharge_card(EUR('0.01')) expected = upcharge_card(PAYIN_CARD_MIN['EUR']) assert actual == expected
def test_upcharge_at_target(self): actual = upcharge_card(PAYIN_CARD_TARGET['EUR']) expected = (EUR('94.19'), EUR('2.19'), EUR('0.32')) assert actual == expected assert actual[1] / actual[0] < D('0.024') # less than 2.4% fee
def test_upcharge_at_min(self): actual = upcharge_card(PAYIN_CARD_MIN['EUR']) expected = (EUR('15.54'), EUR('0.54'), EUR('0.08')) assert actual == expected assert actual[1] / actual[0] < D('0.035') # less than 3.5% fee
def test_upcharge_full_in_rounded_case(self): actual = upcharge_card(EUR('5.00')) expected = upcharge_card(PAYIN_CARD_MIN['EUR']) assert actual == expected
def test_upcharge_basically_works(self): actual = upcharge_card(EUR('20.00')) expected = (EUR('20.65'), EUR('0.65'), EUR('0.10')) assert actual == expected