示例#1
0
 def setUp(self):
     Harness.setUp(self)
     self.david = self.make_participant(
         "david",
         is_suspicious=False,
         mangopay_user_id=self.david_id,
         mangopay_wallet_id=self.david_wallet_id,
         email="*****@*****.**",
     )
     self.janet = self.make_participant(
         "janet",
         is_suspicious=False,
         mangopay_user_id=self.janet_id,
         mangopay_wallet_id=self.janet_wallet_id,
         email="*****@*****.**",
     )
     self.janet_route = ExchangeRoute.insert(self.janet, "mango-cc", self.card_id)
     self.homer = self.make_participant(
         "homer",
         is_suspicious=False,
         mangopay_user_id=self.homer_id,
         mangopay_wallet_id=self.homer_wallet_id,
         email="*****@*****.**",
     )
     self.homer_route = ExchangeRoute.insert(self.homer, "mango-ba", self.bank_account.Id)
示例#2
0
 def setUp(self):
     Harness.setUp(self)
     self.david = self.make_participant(
         'david',
         mangopay_user_id=self.david_id,
         mangopay_wallet_id=self.david_wallet_id,
         email='*****@*****.**')
     self.janet = self.make_participant(
         'janet',
         mangopay_user_id=self.janet_id,
         mangopay_wallet_id=self.janet_wallet_id,
         email='*****@*****.**')
     self.janet_route = ExchangeRoute.insert(self.janet,
                                             'mango-cc',
                                             self.card_id,
                                             'chargeable',
                                             currency='EUR')
     self.homer = self.make_participant(
         'homer',
         mangopay_user_id=self.homer_id,
         mangopay_wallet_id=self.homer_wallet_id,
         email='*****@*****.**')
     self.homer_route = ExchangeRoute.insert(self.homer, 'mango-ba',
                                             self.bank_account.Id,
                                             'chargeable')
示例#3
0
    def make_participant(self, username, **kw):
        platform = kw.pop('elsewhere', 'github')
        domain = kw.pop('domain', '')
        kw2 = {}
        for key in ('last_bill_result', 'balance', 'mangopay_wallet_id'):
            if key in kw:
                kw2[key] = kw.pop(key)

        kind = kw.setdefault('kind', 'individual')
        if kind not in ('group', 'community'):
            kw.setdefault('password', 'x')
            kw.setdefault('session_token', username)
            i = next(self.seq)
            kw.setdefault('mangopay_user_id', -i)
        kw.setdefault('status', 'active')
        if username:
            kw['username'] = username
        if 'join_time' not in kw:
            kw['join_time'] = utcnow()
        cols, vals = zip(*kw.items())
        cols = ', '.join(cols)
        placeholders = ', '.join(['%s']*len(vals))
        participant = self.db.one("""
            INSERT INTO participants
                        ({0})
                 VALUES ({1})
              RETURNING participants.*::participants
        """.format(cols, placeholders), vals)

        self.db.run("""
            INSERT INTO elsewhere
                        (platform, user_id, user_name, participant, domain)
                 VALUES (%s,%s,%s,%s,%s)
        """, (platform, participant.id, username, participant.id, domain))

        if kind not in ('group', 'community') and participant.mangopay_user_id:
            wallet_id = kw2.get('mangopay_wallet_id', -participant.id)
            zero = ZERO[participant.main_currency]
            self.db.run("""
                INSERT INTO wallets
                            (remote_id, balance, owner, remote_owner_id)
                     VALUES (%s, %s, %s, %s)
            """, (wallet_id, zero, participant.id, participant.mangopay_user_id))

        if 'email' in kw:
            self.db.run("""
                INSERT INTO emails
                            (participant, address, verified, verified_time)
                     VALUES (%s, %s, true, now())
            """, (participant.id, kw['email']))
        if 'last_bill_result' in kw2:
            ExchangeRoute.insert(
                participant, 'mango-cc', '-1', kw2['last_bill_result'],
                currency=participant.main_currency
            )
        if 'balance' in kw2 and kw2['balance'] != 0:
            self.make_exchange('mango-cc', kw2['balance'], 0, participant)

        return participant
示例#4
0
 def test_get_tip_distribution_ignores_bad_cc(self):
     bad_cc = self.make_participant('bad_cc')
     ExchangeRoute.insert(bad_cc, 'mango-cc', '-1', 'failed', currency='EUR')
     self.alice.set_tip_to(self.bob, EUR('1.00'))
     self.make_payin_and_transfer(self.alice_card, self.bob, EUR('25.00'))
     bad_cc.set_tip_to(self.bob, EUR('3.00'))
     expected = ([[EUR('1.00'), 1, EUR('1.00'), EUR('1.00'), 1, Decimal('1')]],
                 1, EUR('1.00'))
     actual = self.bob.get_tip_distribution()
     assert actual == expected
