Skip to content

Instantly share code, notes, and snippets.

@SandeR2012
Created April 29, 2015 12:00
Show Gist options
  • Save SandeR2012/b919d611c246550b8c2d to your computer and use it in GitHub Desktop.
Save SandeR2012/b919d611c246550b8c2d to your computer and use it in GitHub Desktop.
MultiSafepay API for Python
import uuid
import random
import hashlib
import requests
from xml.sax.saxutils import escape
from xml.etree import ElementTree
transaction_template = '''<?xml version="1.0" encoding="UTF-8" ?>
<redirecttransaction ua="Example 1.0">
<merchant>
<account>%(account)s</account>
<site_id>%(site_id)s</site_id>
<site_secure_code>%(site_secure_code)s</site_secure_code>
<notification_url>%(notification_url)s</notification_url>
<cancel_url>%(cancel_url)s</cancel_url>
<redirect_url>%(redirect_url)s</redirect_url>
<close_window>false</close_window>
</merchant>
<customer>
<locale>%(locale)s</locale>
<ipaddress>%(ipaddress)s</ipaddress>
<forwardedip></forwardedip>
<firstname></firstname>
<lastname></lastname>
<address1></address1>
<address2></address2>
<housenumber></housenumber>
<zipcode></zipcode>
<city></city>
<state></state>
<country></country>
<phone></phone>
<email>%(email)s</email>
</customer>
<transaction>
<id>%(transaction_id)s</id>
<currency>%(currency)s</currency>
<amount>%(amount)s</amount>
<description>%(description)s</description>
<var1></var1>
<var2></var2>
<var3></var3>
<items></items>
<manual>false</manual>
<gateway></gateway>
<daysactive>%(daysactive)s</daysactive>
</transaction>
<signature>%(signature)s</signature>
</redirecttransaction>'''
status_template = """
<?xml version="1.0" encoding="UTF-8"?>
<status ua="custom-1.1">
<merchant>
<account>%(account)s</account>
<site_id>%(site_id)s</site_id>
<site_secure_code>%(site_secure_code)s</site_secure_code>
</merchant>
<transaction>
<id>%(transaction_id)s</id>
</transaction>
</status>"""
class MSPError(Exception):
def __init__(self, code, description):
self.code = code
self.description = description
def __str__(self):
return '%s: %s' % (self.code, self.description)
class Transaction:
TEST_API_URL = 'https://testapi.multisafepay.com/ewx/'
PROD_API_URL = 'https://api.multisafepay.com/ewx/'
KEYS_FOR_HASH = ('amount', 'currency', 'account', 'site_id', 'transaction_id')
STATUSES = {
'completed': 1, # completed successfully
'initialized': 6, # created, but uncompleted
'uncleared': 6, # created, but not yet exempted (credit cards)
'void': 2, # cancelled
'declined': 2, # rejected
'refunded': 3, # refunded
'expired': 5, # expired
'shipped': 1 # shipped
}
def __init__(self, test=True, **kwargs):
self.kwargs = kwargs
self.kwargs['transaction_id'] = self.new_transaction_id
self.kwargs['signature'] = self.signature
if test:
self.API_URL = self.TEST_API_URL
else:
self.API_URL = self.PROD_API_URL
self.escape_kwargs()
def start(self):
""" Post to msp, this returns the payment url """
xml_str = transaction_template % self.kwargs
return self.get_payment_url(self.API_URL, xml_str)
def escape_kwargs(self):
for k, v in self.kwargs.items():
self.kwargs[k] = escape(v)
@property
def signature(self):
line = ''.join([self.kwargs[key] for key in self.KEYS_FOR_HASH])
return hashlib.md5(line.encode()).hexdigest()
@staticmethod
def get_payment_url(url, xml_str):
r = requests.get(url, data=xml_str)
return Transaction.get_data_by_path(r.text, 'transaction/payment_url')
@staticmethod
def get_data_by_path(data, path):
# from lxml import etree
# root = etree.fromstring(data.encode())
# print(etree.tostring(root, pretty_print=True).decode())
tree = ElementTree.fromstring(data)
result = tree.get('result')
if result == 'ok':
return tree.find(path).text
else:
code = tree.find('error/code').text
description = tree.find('error/description').text
raise MSPError(code, description)
@staticmethod
def get_transaction_status(test=True, **kwargs):
if test:
url = Transaction.TEST_API_URL
else:
url = Transaction.PROD_API_URL
xml_str = status_template % kwargs
r = requests.get(url, data=xml_str)
status = Transaction.get_data_by_path(r.text, 'ewallet/status')
return Transaction.STATUSES[status]
@property
def new_transaction_id(self):
return 'MSP_{0}{1}'.format(uuid.uuid4().hex[4:26], str(random.randint(10, 99)))
def __str__(self):
return str(self.kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment