Skip to content

Commit

Permalink
Merge pull request #373 from Mangopay/feature/virtual-accounts
Browse files Browse the repository at this point in the history
Feature/virtual accounts
  • Loading branch information
iulian03 authored Nov 22, 2024
2 parents 6e06c36 + 5a3bbd9 commit 3016833
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 3 deletions.
59 changes: 58 additions & 1 deletion mangopay/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Reason, ReportTransactionsFilters, ReportWalletsFilters, \
PlatformCategorization, Billing, SecurityInfo, Birthplace, ApplepayPaymentData, GooglepayPaymentData, \
ScopeBlocked, BrowserInfo, Shipping, CurrentState, FallbackReason, InstantPayout, CountryAuthorizationData, \
PayinsLinked, ConversionRate, CardInfo
PayinsLinked, ConversionRate, CardInfo, LocalAccountDetails, InternationalAccountDetails, VirtualAccountCapabilities


class FieldDescriptor(object):
Expand Down Expand Up @@ -935,3 +935,60 @@ def api_value(self, value):
}

return value


class LocalAccountDetailsField(Field):
def python_value(self, value):
if value is not None:
return LocalAccountDetails(address=value['Address'], account=value['Account'])
return value

def api_value(self, value):
value = super(LocalAccountDetailsField, self).api_value(value)

if isinstance(value, LocalAccountDetails):
value = {
'Address': value.address,
'Account': value.account
}

return value


class InternationalAccountDetailsField(Field):
def python_value(self, value):
if value is not None:
return InternationalAccountDetails(address=value['Address'], account=value['Account'])
return value

def api_value(self, value):
value = super(InternationalAccountDetailsField, self).api_value(value)

if isinstance(value, InternationalAccountDetails):
value = {
'Address': value.address,
'Account': value.account
}

return value


class VirtualAccountCapabilitiesField(Field):
def python_value(self, value):
if value is not None:
return VirtualAccountCapabilities(local_pay_in_available=value['LocalPayinAvailable'],
international_pay_in_available=value['InternationalPayinAvailable'],
currencies=value['Currencies'])
return value

def api_value(self, value):
value = super(VirtualAccountCapabilitiesField, self).api_value(value)

if isinstance(value, VirtualAccountCapabilities):
value = {
'LocalPayinAvailable': value.local_pay_in_available,
'InternationalPayinAvailable': value.international_pay_in_available,
'Currencies': value.currencies
}

return value
35 changes: 34 additions & 1 deletion mangopay/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
ReportWalletsFiltersField, BillingField, SecurityInfoField, PlatformCategorizationField,
BirthplaceField, ApplepayPaymentDataField, GooglepayPaymentDataField, ScopeBlockedField,
BrowserInfoField, ShippingField, CurrentStateField, FallbackReasonField, InstantPayoutField,
CountryAuthorizationDataField, PayinsLinkedField, ConversionRateField, CardInfoField)
CountryAuthorizationDataField, PayinsLinkedField, ConversionRateField, CardInfoField,
LocalAccountDetailsField, VirtualAccountCapabilitiesField)
from .query import InsertQuery, UpdateQuery, SelectQuery, ActionQuery


Expand Down Expand Up @@ -2256,3 +2257,35 @@ class Meta:
SelectQuery.identifier: '/deposit-preauthorizations/',
UpdateQuery.identifier: '/deposit-preauthorizations/'
}


class VirtualAccount(BaseModel):
wallet_id = CharField(api_name='WalletId', required=True)
credited_user_id = CharField(api_name='CreditedUserId')
virtual_account_purpose = CharField(api_name='VirtualAccountPurpose', required=True)
country = CharField(api_name='Country', required=True)
status = CharField(api_name='Status')
active = BooleanField(api_name='Active')
account_owner = CharField(api_name='AccountOwner')
local_account_details = LocalAccountDetailsField(api_name='LocalAccountDetails')
international_account_details = ListField(api_name='InternationalAccountDetails')
capabilities = VirtualAccountCapabilitiesField(api_name='Capabilities')

class Meta:
verbose_name = 'virtual_account'
verbose_name_plural = 'virtual_accounts'

url = '/wallets/%(wallet_id)s/virtual-accounts'


class VirtualAccountAvailability(BaseModel):
collection = ListField(api_name='Collection')
user_owned = ListField(api_name='UserOwned')

class Meta:
verbose_name = 'virtual_account_availability'
verbose_name_plural = 'virtual_account_availabilities'

url = {
SelectQuery.identifier: '/virtual-accounts/availability'
}
50 changes: 50 additions & 0 deletions mangopay/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1024,3 +1024,53 @@ def to_api_json(self):
"Carrier": self.carrier,
"NotifyBuyer": self.notify_buyer
}


class LocalAccountDetails(object):
def __init__(self, address=None, account=None):
self.address = address
self.account = account

def __str__(self):
return 'LocalAccountDetails: %s %s' % \
(self.address, self.account)

def to_api_json(self):
return {
"Address": self.address,
"Account": self.account
}


class InternationalAccountDetails(object):
def __init__(self, address=None, account=None):
self.address = address
self.account = account

def __str__(self):
return 'InternationalAccountDetails: %s %s' % \
(self.address, self.account)

def to_api_json(self):
return {
"Address": self.address,
"Account": self.account
}


class VirtualAccountCapabilities(object):
def __init__(self, local_pay_in_available=None, international_pay_in_available=None, currencies=None):
self.local_pay_in_available = local_pay_in_available
self.international_pay_in_available = international_pay_in_available
self.currencies = currencies

def __str__(self):
return 'VirtualAccountCapabilities: %s %s %s' % \
(self.local_pay_in_available, self.international_pay_in_available, self.currencies)

def to_api_json(self):
return {
"LocalPayinAvailable": self.local_pay_in_available,
"InternationalPayinAvailable": self.international_pay_in_available,
"Currencies": self.currencies
}
15 changes: 14 additions & 1 deletion tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
from mangopay import APIRequest
from mangopay import get_default_handler
from mangopay.auth import AuthorizationTokenManager, StaticStorageStrategy
from mangopay.resources import BankAccount, Document, ReportTransactions, UboDeclaration, Ubo, Deposit, DirectPayIn
from mangopay.resources import BankAccount, Document, ReportTransactions, UboDeclaration, Ubo, Deposit, DirectPayIn, \
VirtualAccount
from mangopay.utils import Address, ReportTransactionsFilters, Birthplace, BrowserInfo
from tests import settings
from tests.mocks import RegisteredMocks
Expand Down Expand Up @@ -619,6 +620,18 @@ def create_new_card_registration_for_deposit():

return CardRegistration(**card_registration.save())

@staticmethod
def create_new_virtual_account():
BaseTestLive.get_john()
wallet = BaseTestLive.get_johns_wallet()

virtual_account = VirtualAccount()
virtual_account.wallet_id = wallet.id
virtual_account.country = 'FR'
virtual_account.virtual_account_purpose = 'COLLECTION'

return VirtualAccount(**virtual_account.save())

def test_handler(self):
api_url = "test_api_url"
sandbox_url = "test_sandbox_url"
Expand Down
45 changes: 45 additions & 0 deletions tests/test_virtual_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from mangopay.resources import VirtualAccount, \
VirtualAccountAvailability
from tests.test_base import BaseTestLive


class VirtualAccountTest(BaseTestLive):

def test_create_virtual_account(self):
virtual_account = BaseTestLive.create_new_virtual_account()

self.assertIsNotNone(virtual_account)
self.assertEqual(virtual_account.status, 'ACTIVE')

def test_get_virtual_account(self):
virtual_account = BaseTestLive.create_new_virtual_account()
wallet = BaseTestLive.get_johns_wallet()
fetched = VirtualAccount.get(virtual_account.id, **{'wallet_id': wallet.id})

self.assertIsNotNone(fetched)
self.assertEqual(virtual_account.id, fetched.id)

def test_get_all_virtual_accounts(self):
BaseTestLive.create_new_virtual_account()
wallet = BaseTestLive.get_johns_wallet()
fetched = VirtualAccount.all(**{'wallet_id': wallet.id})

self.assertIsNotNone(fetched)
self.assertEqual(1, len(fetched))

def test_deactivate_virtual_account(self):
virtual_account = BaseTestLive.create_new_virtual_account()
wallet = BaseTestLive.get_johns_wallet()

result_dict = VirtualAccount.update(virtual_account.id, **{'wallet_id': wallet.id}).execute()
deactivated = VirtualAccount(**result_dict)

self.assertIsNotNone(deactivated)
self.assertEqual(virtual_account.id, deactivated.id)
self.assertEqual(deactivated.status, "CLOSED")

def test_get_availabilities(self):
availabilities = VirtualAccountAvailability.all()
self.assertIsNotNone(availabilities)
self.assertEqual(1, len(availabilities))

0 comments on commit 3016833

Please sign in to comment.