示例#5
0
 def _test_payin_bank_wire_callback_amount_mismatch(self, Get, fee):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x')
     e_id = record_exchange(self.db, route, 11, 0, 0, homer, 'pre')
     assert homer.balance == 0
     homer.close(None)
     assert homer.status == 'closed'
     qs = "EventType=PAYIN_NORMAL_SUCCEEDED&RessourceId=123456790"
     payin = BankWirePayIn()
     payin.Status = 'SUCCEEDED'
     payin.ResultCode = '000000'
     payin.ResultMessage = None
     payin.AuthorId = homer.mangopay_user_id
     payin.PaymentType = 'BANK_WIRE'
     payin.DeclaredDebitedFunds = Money(4500, 'EUR')
     payin.DeclaredFees = Money(100, 'EUR')
     payin.DebitedFunds = Money(302, 'EUR')
     payin.Fees = Money(fee, 'EUR')
     payin.CreditedFunds = Money(302 - fee, 'EUR')
     payin.Tag = str(e_id)
     Get.return_value = payin
     r = self.callback(qs)
     assert r.code == 200, r.text
     e = self.db.one("SELECT * FROM exchanges WHERE id = %s", (e_id, ))
     assert e.amount == D(payin.CreditedFunds.Amount) / D(100)
     assert e.fee == D(fee) / D(100)
     assert e.vat == D('0.01')
     assert e.status == 'succeeded'
     homer = homer.refetch()
     assert homer.balance == e.amount
     assert homer.status == 'active'
     emails = self.get_emails()
     assert len(emails) == 1
     assert emails[0]['to'][0] == 'homer <%s>' % homer.email
     assert 'succ' in emails[0]['subject']
示例#6
0
 def setUp(self):
     Harness.setUp(self)
     self.david = self.make_participant(
         'david', mangopay_user_id=self.david_id,
         mangopay_wallet_id=self.david_wallet_id, email='*****@*****.**'
     )
     self.janet = self.make_participant(
         'janet', mangopay_user_id=self.janet_id,
         mangopay_wallet_id=self.janet_wallet_id, email='*****@*****.**'
     )
     self.janet_route = ExchangeRoute.insert(self.janet, 'mango-cc', self.card_id)
     self.homer = self.make_participant(
         'homer', mangopay_user_id=self.homer_id,
         mangopay_wallet_id=self.homer_wallet_id, email='*****@*****.**'
     )
     self.homer_route = ExchangeRoute.insert(self.homer, 'mango-ba', self.bank_account.Id)
示例#7
0
 def test_payout_amount_under_minimum(self, gba):
     usd_user = self.make_participant('usd_user', main_currency='USD')
     route = ExchangeRoute.insert(usd_user, 'mango-ba', 'fake ID', 'chargeable')
     self.make_exchange('mango-cc', USD(8), 0, usd_user)
     gba.return_value = self.bank_account_outside_sepa
     with self.assertRaises(FeeExceedsAmount):
         payout(self.db, route, USD('0.10'))
 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
示例#9
0
    def test_negative_paid_in_advance(self):
        team = self.make_participant('team', kind='group')
        alice = self.make_participant('alice')
        team.set_take_for(alice, EUR('1.00'), team)

        stripe_account_alice = self.add_payment_account(alice, 'stripe')

        donor = self.make_participant('donor')
        donor.set_tip_to(team, EUR('5'))

        donor_card = ExchangeRoute.insert(donor,
                                          'stripe-card',
                                          'x',
                                          'chargeable',
                                          remote_user_id='x')
        payin, pt = self.make_payin_and_transfer(donor_card, team, EUR('10'),
                                                 'stripe')
        assert pt.destination == stripe_account_alice.pk

        self.db.run("UPDATE takes SET paid_in_advance = -paid_in_advance")

        Payday.start().run()

        transfers = self.db.all("SELECT * FROM transfers ORDER BY id")
        assert len(transfers) == 0
示例#10
0
    def test_takes_paid_in_advance(self):
        team = self.make_participant(
            'team', kind='group', accepted_currencies='EUR,USD'
        )
        alice = self.make_participant('alice', main_currency='EUR',
                                      accepted_currencies='EUR,USD')
        team.set_take_for(alice, EUR('1.00'), team)
        bob = self.make_participant('bob', main_currency='USD',
                                    accepted_currencies='EUR,USD')
        team.set_take_for(bob, EUR('1.00'), team)

        stripe_account_alice = self.add_payment_account(alice, 'stripe', default_currency='EUR')
        self.add_payment_account(bob, 'stripe', default_currency='USD')

        carl = self.make_participant('carl')
        carl.set_tip_to(team, EUR('10'))

        carl_card = ExchangeRoute.insert(
            carl, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
        )
        payin, pt = self.make_payin_and_transfer(carl_card, team, EUR('10'))
        assert pt.destination == stripe_account_alice.pk

        Payday.start().run()

        transfers = self.db.all("SELECT * FROM transfers ORDER BY id")
        assert len(transfers) == 1
        assert transfers[0].virtual is True
        assert transfers[0].tipper == carl.id
        assert transfers[0].tippee == alice.id
        assert transfers[0].amount == EUR('1')
