def test_Disputes_ContestDispute(self):
        self.refreshClientDisputes()

        notContestedDispute = None

        for d in self._clientDisputes:
            if ((d.Status == DisputeStatus.PENDING_CLIENT_ACTION or d.Status == DisputeStatus.REOPENED_PENDING_CLIENT_ACTION)
                and (d.DisputeType == DisputeType.CONTESTABLE or d.DisputeType == DisputeType.RETRIEVAL)):
                notContestedDispute = d
                break

        self.assertIsNotNone(notContestedDispute, 'Cannot test contesting dispute because there\'s no dispute that can be contested in the disputes list.')

        result = None

        contestedFunds = None
        if (notContestedDispute.Status == DisputeStatus.PENDING_CLIENT_ACTION):
            contestedFunds = Money()
            contestedFunds.Amount = 100
            contestedFunds.Currency = 'EUR'

        result = self.sdk.disputes.ContestDispute(contestedFunds, notContestedDispute.Id)

        self.assertIsNotNone(result)
        self.assertEqual(result.Id, notContestedDispute.Id)
    def getJohnsPayInCardDirect(self, wallet=None):
        """Creates Pay-In Card Direct object
        return PayIn
        """
        if wallet == None:
            wallet = self.getJohnsWallet()

        cardRegistration = CardRegistration()
        cardRegistration.UserId = wallet.Owners[0]
        cardRegistration.Currency = 'EUR'
        cardRegistration = self.sdk.cardRegistrations.Create(cardRegistration)
        cardRegistration.RegistrationData = self.getPaylineCorrectRegistartionData(
            cardRegistration)
        cardRegistration = self.sdk.cardRegistrations.Update(cardRegistration)
        card = self.sdk.cards.Get(cardRegistration.CardId)

        # create pay-in CARD DIRECT
        payIn = PayIn()
        payIn.CreditedWalletId = wallet.Id
        payIn.AuthorId = wallet.Owners[0]
        payIn.DebitedFunds = Money()
        payIn.DebitedFunds.Amount = 10000
        payIn.DebitedFunds.Currency = 'EUR'
        payIn.Fees = Money()
        payIn.Fees.Amount = 0
        payIn.Fees.Currency = 'EUR'
        # payment type as CARD
        payIn.PaymentDetails = PayInPaymentDetailsCard()
        payIn.PaymentDetails.CardType = card.CardType
        # execution type as DIRECT
        payIn.ExecutionDetails = PayInExecutionDetailsDirect()
        payIn.ExecutionDetails.CardId = card.Id
        payIn.ExecutionDetails.SecureModeReturnURL = 'http://test.com'
        return self.sdk.payIns.Create(payIn)
Esempio n. 3
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
Esempio n. 4
0
    def getJohnsTransfer(self, walletWithMoney=None, wallet=None):
        """Creates Pay-Out  Bank Wire object"""

        if walletWithMoney == None:
            walletWithMoney = self.getJohnsWalletWithMoney()
        if wallet == None:
            wallet = Wallet()
            wallet.Owners = [walletWithMoney.Owners[0]]
            wallet.Currency = 'EUR'
            wallet.Description = 'WALLET IN EUR'
            wallet = self.sdk.wallets.Create(wallet)

        transfer = Transfer()
        transfer.Tag = 'DefaultTag'
        transfer.AuthorId = walletWithMoney.Owners[0]
        transfer.CreditedUserId = walletWithMoney.Owners[0]
        transfer.DebitedFunds = Money()
        transfer.DebitedFunds.Currency = 'EUR'
        transfer.DebitedFunds.Amount = 100
        transfer.Fees = Money()
        transfer.Fees.Currency = 'EUR'
        transfer.Fees.Amount = 0
        transfer.DebitedWalletId = walletWithMoney.Id
        transfer.CreditedWalletId = wallet.Id
        return self.sdk.transfers.Create(transfer)
Esempio n. 5
0
def transfer(db, tipper, tippee, amount, context, **kw):
    t_id = db.one(
        """
        INSERT INTO transfers
                    (tipper, tippee, amount, context, team, status)
             VALUES (%s, %s, %s, %s, %s, 'pre')
          RETURNING id
    """, (tipper, tippee, amount, context, kw.get('team')))
    get = lambda id, col: db.one(
        "SELECT {0} FROM participants WHERE id = %s".format(col), (id, ))
    tr = Transfer()
    tr.AuthorId = kw.get('tipper_mango_id') or get(tipper, 'mangopay_user_id')
    tr.CreditedUserId = kw.get('tippee_mango_id') or get(
        tippee, 'mangopay_user_id')
    tr.CreditedWalletID = kw.get('tippee_wallet_id') or get(
        tippee, 'mangopay_wallet_id')
    if not tr.CreditedWalletID:
        tr.CreditedWalletID = create_wallet(db, Participant.from_id(tippee))
    tr.DebitedFunds = Money(int(amount * 100), 'EUR')
    tr.DebitedWalletID = kw.get('tipper_wallet_id') or get(
        tipper, 'mangopay_wallet_id')
    tr.Fees = Money(0, 'EUR')
    tr.Tag = str(t_id)
    tr = mangoapi.transfers.Create(tr)
    return record_transfer_result(db, t_id, tr)
Esempio n. 6
0
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_Disputes_GetSettlementTransfer(self):
        self.refreshClientDisputes()

        dispute = None

        for d in self._clientDisputes:
            if (d.Status == DisputeStatus.CLOSED
                    and d.DisputeType == DisputeType.NOT_CONTESTABLE):
                dispute = d
                break

        self.assertIsNotNone(
            dispute,
            'Cannot test getting settlement transfer because there\'s no closed and not contestable disputes in the disputes list.'
        )

        repudiationId = self.sdk.disputes.GetTransactions(
            dispute.Id, Pagination(1, 1))[0].Id
        repudiation = self.sdk.disputes.GetRepudiation(repudiationId)

        post = Settlement()
        post.AuthorId = repudiation.AuthorId
        post.DebitedFunds = Money(1, 'EUR')
        post.Fees = Money(0, 'EUR')

        transfer = self.sdk.disputes.CreateSettlementTransfer(
            post, repudiationId)

        self.assertIsNotNone(transfer)

        result = self.sdk.disputes.GetSettlementTransfer(transfer.Id)

        self.assertIsNotNone(result)
        self.assertIsNotNone(result.RepudiationId)
        self.assertEqual(result.RepudiationId, repudiation.Id)
    def test_Disputes_ContestDispute(self):
        self.refreshClientDisputes()

        notContestedDispute = None

        for d in self._clientDisputes:
            if ((d.Status == DisputeStatus.PENDING_CLIENT_ACTION
                 or d.Status == DisputeStatus.REOPENED_PENDING_CLIENT_ACTION)
                    and (d.DisputeType == DisputeType.CONTESTABLE
                         or d.DisputeType == DisputeType.RETRIEVAL)):
                notContestedDispute = d
                break

        self.assertIsNotNone(
            notContestedDispute,
            'Cannot test contesting dispute because there\'s no dispute that can be contested in the disputes list.'
        )

        result = None

        contestedFunds = None
        if (notContestedDispute.Status == DisputeStatus.PENDING_CLIENT_ACTION):
            contestedFunds = Money()
            contestedFunds.Amount = 100
            contestedFunds.Currency = 'EUR'

        result = self.sdk.disputes.ContestDispute(contestedFunds,
                                                  notContestedDispute.Id)

        self.assertIsNotNone(result)
        self.assertEqual(result.Id, notContestedDispute.Id)
Esempio n. 9
0
    def getJohnsPayOutBankWire(self):
        """Creates Pay-Out  Bank Wire object"""
        if self._johnsPayOutBankWire == None:
            wallet = self.getJohnsWallet()
            user = self.getJohn()
            account = self.getJohnsAccount()

            payOut = PayOut()
            payOut.Tag = 'DefaultTag'
            payOut.AuthorId = user.Id
            payOut.CreditedUserId = user.Id
            payOut.DebitedFunds = Money()
            payOut.DebitedFunds.Currency = 'EUR'
            payOut.DebitedFunds.Amount = 10
            payOut.Fees = Money()
            payOut.Fees.Currency = 'EUR'
            payOut.Fees.Amount = 5

            payOut.DebitedWalletId = wallet.Id
            payOut.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire()
            payOut.MeanOfPaymentDetails.BankAccountId = account.Id
            payOut.MeanOfPaymentDetails.Communication = 'Communication text'

            self._johnsPayOutBankWire = self.sdk.payOuts.Create(payOut)
        return self._johnsPayOutBankWire
    def test_Idempotency(self):
        key = random.randrange(100000000000000000, 999999999999999999)
        wallet = self.getJohnsWallet()
        user = self.getJohn()
        account = self.getJohnsAccount()

        payOutPost = PayOut()
        payOutPost.AuthorId = user.Id
        payOutPost.DebitedWalletId = wallet.Id
        payOutPost.DebitedFunds = Money(10, 'EUR')
        payOutPost.Fees = Money(5, 'EUR')
        payOutPost.MeanOfPaymentDetails = PayOutPaymentDetailsBankWire()
        payOutPost.MeanOfPaymentDetails.BankAccountId = account.Id
        payOutPost.MeanOfPaymentDetails.BankWireRef = 'Johns bank wire ref'
        payOutPost.Tag = 'DefaultTag'
        payOutPost.CreditedUserId = user.Id

        payOut = self.sdk.payOuts.CreateIdempotent(key, payOutPost)

        self.assertIsNotNone(payOut)

        # test existing key
        result = self.sdk.idempotency.Get(key)
        self.assertIsNotNone(result)

        # test non-existing key
        try:
            result = self.sdk.idempotency.Get(key + '_no')

            # expecting a response error
            self.assertTrue(1 == 0)
        except:
            result = None
Esempio n. 11
0
    def test_PayIns_Create_DirectDebitDirect(self):
        #	! IMPORTANT NOTE !
        #
        # This test needs your manual confirmation on the web page (see note below)
        # Comment out line below to test payins with a mandate.
        return

        wallet = self.getJohnsWallet()
        user = self.getJohn()
        bankAccountId = self.getJohnsAccount().Id
        returnUrl = 'http://test.test'
        mandatePost = Mandate()
        mandatePost.BankAccountId = bankAccountId
        mandatePost.Culture = 'EN'
        mandatePost.ReturnURL = returnUrl
        mandate = self.sdk.mandates.Create(mandatePost)

        #	! IMPORTANT NOTE !
        #
        #	In order to make this test pass, at this place you have to set a breakpoint,
        #	navigate to URL the mandate.RedirectURL property points to and click "CONFIRM" button.

        payIn = PayIn()
        payIn.CreditedWalletId = wallet.Id
        payIn.AuthorId = user.Id
        payIn.DebitedFunds = Money()
        payIn.DebitedFunds.Amount = 1000
        payIn.DebitedFunds.Currency = 'EUR'
        payIn.Fees = Money()
        payIn.Fees.Amount = 1
        payIn.Fees.Currency = 'EUR'

        payIn.PaymentDetails = PayInPaymentDetailsDirectDebit()
        payIn.PaymentDetails.MandateId = mandate.Id
        payIn.ExecutionDetails = PayInExecutionDetailsDirect()

        createPayIn = self.sdk.payIns.Create(payIn)

        self.assertTrue(int(createPayIn.Id) > 0)
        self.assertEqual(wallet.Id, createPayIn.CreditedWalletId)
        self.assertEqual('DIRECT_DEBIT', createPayIn.PaymentType)
        self.assertIsInstance(createPayIn.PaymentDetails,
                              PayInPaymentDetailsDirectDebit)
        self.assertEqual(createPayIn.PaymentDetails.MandateId, mandate.Id)
        self.assertEqual('DIRECT', createPayIn.ExecutionType)
        self.assertIsInstance(createPayIn.ExecutionDetails,
                              PayInExecutionDetailsDirect)
        self.assertEqual(user.Id, createPayIn.AuthorId)
        self.assertEqual('CREATED', createPayIn.Status)
        self.assertEqual('PAYIN', createPayIn.Type)
        self.assertIsInstance(createPayIn.DebitedFunds, Money)
        self.assertEqual(1000, createPayIn.DebitedFunds.Amount)
        self.assertEqual('EUR', createPayIn.DebitedFunds.Currency)
        self.assertIsInstance(createPayIn.Fees, Money)
        self.assertEqual(1, createPayIn.Fees.Amount)
        self.assertEqual('EUR', createPayIn.Fees.Currency)
