def payout(db, participant, amount): if participant.is_suspicious: raise UserIsSuspicious route = ExchangeRoute.from_network(participant, 'mango-ba') assert route ba = mangoapi.users.GetBankAccount(participant.mangopay_user_id, route.address) # Do final calculations credit_amount, fee = skim_credit(amount, ba) if credit_amount <= 0 or fee / credit_amount > 0.1: raise TransactionFeeTooHigh # Try to dance with MangoPay e_id = record_exchange(db, route, -credit_amount, fee, participant, 'pre') payout = PayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = Money(int(credit_amount * 100), 'EUR') payout.DebitedWalletId = participant.mangopay_wallet_id payout.Fees = Money(int(fee * 100), 'EUR') payout.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire( BankAccountId=route.address, BankWireRef=str(e_id), ) payout.Tag = str(e_id) try: test_hook() mangoapi.payOuts.Create(payout) return record_exchange_result(db, e_id, 'created', None, participant) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant)
def payin_bank_wire(db, participant, debit_amount): """Prepare to receive a bank wire payin. The amount should be how much the user intends to send, not how much will arrive in the wallet. """ route = ExchangeRoute.from_network(participant, 'mango-bw') if not route: route = ExchangeRoute.insert(participant, 'mango-bw', 'x') amount, fee, vat = skim_amount(debit_amount, FEE_PAYIN_BANK_WIRE) e_id = record_exchange(db, route, amount, fee, vat, participant, 'pre') payin = PayIn() payin.AuthorId = participant.mangopay_user_id if not participant.mangopay_wallet_id: create_wallet(db, participant) payin.CreditedWalletId = participant.mangopay_wallet_id payin.ExecutionDetails = PayInExecutionDetailsDirect() payin.PaymentDetails = PayInPaymentDetailsBankWire( DeclaredDebitedFunds=Money(int(debit_amount * 100), 'EUR'), DeclaredFees=Money(int(fee * 100), 'EUR'), ) payin.Tag = str(e_id) try: test_hook() payin = mangoapi.payIns.Create(payin) except Exception as e: error = repr_exception(e) return None, record_exchange_result(db, e_id, 'failed', error, participant) e = record_exchange_result(db, e_id, payin.Status.lower(), repr_error(payin), participant) return payin, e
def test_associate_nonexistent_card(self, Card_get): Card_get.side_effect = Card.DoesNotExist r = self.client.PxST('/homer/routes/credit-card.json', data={'CardId': '-1'}, auth_as=self.homer) assert r.code == 400 cards = ExchangeRoute.from_network(self.homer, 'mango-cc') assert not cards
def make_exchange(self, route, amount, fee, participant, status='succeeded', error='', vat=0): amount = amount if isinstance(amount, Money) else Money(amount, 'EUR') fee = fee if isinstance(fee, Money) else Money(fee, amount.currency) vat = vat if isinstance(vat, Money) else Money(vat, fee.currency) if not isinstance(route, ExchangeRoute): network = route currency = amount.currency if network == 'mango-cc' else None routes = ExchangeRoute.from_network(participant, network, currency=currency) if routes: route = routes[0] else: from .mangopay import MangopayHarness address = MangopayHarness.card_id if network == 'mango-cc' else -participant.id route = ExchangeRoute.insert(participant, network, address, 'chargeable', currency=currency) assert route e_id = record_exchange(self.db, route, amount, fee, vat, participant, 'pre').id record_exchange_result(self.db, e_id, -e_id, status, error, participant) return e_id
def fake_exchange(db, participant, amount, fee, vat, timestamp): route = ExchangeRoute.from_network(participant, 'mango-cc') if not route: route = _fake_thing( db, "exchange_routes", participant=participant.id, network='mango-cc', address='-1', error='', one_off=False, ) e = _fake_thing( db, "exchanges", timestamp=timestamp, participant=participant.id, amount=amount, fee=fee, vat=vat, status='pre', route=route.id, ) record_exchange_result(db, e.id, 'succeeded', '', participant) return e
def payout(db, participant, amount): if participant.is_suspicious: raise UserIsSuspicious route = ExchangeRoute.from_network(participant, 'mango-ba') assert route ba = mangoapi.users.GetBankAccount(participant.mangopay_user_id, route.address) # Do final calculations credit_amount, fee = skim_credit(amount, ba) if credit_amount <= 0 or fee / credit_amount > 0.1: raise TransactionFeeTooHigh # Try to dance with MangoPay e_id = record_exchange(db, route, -credit_amount, fee, participant, 'pre') payout = PayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = Money(int(credit_amount * 100), 'EUR') payout.DebitedWalletId = participant.mangopay_wallet_id payout.Fees = Money(int(fee * 100), 'EUR') payout.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire( BankAccountId=route.address, BankWireRef=str(e_id), ) payout.Tag = str(e_id) try: test_hook() mangoapi.payOuts.Create(payout) return record_exchange_result(db, e_id, 'created', None, participant) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant)
def test_delete_card(self): self.hit('janet', 'delete', 'mango-cc', self.card_id) janet = Participant.from_username('janet') cards = ExchangeRoute.from_network(janet, 'mango-cc') assert not cards assert janet.mangopay_user_id
def fake_exchange(db, participant, amount, fee, vat, timestamp): routes = ExchangeRoute.from_network(participant, 'mango-cc', currency='EUR') if routes: route = routes[0] else: route = _fake_thing( db, "exchange_routes", participant=participant.id, network='mango-cc', address='-1', status='chargeable', one_off=False, remote_user_id=participant.mangopay_user_id, currency='EUR', ) e = _fake_thing( db, "exchanges", timestamp=timestamp, participant=participant.id, amount=amount, fee=fee, vat=vat, status='pre', route=route.id, wallet_id='-%i' % participant.id, ) record_exchange_result(db, e.id, -e.id, 'succeeded', '', participant) return e
def test_associate_nonexistent_card(self, Card_get): Card_get.side_effect = Card.DoesNotExist r = self.client.PxST('/homer/routes/credit-card.json', data={'CardId': '-1'}, auth_as=self.homer) assert r.code == 400 cards = ExchangeRoute.from_network(self.homer, 'mango-cc') assert not cards
def payin_bank_wire(db, participant, debit_amount): """Prepare to receive a bank wire payin. The amount should be how much the user intends to send, not how much will arrive in the wallet. """ route = ExchangeRoute.from_network(participant, 'mango-bw') if not route: route = ExchangeRoute.insert(participant, 'mango-bw', 'x') amount, fee, vat = skim_bank_wire(debit_amount) e_id = record_exchange(db, route, amount, fee, vat, participant, 'pre') payin = BankWirePayIn() payin.AuthorId = participant.mangopay_user_id if not participant.mangopay_wallet_id: create_wallet(db, participant) payin.CreditedWalletId = participant.mangopay_wallet_id payin.DeclaredDebitedFunds = Money(int(debit_amount * 100), 'EUR') payin.DeclaredFees = Money(int(fee * 100), 'EUR') payin.Tag = str(e_id) try: test_hook() payin.save() except Exception as e: error = repr_exception(e) return None, record_exchange_result(db, e_id, 'failed', error, participant) e = record_exchange_result(db, e_id, payin.Status.lower(), repr_error(payin), participant) return payin, e
def test_delete_card(self): self.hit('janet', 'delete', 'mango-cc', self.card_id) janet = Participant.from_username('janet') cards = ExchangeRoute.from_network(janet, 'mango-cc') assert not cards assert janet.mangopay_user_id
def fake_exchange(db, participant, amount, fee, vat, timestamp): routes = ExchangeRoute.from_network(participant, 'mango-cc') if routes: route = routes[0] else: route = _fake_thing( db, "exchange_routes", participant=participant.id, network='mango-cc', address='-1', error='', one_off=False, remote_user_id=participant.mangopay_user_id, ) e = _fake_thing( db, "exchanges", timestamp=timestamp, participant=participant.id, amount=amount, fee=fee, vat=vat, status='pre', route=route.id, wallet_id=participant.mangopay_wallet_id, ) record_exchange_result(db, e.id, -e.id, 'succeeded', '', participant) return e
def make_exchange(self, route, amount, fee, participant, status='succeeded', error='', vat=0): if not isinstance(route, ExchangeRoute): network = route route = ExchangeRoute.from_network(participant, network) if not route: from .mangopay import MangopayHarness route = ExchangeRoute.insert(participant, network, MangopayHarness.card_id) assert route e_id = record_exchange(self.db, route, amount, fee, vat, participant, 'pre') record_exchange_result(self.db, e_id, status, error, participant) return e_id
def make_exchange(self, route, amount, fee, participant, status='succeeded', error='', vat=0): if not isinstance(route, ExchangeRoute): network = route route = ExchangeRoute.from_network(participant, network) if not route: from .mangopay import MangopayHarness route = ExchangeRoute.insert(participant, network, MangopayHarness.card_id) assert route e_id = record_exchange(self.db, route, amount, fee, vat, participant, 'pre') record_exchange_result(self.db, e_id, status, error, participant) return e_id
def charge(db, participant, amount, return_url): """Charge the participant's credit card. Amount should be the nominal amount. We'll compute fees below this function and add it to amount to end up with charge_amount. """ typecheck(amount, Decimal) if participant.is_suspicious: raise UserIsSuspicious route = ExchangeRoute.from_network(participant, 'mango-cc') assert route charge_amount, fee = upcharge(amount) amount = charge_amount - fee e_id = record_exchange(db, route, amount, fee, participant, 'pre') payin = PayIn() payin.AuthorId = participant.mangopay_user_id if not participant.mangopay_wallet_id: create_wallet(db, participant) payin.CreditedWalletId = participant.mangopay_wallet_id payin.DebitedFunds = Money(int(charge_amount * 100), 'EUR') payin.ExecutionDetails = PayInExecutionDetailsDirect( CardId=route.address, SecureModeReturnURL=return_url, ) payin.Fees = Money(int(fee * 100), 'EUR') payin.PaymentDetails = PayInPaymentDetailsCard( CardType='CB_VISA_MASTERCARD') payin.Tag = str(e_id) try: test_hook() payin = mangoapi.payIns.Create(payin) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant) if payin.ExecutionDetails.SecureModeRedirectURL: raise Response( 302, headers={'Location': payin.ExecutionDetails.SecureModeRedirectURL}) return record_exchange_result(db, e_id, 'succeeded', None, participant)
def make_exchange(self, route, amount, fee, participant, status='succeeded', error='', vat=0): amount = amount if isinstance(amount, Money) else Money(amount, 'EUR') fee = fee if isinstance(fee, Money) else Money(fee, amount.currency) vat = vat if isinstance(vat, Money) else Money(vat, fee.currency) if not isinstance(route, ExchangeRoute): network = route currency = amount.currency if network == 'mango-cc' else None routes = ExchangeRoute.from_network(participant, network, currency=currency) if routes: route = routes[0] else: from .mangopay import MangopayHarness address = MangopayHarness.card_id if network == 'mango-cc' else -participant.id route = ExchangeRoute.insert(participant, network, address, currency=currency) assert route e_id = record_exchange(self.db, route, amount, fee, vat, participant, 'pre').id record_exchange_result(self.db, e_id, -e_id, status, error, participant) return e_id
def fake_exchange(db, participant, amount, fee, timestamp): route = ExchangeRoute.from_network(participant, "mango-cc") if not route: route = _fake_thing( db, "exchange_routes", participant=participant.id, network="mango-cc", address="-1", error="", one_off=False ) e = _fake_thing( db, "exchanges", timestamp=timestamp, participant=participant.id, amount=amount, fee=fee, status="pre", route=route.id, ) record_exchange_result(db, e.id, "succeeded", "", participant) return e
def payout(db, participant, amount, ignore_high_fee=False): assert amount > 0 if participant.is_suspended: raise AccountSuspended() payday = db.one("SELECT * FROM paydays WHERE ts_start > ts_end") if payday: raise PaydayIsRunning route = ExchangeRoute.from_network(participant, 'mango-ba') assert route ba = mangoapi.users.GetBankAccount(participant.mangopay_user_id, route.address) # Do final calculations credit_amount, fee, vat = skim_credit(amount, ba) if credit_amount <= 0 and fee > 0: raise FeeExceedsAmount fee_percent = fee / amount if fee_percent > FEE_PAYOUT_WARN and not ignore_high_fee: raise TransactionFeeTooHigh(fee_percent, fee, amount) # Try to dance with MangoPay e_id = record_exchange(db, route, -credit_amount, fee, vat, participant, 'pre') payout = PayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = Money(int(amount * 100), 'EUR') payout.DebitedWalletId = participant.mangopay_wallet_id payout.Fees = Money(int(fee * 100), 'EUR') payout.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire( BankAccountId=route.address, BankWireRef=str(e_id), ) payout.Tag = str(e_id) try: test_hook() payout = mangoapi.payOuts.Create(payout) return record_exchange_result(db, e_id, payout.Status.lower(), repr_error(payout), participant) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant)
def charge(db, participant, amount, return_url): """Charge the participant's credit card. Amount should be the nominal amount. We'll compute fees below this function and add it to amount to end up with charge_amount. """ typecheck(amount, Decimal) if participant.is_suspicious: raise UserIsSuspicious route = ExchangeRoute.from_network(participant, 'mango-cc') assert route charge_amount, fee = upcharge(amount) amount = charge_amount - fee e_id = record_exchange(db, route, amount, fee, participant, 'pre') payin = PayIn() payin.AuthorId = participant.mangopay_user_id if not participant.mangopay_wallet_id: create_wallet(db, participant) payin.CreditedWalletId = participant.mangopay_wallet_id payin.DebitedFunds = Money(int(charge_amount * 100), 'EUR') payin.ExecutionDetails = PayInExecutionDetailsDirect( CardId=route.address, SecureModeReturnURL=return_url, ) payin.Fees = Money(int(fee * 100), 'EUR') payin.PaymentDetails = PayInPaymentDetailsCard(CardType='CB_VISA_MASTERCARD') payin.Tag = str(e_id) try: test_hook() payin = mangoapi.payIns.Create(payin) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant) if payin.ExecutionDetails.SecureModeRedirectURL: raise Response(302, headers={'Location': payin.ExecutionDetails.SecureModeRedirectURL}) return record_exchange_result(db, e_id, 'succeeded', None, participant)
def payout(db, participant, amount, ignore_high_fee=False): assert amount > 0 payday = db.one("SELECT * FROM paydays WHERE ts_start > ts_end") if payday: raise PaydayIsRunning route = ExchangeRoute.from_network(participant, 'mango-ba') assert route ba = mangoapi.users.GetBankAccount(participant.mangopay_user_id, route.address) # Do final calculations credit_amount, fee, vat = skim_credit(amount, ba) if credit_amount <= 0 and fee > 0: raise FeeExceedsAmount fee_percent = fee / amount if fee_percent > FEE_CREDIT_WARN and not ignore_high_fee: raise TransactionFeeTooHigh(fee_percent, fee, amount) # Try to dance with MangoPay e_id = record_exchange(db, route, -credit_amount, fee, vat, participant, 'pre') payout = PayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = Money(int(amount * 100), 'EUR') payout.DebitedWalletId = participant.mangopay_wallet_id payout.Fees = Money(int(fee * 100), 'EUR') payout.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire( BankAccountId=route.address, BankWireRef=str(e_id), ) payout.Tag = str(e_id) try: test_hook() mangoapi.payOuts.Create(payout) return record_exchange_result(db, e_id, 'created', None, participant) except Exception as e: error = repr_exception(e) return record_exchange_result(db, e_id, 'failed', error, participant)
def charge(db, participant, amount, return_url): """Charge the participant's credit card. Amount should be the nominal amount. We'll compute fees below this function and add it to amount to end up with charge_amount. """ typecheck(amount, Decimal) route = ExchangeRoute.from_network(participant, 'mango-cc') assert route charge_amount, fee, vat = upcharge_card(amount) amount = charge_amount - fee e_id = record_exchange(db, route, amount, fee, vat, participant, 'pre') payin = DirectPayIn() payin.AuthorId = participant.mangopay_user_id if not participant.mangopay_wallet_id: create_wallet(db, participant) payin.CreditedWalletId = participant.mangopay_wallet_id payin.DebitedFunds = Money(int(charge_amount * 100), 'EUR') payin.CardId = route.address payin.SecureModeReturnURL = return_url payin.Fees = Money(int(fee * 100), 'EUR') 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.Status.lower(), repr_error(payin), participant)
def fake_exchange(db, participant, amount, fee, timestamp): route = ExchangeRoute.from_network(participant, 'mango-cc') if not route: route = _fake_thing( db, "exchange_routes", participant=participant.id, network='mango-cc', address='-1', error='', one_off=False, ) e = _fake_thing( db, "exchanges", timestamp=timestamp, participant=participant.id, amount=amount, fee=fee, status='pre', route=route.id, ) record_exchange_result(db, e.id, 'succeeded', '', participant) return e