示例#11
0
    def test_takes_paid_in_advance(self):
        team = self.make_participant(
            'team', kind='group', accepted_currencies='EUR,USD'
        )
        alice = self.make_participant('alice', main_currency='EUR',
                                      accepted_currencies='EUR,USD')
        team.set_take_for(alice, EUR('1.00'), team)
        bob = self.make_participant('bob', main_currency='USD',
                                    accepted_currencies='EUR,USD')
        team.set_take_for(bob, EUR('1.00'), team)

        stripe_account_alice = self.add_payment_account(alice, 'stripe', default_currency='EUR')
        self.add_payment_account(bob, 'stripe', country='US', default_currency='USD')

        carl = self.make_participant('carl')
        carl.set_tip_to(team, EUR('10'))

        carl_card = ExchangeRoute.insert(
            carl, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
        )
        payin, pt = self.make_payin_and_transfer(carl_card, team, EUR('10'))
        assert pt.destination == stripe_account_alice.pk

        Payday.start().run()

        transfers = self.db.all("SELECT * FROM transfers ORDER BY id")
        assert len(transfers) == 1
        assert transfers[0].virtual is True
        assert transfers[0].tipper == carl.id
        assert transfers[0].tippee == alice.id
        assert transfers[0].amount == EUR('1')
示例#12
0
 def test_payout_amount_under_minimum(self, gba):
     usd_user = self.make_participant('usd_user', main_currency='USD')
     route = ExchangeRoute.insert(usd_user, 'mango-ba', 'fake ID')
     self.make_exchange('mango-cc', USD(8), 0, usd_user)
     gba.return_value = self.bank_account_outside_sepa
     with self.assertRaises(FeeExceedsAmount):
         payout(self.db, route, USD('0.10'))
    def test_identity_form(self):
        janeway = self.make_participant(
            'janeway',
            email='*****@*****.**',
            mangopay_user_id=None,
        )
        assert janeway.mangopay_user_id is None

        # Create a mangopay natural user
        data = dict(user_data, terms='agree')
        kw = dict(auth_as=janeway, raise_immediately=False, xhr=True)
        r = self.client.POST('/janeway/identity', data, **kw)
        assert r.code == 200, r.text
        janeway = janeway.refetch()
        assert janeway.mangopay_user_id

        # Test the rendering of the identity page
        r = self.client.GET('/janeway/identity.html', auth_as=janeway)
        assert r.code == 200, r.text
        assert user_data['FirstName'] in r.text

        # Edit the natural user
        data2 = dict(data,
                     FirstName='Kathryn',
                     Nationality='US',
                     Birthday='1970-01-01')
        r = self.client.POST('/janeway/identity', data2, **kw)
        assert r.code == 200, r.text
        janeway2 = janeway.refetch()
        assert janeway2.mangopay_user_id == janeway.mangopay_user_id

        # Add some money for the next test
        create_wallet(self.db, janeway, 'EUR')
        cr = create_card(janeway.mangopay_user_id)
        route = ExchangeRoute.insert(janeway,
                                     'mango-cc',
                                     cr.CardId,
                                     'chargeable',
                                     currency='EUR')
        charge(self.db, route, EUR('20.00'), 'http://127.0.0.1/')

        # Switch to a legal user
        data = dict(data2)
        data['organization'] = 'yes'
        data['LegalPersonType'] = 'BUSINESS'
        data['Name'] = 'Starfleet'
        data['confirmed'] = 'yes'
        r = self.client.POST('/janeway/identity', data, **kw)
        assert r.code == 200, r.text
        janeway = janeway.refetch()
        assert janeway.mangopay_user_id != janeway2.mangopay_user_id
        assert janeway.kind == 'organization'
        self.db.self_check()

        # Edit the legal user
        data2 = dict(data, LegalPersonType='ORGANIZATION')
        r = self.client.POST('/janeway/identity', data2, **kw)
        assert r.code == 200, r.text
        janeway2 = janeway.refetch()
        assert janeway2.mangopay_user_id == janeway.mangopay_user_id
示例#14
0
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
示例#15
0
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
示例#16
0
 def test_payin_bank_wire_callback(self, Get):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x')
     for status in ('failed', 'succeeded'):
         status_up = status.upper()
         error = 'FOO' if status == 'failed' else None
         e_id = record_exchange(self.db, route, 11, 0, 0, homer, 'pre')
         assert homer.balance == 0
         homer.close(None)
         assert homer.status == 'closed'
         qs = "EventType=PAYIN_NORMAL_"+status_up+"&RessourceId=123456790"
         payin = PayIn()
         payin.Status = status_up
         payin.ResultCode = '000001' if error else '000000'
         payin.ResultMessage = error
         payin.AuthorId = homer.mangopay_user_id
         payin.PaymentType = 'BANK_WIRE'
         payin.Tag = str(e_id)
         Get.return_value = payin
         r = self.callback(qs)
         assert r.code == 200, r.text
         homer = homer.refetch()
         if status == 'succeeded':
             assert homer.balance == 11
             assert homer.status == 'active'
         else:
             assert homer.balance == 0
             assert homer.status == 'closed'
         emails = self.get_emails()
         assert len(emails) == 1
         assert emails[0]['to'][0] == 'homer <%s>' % homer.email
         assert status[:4] in emails[0]['subject']
         homer.update_status('active')  # reset for next loop run