Esempio n. 12
0
    def test_PayIns_Create_DirectDebitWeb(self):
        wallet = self.getJohnsWallet()
        user = self.getJohn()
        # create pay-in PRE-AUTHORIZED DIRECT
        payIn = PayIn()
        payIn.CreditedWalletId = wallet.Id
        payIn.AuthorId = user.Id
        payIn.DebitedFunds = Money()
        payIn.DebitedFunds.Amount = 10000
        payIn.DebitedFunds.Currency = 'EUR'
        payIn.Fees = Money()
        payIn.Fees.Amount = 100
        payIn.Fees.Currency = 'EUR'

        # payment type as CARD
        payIn.PaymentDetails = PayInPaymentDetailsDirectDebit()
        payIn.PaymentDetails.DirectDebitType = 'GIROPAY'
        payIn.ExecutionDetails = PayInExecutionDetailsWeb()
        payIn.ExecutionDetails.ReturnURL = 'http://www.mysite.com/returnURL/'
        payIn.ExecutionDetails.Culture = 'FR'
        payIn.ExecutionDetails.TemplateURLOptions = PayInTemplateURLOptions()
        payIn.ExecutionDetails.TemplateURLOptions.PAYLINE = 'https://www.maysite.com/payline_template/'

        createPayIn = self.sdk.payIns.Create(payIn)

        self.assertTrue(int(createPayIn.Id) > 0)
        self.assertEqual(wallet.Id, createPayIn.CreditedWalletId)
        self.assertEqual('DIRECT_DEBIT', createPayIn.PaymentType)
        self.assertIsInstance(createPayIn.PaymentDetails,
                              PayInPaymentDetailsDirectDebit)
        self.assertEqual(createPayIn.PaymentDetails.DirectDebitType, 'GIROPAY')
        self.assertEqual('WEB', createPayIn.ExecutionType)
        self.assertIsInstance(createPayIn.ExecutionDetails,
                              PayInExecutionDetailsWeb)
        self.assertEqual('FR', createPayIn.ExecutionDetails.Culture)
        self.assertEqual(user.Id, createPayIn.AuthorId)
        self.assertEqual('CREATED', createPayIn.Status)
        self.assertEqual('PAYIN', createPayIn.Type)
        self.assertIsInstance(createPayIn.DebitedFunds, Money)
        self.assertEqual(10000, createPayIn.DebitedFunds.Amount)
        self.assertEqual('EUR', createPayIn.DebitedFunds.Currency)
        self.assertIsInstance(createPayIn.CreditedFunds, Money)
        self.assertEqual(9900, createPayIn.CreditedFunds.Amount)
        self.assertEqual('EUR', createPayIn.CreditedFunds.Currency)
        self.assertIsInstance(createPayIn.Fees, Money)
        self.assertEqual(100, createPayIn.Fees.Amount)
        self.assertEqual('EUR', createPayIn.Fees.Currency)
        self.assertIsNotNone(createPayIn.ExecutionDetails.ReturnURL)
        self.assertIsNotNone(createPayIn.ExecutionDetails.RedirectURL)
        self.assertIsNotNone(createPayIn.ExecutionDetails.TemplateURL)
    def test_Disputes_CreateSettlementTransfer(self):
        self.refreshClientDisputes()

        dispute = None

        for d in self._clientDisputes:
            if (d.Status == DisputeStatus.CLOSED
                    and d.DisputeType == DisputeType.NOT_CONTESTABLE):
                dispute = d
                break

        self.assertIsNotNone(
            dispute,
            'Cannot test creating settlement transfer because there\'s no closed dispute in the disputes list.'
        )

        repudiationId = self.sdk.disputes.GetTransactions(dispute.Id)[0].Id
        repudiation = self.sdk.disputes.GetRepudiation(repudiationId)

        debitedFunds = Money()
        fees = Money()
        debitedFunds.Currency = 'EUR'
        debitedFunds.Amount = 1
        fees.Currency = 'EUR'
        fees.Amount = 0

        post = Transfer()
        post.AuthorId = repudiation.AuthorId
        post.DebitedFunds = debitedFunds
        post.Fees = fees

        result = self.sdk.disputes.CreateSettlementTransfer(
            post, repudiationId)

        self.assertIsNotNone(result)
