1
# Copyright (c) 2008 Chris Moyer http://coredumped.org/
3
# Permission is hereby granted, free of charge, to any person obtaining a
4
# copy of this software and associated documentation files (the
5
# "Software"), to deal in the Software without restriction, including
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
8
# persons to whom the Software is furnished to do so, subject to the fol-
11
# The above copyright notice and this permission notice shall be included
12
# in all copies or substantial portions of the Software.
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27
from boto import handler
28
from boto.connection import AWSQueryConnection
29
from boto.resultset import ResultSet
30
from boto.exception import FPSResponseError
32
class FPSConnection(AWSQueryConnection):
34
APIVersion = '2007-01-08'
35
SignatureVersion = '1'
37
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
38
is_secure=True, port=None, proxy=None, proxy_port=None,
39
host='fps.sandbox.amazonaws.com', debug=0,
40
https_connection_factory=None):
41
AWSQueryConnection.__init__(self, aws_access_key_id,
42
aws_secret_access_key,
43
is_secure, port, proxy, proxy_port,
44
host, debug, https_connection_factory)
46
def install_payment_instruction(self, instruction, token_type="Unrestricted", transaction_id=None):
48
InstallPaymentInstruction
49
instruction: The PaymentInstruction to send, for example:
51
MyRole=='Caller' orSay 'Roles do not match';
53
token_type: Defaults to "Unrestricted"
54
transaction_id: Defaults to a new ID
57
if(transaction_id == None):
58
transaction_id = uuid.uuid4()
60
params['PaymentInstruction'] = instruction
61
params['TokenType'] = token_type
62
params['CallerReference'] = transaction_id
63
response = self.make_request("InstallPaymentInstruction", params)
66
def install_caller_instruction(self, token_type="Unrestricted", transaction_id=None):
69
This will install a new caller_token into the FPS section.
70
This should really only be called to regenerate the caller token.
72
response = self.install_payment_instruction("MyRole=='Caller';", token_type=token_type, transaction_id=transaction_id)
73
body = response.read()
74
if(response.status == 200):
76
h = handler.XmlHandler(rs, self)
77
xml.sax.parseString(body, h)
78
caller_token = rs.TokenId
80
boto.config.save_system_option("FPS", "caller_token", caller_token)
82
boto.config.save_user_option("FPS", "caller_token", caller_token)
85
raise FPSResponseError(response.status, response.reason, body)
87
def install_recipient_instruction(self, token_type="Unrestricted", transaction_id=None):
89
Set us up as a Recipient
90
This will install a new caller_token into the FPS section.
91
This should really only be called to regenerate the recipient token.
93
response = self.install_payment_instruction("MyRole=='Recipient';", token_type=token_type, transaction_id=transaction_id)
94
body = response.read()
95
if(response.status == 200):
97
h = handler.XmlHandler(rs, self)
98
xml.sax.parseString(body, h)
99
recipient_token = rs.TokenId
101
boto.config.save_system_option("FPS", "recipient_token", recipient_token)
103
boto.config.save_user_option("FPS", "recipient_token", recipient_token)
105
return recipient_token
107
raise FPSResponseError(response.status, response.reason, body)
109
def make_url(self, returnURL, paymentReason, pipelineName, **params):
111
Generate the URL with the signature required for a transaction
113
params['callerKey'] = str(self.aws_access_key_id)
114
params['returnURL'] = str(returnURL)
115
params['paymentReason'] = str(paymentReason)
116
params['pipelineName'] = pipelineName
118
if(not params.has_key('callerReference')):
119
params['callerReference'] = str(uuid.uuid4())
125
url += "&%s=%s" % (k, urllib.quote_plus(str(params[k])))
127
url = "/cobranded-ui/actions/start?%s" % ( url[1:])
128
signature= boto.utils.encode(self.aws_secret_access_key, url, True)
129
return "https://authorize.payments-sandbox.amazon.com%s&awsSignature=%s" % (url, signature)
131
def make_payment(self, amount, sender_token, charge_fee_to="Recipient", reference=None, senderReference=None, recipientReference=None, senderDescription=None, recipientDescription=None, callerDescription=None, metadata=None, transactionDate=None):
133
Make a payment transaction
134
You must specify the amount and the sender token.
137
params['RecipientTokenId'] = boto.config.get("FPS", "recipient_token")
138
params['CallerTokenId'] = boto.config.get("FPS", "caller_token")
139
params['SenderTokenId'] = sender_token
140
params['TransactionAmount.Amount'] = str(amount)
141
params['TransactionAmount.CurrencyCode'] = "USD"
142
params['ChargeFeeTo'] = charge_fee_to
144
if(transactionDate != None):
145
params['TransactionDate'] = transactionDate
146
if(senderReference != None):
147
params['SenderReference'] = senderReference
148
if(recipientReference != None):
149
params['RecipientReference'] = recipientReference
150
if(senderDescription != None):
151
params['SenderDescription'] = senderDescription
152
if(recipientDescription != None):
153
params['RecipientDescription'] = recipientDescription
154
if(callerDescription != None):
155
params['CallerDescription'] = callerDescription
156
if(metadata != None):
157
params['MetaData'] = metadata
158
if(transactionDate != None):
159
params['TransactionDate'] = transactionDate
160
if(reference == None):
161
reference = uuid.uuid4()
162
params['CallerReference'] = reference
164
response = self.make_request("Pay", params)
165
body = response.read()
166
if(response.status == 200):
168
h = handler.XmlHandler(rs, self)
169
xml.sax.parseString(body, h)
172
raise FPSResponseError(response.status, response.reason, body)