def refund(self, transaction, amount): xml = self.build_xml( 'createTransactionRequest', OrderedDict([ ('transactionRequest', OrderedDict([ ('transactionType', 'refundTransaction'), ('amount', amount), ('payment', self._payment_xml({ 'number': transaction.data['account_number'], 'year': 'XXXX', 'month': 'XX' })), ('refTransId', transaction.transaction_id), ])), ])) resp = xml_to_dict(xml_post(self.url, xml)) self.check_for_error(resp) return True
def _update_customer_xml(self, customer_id, options): stuff = [('email', options['email']), ('customerProfileId', customer_id)] root = OrderedDict([ ('profile', OrderedDict(stuff)), ]) return self.build_xml('updateCustomerProfileRequest', root)
def add_card_to_customer(self, customer, options): root = OrderedDict([ ('customerProfileId', customer.customer_id), ('paymentProfile', OrderedDict([ ('billTo', self._billto_xml(options)), ('payment', self._payment_xml(options)), ])), ('validationMode', 'liveMode'), ]) xml = self.build_xml('createCustomerPaymentProfileRequest', root) resp = xml_to_dict(xml_post(self.url, xml)) try: self.check_for_error(resp) except GatewayException as e: error_code = e.args[0][0][0] if error_code == 'E00039': # Duplicate Record raise DuplicateCardError(e) elif error_code == 'E00013': # Expiration Date is invalid raise InvalidCardError(e) raise card = self._dict_to_payment_profile(root['paymentProfile']) card.update({ 'customer_id': customer.customer_id, 'card_id': resp['customerPaymentProfileId'], }) return card
def _transaction_xml(self, price, options): transaction_xml = OrderedDict([ ('transactionType', 'authCaptureTransaction'), ('amount', price), ]) payment = self._payment_xml(options) if payment: transaction_xml['payment'] = payment # customer node causes fail if it is present, but empty. customer_xml = self._simple_customer_xml(options) if customer_xml: transaction_xml['customer'] = customer_xml billto = self._billto_xml(options) if billto: transaction_xml['billTo'] = billto transaction_xml['transactionSettings'] = OrderedDict([ ('setting', [ OrderedDict([ ('settingName', 'duplicateWindow'), ('settingValue', 0), ]), OrderedDict([ ('settingName', 'testRequest'), ('settingValue', 'false'), ]), ],) ]) xml = self.build_xml('createTransactionRequest', OrderedDict([ ('transactionRequest', transaction_xml,), ])) return xml
def build_xml(self, root_name, root): root = OrderedDict( [('merchantAuthentication', OrderedDict([ ('name', self.login_id), ('transactionKey', self.transaction_key), ]))] + list(root.items())) return _dict_to_xml(root_name, root, self.ns)
def _charge_customer_xml(self, customer_id, customer_payment_profile_id, price, options): return self.build_xml('createCustomerProfileTransactionRequest', OrderedDict([ ('transaction', OrderedDict([ ('profileTransAuthOnly', OrderedDict([ ('amount', price), ('customerProfileId', customer_id), ('customerPaymentProfileId', customer_payment_profile_id), ('cardCode', options.get('cvv')), ])), ])) ]))
def settle(self, transaction, amount): xml = self.build_xml('createTransactionRequest', OrderedDict([ ('transactionRequest', OrderedDict([ ('transactionType', 'priorAuthCaptureTransaction'), ('amount', amount), ('refTransId', transaction.transaction_id), ])), ])) resp = xml_to_dict(xml_post(self.url, xml)) transaction.auth_code = resp['transactionResponse']['authCode'] return transaction
def void(self, transaction): xml = self.build_xml('createTransactionRequest', OrderedDict([ ('transactionRequest', OrderedDict([ ('transactionType', 'voidTransaction'), ('refTransId', transaction.transaction_id), ])), ])) resp = xml_to_dict(xml_post(self.url, xml)) self.check_for_error(resp) return True
def update_card(self, card): xml = self.build_xml('updateCustomerPaymentProfileRequest', OrderedDict([ ('customerProfileId', card.customer_id), ('paymentProfile', OrderedDict([ ('billTo', self._billto_xml(card.data)), ('payment', self._payment_xml(card.data)), ('customerPaymentProfileId', card.card_id), ])), ('validationMode', 'liveMode'), ])) resp = xml_to_dict(xml_post(self.url, xml)) try: self.check_for_error(resp) except GatewayException as e: error_code = e.args[0][0][0] raise
def _billto_xml(self, options): billto_xml = OrderedDict([ ('firstName', options.get('first_name')), ('lastName', options.get('last_name')), ('company', options.get('company')), ('address', options.get('address')), ('city', options.get('city')), ('state', options.get('state')), ('zip', options.get('zip')), ('country', options.get('country')), ('phoneNumber', options.get('phone')), ('faxNumber', options.get('fax')), ]) if any(val != None for val in billto_xml.values()): return billto_xml return None
def _simple_customer_xml(self, options): if not ('customer_id' in options or 'email' in options): return None return OrderedDict([ ('id', options.get('customer_id')), ('email', options.get('email')), ])
def xml_to_dict(parent): ret = OrderedDict() parent_tag = get_tag(parent) if parent_tag in ('messages', 'errors'): ret[parent_tag[:-1]] = [] if parent_tag == 'profile': ret['paymentProfiles'] = [] for child in parent: tag = get_tag(child) if len(child): child_value = xml_to_dict(child) else: child_value = child.text and child.text.strip() or '' if tag in ret and isinstance(ret[tag], list): x = ret[tag] del (ret[tag]) ret[tag] = x ret[tag].append(child_value) else: ret[tag] = child_value return ret
def _charge_customer_xml(self, customer_id, card_id, price, options): if options.get('settle', True): txn_type = 'profileTransAuthCapture' else: txn_type = 'profileTransAuthOnly' return self.build_xml('createCustomerProfileTransactionRequest', OrderedDict([ ('transaction', OrderedDict([ (txn_type, OrderedDict([ ('amount', price), ('customerProfileId', customer_id), ('customerPaymentProfileId', card_id), ('cardCode', options.get('cvv')), ])), ])) ]))
def delete_card(self, card): xml = self.build_xml('deleteCustomerPaymentProfileRequest', OrderedDict([ ('customerProfileId', card.customer_id), ('customerPaymentProfileId', card.card_id), ])) resp = xml_to_dict(xml_post(self.url, xml)) self.check_for_error(resp)
def _create_customer_xml(self, options): # include <billTo> and <payment> fields only if # the necessary data was included # build <billTo> entry? billto_fields = [ 'first_name', 'last_name', 'company', 'address', 'city', 'state', 'zip', 'country', 'phone', 'fax', ] if any(field in options for field in billto_fields): billto = ('billTo', self._billto_xml(options)) else: billto = None # build <payment> entry? if 'number' in options: payment = ('payment', self._payment_xml(options)) else: payment = None if billto or payment: stuff = [] if billto: stuff.append(billto) if payment: stuff.append(payment) payment_profiles = ('paymentProfiles', OrderedDict(stuff)) else: payment_profiles = None stuff = [('email', options['email'])] if payment_profiles: stuff.append(payment_profiles) root = OrderedDict([ ('profile', OrderedDict(stuff)), ]) return self.build_xml('createCustomerProfileRequest', root)
def retrieve(self, transaction_id): xml = self.build_xml('getTransactionDetailsRequest', OrderedDict([ ('transId', transaction_id), ])) resp = xml_to_dict(xml_post(self.url, xml)) self.check_for_error(resp) return self._resp_to_transaction_dict(resp['transaction'], resp['transaction']['authAmount'])
def _payment_xml(self, options): year = str(options.get('year', '0')) if year != 'XXXX' and int(year) < 100: century = date.today().year // 100 year = str(century) + str(year).zfill(2) # zeropad the month expiry = str(year) + '-' + str(options.get('month', '0')).zfill(2) if expiry == 'XXXX-XX': expiry = 'XXXX' payment_xml = OrderedDict([ ('creditCard', OrderedDict([ ('cardNumber', prepare_number(options['number'])), ('expirationDate', expiry), ('cardCode', options.get('cvv')), ])), ]) if any(val != None for val in payment_xml.values()): return payment_xml return None
def delete_customer(self, customer_id): xml = self.build_xml('deleteCustomerProfileRequest', OrderedDict([ ('customerProfileId', customer_id), ])) resp = xml_to_dict(xml_post(self.url, xml)) try: self.check_for_error(resp) except GatewayException as e: error_code = e.args[0][0][0] if error_code == 'E00040': # NotFound raise CustomerNotFoundError(e) raise return True
def _get_customer_payment_profile(self, customer_id, card_id): xml = self.build_xml('getCustomerPaymentProfileRequest', OrderedDict([ ('customerProfileId', customer_id), ('customerPaymentProfileId', card_id), ])) resp = xml_to_dict(xml_post(self.url, xml)) try: self.check_for_error(resp) except GatewayException as e: error_code = e.args[0][0][0] if error_code == 'E00040': # NotFound raise CustomerNotFoundError(e) raise return resp
def test_none_is_no_element(self): self._test("<root></root>", OrderedDict([ ('whatever', None), ]), 'root')
from lxml import etree import unittest from pprint import pprint from dinero.ordereddict import OrderedDict import dinero barebones = ("<root><a>b</a></root>", OrderedDict([('a', 'b')])) simple = (""" <root> <x> <a>Text</a> <b>Something Else</b> </x> </root> """, OrderedDict([ ('x', OrderedDict([ ('a', 'Text'), ('b', 'Something Else'), ])), ])) list_example = (""" <root> <messages> <message>1</message> <message>2</message> <message>3</message> <message> <a>Text</a>
def _update_customer_payment(self, customer_id, options): # update <billTo> and <payment> fields only if # the necessary data was included # update <billTo> entry? billto_fields = [ 'first_name', 'last_name', 'company', 'address', 'city', 'state', 'zip', 'country', 'phone', 'fax', ] if any(field in options for field in billto_fields): billto = ('billTo', self._billto_xml(options)) else: billto = None # update <payment> entry? if 'number' in options: payment = ('payment', self._payment_xml(options)) else: payment = None if billto or payment: if 'card_id' in options: card_id = options['card_id'] else: customer = self.retrieve_customer(customer_id) card_id = customer.card_id merge = None if card_id: try: profile = self._get_customer_payment_profile( customer_id, card_id) # TODO: test this, sorry merge = self._dict_to_payment_profile( profile['paymentProfile']) merge.update(options) options = merge except CustomerNotFoundError: pass stuff = [] # refresh billto and payment if merge came back with anything if merge: billto = ('billTo', self._billto_xml(options)) if billto: stuff.append(billto) if merge: payment = ('payment', self._payment_xml(options)) if payment: stuff.append(payment) if card_id: stuff.append(('customerPaymentProfileId', card_id)) root = OrderedDict([ ('customerProfileId', customer_id), ('paymentProfile', OrderedDict(stuff)), ]) xml = self.build_xml('updateCustomerPaymentProfileRequest', root) resp = xml_to_dict(xml_post(self.url, xml)) else: root = OrderedDict([ ('customerProfileId', customer_id), ('paymentProfile', OrderedDict(stuff)), ]) xml = self.build_xml('createCustomerPaymentProfileRequest', root) resp = xml_to_dict(xml_post(self.url, xml)) try: self.check_for_error(resp) except GatewayException as e: error_code = e.args[0][0][0] if error_code == 'E00039': # Duplicate Record raise DuplicateCustomerError(e) elif error_code == 'E00013': # Expiration Date is invalid raise InvalidCardError(e) raise