Esempio n. 14
0
    def getJohnsWalletWithMoney(self, amount=10000):
        """Creates static JohnsWallet (wallets belonging to John) if not created yet
        return Wallet
        """
        if self._johnsWalletWithMoney == None:
            john = self.getJohn()
            wallet = Wallet()
            wallet.Owners = [john.Id]
            wallet.Currency = 'EUR'
            wallet.Description = 'WALLET IN EUR'
            wallet = self.sdk.wallets.Create(wallet)
            cardRegistration = CardRegistration()
            cardRegistration.UserId = wallet.Owners[0]
            cardRegistration.Currency = 'EUR'
            cardRegistration = self.sdk.cardRegistrations.Create(
                cardRegistration)
            cardRegistration.RegistrationData = self.getPaylineCorrectRegistartionData(
                cardRegistration)
            cardRegistration = self.sdk.cardRegistrations.Update(
                cardRegistration)
            card = self.sdk.cards.Get(cardRegistration.CardId)
            # create pay-in CARD DIRECT
            payIn = PayIn()
            payIn.CreditedWalletId = wallet.Id
            payIn.AuthorId = cardRegistration.UserId
            payIn.DebitedFunds = Money()
            payIn.DebitedFunds.Amount = amount
            payIn.DebitedFunds.Currency = 'EUR'
            payIn.Fees = Money()
            payIn.Fees.Amount = 0
            payIn.Fees.Currency = 'EUR'
            # payment type as CARD
            payIn.PaymentDetails = PayInPaymentDetailsCard()
            if (card.CardType == 'CB' or card.CardType == 'VISA'
                    or card.CardType == 'MASTERCARD'
                    or card.CardType == CardType.CB_VISA_MASTERCARD):
                payIn.PaymentDetails.CardType = CardType.CB_VISA_MASTERCARD
            # elif (card.CardType == CardType.AMEX):
            #    payIn.PaymentDetails.CardType = CardType.AMEX

            # execution type as DIRECT
            payIn.ExecutionDetails = PayInExecutionDetailsDirect()
            payIn.ExecutionDetails.CardId = card.Id
            payIn.ExecutionDetails.SecureModeReturnURL = 'http://test.com'
            # create Pay-In
            self.sdk.payIns.Create(payIn)
            self._johnsWalletWithMoney = self.sdk.wallets.Get(wallet.Id)
        return self._johnsWalletWithMoney
Esempio n. 15
0
 def getJohnsRefundForTransfer(self, transfer=None):
     """Creates refund object for transfer
     return Refund
     """
     if transfer == None:
         transfer = self.getJohnsTransfer()
     refund = Refund()
     refund.DebitedWalletId = transfer.DebitedWalletId
     refund.CreditedWalletId = transfer.CreditedWalletId
     refund.AuthorId = transfer.AuthorId
     refund.DebitedFunds = Money()
     refund.DebitedFunds.Amount = transfer.DebitedFunds.Amount
     refund.DebitedFunds.Currency = transfer.DebitedFunds.Currency
     refund.Fees = Money()
     refund.Fees.Amount = transfer.Fees.Amount
     refund.Fees.Currency = transfer.Fees.Currency
     return self.sdk.transfers.CreateRefund(transfer.Id, refund)
Esempio n. 16
0
    def getJohnsRefundForPayIn(self, payIn=None):
        """ Creates refund object for PayIn
        return Refund
        """
        if payIn == None:
            payIn = self.getJohnsPayInCardDirect()

        refund = Refund()
        refund.CreditedWalletId = payIn.CreditedWalletId
        refund.AuthorId = payIn.AuthorId
        refund.DebitedFunds = Money()
        refund.DebitedFunds.Amount = payIn.DebitedFunds.Amount
        refund.DebitedFunds.Currency = payIn.DebitedFunds.Currency
        refund.Fees = Money()
        refund.Fees.Amount = payIn.Fees.Amount
        refund.Fees.Currency = payIn.Fees.Currency
        return self.sdk.payIns.CreateRefund(payIn.Id, refund)
Esempio n. 17
0
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)
Esempio n. 18
0
def propagate_exchange(cursor, participant, exchange, route, error, amount):
    """Propagates an exchange's result to the participant's balance and the
    route's status.
    """
    route.update_error(error or '')

    new_balance = cursor.one(
        """
        UPDATE participants
           SET balance=(balance + %s)
         WHERE id=%s
     RETURNING balance
    """, (amount, participant.id))

    if amount < 0 and new_balance < 0:
        raise NegativeBalance

    if amount < 0:
        bundles = cursor.all(
            """
            LOCK TABLE cash_bundles IN EXCLUSIVE MODE;
            SELECT *
              FROM cash_bundles
             WHERE owner = %s
               AND ts < now() - INTERVAL %s
          ORDER BY ts
        """, (participant.id, QUARANTINE))
        withdrawable = sum(b.amount for b in bundles)
        x = -amount
        if x > withdrawable:
            raise NotEnoughWithdrawableMoney(Money(withdrawable, 'EUR'))
        for b in bundles:
            if x >= b.amount:
                cursor.run("DELETE FROM cash_bundles WHERE id = %s", (b.id, ))
                x -= b.amount
                if x == 0:
                    break
            else:
                assert x > 0
                cursor.run(
                    """
                    UPDATE cash_bundles
                       SET amount = (amount - %s)
                     WHERE id = %s
                """, (x, b.id))
                break
    elif amount > 0:
        cursor.run(
            """
            INSERT INTO cash_bundles
                        (owner, origin, amount, ts)
                 VALUES (%s, %s, %s, %s)
        """, (participant.id, exchange.id, amount, exchange.timestamp))

    participant.set_attributes(balance=new_balance)

    if amount != 0:
        participant.update_giving_and_tippees(cursor)
Esempio n. 19
0
def record_payout_refund(db, payout_refund):
    orig_payout = mangoapi.payOuts.Get(payout_refund.InitialTransactionId)
    e_origin = db.one("SELECT * FROM exchanges WHERE id = %s" % (orig_payout.Tag,))
    e_refund_id = db.one("SELECT id FROM exchanges WHERE refund_ref = %s", (e_origin.id,))
    if e_refund_id:
        # Already recorded
        return e_refund_id
    amount, fee, vat = -e_origin.amount, -e_origin.fee, -e_origin.vat
    assert payout_refund.DebitedFunds == Money(int(amount * 100), 'EUR')
    assert payout_refund.Fees == Money(int(fee * 100), 'EUR')
    route = ExchangeRoute.from_id(e_origin.route)
    participant = Participant.from_id(e_origin.participant)
    return db.one("""
        INSERT INTO exchanges
               (amount, fee, vat, participant, status, route, note, refund_ref)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
     RETURNING id
    """, (amount, fee, vat, participant.id, 'created', route.id, None, e_origin.id))
Esempio n. 20
0
    def getJohnsPayInCardWeb(self):
        """Creates Pay-In Card Web object"""
        wallet = self.getJohnsWallet()
        user = self.getJohn()

        payIn = PayIn()
        payIn.AuthorId = user.Id
        payIn.CreditedUserId = user.Id
        payIn.DebitedFunds = Money()
        payIn.DebitedFunds.Currency = 'EUR'
        payIn.DebitedFunds.Amount = 1000
        payIn.Fees = Money()
        payIn.Fees.Currency = 'EUR'
        payIn.Fees.Amount = 5
        payIn.CreditedWalletId = wallet.Id
        payIn.PaymentDetails = self.getPayInPaymentDetailsCard()
        payIn.ExecutionDetails = self.getPayInExecutionDetailsWeb()
        return self.sdk.payIns.Create(payIn)
