def create(self, user): # Only CB_VISA_MC is accepted for now if self.amount < 30: self.secure_mode = False mid = MangoUser.objects.get(user=user).mid wallet = MangoWallet.objects.get(mid=mid) payin = CardWebPayIn(AuthorId=mid, DebitedFunds=Money(self.amount * 100, self.currency), Fees=Money(int(self.fees * 100), self.currency), ReturnURL=self.return_url, CardType=self.card_type, CreditedWalletId=wallet, SecureMode=self.secure_mode, Culture=self.culture, TemplateURLOptions={'PaylineV2': ''}, StatementDescriptor=self.statement_descriptor) # check if the Money fuction works like this. # if payin.status == 'FAILED': # check = _check_payin(payin) marks unresolved ref?? # Need to make a template and view to receive the user after the payment # Check to see if these dictionaries are workiing the way they should, intuitively they should. Or use the helper func # also should I dump the answer from json into a dict?? Like I read? payin.save() self.piid = payin.get_pk() self.creation_date = payin.execution_date self.result_code = payin.result_code self.result_message = payin.result_message self.return_url = payin.return_url self.nature = payin.nature self.save()
def create(self, author, recipient, amount): sender = MangoUser.objects.get(user=author) receiver = MangoUser.objects.get(user=recipient) swid = MangoWallet.objects.get(mid=sender.mid).wid credwallet = MangoWallet.objects.get(mid=receiver.mid).wid rwid = credwallet.wid self.currency = credwallet.currency transfer = Transfer(AuthorId=sender.mid, DebitedFunds=Money(amount, self.currency), Fees=Money(self.fees, self.currency), DebitedWalletId=swid, CreditedWalletId=rwid) transfer.save() self.tid = transfer.get_pk() self.creation_date = transfer.execution_date self.author = sender.mid self.recipient = receiver.mid self.dwid = transfer.DebitedWalletId self.cwid = transfer.CreditedWalletId self.amount = amount self.status = transfer.status self.result_code = transfer.result_code self.result_message = transfer.result_message self.save()
def test_RecurringPayment_Get(self): user = self.get_john(True) wallet = self.get_johns_wallet(True) card = BaseTestLive.get_johns_card_3dsecure(True) recurring = RecurringPayInRegistration() recurring.author = user recurring.card = card recurring.user = user recurring.credited_wallet = wallet recurring.first_transaction_fees = Money() recurring.first_transaction_fees.amount = 1 recurring.first_transaction_fees.currency = "EUR" recurring.first_transaction_debited_funds = Money() recurring.first_transaction_debited_funds.amount = 10 recurring.first_transaction_debited_funds.currency = "EUR" address = Address() address.address_line_1 = "Big Street" address.address_line_2 = "no 2 ap 6" address.country = "FR" address.city = "Lyon" address.postal_code = "68400" recurring.billing = Billing(first_name="John", last_name="Doe", address=address) recurring.shipping = Shipping(first_name="John", last_name="Doe", address=address) result = recurring.save() self.assertIsNotNone(result) rec_id = result.get("id") get = RecurringPayInRegistration.get(rec_id) self.assertIsNotNone(get)
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 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.upsert_bankwire_route(participant) if not isinstance(debit_amount, Money): debit_amount = Money(debit_amount, 'EUR') amount, fee, vat = skim_bank_wire(debit_amount) wallet = participant.get_current_wallet(amount.currency, create=True) e_id = record_exchange(db, route, amount, fee, vat, participant, 'pre').id payin = BankWirePayIn() payin.AuthorId = participant.mangopay_user_id payin.CreditedWalletId = wallet.remote_id payin.DeclaredDebitedFunds = debit_amount.int() payin.DeclaredFees = fee.int() 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.Id, payin.Status.lower(), repr_error(payin), participant ) return payin, e
def test_GooglePay_payIn(self): user = self.get_john(True) debited_wallet = self.get_johns_wallet() # create wallet credited_wallet = Wallet() credited_wallet.owners = (user, ) credited_wallet.currency = 'EUR' credited_wallet.description = 'WALLET IN EUR' credited_wallet = Wallet(**credited_wallet.save()) card = BaseTestLive.get_johns_card(True) pay_in = GooglepayPayIn() pay_in.author = user pay_in.credited_user = user pay_in.credited_wallet = credited_wallet pay_in.fees = Money() pay_in.fees.amount = 1 pay_in.fees.currency = "EUR" pay_in.debited_funds = Money() pay_in.debited_funds.amount = 199 pay_in.debited_funds.currency = "EUR" payment_data = GooglepayPaymentData() # can't be tested payment_data.transaction_id = "placeholder" payment_data.network = 'VISA' payment_data.token_data = "placeholder" pay_in.payment_data = payment_data pay_in.statement_descriptor = 'Python' pay_in.payment_type = constants.PAYIN_PAYMENT_TYPE.googlepay pay_in.execution_type = constants.EXECUTION_TYPE_CHOICES.direct result = pay_in.save() self.assertIsNotNone(result)
def transfer(db, tipper, tippee, amount, context, **kw): get = lambda id, col: db.one( "SELECT {0} FROM participants WHERE id = %s".format(col), (id, )) wallet_from = kw.get('tipper_wallet_id') or get(tipper, 'mangopay_wallet_id') wallet_to = kw.get('tippee_wallet_id') or get(tippee, 'mangopay_wallet_id') if not wallet_to: wallet_to = create_wallet(db, Participant.from_id(tippee)) t_id = prepare_transfer( db, tipper, tippee, amount, context, wallet_from, wallet_to, team=kw.get('team'), invoice=kw.get('invoice'), bundles=kw.get('bundles'), ) 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 = wallet_to tr.DebitedFunds = Money(int(amount * 100), 'EUR') tr.DebitedWalletId = wallet_from tr.Fees = Money(0, 'EUR') tr.Tag = str(t_id) tr.save() return record_transfer_result(db, t_id, tr), t_id
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_ApplePay_Payin(self): user = self.get_john(True) debited_wallet = self.get_johns_wallet() # create wallet credited_wallet = Wallet() credited_wallet.owners = (user,) credited_wallet.currency = 'EUR' credited_wallet.description = 'WALLET IN EUR' credited_wallet = Wallet(**credited_wallet.save()) card = BaseTestLive.get_johns_card(True) pay_in = ApplepayPayIn() pay_in.author = user pay_in.credited_user = user pay_in.credited_wallet = credited_wallet pay_in.fees = Money() pay_in.fees.amount = 1 pay_in.fees.currency = "EUR" pay_in.debited_funds = Money() pay_in.debited_funds.amount = 199 pay_in.debited_funds.currency = "EUR" payment_data = ApplepayPaymentData() payment_data.transaction_id = '061EB32181A2D9CA42AD16031B476EEBAA62A9A095AD660E2759FBA52B51A61' payment_data.network = 'VISA' payment_data.token_data = "{\"version\":\"EC_v1\",\"data\":\"w4HMBVqNC9ghPP4zncTA\\/0oQAsduERfsx78oxgniynNjZLANTL6+0koEtkQnW\\/K38Zew8qV1GLp+fLHo+qCBpiKCIwlz3eoFBTbZU+8pYcjaeIYBX9SOxcwxXsNGrGLk+kBUqnpiSIPaAG1E+WPT8R1kjOCnGvtdombvricwRTQkGjtovPfzZo8LzD3ZQJnHMsWJ8QYDLyr\\/ZN9gtLAtsBAMvwManwiaG3pOIWpyeOQOb01YcEVO16EZBjaY4x4C\\/oyFLWDuKGvhbJwZqWh1d1o9JT29QVmvy3Oq2JEjq3c3NutYut4rwDEP4owqI40Nb7mP2ebmdNgnYyWfPmkRfDCRHIWtbMC35IPg5313B1dgXZ2BmyZRXD5p+mr67vAk7iFfjEpu3GieFqwZrTl3\\/pI5V8Sxe3SIYKgT5Hr7ow==\",\"signature\":\"MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIID5jCCA4ugAwIBAgIIaGD2mdnMpw8wCgYIKoZIzj0EAwIwejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE2MDYwMzE4MTY0MFoXDTIxMDYwMjE4MTY0MFowYjEoMCYGA1UEAwwfZWNjLXNtcC1icm9rZXItc2lnbl9VQzQtU0FOREJPWDEUMBIGA1UECwwLaU9TIFN5c3RlbXMxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgjD9q8Oc914gLFDZm0US5jfiqQHdbLPgsc1LUmeY+M9OvegaJajCHkwz3c6OKpbC9q+hkwNFxOh6RCbOlRsSlaOCAhEwggINMEUGCCsGAQUFBwEBBDkwNzA1BggrBgEFBQcwAYYpaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwNC1hcHBsZWFpY2EzMDIwHQYDVR0OBBYEFAIkMAua7u1GMZekplopnkJxghxFMAwGA1UdEwEB\\/wQCMAAwHwYDVR0jBBgwFoAUI\\/JJxE+T5O8n5sT2KGw\\/orv9LkswggEdBgNVHSAEggEUMIIBEDCCAQwGCSqGSIb3Y2QFATCB\\/jCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjA2BggrBgEFBQcCARYqaHR0cDovL3d3dy5hcHBsZS5jb20vY2VydGlmaWNhdGVhdXRob3JpdHkvMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwuYXBwbGUuY29tL2FwcGxlYWljYTMuY3JsMA4GA1UdDwEB\\/wQEAwIHgDAPBgkqhkiG92NkBh0EAgUAMAoGCCqGSM49BAMCA0kAMEYCIQDaHGOui+X2T44R6GVpN7m2nEcr6T6sMjOhZ5NuSo1egwIhAL1a+\\/hp88DKJ0sv3eT3FxWcs71xmbLKD\\/QJ3mWagrJNMIIC7jCCAnWgAwIBAgIISW0vvzqY2pcwCgYIKoZIzj0EAwIwZzEbMBkGA1UEAwwSQXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcNMTQwNTA2MjM0NjMwWhcNMjkwNTA2MjM0NjMwWjB6MS4wLAYDVQQDDCVBcHBsZSBBcHBsaWNhdGlvbiBJbnRlZ3JhdGlvbiBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATwFxGEGddkhdUaXiWBB3bogKLv3nuuTeCN\\/EuT4TNW1WZbNa4i0Jd2DSJOe7oI\\/XYXzojLdrtmcL7I6CmE\\/1RFo4H3MIH0MEYGCCsGAQUFBwEBBDowODA2BggrBgEFBQcwAYYqaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwNC1hcHBsZXJvb3RjYWczMB0GA1UdDgQWBBQj8knET5Pk7yfmxPYobD+iu\\/0uSzAPBgNVHRMBAf8EBTADAQH\\/MB8GA1UdIwQYMBaAFLuw3qFYM4iapIqZ3r6966\\/ayySrMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuYXBwbGUuY29tL2FwcGxlcm9vdGNhZzMuY3JsMA4GA1UdDwEB\\/wQEAwIBBjAQBgoqhkiG92NkBgIOBAIFADAKBggqhkjOPQQDAgNnADBkAjA6z3KDURaZsYb7NcNWymK\\/9Bft2Q91TaKOvvGcgV5Ct4n4mPebWZ+Y1UENj53pwv4CMDIt1UQhsKMFd2xd8zg7kGf9F3wsIW2WT8ZyaYISb1T4en0bmcubCYkhYQaZDwmSHQAAMYIBizCCAYcCAQEwgYYwejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTAghoYPaZ2cynDzANBglghkgBZQMEAgEFAKCBlTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xOTA1MjMxMTA1MDdaMCoGCSqGSIb3DQEJNDEdMBswDQYJYIZIAWUDBAIBBQChCgYIKoZIzj0EAwIwLwYJKoZIhvcNAQkEMSIEIIvfGVQYBeOilcB7GNI8m8+FBVZ28QfA6BIXaggBja2PMAoGCCqGSM49BAMCBEYwRAIgU01yYfjlx9bvGeC5CU2RS5KBEG+15HH9tz\\/sg3qmQ14CID4F4ZJwAz+tXAUcAIzoMpYSnM8YBlnGJSTSp+LhspenAAAAAAAA\",\"header\":{\"ephemeralPublicKey\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0rs3wRpirXjPbFDQfPRdfEzRIZDWm0qn7Y0HB0PNzV1DDKfpYrnhRb4GEhBF\\/oEXBOe452PxbCnN1qAlqcSUWw==\",\"publicKeyHash\":\"saPRAqS7TZ4bAYwzBj8ezDDC55ZolyH1FL+Xc8fd93o=\",\"transactionId\":\"b061eb32181a2d9ca42ad16031b476eebaa62a9a095ad660e2759fba52b51a61\"}}" pay_in.payment_data = payment_data pay_in.statement_descriptor = 'Python' pay_in.payment_type = constants.PAYIN_PAYMENT_TYPE.applepay pay_in.execution_type = constants.EXECUTION_TYPE_CHOICES.direct result = pay_in.save() self.assertIsNotNone(result)
def create(self, account): # Only CB_VISA_MC is accepted for now am = float(self.amount) if am > 50.0 and not self.secure_mode == SECURE_MODE_CHOICES['DEFAULT']: self.secure_mode = SECURE_MODE_CHOICES[1] self.cwid = account.wid self.fees = round(am * 0.1, 2) am = am * 100 fe = self.fees*100 payin = CardWebPayIn(AuthorId=self.saver.mid, DebitedFunds=Money(amount=am, currency=self.currency), Fees=Money(amount=fe, currency=self.currency), ReturnURL=self.return_url, CardType=self.card_type, CreditedWalletId=self.cwid, SecureMode=self.secure_mode, Culture=self.culture, StatementDescriptor=self.statement_descriptor, tag=self.tag) payin.save() self.piid = payin.Id self.status = payin.Status # self.creation_date = _from_timestamp(payin.CreationDate) self.creation_date = datetime.datetime.now() # do I need to do something like response.json() to dump the strings and use them??? self.save() if payin.RedirectURL: return payin return HttpResponse('redirect failed, if-condition not met')
def make_standard_tip(label, weekly, currency): return StandardTip( label, Money(weekly, currency), Money(weekly / PERIOD_CONVERSION_RATES['monthly'], currency), Money(weekly / PERIOD_CONVERSION_RATES['yearly'], currency), )
def test_camelcase_aliases_on_Money(self): m = Money(10, 'EUR') self.assertEqual(m.Amount, 10) self.assertEqual(m.Currency, 'EUR') m.Amount = 5 m.Currency = 'USD' self.assertEqual(m.amount, 5) self.assertEqual(m.currency, 'USD')
def _Money_parse(cls, amount_str, default_currency='EUR'): split_str = amount_str.split() if len(split_str) == 2: return Money(*split_str) elif len(split_str) == 1: return Money(split_str, default_currency) else: raise ValueError("%r is not a valid money amount" % amount_str)
def make_standard_tip(label, weekly, currency): precision = get_currency_precision(currency) minimum = D_CENT if precision == 2 else Decimal(10) ** (-precision) return StandardTip( label, Money(weekly, currency), Money((weekly / PERIOD_CONVERSION_RATES['monthly']).quantize(minimum), currency), Money((weekly / PERIOD_CONVERSION_RATES['yearly']).quantize(minimum), currency), )
def create(self): transfer = Transfer(AuthorId=self.saver.mid, DebitedFunds=Money(self.amount, self.currency), Fees=Money(msdfsdfsdfsdfsdf(self.amount*0.05), self.currency), DebitedWalletId=self.debited_cuenta.wid, CreditedWalletId=self.credited_cuenta.wid) transfer.save() self.tid = transfer.Id #try the Id thingy like this. self.execution_date = datetime.datetime.fromtimestamp(transfer.execution_date) self.save()
def fuzzy_sum(self, currency, rounding=ROUND_UP): a = Money.ZEROS[currency].amount fuzzy = False for m in self: if m.currency == currency: a += m.amount elif m.amount: a += m.convert(currency, rounding=None).amount fuzzy = True r = Money(a, currency, rounding=rounding) r.fuzzy = fuzzy return r
def fuzzy_sum(self, currency): a = ZERO[currency].amount fuzzy = False for m in self: if m.currency == currency: a += m.amount elif m.amount: a += m.amount * website.currency_exchange_rates[(m.currency, currency)] fuzzy = True r = Money(a, currency) r.fuzzy = fuzzy return r
def fuzzy_sum(self, currency, rounding=ROUND_UP): a = ZERO[currency].amount fuzzy = False for m in self: if m.currency == currency: a += m.amount elif m.amount: a += m.amount * website.currency_exchange_rates[(m.currency, currency)] fuzzy = True r = Money(a.quantize(D_CENT, rounding=rounding), currency) r.fuzzy = fuzzy return r
def test_using_api_names_as_payin_attributes(self): payin = BankWirePayIn( AuthorId=1, declared_debited_funds=Money(100, 'EUR'), DeclaredFees=Money(1, 'EUR'), credited_wallet=Wallet(Id=1), ) self.assertEqual(payin.AuthorId, 1) self.assertIs(payin.declared_debited_funds, payin.DeclaredDebitedFunds) self.assertIs(payin.DeclaredFees, payin.declared_fees) self.assertEqual(payin.credited_wallet.id, payin.CreditedWalletId) payin.Tag = 'x' self.assertIs(payin.Tag, payin.tag)
def test_PreAuthorizations_CreateWithAvs(self): user = BaseTestLive.get_john() card_registration = CardRegistration() card_registration.user = user card_registration.currency = "EUR" saved_registration = card_registration.save() data = { 'cardNumber': '4972485830400049', 'cardCvx': '123', 'cardExpirationDate': '0821', 'accessKeyRef': card_registration.access_key, 'data': card_registration.preregistration_data } headers = {'content-type': 'application/x-www-form-urlencoded'} registration_data_response = requests.post( card_registration.card_registration_url, data=data, headers=headers) saved_registration[ 'registration_data'] = registration_data_response.text updated_registration = CardRegistration(**saved_registration).save() card = Card.get(updated_registration['card_id']) pre_authorization = PreAuthorization() pre_authorization.card = card pre_authorization.author = user pre_authorization.debited_funds = Money() pre_authorization.debited_funds.currency = "EUR" pre_authorization.debited_funds.amount = 500 pre_authorization.remaining_funds = Money() pre_authorization.remaining_funds.currency = "EUR" pre_authorization.remaining_funds.amount = 500 pre_authorization.secure_mode_return_url = "http://www.example.com/" billing = Billing() billing.address = Address() billing.address.address_line_1 = "Main Street" billing.address.address_line_2 = "no. 5 ap. 6" billing.address.country = "FR" billing.address.city = "Lyon" billing.address.postal_code = "65400" billing.last_name = "Doe" billing.first_name = "John" pre_authorization.billing = billing saved_pre_authorization = pre_authorization.save() self.assertIsNotNone(saved_pre_authorization) security_info = saved_pre_authorization['security_info'] self.assertIsInstance(security_info, SecurityInfo) self.assertEqual(security_info.avs_result, "NO_CHECK")
def test_CreateSettlementTransfer(self): dispute = None for d in self._client_disputes: if d.status == 'CLOSED' and d.dispute_type == 'NOT_CONTESTABLE': dispute = d break self.assertIsNotNone( dispute, 'Cannot test creating settlement transfer because there\'s no closed and not contestable disputes in the disputes list.' ) repudiation = dispute.transactions.all()[0] self.assertIsNotNone(repudiation) debit_funds = Money() fees = Money() debit_funds.currency = 'EUR' debit_funds.amount = 1 fees.currency = 'EUR' fees.amount = 0 st = SettlementTransfer() st.author = repudiation.author st.debited_funds = debit_funds st.fees = fees st.repudiation_id = repudiation.id result = st.save() self.assertIsNotNone(result) self.assertEqual(result['author_id'], st.author.id)
def __missing__(self, currency): r = { period: (Money( convert_symbolic_amount(eur_amounts[0], currency, rounding=ROUND_UP), currency), Money( convert_symbolic_amount(eur_amounts[1], currency, rounding=ROUND_UP), currency)) for period, eur_amounts in DONATION_LIMITS_EUR_USD.items() } self[currency] = r return r
def payout(db, route, amount, ignore_high_fee=False): """Withdraw money to the specified bank account (`route`). """ assert amount > 0 assert route assert route.network == 'mango-ba' participant = route.participant if participant.is_suspended: raise AccountSuspended() payday = db.one("SELECT * FROM paydays WHERE ts_start > ts_end") if payday: raise PaydayIsRunning ba = BankAccount.get(route.address, user_id=participant.mangopay_user_id) # Do final calculations amount = Money(amount, 'EUR') if isinstance(amount, Decimal) else amount 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').id payout = BankWirePayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = amount.int() payout.DebitedWalletId = participant.get_current_wallet( amount.currency).remote_id payout.Fees = fee.int() payout.BankAccountId = route.address payout.BankWireRef = str(e_id) payout.Tag = str(e_id) try: test_hook() payout.save() return record_exchange_result(db, e_id, payout.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 __missing__(self, currency): exponent = website.db.one("SELECT get_currency_exponent(%s)", (currency, )) minimum = Money( (D_CENT if exponent == 2 else Decimal(10)**(-exponent)), currency) self[currency] = minimum return minimum
def __missing__(self, currency): r = Money( convert_symbolic_amount(self['EUR'].amount, currency, self.precision), currency ) self[currency] = r return r
def fake_participant(db, kind=None): """Create a fake User. """ username = faker.first_name() + fake_text_id(3) kind = kind or random.choice(('individual', 'organization')) is_a_person = kind in ('individual', 'organization') try: p = _fake_thing( db, "participants", username=username, email=username+'@example.org', balance=Money('0.00', 'EUR'), hide_giving=is_a_person and (random.randrange(5) == 0), hide_receiving=is_a_person and (random.randrange(5) == 0), status='active', join_time=faker.date_time_this_year(), kind=kind, mangopay_user_id=username, _cast=True, ) except IntegrityError: return fake_participant(db) # Create wallet _fake_thing( db, "wallets", remote_id='-%i' % p.id, balance=p.balance, owner=p.id, remote_owner_id=p.mangopay_user_id, ) return p
def initiate_transfer(db, t_id): amount, status = db.one( """ SELECT t.amount, t.status FROM transfers t WHERE t.id = %s AND t.status = 'pre' """, (t_id, )) assert status == 'pre', (t_id, status) tipper_wallet = db.one( """ SELECT w.remote_id, w.remote_owner_id FROM transfers t JOIN wallets w ON w.remote_id = t.wallet_from WHERE t.id = %s """, (t_id, )) tippee_wallet = db.one( """ SELECT w.remote_id, w.remote_owner_id FROM transfers t JOIN wallets w ON w.remote_id = t.wallet_to WHERE t.id = %s """, (t_id, )) tr = Transfer() tr.AuthorId = tipper_wallet.remote_owner_id tr.CreditedUserId = tippee_wallet.remote_owner_id tr.CreditedWalletId = tippee_wallet.remote_id tr.DebitedFunds = amount.int() tr.DebitedWalletId = tipper_wallet.remote_id tr.Fees = Money(0, amount.currency) tr.Tag = str(t_id) execute_transfer(db, t_id, tr) return tr
def transfer(db, tipper, tippee, amount, context, **kw): tipper_wallet = NS(remote_id=kw.get('tipper_wallet_id'), remote_owner_id=kw.get('tipper_mango_id')) if not all(tipper_wallet.__dict__.values()): tipper_wallet = Participant.from_id(tipper).get_current_wallet( amount.currency) tippee_wallet = NS(remote_id=kw.get('tippee_wallet_id'), remote_owner_id=kw.get('tippee_mango_id')) if not all(tippee_wallet.__dict__.values()): tippee_wallet = Participant.from_id(tippee).get_current_wallet( amount.currency, create=True) wallet_from = tipper_wallet.remote_id wallet_to = tippee_wallet.remote_id t_id = prepare_transfer( db, tipper, tippee, amount, context, wallet_from, wallet_to, team=kw.get('team'), invoice=kw.get('invoice'), bundles=kw.get('bundles'), unit_amount=kw.get('unit_amount'), ) tr = Transfer() tr.AuthorId = tipper_wallet.remote_owner_id tr.CreditedUserId = tippee_wallet.remote_owner_id tr.CreditedWalletId = wallet_to tr.DebitedFunds = amount.int() tr.DebitedWalletId = wallet_from tr.Fees = Money(0, amount.currency) tr.Tag = str(t_id) return execute_transfer(db, t_id, tr), t_id
def recover_lost_funds(db, exchange, lost_amount, repudiation_id): """Recover as much money as possible from a payin which has been reverted. """ original_owner = exchange.participant # Try (again) to swap the disputed bundles with db.get_cursor() as cursor: cursor.run("LOCK TABLE cash_bundles IN EXCLUSIVE MODE") disputed_bundles = [ NS(d._asdict()) for d in cursor.all( """ SELECT * FROM cash_bundles WHERE origin = %s AND disputed = true """, (exchange.id, )) ] bundles_sum = sum(b.amount for b in disputed_bundles) assert bundles_sum == lost_amount - exchange.fee for b in disputed_bundles: if b.owner == original_owner: continue try_to_swap_bundle(cursor, b, original_owner) # Move the funds back to the original wallet currency = exchange.amount.currency chargebacks_account, credit_wallet = Participant.get_chargebacks_account( currency) LiberapayOrg = Participant.from_username('LiberapayOrg') assert LiberapayOrg return_payin_bundles_to_origin(db, exchange, LiberapayOrg, create_debts=True) # Add a debt for the fee create_debt(db, original_owner, LiberapayOrg.id, exchange.fee, exchange.id) # Send the funds to the credit wallet # We have to do a SettlementTransfer instead of a normal Transfer. The amount # can't exceed the original payin amount, so we can't settle the fee debt. original_owner = Participant.from_id(original_owner) from_wallet = original_owner.get_current_wallet(currency).remote_id to_wallet = credit_wallet.remote_id t_id = prepare_transfer( db, original_owner.id, chargebacks_account.id, exchange.amount, 'chargeback', from_wallet, to_wallet, prefer_bundles_from=exchange.id, ) tr = SettlementTransfer() tr.AuthorId = original_owner.mangopay_user_id tr.CreditedUserId = chargebacks_account.mangopay_user_id tr.CreditedWalletId = to_wallet tr.DebitedFunds = exchange.amount.int() tr.DebitedWalletId = from_wallet tr.Fees = Money(0, currency) tr.RepudiationId = repudiation_id tr.Tag = str(t_id) return execute_transfer(db, t_id, tr)
def parse_money_amount(self, string, currency, maximum=D_MAX): group_symbol = self.number_symbols['group'] decimal_symbol = self.number_symbols['decimal'] try: decimal = Decimal( string.replace(group_symbol, '').replace(decimal_symbol, '.')) except (InvalidOperation, ValueError): raise InvalidNumber(string) if group_symbol in string: proper = self.format_decimal(decimal, decimal_quantization=False) if string != proper and string.rstrip('0') != (proper + decimal_symbol): # Irregular number format (e.g. `10.00` in German) try: decimal_alt = Decimal( string.replace(decimal_symbol, '').replace(group_symbol, '.')) except (InvalidOperation, ValueError): raise AmbiguousNumber(string, [proper]) else: proper_alt = self.format_decimal( decimal_alt, decimal_quantization=False) raise AmbiguousNumber(string, [proper, proper_alt]) if maximum is not None and decimal > maximum: raise InvalidNumber(string) money = Money(decimal, currency).round_down() if money.amount != decimal: # The input amount exceeds maximum precision (e.g. $0.001). raise InvalidNumber(string) return money
def payout(db, route, amount, ignore_high_fee=False): """Withdraw money to the specified bank account (`route`). """ assert amount > 0 assert route assert route.network == 'mango-ba' participant = route.participant if participant.is_suspended: raise AccountSuspended() payday = db.one("SELECT * FROM paydays WHERE ts_start > ts_end") if payday: raise PaydayIsRunning ba = BankAccount.get(route.address, user_id=participant.mangopay_user_id) # Do final calculations amount = Money(amount, 'EUR') if isinstance(amount, Decimal) else amount 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').id payout = BankWirePayOut() payout.AuthorId = participant.mangopay_user_id payout.DebitedFunds = amount.int() payout.DebitedWalletId = participant.get_current_wallet(amount.currency).remote_id payout.Fees = fee.int() payout.BankAccountId = route.address payout.BankWireRef = str(e_id) payout.Tag = str(e_id) try: test_hook() payout.save() return record_exchange_result( db, e_id, payout.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 test_CreateSettlementTransfer(self): dispute = None for d in self._client_disputes: if d.status == 'CLOSED' and d.dispute_type == 'NOT_CONTESTABLE': dispute = d break self.assertIsNotNone(dispute, 'Cannot test creating settlement transfer because there\'s no closed and not contestable disputes in the disputes list.') repudiation = dispute.transactions.all()[0] self.assertIsNotNone(repudiation) debit_funds = Money() fees = Money() debit_funds.currency = 'EUR' debit_funds.amount = 1 fees.currency = 'EUR' fees.amount = 0 st = SettlementTransfer() st.author = repudiation.author st.debited_funds = debit_funds st.fees = fees st.repudiation_id = repudiation.id result = st.save() self.assertIsNotNone(result) self.assertEqual(result['author_id'], st.author.id)
def test_Idempotency(self): key = str(int(time.time())) + 'abcdefg' pay_out = None #create bankwire try: pay_out_post = BankWirePayOut() pay_out_post.author = BaseTestLive.get_john() pay_out_post.debited_wallet = BaseTestLive.get_johns_wallet() debited_funds = Money() debited_funds.amount = 10 debited_funds.currency = 'EUR' pay_out_post.debited_funds = debited_funds fees = Money() fees.amount = 5 fees.currency = 'EUR' pay_out_post.fees = fees pay_out_post.bank_account = BaseTestLive.get_johns_account() pay_out_post.bank_wire_ref = "Johns bank wire ref" pay_out_post.tag = "DefaultTag" pay_out_post.credited_user = BaseTestLive.get_john() pay_out = pay_out_post.save(idempotency_key=key) except Exception as e: self.assertFalse(True, str(e)) self.assertIsNotNone(pay_out) #test existing key result = None try: result = IdempotencyResponse.get(key) except Exception as e: self.assertFalse(True, str(e)) self.assertIsNotNone(result) #test non existing key try: IdempotencyResponse.get(key+'_no') #expecting a APIError to be thrown self.assertFalse(True, 'Api Error should have been thrown') except APIError as e: self.assertEqual(e.content['Type'], 'correlationid_not_found') self.assertTrue(e.code == 400) except Exception as ex: self.assertFalse(True, str(ex))
def Money_to_cents(m): r = Money(currency=m.currency) r.amount = int(m.amount * 100) return r