1 | """ |
---|
2 | DowCommerce class to process credit card payments with DowCommerce.com |
---|
3 | |
---|
4 | Modifications to support Dow Commerce API from code originally written by John Conde |
---|
5 | http://www.johnconde.net/blog/integrate-the-authorizenet-aim-api-with-python-3-2/ |
---|
6 | BSDv3 License |
---|
7 | |
---|
8 | Modifed by Dave Stoll dave.stoll@gmail.com |
---|
9 | |
---|
10 | - modifed to support Dow Commerce API |
---|
11 | """ |
---|
12 | from __future__ import print_function |
---|
13 | |
---|
14 | __all__ = ['DowCommerce'] |
---|
15 | |
---|
16 | from operator import itemgetter |
---|
17 | from gluon._compat import urlopen, urlencode, FancyURLopene |
---|
18 | |
---|
19 | |
---|
20 | class DowCommerce: |
---|
21 | |
---|
22 | class DowCommerceError(Exception): |
---|
23 | def __init__(self, value): |
---|
24 | self.parameter = value |
---|
25 | |
---|
26 | def __str__(self): |
---|
27 | return str(self.parameter) |
---|
28 | |
---|
29 | def __init__(self, username=None, password=None, demomode=False): |
---|
30 | if not demomode: |
---|
31 | if str(username).strip() == '' or username is None: |
---|
32 | raise DowCommerce.DowCommerceError('No username provided') |
---|
33 | if str(password).strip() == '' or password is None: |
---|
34 | raise DowCommerce.DowCommerceError('No password provided') |
---|
35 | else: |
---|
36 | username = 'demo' |
---|
37 | password = 'password' |
---|
38 | |
---|
39 | self.proxy = None |
---|
40 | self.delimiter = '&' |
---|
41 | self.results = {} |
---|
42 | self.error = True |
---|
43 | self.success = False |
---|
44 | self.declined = False |
---|
45 | self.url = 'https://secure.dowcommerce.net/api/transact.php' |
---|
46 | |
---|
47 | self.parameters = {} |
---|
48 | self.setParameter('username', username) |
---|
49 | self.setParameter('password', password) |
---|
50 | |
---|
51 | def process(self): |
---|
52 | encoded_args = urlencode(self.parameters) |
---|
53 | if self.proxy is None: |
---|
54 | results = str(urlopen( |
---|
55 | self.url, encoded_args).read()).split(self.delimiter) |
---|
56 | else: |
---|
57 | opener = FancyURLopener(self.proxy) |
---|
58 | opened = opener.open(self.url, encoded_args) |
---|
59 | try: |
---|
60 | results = str(opened.read()).split(self.delimiter) |
---|
61 | finally: |
---|
62 | opened.close() |
---|
63 | |
---|
64 | for result in results: |
---|
65 | (key, val) = result.split('=') |
---|
66 | self.results[key] = val |
---|
67 | |
---|
68 | if self.results['response'] == '1': |
---|
69 | self.error = False |
---|
70 | self.success = True |
---|
71 | self.declined = False |
---|
72 | elif self.results['response'] == '2': |
---|
73 | self.error = False |
---|
74 | self.success = False |
---|
75 | self.declined = True |
---|
76 | elif self.results['response'] == '3': |
---|
77 | self.error = True |
---|
78 | self.success = False |
---|
79 | self.declined = False |
---|
80 | else: |
---|
81 | self.error = True |
---|
82 | self.success = False |
---|
83 | self.declined = False |
---|
84 | raise DowCommerce.DowCommerceError(self.results) |
---|
85 | |
---|
86 | def setTransaction( |
---|
87 | self, creditcard, expiration, total, cvv=None, orderid=None, orderdescription=None, |
---|
88 | ipaddress=None, tax=None, shipping=None, |
---|
89 | firstname=None, lastname=None, company=None, address1=None, address2=None, city=None, state=None, zipcode=None, |
---|
90 | country=None, phone=None, fax=None, emailaddress=None, website=None, |
---|
91 | shipping_firstname=None, shipping_lastname=None, shipping_company=None, shipping_address1=None, shipping_address2=None, |
---|
92 | shipping_city=None, shipping_state=None, shipping_zipcode=None, shipping_country=None, shipping_emailaddress=None): |
---|
93 | if str(creditcard).strip() == '' or creditcard is None: |
---|
94 | raise DowCommerce.DowCommerceError('No credit card number passed to setTransaction(): {0}'.format(creditcard)) |
---|
95 | if str(expiration).strip() == '' or expiration is None: |
---|
96 | raise DowCommerce.DowCommerceError('No expiration number passed to setTransaction(): {0}'.format(expiration)) |
---|
97 | if str(total).strip() == '' or total is None: |
---|
98 | raise DowCommerce.DowCommerceError('No total amount passed to setTransaction(): {0}'.format(total)) |
---|
99 | |
---|
100 | self.setParameter('ccnumber', creditcard) |
---|
101 | self.setParameter('ccexp', expiration) |
---|
102 | self.setParameter('amount', total) |
---|
103 | |
---|
104 | if cvv: |
---|
105 | self.setParameter('cvv', cvv) |
---|
106 | if orderid: |
---|
107 | self.setParameter('orderid', orderid) |
---|
108 | if orderdescription: |
---|
109 | self.setParameter('orderdescription', orderdescription) |
---|
110 | if ipaddress: |
---|
111 | self.setParameter('ipaddress', ipaddress) |
---|
112 | if tax: |
---|
113 | self.setParameter('tax', tax) |
---|
114 | if shipping: |
---|
115 | self.setParameter('shipping', shipping) |
---|
116 | |
---|
117 | ## billing info |
---|
118 | if firstname: |
---|
119 | self.setParameter('firstname', firstname) |
---|
120 | if lastname: |
---|
121 | self.setParameter('lastname', lastname) |
---|
122 | if company: |
---|
123 | self.setParameter('company', company) |
---|
124 | if address1: |
---|
125 | self.setParameter('address1', address1) |
---|
126 | if address2: |
---|
127 | self.setParameter('address2', address2) |
---|
128 | if city: |
---|
129 | self.setParameter('city', city) |
---|
130 | if state: |
---|
131 | self.setParameter('state', state) |
---|
132 | if zipcode: |
---|
133 | self.setParameter('zip', zipcode) |
---|
134 | if country: |
---|
135 | self.setParameter('country', country) |
---|
136 | if phone: |
---|
137 | self.setParameter('phone', phone) |
---|
138 | if fax: |
---|
139 | self.setParameter('fax', fax) |
---|
140 | if emailaddress: |
---|
141 | self.setParameter('email', emailaddress) |
---|
142 | if website: |
---|
143 | self.setParameter('website', website) |
---|
144 | |
---|
145 | ## shipping info |
---|
146 | if shipping_firstname: |
---|
147 | self.setParameter('shipping_firstname', shipping_firstname) |
---|
148 | if shipping_lastname: |
---|
149 | self.setParameter('shipping_lastname', shipping_lastname) |
---|
150 | if shipping_company: |
---|
151 | self.setParameter('shipping_company', shipping_company) |
---|
152 | if shipping_address1: |
---|
153 | self.setParameter('shipping_address1', shipping_address1) |
---|
154 | if shipping_address2: |
---|
155 | self.setParameter('shipping_address2', shipping_address2) |
---|
156 | if shipping_city: |
---|
157 | self.setParameter('shipping_city', shipping_city) |
---|
158 | if shipping_state: |
---|
159 | self.setParameter('shipping_state', shipping_state) |
---|
160 | if shipping_zipcode: |
---|
161 | self.setParameter('shipping_zip', shipping_zipcode) |
---|
162 | if shipping_country: |
---|
163 | self.setParameter('shipping_country', shipping_country) |
---|
164 | |
---|
165 | def setTransactionType(self, transtype=None): |
---|
166 | types = ['sale', 'auth', 'credit'] |
---|
167 | if transtype.lower() not in types: |
---|
168 | raise DowCommerce.DowCommerceError('Incorrect Transaction Type passed to setTransactionType(): {0}'.format(transtype)) |
---|
169 | self.setParameter('type', transtype.lower()) |
---|
170 | |
---|
171 | def setProxy(self, proxy=None): |
---|
172 | if str(proxy).strip() == '' or proxy is None: |
---|
173 | raise DowCommerce.DowCommerceError('No proxy passed to setProxy()') |
---|
174 | self.proxy = {'http': str(proxy).strip()} |
---|
175 | |
---|
176 | def setParameter(self, key=None, value=None): |
---|
177 | if key is not None and value is not None and str(key).strip() != '' and str(value).strip() != '': |
---|
178 | self.parameters[key] = str(value).strip() |
---|
179 | else: |
---|
180 | raise DowCommerce.DowCommerceError('Incorrect parameters passed to setParameter(): {0}:{1}'.format(key, value)) |
---|
181 | |
---|
182 | def isApproved(self): |
---|
183 | return self.success |
---|
184 | |
---|
185 | def isDeclined(self): |
---|
186 | return self.declined |
---|
187 | |
---|
188 | def isError(self): |
---|
189 | return self.error |
---|
190 | |
---|
191 | def getResultResponseShort(self): |
---|
192 | responses = ['', 'Approved', 'Declined', 'Error'] |
---|
193 | return responses[int(self.results['response'])] |
---|
194 | |
---|
195 | def getFullResponse(self): |
---|
196 | return self.results |
---|
197 | |
---|
198 | def getResponseText(self): |
---|
199 | return self.results['responsetext'] |
---|
200 | |
---|
201 | |
---|
202 | def test(): |
---|
203 | import socket |
---|
204 | import sys |
---|
205 | from time import time |
---|
206 | |
---|
207 | ## TEST VALUES FROM API DOC: |
---|
208 | # Visa: 4111111111111111 |
---|
209 | # MasterCard 5431111111111111 |
---|
210 | # DiscoverCard: 6011601160116611 |
---|
211 | # American Express: 341111111111111 |
---|
212 | # Expiration: 10/10 |
---|
213 | # Amount: > 1.00 (( passing less than $1.00 will cause it to be declined )) |
---|
214 | # CVV: 999 |
---|
215 | creditcard = '4111111111111111' |
---|
216 | expiration = '1010' |
---|
217 | total = '1.00' |
---|
218 | cvv = '999' |
---|
219 | tax = '0.00' |
---|
220 | orderid = str(time())[4:10] # get a random invoice number |
---|
221 | |
---|
222 | try: |
---|
223 | payment = DowCommerce(demomode=True) |
---|
224 | payment.setTransaction( |
---|
225 | creditcard, expiration, total, cvv=cvv, tax=tax, orderid=orderid, orderdescription='Test Transaction', |
---|
226 | firstname='John', lastname='Doe', company='Acme', address1='123 Min Street', city='Hometown', state='VA', |
---|
227 | zipcode='12345', country='US', phone='888-555-1212', emailaddress='john@noemail.local', ipaddress='192.168.1.1') |
---|
228 | |
---|
229 | payment.process() |
---|
230 | if payment.isApproved(): |
---|
231 | print('Payment approved!') |
---|
232 | print(payment.getFullResponse()) |
---|
233 | elif payment.isDeclined(): |
---|
234 | print('Your credit card was declined by your bank') |
---|
235 | elif payment.isError(): |
---|
236 | raise DowCommerce.DowCommerceError('An uncaught error occurred') |
---|
237 | except DowCommerce.DowCommerceError as e: |
---|
238 | print("Exception thrown:", e) |
---|
239 | print('An error occured') |
---|
240 | print('approved', payment.isApproved()) |
---|
241 | print('declined', payment.isDeclined()) |
---|
242 | print('error', payment.isError()) |
---|
243 | |
---|
244 | if __name__ == '__main__': |
---|
245 | test() |
---|