Esempio n. 21
0
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)
Esempio n. 22
0
    def getJohnsPayInBankWireDirect(self):
        wallet = self.getJohnsWallet()
        payIn = PayIn()
        payIn.CreditedWalletId = wallet.Id
        payIn.AuthorId = wallet.Owners[0]

        # payment type as CARD
        payIn.PaymentDetails = PayInPaymentDetailsBankWire()
        payIn.PaymentDetails.DeclaredDebitedFunds = Money()
        payIn.PaymentDetails.DeclaredFees = Money()
        payIn.PaymentDetails.DeclaredDebitedFunds.Currency = 'EUR'
        payIn.PaymentDetails.DeclaredFees.Currency = 'EUR'
        payIn.PaymentDetails.DeclaredDebitedFunds.Amount = 10000
        payIn.PaymentDetails.DeclaredFees.Amount = 1000

        # execution type as DIRECT
        payIn.ExecutionDetails = PayInExecutionDetailsDirect()
        payIn.ExecutionType = ExecutionType.DIRECT
        return self.sdk.payIns.Create(payIn)
Esempio n. 23
0
    def test_Disputes_CreateSettlementTransfer(self):
        self.refreshClientDisputes()

        dispute = None

        for d in self._clientDisputes:
            if (d.Status == DisputeStatus.CLOSED and d.DisputeType == DisputeType.NOT_CONTESTABLE):
                dispute = d
                break

        self.assertIsNotNone(dispute, 'Cannot test creating settlement transfer because there\'s no closed dispute in the disputes list.')

        repudiationId = self.sdk.disputes.GetTransactions(dispute.Id)[0].Id
        repudiation = self.sdk.disputes.GetRepudiation(repudiationId)

        debitedFunds = Money()
        fees = Money()
        debitedFunds.Currency = 'EUR'
        debitedFunds.Amount = 1
        fees.Currency = 'EUR'
        fees.Amount = 0

        post = Transfer()
        post.AuthorId = repudiation.AuthorId
        post.DebitedFunds = debitedFunds
        post.Fees = fees

        result = self.sdk.disputes.CreateSettlementTransfer(post, repudiationId)

        self.assertIsNotNone(result)
Esempio n. 24
0
    def test_PayIns_PreAuthorizedDirect(self):
        cardPreAuthorization = self.getJohnsCardPreAuthorization()
        wallet = self.getJohnsWalletWithMoney()
        user = self.getJohn()
        # create pay-in PRE-AUTHORIZED DIRECT
        payIn = PayIn()
        payIn.CreditedWalletId = wallet.Id
        payIn.AuthorId = user.Id
        payIn.DebitedFunds = Money()
        payIn.DebitedFunds.Amount = 1000
        payIn.DebitedFunds.Currency = 'EUR'
        payIn.Fees = Money()
        payIn.Fees.Amount = 0
        payIn.Fees.Currency = 'EUR'
        # payment type as CARD
        payIn.PaymentDetails = PayInPaymentDetailsPreAuthorized()
        payIn.PaymentDetails.PreauthorizationId = cardPreAuthorization.Id
        # execution type as DIRECT
        payIn.ExecutionDetails = PayInExecutionDetailsDirect()
        payIn.ExecutionDetails.SecureModeReturnURL = 'http://test.com'

        createPayIn = self.sdk.payIns.Create(payIn)

        self.assertTrue(len(createPayIn.Id) > 0)
        self.assertEqual(wallet.Id, createPayIn.CreditedWalletId)
        self.assertEqual('PREAUTHORIZED', createPayIn.PaymentType)
        self.assertIsInstance(createPayIn.PaymentDetails,
                              PayInPaymentDetailsPreAuthorized)
        self.assertEqual('DIRECT', createPayIn.ExecutionType)
        self.assertIsInstance(createPayIn.ExecutionDetails,
                              PayInExecutionDetailsDirect)
        self.assertIsInstance(createPayIn.DebitedFunds, Money)
        self.assertIsInstance(createPayIn.CreditedFunds, Money)
        self.assertIsInstance(createPayIn.Fees, Money)
        self.assertEqual(user.Id, createPayIn.AuthorId)
        self.assertEqual('SUCCEEDED', createPayIn.Status)
        self.assertEqual('PAYIN', createPayIn.Type)