示例#17
0
 def test_charge_invalidated_card(self):
     bob = self.make_participant('bob')
     route = ExchangeRoute.insert(bob,
                                  'mango-cc',
                                  '-1',
                                  'canceled',
                                  currency='EUR')
     with self.assertRaises(AssertionError):
         charge(self.db, route, EUR('10.00'), 'http://localhost/')
示例#18
0
    def make_participant(self, username, **kw):
        platform = kw.pop('elsewhere', 'github')
        kw2 = {}
        for key in ('last_bill_result', 'balance'):
            if key in kw:
                kw2[key] = kw.pop(key)

        kind = kw.setdefault('kind', 'individual')
        if kind not in ('group', 'community'):
            kw.setdefault('password', 'x')
            kw.setdefault('session_token', username)
            i = next(self.seq)
            kw.setdefault('mangopay_user_id', -i)
            kw.setdefault('mangopay_wallet_id', -i)
        kw.setdefault('status', 'active')
        if not 'join_time' in kw:
            kw['join_time'] = utcnow()
        cols, vals = zip(*kw.items())
        cols = ', '.join(cols)
        placeholders = ', '.join(['%s'] * len(vals))
        participant = self.db.one(
            """
            INSERT INTO participants
                        (username, {0})
                 VALUES (%s, {1})
              RETURNING participants.*::participants
        """.format(cols, placeholders), (username, ) + vals)

        self.db.run(
            """
            INSERT INTO elsewhere
                        (platform, user_id, user_name, participant)
                 VALUES (%s,%s,%s,%s)
        """, (platform, participant.id, username, participant.id))

        if 'last_bill_result' in kw2:
            ExchangeRoute.insert(participant, 'mango-cc', '-1',
                                 kw2['last_bill_result'])
        if 'balance' in kw2 and kw2['balance'] != 0:
            self.make_exchange('mango-cc', kw2['balance'], 0, participant)

        return participant
示例#19
0
 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
示例#20
0
 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
示例#21
0
    def make_participant(self, username, **kw):
        platform = kw.pop('elsewhere', 'github')
        kw2 = {}
        for key in ('last_bill_result', 'balance'):
            if key in kw:
                kw2[key] = kw.pop(key)

        kind = kw.setdefault('kind', 'individual')
        if kind != 'group':
            kw.setdefault('password', 'x')
            kw.setdefault('session_token', username)
        kw.setdefault('status', 'active')
        if not 'join_time' in kw:
            kw['join_time'] = utcnow()
        i = next(self.seq)
        kw.setdefault('mangopay_user_id', -i)
        kw.setdefault('mangopay_wallet_id', -i)
        cols, vals = zip(*kw.items())
        cols = ', '.join(cols)
        placeholders = ', '.join(['%s']*len(vals))
        participant = self.db.one("""
            INSERT INTO participants
                        (username, {0})
                 VALUES (%s, {1})
              RETURNING participants.*::participants
        """.format(cols, placeholders), (username,)+vals)

        self.db.run("""
            INSERT INTO elsewhere
                        (platform, user_id, user_name, participant)
                 VALUES (%s,%s,%s,%s)
        """, (platform, participant.id, username, participant.id))

        if 'last_bill_result' in kw2:
            ExchangeRoute.insert(participant, 'mango-cc', '-1', kw2['last_bill_result'])
        if 'balance' in kw2:
            self.make_exchange('mango-cc', kw2['balance'], 0, participant)

        return participant
