18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# Copyright (c) 2012 Andy Davidoff http://www.disruptek.com/ 28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# Copyright (c) 2010 Jason R. Coombs http://www.jaraco.com/ 38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# Copyright (c) 2008 Chris Moyer http://coredumped.org/ 48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# 58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# Permission is hereby granted, free of charge, to any person obtaining a 68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# copy of this software and associated documentation files (the 78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# "Software"), to deal in the Software without restriction, including 88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# without limitation the rights to use, copy, modify, merge, publish, dis- 98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# tribute, sublicense, and/or sell copies of the Software, and to permit 108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# persons to whom the Software is furnished to do so, subject to the fol- 118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# lowing conditions: 128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# 138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# The above copyright notice and this permission notice shall be included 148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# in all copies or substantial portions of the Software. 158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# 168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi# IN THE SOFTWARE. 238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport urllib 258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport uuid 268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom boto.connection import AWSQueryConnection 278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom boto.fps.exception import ResponseErrorFactory 288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom boto.fps.response import ResponseFactory 298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport boto.fps.response 308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi__all__ = ['FPSConnection'] 328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidecorated_attrs = ('action', 'response') 348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef add_attrs_from(func, to): 378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for attr in decorated_attrs: 388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi setattr(to, attr, getattr(func, attr, None)) 398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return to 408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef complex_amounts(*fields): 438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def decorator(func): 448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def wrapper(self, *args, **kw): 458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for field in filter(kw.has_key, fields): 468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi amount = kw.pop(field) 478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw[field + '.Value'] = getattr(amount, 'Value', str(amount)) 488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw[field + '.CurrencyCode'] = getattr(amount, 'CurrencyCode', 498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.currencycode) 508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return func(self, *args, **kw) 518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi wrapper.__doc__ = "{0}\nComplex Amounts: {1}".format(func.__doc__, 528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ', '.join(fields)) 538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return add_attrs_from(func, to=wrapper) 548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return decorator 558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef requires(*groups): 588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def decorator(func): 608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def wrapper(*args, **kw): 628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi hasgroup = lambda x: len(x) == len(filter(kw.has_key, x)) 638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if 1 != len(filter(hasgroup, groups)): 648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi message = ' OR '.join(['+'.join(g) for g in groups]) 658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi message = "{0} requires {1} argument(s)" \ 668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "".format(getattr(func, 'action', 'Method'), message) 678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise KeyError(message) 688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return func(*args, **kw) 698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi message = ' OR '.join(['+'.join(g) for g in groups]) 708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi wrapper.__doc__ = "{0}\nRequired: {1}".format(func.__doc__, 718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi message) 728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return add_attrs_from(func, to=wrapper) 738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return decorator 748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef needs_caller_reference(func): 778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def wrapper(*args, **kw): 798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw.setdefault('CallerReference', uuid.uuid4()) 808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return func(*args, **kw) 818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi wrapper.__doc__ = "{0}\nUses CallerReference, defaults " \ 828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "to uuid.uuid4()".format(func.__doc__) 838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return add_attrs_from(func, to=wrapper) 848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef api_action(*api): 878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def decorator(func): 898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi action = ''.join(api or map(str.capitalize, func.__name__.split('_'))) 908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi response = ResponseFactory(action) 918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if hasattr(boto.fps.response, action + 'Response'): 928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi response = getattr(boto.fps.response, action + 'Response') 938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def wrapper(self, *args, **kw): 958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return func(self, action, response, *args, **kw) 968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi wrapper.action, wrapper.response = action, response 978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi wrapper.__doc__ = "FPS {0} API call\n{1}".format(action, 988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi func.__doc__) 998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return wrapper 1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return decorator 1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass FPSConnection(AWSQueryConnection): 1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi APIVersion = '2010-08-28' 1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ResponseError = ResponseErrorFactory 1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi currencycode = 'USD' 1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __init__(self, *args, **kw): 1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.currencycode = kw.pop('CurrencyCode', self.currencycode) 1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw.setdefault('host', 'fps.sandbox.amazonaws.com') 1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi super(FPSConnection, self).__init__(*args, **kw) 1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def _required_auth_capability(self): 1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return ['fps'] 1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('SettlementAmount') 1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['CreditInstrumentId', 'SettlementAmount.Value', 1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'SenderTokenId', 'SettlementAmount.CurrencyCode']) 1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def settle_debt(self, action, response, **kw): 1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Allows a caller to initiate a transaction that atomically transfers 1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi money from a sender's payment instrument to the recipient, while 1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi decreasing corresponding debt balance. 1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TransactionId']) 1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_transaction_status(self, action, response, **kw): 1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Gets the latest status of a transaction. 1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['StartDate']) 1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_account_activity(self, action, response, **kw): 1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns transactions for a given date range. 1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TransactionId']) 1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_transaction(self, action, response, **kw): 1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns all details of a transaction. 1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_outstanding_debt_balance(self, action, response): 1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the total outstanding balance for all the credit instruments 1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for the given creditor account. 1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, {}, response) 1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['PrepaidInstrumentId']) 1638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_prepaid_balance(self, action, response, **kw): 1658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the balance available on the given prepaid instrument. 1678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_total_prepaid_liability(self, action, response): 1728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the total liability held by the given account corresponding to 1748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi all the prepaid instruments owned by the account. 1758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, {}, response) 1778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_account_balance(self, action, response): 1808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the account balance for an account in real time. 1828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, {}, response) 1848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 1868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['PaymentInstruction', 'TokenType']) 1878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 1888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def install_payment_instruction(self, action, response, **kw): 1898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Installs a payment instruction for caller. 1918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 1938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 1958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['returnURL', 'pipelineName']) 1968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def cbui_url(self, **kw): 1978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Generate a signed URL for the Co-Branded service API given arguments as 1998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi payload. 2008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi sandbox = 'sandbox' in self.host and 'payments-sandbox' or 'payments' 2028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi endpoint = 'authorize.{0}.amazon.com'.format(sandbox) 2038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi base = '/cobranded-ui/actions/start' 2048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi validpipelines = ('SingleUse', 'MultiUse', 'Recurring', 'Recipient', 2068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'SetupPrepaid', 'SetupPostpaid', 'EditToken') 2078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi assert kw['pipelineName'] in validpipelines, "Invalid pipelineName" 2088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw.update({ 2098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'signatureMethod': 'HmacSHA256', 2108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'signatureVersion': '2', 2118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 2128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi kw.setdefault('callerKey', self.aws_access_key_id) 2138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi safestr = lambda x: x is not None and str(x) or '' 2158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi safequote = lambda x: urllib.quote(safestr(x), safe='~') 2168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi payload = sorted([(k, safequote(v)) for k, v in kw.items()]) 2178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi encoded = lambda p: '&'.join([k + '=' + v for k, v in p]) 2198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi canonical = '\n'.join(['GET', endpoint, base, encoded(payload)]) 2208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi signature = self._auth_handler.sign_string(canonical) 2218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi payload += [('signature', safequote(signature))] 2228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi payload.sort() 2238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return 'https://{0}{1}?{2}'.format(endpoint, base, encoded(payload)) 2258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 2278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('TransactionAmount') 2288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['SenderTokenId', 'TransactionAmount.Value', 2298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'TransactionAmount.CurrencyCode']) 2308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def reserve(self, action, response, **kw): 2328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Reserve API is part of the Reserve and Settle API conjunction that 2348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi serve the purpose of a pay where the authorization and settlement have 2358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi a timing difference. 2368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 2408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('TransactionAmount') 2418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['SenderTokenId', 'TransactionAmount.Value', 2428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'TransactionAmount.CurrencyCode']) 2438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def pay(self, action, response, **kw): 2458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Allows calling applications to move money from a sender to a recipient. 2478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TransactionId']) 2518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def cancel(self, action, response, **kw): 2538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Cancels an ongoing transaction and puts it in cancelled state. 2558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('TransactionAmount') 2598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['ReserveTransactionId', 'TransactionAmount.Value', 2608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'TransactionAmount.CurrencyCode']) 2618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def settle(self, action, response, **kw): 2638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi The Settle API is used in conjunction with the Reserve API and is used 2658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi to settle previously reserved transaction. 2668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('RefundAmount') 2708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TransactionId', 'RefundAmount.Value', 2718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'CallerReference', 'RefundAmount.CurrencyCode']) 2728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def refund(self, action, response, **kw): 2748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Refunds a previously completed transaction. 2768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['RecipientTokenId']) 2808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_recipient_verification_status(self, action, response, **kw): 2828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the recipient status. 2848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['CallerReference'], ['TokenId']) 2888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_token_by_caller(self, action, response, **kw): 2908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the details of a particular token installed by this calling 2928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi application using the subway co-branded UI. 2938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 2958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['UrlEndPoint', 'HttpParameters']) 2978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 2988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def verify_signature(self, action, response, **kw): 2998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Verify the signature that FPS sent in IPN or callback urls. 3018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_tokens(self, action, response, **kw): 3068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns a list of tokens installed on the given account. 3088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TokenId']) 3128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_token_usage(self, action, response, **kw): 3148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the usage of a token. 3168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TokenId']) 3208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def cancel_token(self, action, response, **kw): 3228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Cancels any token installed by the calling application on its own 3248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi account. 3258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 3298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('FundingAmount') 3308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['PrepaidInstrumentId', 'FundingAmount.Value', 3318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'SenderTokenId', 'FundingAmount.CurrencyCode']) 3328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def fund_prepaid(self, action, response, **kw): 3348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Funds the prepaid balance on the given prepaid instrument. 3368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['CreditInstrumentId']) 3408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_debt_balance(self, action, response, **kw): 3428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the balance corresponding to the given credit instrument. 3448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 3488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('AdjustmentAmount') 3498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['CreditInstrumentId', 'AdjustmentAmount.Value', 3508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'AdjustmentAmount.CurrencyCode']) 3518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def write_off_debt(self, action, response, **kw): 3538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Allows a creditor to write off the debt balance accumulated partially 3558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi or fully at any time. 3568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['SubscriptionId']) 3608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_transactions_for_subscription(self, action, response, **kw): 3628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the transactions for a given subscriptionID. 3648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['SubscriptionId']) 3688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_subscription_details(self, action, response, **kw): 3708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the details of Subscription for a given subscriptionID. 3728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @needs_caller_reference 3768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @complex_amounts('RefundAmount') 3778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['SubscriptionId']) 3788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def cancel_subscription_and_refund(self, action, response, **kw): 3808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Cancels a subscription. 3828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi message = "If you specify a RefundAmount, " \ 3848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "you must specify CallerReference." 3858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi assert not 'RefundAmount.Value' in kw \ 3868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi or 'CallerReference' in kw, message 3878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 3888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @requires(['TokenId']) 3908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi @api_action() 3918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def get_payment_instruction(self, action, response, **kw): 3928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Gets the payment instruction of a token. 3948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.get_object(action, kw, response) 396