Esempio n. 25
0
 def getJohnsCardPreAuthorization(self):
     """Creates card pre authorization object.
     return CardPreAuthorization 
     """
     if (self._johnsCardPreAuthorization == None):
         user = self.getJohn()
         payIn = self.getJohnsPayInCardDirect()
         cardPreAuthorization = CardPreAuthorization()
         cardPreAuthorization.AuthorId = user.Id
         cardPreAuthorization.Tag = 'Test Card PreAuthorization'
         cardPreAuthorization.CardId = payIn.ExecutionDetails.CardId
         cardPreAuthorization.SecureMode = Mode3DSType.DEFAULT
         cardPreAuthorization.SecureModeReturnURL = 'https://test.com'
         cardPreAuthorization.DebitedFunds = Money()
         cardPreAuthorization.DebitedFunds.Amount = 1000
         cardPreAuthorization.DebitedFunds.Currency = 'EUR'
         self._johnsCardPreAuthorization = self.sdk.cardPreAuthorizations.Create(cardPreAuthorization)
     return self._johnsCardPreAuthorization
Esempio n. 26
0
def python_money_to_mangopay_money(python_money):
    amount = python_money.amount.quantize(Decimal('.01'),
                                          rounding=ROUND_FLOOR) * 100
    return Money(amount=int(amount), currency=str(python_money.currency))
Esempio n. 27
0
 def Get(self, wallet_id):
     wallet = Wallet()
     wallet.id = wallet_id
     wallet.Balance = Money(10000, currency="EUR")
     return wallet
Esempio n. 28
0
def propagate_exchange(cursor, participant, exchange, route, error, amount):
    """Propagates an exchange's result to the participant's balance and the
    route's status.
    """
    route.update_error(error or '')

    new_balance = cursor.one(
        """
        UPDATE participants
           SET balance=(balance + %s)
         WHERE id=%s
     RETURNING balance
    """, (amount, participant.id))

    if amount < 0 and new_balance < 0:
        raise NegativeBalance

    if amount < 0:
        bundles = cursor.all(
            """
            LOCK TABLE cash_bundles IN EXCLUSIVE MODE;
            SELECT b.*
              FROM cash_bundles b
              JOIN exchanges e ON e.id = b.origin
             WHERE b.owner = %s
               AND b.ts < now() - INTERVAL %s
          ORDER BY b.owner = e.participant DESC, b.ts
        """, (participant.id, QUARANTINE))
        withdrawable = sum(b.amount for b in bundles)
        x = -amount
        if x > withdrawable:
            raise NotEnoughWithdrawableMoney(Money(withdrawable, 'EUR'))
        for b in bundles:
            if x >= b.amount:
                cursor.run(
                    """
                    INSERT INTO e2e_transfers
                                (origin, withdrawal, amount)
                         VALUES (%s, %s, %s)
                """, (b.origin, exchange.id, b.amount))
                cursor.run("DELETE FROM cash_bundles WHERE id = %s", (b.id, ))
                x -= b.amount
                if x == 0:
                    break
            else:
                assert x > 0
                cursor.run(
                    """
                    INSERT INTO e2e_transfers
                                (origin, withdrawal, amount)
                         VALUES (%s, %s, %s)
                """, (b.origin, exchange.id, x))
                cursor.run(
                    """
                    UPDATE cash_bundles
                       SET amount = (amount - %s)
                     WHERE id = %s
                """, (x, b.id))
                break
    elif amount > 0 and exchange.amount < 0:
        cursor.run(
            """
            LOCK TABLE cash_bundles IN EXCLUSIVE MODE;
            INSERT INTO cash_bundles
                        (owner, origin, amount, ts)
                 SELECT %(p_id)s, t.origin, t.amount, e.timestamp
                   FROM e2e_transfers t
                   JOIN exchanges e ON e.id = t.origin
                  WHERE t.withdrawal = %(e_id)s;
            DELETE FROM e2e_transfers WHERE withdrawal = %(e_id)s;
        """, dict(p_id=participant.id, e_id=exchange.id))
    elif amount > 0:
        cursor.run(
            """
            INSERT INTO cash_bundles
                        (owner, origin, amount, ts)
                 VALUES (%s, %s, %s, %s)
        """, (participant.id, exchange.id, amount, exchange.timestamp))

    participant.set_attributes(balance=new_balance)

    if amount != 0:
        participant.update_giving_and_tippees(cursor)
        merge_cash_bundles(cursor, participant.id)