示例#22
0
    def test_identity_form(self):
        janeway = self.make_participant(
            'janeway', email='*****@*****.**', mangopay_user_id=None,
        )
        assert janeway.mangopay_user_id is None

        # Create a mangopay natural user
        data = dict(user_data, terms='agree')
        kw = dict(auth_as=janeway, raise_immediately=False, xhr=True)
        r = self.client.POST('/janeway/identity-v1', data, **kw)
        assert r.code == 200, r.text
        janeway = janeway.refetch()
        assert janeway.mangopay_user_id

        # Test the rendering of the identity page
        r = self.client.GET('/janeway/identity-v1.html', auth_as=janeway)
        assert r.code == 200, r.text
        assert user_data['FirstName'] in r.text

        # Edit the natural user
        data2 = dict(data, FirstName='Kathryn', Nationality='US', Birthday='1970-01-01')
        r = self.client.POST('/janeway/identity-v1', data2, **kw)
        assert r.code == 200, r.text
        janeway2 = janeway.refetch()
        assert janeway2.mangopay_user_id == janeway.mangopay_user_id

        # Add some money for the next test
        create_wallet(self.db, janeway, 'EUR')
        cr = create_card(janeway.mangopay_user_id)
        route = ExchangeRoute.insert(janeway, 'mango-cc', cr.CardId, 'chargeable', currency='EUR')
        charge(self.db, route, EUR('20.00'), 'http://127.0.0.1/')

        # Switch to a legal user
        data = dict(data2)
        data['organization'] = 'yes'
        data['LegalPersonType'] = 'BUSINESS'
        data['Name'] = 'Starfleet'
        data['confirmed'] = 'yes'
        r = self.client.POST('/janeway/identity-v1', data, **kw)
        assert r.code == 200, r.text
        janeway = janeway.refetch()
        assert janeway.mangopay_user_id != janeway2.mangopay_user_id
        assert janeway.kind == 'organization'
        self.db.self_check()

        # Edit the legal user
        data2 = dict(data, LegalPersonType='ORGANIZATION')
        r = self.client.POST('/janeway/identity-v1', data2, **kw)
        assert r.code == 200, r.text
        janeway2 = janeway.refetch()
        assert janeway2.mangopay_user_id == janeway.mangopay_user_id
示例#23
0
 def test_user_page_shows_pledges(self, get_user_info):
     alice = self.make_elsewhere('github', 1, 'alice').participant
     bob = self.make_participant('bob')
     carl = self.make_participant('carl')
     # bob needs to be an active donor for his pledge to be counted
     bob.set_tip_to(carl, EUR('1.00'))
     bob_card = ExchangeRoute.insert(
         bob, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
     )
     self.add_payment_account(carl, 'stripe')
     self.make_payin_and_transfer(bob_card, carl, EUR('1.00'))
     Payday.start().run()
     # okay, let's check
     amount = EUR('14.97')
     bob.set_tip_to(alice, amount)
     assert alice.receiving == amount
     r = self.client.GET('/on/github/alice/')
     assert str(amount.amount) in r.text, r.text
示例#24
0
 def test_user_page_shows_pledges(self, get_user_info):
     alice = self.make_elsewhere('github', 1, 'alice').participant
     bob = self.make_participant('bob')
     carl = self.make_participant('carl')
     # bob needs to be an active donor for his pledge to be counted
     bob.set_tip_to(carl, EUR('1.00'))
     bob_card = ExchangeRoute.insert(
         bob, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
     )
     self.add_payment_account(carl, 'stripe')
     self.make_payin_and_transfer(bob_card, carl, EUR('1.00'))
     Payday.start().run()
     # okay, let's check
     amount = EUR('14.97')
     bob.set_tip_to(alice, amount)
     assert alice.receiving == amount
     r = self.client.GET('/on/github/alice/')
     assert str(amount.amount) in r.text, r.text
示例#25
0
 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
示例#26
0
 def test_payin_bank_wire_callback(self, Get):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x', 'chargeable')
     cases = (
         ('failed', '000001', 'FOO'),
         ('failed', '101109', 'The payment period has expired'),
         ('succeeded', '000000', None),
     )
     for status, result_code, error in cases:
         status_up = status.upper()
         e_id = record_exchange(self.db, route, EUR(11), EUR(0), EUR(0),
                                homer, 'pre').id
         assert homer.balance == 0
         homer.close(None)
         assert homer.status == 'closed'
         qs = "EventType=PAYIN_NORMAL_" + status_up + "&RessourceId=123456790"
         payin = BankWirePayIn(Id=-1)
         payin.Status = status_up
         payin.ResultCode = result_code
         payin.ResultMessage = error
         payin.AuthorId = homer.mangopay_user_id
         payin.PaymentType = 'BANK_WIRE'
         payin.DeclaredDebitedFunds = Money(1100, 'EUR')
         payin.DeclaredFees = Money(0, 'EUR')
         payin.CreditedFunds = Money(0, 'XXX') if error else Money(
             1100, 'EUR')
         payin.Tag = str(e_id)
         Get.return_value = payin
         r = self.callback(qs)
         assert r.code == 200, r.text
         homer = homer.refetch()
         if status == 'succeeded':
             assert homer.balance == 11
             assert homer.status == 'active'
         else:
             assert homer.balance == 0
             assert homer.status == 'closed'
         emails = self.get_emails()
         assert len(emails) == 1
         assert emails[0]['to'][0] == 'homer <%s>' % homer.email
         expected = 'expired' if result_code == '101109' else status[:4]
         assert expected in emails[0]['subject']
         self.db.self_check()
         homer.update_status('active')  # reset for next loop run
示例#27
0
 def test_payin_bank_wire_callback(self, Get):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x')
     cases = (
         ('failed', '000001', 'FOO'),
         ('failed', '101109', 'The payment period has expired'),
         ('succeeded', '000000', None),
     )
     for status, result_code, error in cases:
         status_up = status.upper()
         e_id = record_exchange(self.db, route, EUR(11), EUR(0), EUR(0), homer, 'pre').id
         assert homer.balance == 0
         homer.close(None)
         assert homer.status == 'closed'
         qs = "EventType=PAYIN_NORMAL_"+status_up+"&RessourceId=123456790"
         payin = BankWirePayIn(Id=-1)
         payin.Status = status_up
         payin.ResultCode = result_code
         payin.ResultMessage = error
         payin.AuthorId = homer.mangopay_user_id
         payin.PaymentType = 'BANK_WIRE'
         payin.DeclaredDebitedFunds = Money(1100, 'EUR')
         payin.DeclaredFees = Money(0, 'EUR')
         payin.CreditedFunds = Money(0, 'XXX') if error else Money(1100, 'EUR')
         payin.Tag = str(e_id)
         Get.return_value = payin
         r = self.callback(qs)
         assert r.code == 200, r.text
         homer = homer.refetch()
         if status == 'succeeded':
             assert homer.balance == 11
             assert homer.status == 'active'
         else:
             assert homer.balance == 0
             assert homer.status == 'closed'
         emails = self.get_emails()
         assert len(emails) == 1
         assert emails[0]['to'][0] == 'homer <%s>' % homer.email
         expected = 'expired' if result_code == '101109' else status[:4]
         assert expected in emails[0]['subject']
         self.db.self_check()
         homer.update_status('active')  # reset for next loop run
示例#28
0
    def test_negative_paid_in_advance(self):
        team = self.make_participant('team', kind='group')
        alice = self.make_participant('alice')
        team.set_take_for(alice, EUR('1.00'), team)

        stripe_account_alice = self.add_payment_account(alice, 'stripe')

        donor = self.make_participant('donor')
        donor.set_tip_to(team, EUR('5'))

        donor_card = ExchangeRoute.insert(
            donor, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
        )
        payin, pt = self.make_payin_and_transfer(donor_card, team, EUR('10'))
        assert pt.destination == stripe_account_alice.pk

        self.db.run("UPDATE takes SET paid_in_advance = -paid_in_advance")

        Payday.start().run()

        transfers = self.db.all("SELECT * FROM transfers ORDER BY id")
        assert len(transfers) == 0
示例#29
0
 def test_payin_bank_wire_callback(self, Get):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x')
     for status in ('failed', 'succeeded'):
         status_up = status.upper()
         error = 'FOO' if status == 'failed' else None
         e_id = record_exchange(self.db, route, 11, 0, 0, homer, 'pre')
         assert homer.balance == 0
         homer.close(None)
         assert homer.status == 'closed'
         qs = "EventType=PAYIN_NORMAL_" + status_up + "&RessourceId=123456790"
         payin = PayIn()
         payin.Status = status_up
         payin.ResultCode = '000001' if error else '000000'
         payin.ResultMessage = error
         payin.AuthorId = homer.mangopay_user_id
         payin.PaymentType = 'BANK_WIRE'
         pd = payin.PaymentDetails = PayInPaymentDetailsBankWire()
         pd.DeclaredDebitedFunds = Money(1100, 'EUR').__dict__
         pd.DeclaredFees = Money(0, 'EUR').__dict__
         payin.CreditedFunds = Money(1100, 'EUR')
         payin.Tag = str(e_id)
         Get.return_value = payin
         r = self.callback(qs)
         assert r.code == 200, r.text
         homer = homer.refetch()
         if status == 'succeeded':
             assert homer.balance == 11
             assert homer.status == 'active'
         else:
             assert homer.balance == 0
             assert homer.status == 'closed'
         emails = self.get_emails()
         assert len(emails) == 1
         assert emails[0]['to'][0] == 'homer <%s>' % homer.email
         assert status[:4] in emails[0]['subject']
         homer.update_status('active')  # reset for next loop run
示例#30
0
 def _test_payin_bank_wire_callback_amount_mismatch(self, Get, fee):
     homer = self.homer
     route = ExchangeRoute.insert(homer, 'mango-bw', 'x')
     e_id = record_exchange(self.db, route, EUR(11), EUR(0), EUR(0), homer, 'pre').id
     assert homer.balance == 0
     homer.close(None)
     assert homer.status == 'closed'
     qs = "EventType=PAYIN_NORMAL_SUCCEEDED&RessourceId=123456790"
     payin = BankWirePayIn(Id=-1)
     payin.Status = 'SUCCEEDED'
     payin.ResultCode = '000000'
     payin.ResultMessage = None
     payin.AuthorId = homer.mangopay_user_id
     payin.PaymentType = 'BANK_WIRE'
     payin.DeclaredDebitedFunds = Money(4500, 'EUR')
     payin.DeclaredFees = Money(100, 'EUR')
     payin.DebitedFunds = Money(302, 'EUR')
     payin.Fees = Money(fee, 'EUR')
     payin.CreditedFunds = Money(302 - fee, 'EUR')
     payin.Tag = str(e_id)
     Get.return_value = payin
     r = self.callback(qs)
     assert r.code == 200, r.text
     e = self.db.one("SELECT * FROM exchanges WHERE id = %s", (e_id,))
     assert e.amount == D(payin.CreditedFunds.Amount) / D(100)
     assert e.fee == D(fee) / D(100)
     assert e.vat == D('0.01')
     assert e.status == 'succeeded'
     homer = homer.refetch()
     assert homer.balance == e.amount
     assert homer.status == 'active'
     emails = self.get_emails()
     assert len(emails) == 1
     assert emails[0]['to'][0] == 'homer <%s>' % homer.email
     assert 'succ' in emails[0]['subject']
     self.db.self_check()
示例#31
0
    def test_resolve_destination(self):
        alice = self.make_participant('alice')
        bob = self.make_participant('bob')
        carl = self.make_participant('carl')
        team = self.make_participant('team', kind='group')
        alice.set_tip_to(team, EUR('10'))

        # Test without payment account
        team.add_member(bob)
        with self.assertRaises(MissingPaymentAccount):
            resolve_destination(self.db, team, 'stripe', alice, 'FR', EUR('10'))

        # Test without payment account at the requested provider
        stripe_account_bob = self.add_payment_account(bob, 'stripe')
        with self.assertRaises(MissingPaymentAccount):
            resolve_destination(self.db, team, 'paypal', alice, 'US', EUR('10'))

        # Test with a single member and the take at zero
        account = resolve_destination(self.db, team, 'stripe', alice, 'GB', EUR('7'))
        assert account == stripe_account_bob

        # Test with two members but only one payment account
        team.add_member(carl)
        account = resolve_destination(self.db, team, 'stripe', alice, 'CH', EUR('8'))
        assert account == stripe_account_bob

        # Test with two members but only one payment account at the requested provider
        paypal_account_carl = self.add_payment_account(carl, 'paypal')
        account = resolve_destination(self.db, team, 'stripe', alice, 'BE', EUR('42'))
        assert account == stripe_account_bob

        # Test with two members and both takes at zero
        stripe_account_carl = self.add_payment_account(carl, 'stripe')
        account = resolve_destination(self.db, team, 'stripe', alice, 'PL', EUR('5.46'))
        assert account == stripe_account_bob
        account = resolve_destination(self.db, team, 'paypal', alice, 'PL', EUR('99.9'))
        assert account == paypal_account_carl

        # Test with two members and one non-zero take
        team.set_take_for(bob, EUR('1'), bob)
        account = resolve_destination(self.db, team, 'stripe', alice, 'RU', EUR('50.02'))
        assert account == stripe_account_bob
        account = resolve_destination(self.db, team, 'paypal', alice, 'RU', EUR('33'))
        assert account == paypal_account_carl

        # Test with two members and two different non-zero takes
        team.set_take_for(carl, EUR('2'), carl)
        account = resolve_destination(self.db, team, 'stripe', alice, 'BR', EUR('10'))
        assert account == stripe_account_carl
        account = resolve_destination(self.db, team, 'stripe', alice, 'BR', EUR('1'))
        assert account == stripe_account_carl
        account = resolve_destination(self.db, team, 'paypal', alice, 'BR', EUR('5'))
        assert account == paypal_account_carl

        # Check that members are cycled through
        alice_card = ExchangeRoute.insert(
            alice, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
        )
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('2'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('1'))
        assert pt.destination == stripe_account_bob.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('4'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('10'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('2'))
        assert pt.destination == stripe_account_bob.pk
示例#32
0
    def test_takes_paid_in_advance_to_now_inactive_members(self):
        team = self.make_participant('team', kind='group', accepted_currencies=None)
        alice = self.make_participant('alice', main_currency='EUR', accepted_currencies=None)
        team.set_take_for(alice, EUR('1.00'), team)
        bob = self.make_participant('bob', main_currency='USD', accepted_currencies=None)
        team.set_take_for(bob, USD('1.00'), team)

        stripe_account_alice = self.add_payment_account(
            alice, 'stripe', default_currency='EUR'
        )
        stripe_account_bob = self.add_payment_account(
            bob, 'stripe', country='US', default_currency='USD'
        )

        carl = self.make_participant('carl')
        carl.set_tip_to(team, JPY('250'))

        carl_card = ExchangeRoute.insert(
            carl, 'stripe-card', 'x', 'chargeable', remote_user_id='x'
        )
        payin, pt = self.make_payin_and_transfer(carl_card, team, JPY('1250'))
        assert pt.destination == stripe_account_alice.pk
        payin, pt = self.make_payin_and_transfer(carl_card, team, JPY('1250'))
        assert pt.destination == stripe_account_bob.pk

        team.set_take_for(alice, EUR('0.00'), team)
        team.set_take_for(bob, None, team)
        takes = dict(self.db.all("""
            SELECT DISTINCT ON (member)
                   member, paid_in_advance
              FROM takes
          ORDER BY member, mtime DESC
        """))
        assert takes == {
            alice.id: EUR('10.00'),
            bob.id: USD('12.00'),
        }

        Payday.start().run()

        transfers = self.db.all("SELECT * FROM transfers ORDER BY id")
        assert len(transfers) == 2
        assert transfers[0].virtual is True
        assert transfers[0].tipper == carl.id
        assert transfers[0].tippee == alice.id
        assert transfers[0].amount == JPY('125')
        assert transfers[1].virtual is True
        assert transfers[1].tipper == carl.id
        assert transfers[1].tippee == bob.id
        assert transfers[1].amount == JPY('125')

        takes = dict(self.db.all("""
            SELECT DISTINCT ON (member)
                   member, paid_in_advance
              FROM takes
          ORDER BY member, mtime DESC
        """))
        assert takes == {
            alice.id: EUR('9.00'),
            bob.id: USD('10.80'),
        }

        notifications = self.db.all("SELECT * FROM notifications")
        assert len(notifications) == 0

        leftovers = dict(self.db.all("SELECT username, leftover FROM participants"))
        assert leftovers == {
            'team': MoneyBasket(JPY('250.00')),
            'alice': None,
            'bob': None,
            'carl': None,
        }
示例#33
0
 def test_charge_invalidated_card(self):
     bob = self.make_participant('bob')
     route = ExchangeRoute.insert(bob, 'mango-cc', '-1', error='invalidated', currency='EUR')
     with self.assertRaises(AssertionError):
         charge(self.db, route, D('10.00'), 'http://localhost/')
示例#34
0
    def test_resolve_destination(self):
        alice = self.make_participant('alice')
        bob = self.make_participant('bob')
        carl = self.make_participant('carl')
        team = self.make_participant('team', kind='group')
        alice.set_tip_to(team, EUR('10'))

        # Test without payment account
        team.add_member(bob)
        with self.assertRaises(MissingPaymentAccount):
            resolve_destination(self.db, team, 'stripe', alice, 'FR',
                                EUR('10'))

        # Test without payment account at the requested provider
        stripe_account_bob = self.add_payment_account(bob, 'stripe')
        with self.assertRaises(MissingPaymentAccount):
            resolve_destination(self.db, team, 'paypal', alice, 'US',
                                EUR('10'))

        # Test with a single member and the take at zero
        account = resolve_destination(self.db, team, 'stripe', alice, 'GB',
                                      EUR('7'))
        assert account == stripe_account_bob

        # Test with two members but only one payment account
        team.add_member(carl)
        account = resolve_destination(self.db, team, 'stripe', alice, 'CH',
                                      EUR('8'))
        assert account == stripe_account_bob

        # Test with two members but only one payment account at the requested provider
        paypal_account_carl = self.add_payment_account(carl, 'paypal')
        account = resolve_destination(self.db, team, 'stripe', alice, 'BE',
                                      EUR('42'))
        assert account == stripe_account_bob

        # Test with two members and both takes at zero
        stripe_account_carl = self.add_payment_account(carl, 'stripe')
        account = resolve_destination(self.db, team, 'stripe', alice, 'PL',
                                      EUR('5.46'))
        assert account == stripe_account_bob
        account = resolve_destination(self.db, team, 'paypal', alice, 'PL',
                                      EUR('99.9'))
        assert account == paypal_account_carl

        # Test with two members and one non-zero take
        team.set_take_for(bob, EUR('1'), bob)
        account = resolve_destination(self.db, team, 'stripe', alice, 'RU',
                                      EUR('50.02'))
        assert account == stripe_account_bob
        account = resolve_destination(self.db, team, 'paypal', alice, 'RU',
                                      EUR('33'))
        assert account == paypal_account_carl

        # Test with two members and two different non-zero takes
        team.set_take_for(carl, EUR('2'), carl)
        account = resolve_destination(self.db, team, 'stripe', alice, 'BR',
                                      EUR('10'))
        assert account == stripe_account_carl
        account = resolve_destination(self.db, team, 'stripe', alice, 'BR',
                                      EUR('1'))
        assert account == stripe_account_carl
        account = resolve_destination(self.db, team, 'paypal', alice, 'BR',
                                      EUR('5'))
        assert account == paypal_account_carl

        # Check that members are cycled through
        alice_card = ExchangeRoute.insert(alice,
                                          'stripe-card',
                                          'x',
                                          'chargeable',
                                          remote_user_id='x')
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('2'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('1'))
        assert pt.destination == stripe_account_bob.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('4'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('10'))
        assert pt.destination == stripe_account_carl.pk
        payin, pt = self.make_payin_and_transfer(alice_card, team, EUR('2'))
        assert pt.destination == stripe_account_bob.pk