示例#1
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, PATH, 'text/xml')
     self.login = login
     self.key = key
     self.schedule = None
     self.amount = None
     self.trial = None
     self.payment = None
     self.customer = None
     self.subscription_id = None
示例#2
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, PATH, 'text/xml')
     self.login = login
     self.key = key
     self.payment = []
     self.billto = []
     self.shipping = []
     self.amount = None
     self.customer_id = None
     self.request_id = None
     self.validation_mode = 'none'
示例#3
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, '/gateway/transact.dll',
                              'application/x-www-form-urlencoded')
     self.login = login
     self.key = key
     self.delimiter = FIELD_DELIM
     self.amount = None
     self.payment = None
     self.customer = None
     self.is_test = False
     self.require_ccv = False
     self.require_avs = False
     self.duplicate_window = None
示例#4
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, PATH, 'text/xml')
     self.login = login
     self.key = key
     self.schedule = None
     self.amount = None
     self.trial = None
     self.payment = None
     self.customer = None
     self.subscription_id = None
示例#5
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, PATH, 'text/xml')
     self.login = login
     self.key = key
     self.payment = []
     self.billto = []
     self.shipping = []
     self.amount = None
     self.customer_id = None
     self.request_id = None
     self.validation_mode = 'none'
示例#6
0
 def __init__(self, host, login, key):
     self.conn = AuthorizeNet(host, '/gateway/transact.dll', 'application/x-www-form-urlencoded')
     self.login = login
     self.key = key
     self.delimiter = FIELD_DELIM
     self.amount = None
     self.payment = None
     self.customer = None
     self.is_test = False
     self.require_ccv = False
     self.require_avs = False
     self.duplicate_window = None
示例#7
0
class Transaction(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, '/gateway/transact.dll',
                                 'application/x-www-form-urlencoded')
        self.login = login
        self.key = key
        self.delimiter = FIELD_DELIM
        self.amount = None
        self.payment = None
        self.customer = None
        self.is_test = False
        self.require_ccv = False
        self.require_avs = False
        self.duplicate_window = None

    def set_amount(self, amount):
        if not isinstance(amount, str):
            raise Exception('You must provide the amount as a string!')
        self.amount = amount

    def set_credit(self, card_num, card_exp, card_code=None):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception(
                'card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment = (TYPE_CREDIT, card_num, tuple(card_exp), card_code)

    def set_customer(self,
                     first_name,
                     last_name,
                     company=None,
                     address=None,
                     city=None,
                     state=None,
                     zip=None,
                     ip=None):
        self.customer = (first_name, last_name, company, address, city, state,
                         zip, ip)

    def set_transaction_id(self, id):
        self.trans_id = id

    def set_is_test(self, is_test=False):
        self.is_test = is_test

    def set_require_ccv(self, require_ccv=False):
        self.require_ccv = require_ccv

    def set_require_avs(self, require_avs=False):
        self.require_avs = require_avs

    def set_duplicate_window(self, duplicate_window=None):
        self.duplicate_window = duplicate_window

    def _toPost(self, requestType):
        post = {
            'x_login': self.login,
            'x_tran_key': self.key,
            'x_version': '3.1',
            'x_type': requestType,
            'x_recurring_billing': 'NO',
            'x_delim_data': 'TRUE',
            'x_delim_char': self.delimiter,
            'x_relay_response': 'FALSE',
        }
        if self.amount:
            post['x_amount'] = self.amount
        if self.payment:
            if self.payment[0] == TYPE_CREDIT:
                post['x_method'] = 'CC'
            type, card_num, exp_date, ccv = self.payment
            post.update({
                'x_card_num': card_num,
                'x_exp_date': '%s-%s' % exp_date
            })
            if self.require_ccv:
                if not ccv:
                    raise Exception(
                        'CCV required by options but not provided!')
                post['x_card_code'] = ccv
        if self.is_test:
            post['x_test_request'] = 'YES'
        if self.duplicate_window is not None:
            post['x_duplicate_window'] = str(self.duplicate_window)
        if requestType in ('CREDIT', 'PRIOR_AUTH_CAPTURE', 'VOID'):
            if not self.trans_id:
                raise Exception(
                    'You must provide a trans_id for %s transactions!' %
                    requestType)
            post['x_trans_id'] = self.trans_id
        if self.customer:
            (first_name, last_name, company, address, city, state, zip,
             ip) = self.customer
            post['x_first_name'] = first_name
            post['x_last_name'] = last_name
            if self.require_avs:
                if not (address and city and state and zip):
                    raise Exception(
                        'AVS required by options but no customer data provided!'
                    )
                if company:
                    post['x_company'] = company
                if address:
                    post['x_address'] = address
                if city:
                    post['x_city'] = city
                if state:
                    post['x_state'] = state
                if zip:
                    post['x_zip'] = zip
                if ip:
                    post['x_customer_ip'] = ip
        for name, value in post.items():
            post[name] = value.encode('utf-8')
        return urllib.urlencode(post)

    def _fromPost(self, data):
        return TransactionResult(data, self.delimiter)

    def authorize(self):
        data = self._toPost('AUTH_ONLY')
        response = self.conn.send(data)
        return self._fromPost(response)

    def capture(self):
        data = self._toPost('PRIOR_AUTH_CAPTURE')
        response = self.conn.send(data)
        return self._fromPost(response)

    def auth_capture(self):
        data = self._toPost('AUTH_CAPTURE')
        response = self.conn.send(data)
        return self._fromPost(response)

    def credit(self):
        pass

    def void(self):
        data = self._toPost('VOID')
        response = self.conn.send(data)
        return self._fromPost(response)
示例#8
0
class Transaction(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, '/gateway/transact.dll', 'application/x-www-form-urlencoded')
        self.login = login
        self.key = key
        self.delimiter = FIELD_DELIM
        self.amount = None
        self.payment = None
        self.customer = None
        self.is_test = False
        self.require_ccv = False
        self.require_avs = False
        self.duplicate_window = None

    def set_amount(self, amount):
        if not isinstance(amount, str):
            raise Exception('You must provide the amount as a string!')
        self.amount = amount

    def set_credit(self, card_num, card_exp, card_code=None):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception('card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment = (TYPE_CREDIT, card_num, tuple(card_exp), card_code)

    def set_customer(self, first_name, last_name, company=None, address=None, city=None, state=None, zip=None, ip=None):
        self.customer = (first_name, last_name, company, address, city, state, zip, ip)

    def set_transaction_id(self, id):
        self.trans_id = id

    def set_is_test(self, is_test=False):
        self.is_test = is_test

    def set_require_ccv(self, require_ccv=False):
        self.require_ccv = require_ccv

    def set_require_avs(self, require_avs=False):
        self.require_avs = require_avs

    def set_duplicate_window(self, duplicate_window=None):
        self.duplicate_window = duplicate_window

    def _toPost(self, requestType):
        post = {
            'x_login': self.login,
            'x_tran_key': self.key,
            'x_version': '3.1',
            'x_type': requestType,
            'x_recurring_billing': 'NO',
            'x_delim_data': 'TRUE',
            'x_delim_char': self.delimiter,
            'x_relay_response': 'FALSE',
        }
        if self.amount:
            post['x_amount'] = self.amount
        if self.payment:
            if self.payment[0] == TYPE_CREDIT:
                post['x_method'] = 'CC'
            type, card_num, exp_date, ccv = self.payment
            post.update(
                {
                    'x_card_num': card_num,
                    'x_exp_date': '%s-%s' % exp_date
                }
            )
            if self.require_ccv:
                if not ccv:
                    raise Exception('CCV required by options but not provided!')
                post['x_card_code'] = ccv
        if self.is_test:
            post['x_test_request'] = 'YES'
        if self.duplicate_window is not None:
            post['x_duplicate_window'] = str(self.duplicate_window)
        if requestType in ('CREDIT', 'PRIOR_AUTH_CAPTURE', 'VOID'):
            if not self.trans_id:
                raise Exception('You must provide a trans_id for %s transactions!' % requestType)
            post['x_trans_id'] = self.trans_id
        if self.customer:
            (first_name, last_name, company, address, city, state, zip, ip) = self.customer
            post['x_first_name'] = first_name
            post['x_last_name'] = last_name
            if self.require_avs:
                if not (address and city and state and zip):
                    raise Exception('AVS required by options but no customer data provided!')
                if company:
                    post['x_company'] = company
                if address:
                    post['x_address'] = address
                if city:
                    post['x_city'] = city
                if state:
                    post['x_state'] = state
                if zip:
                    post['x_zip'] = zip
                if ip:
                    post['x_customer_ip'] = ip
        for name, value in post.items():
            post[name] = value.encode('utf-8')
        return urllib.urlencode(post)

    def _fromPost(self, data):
        return TransactionResult(data, self.delimiter)

    def authorize(self):
        data = self._toPost('AUTH_ONLY')
        response = self.conn.send(data)
        return self._fromPost(response)

    def capture(self):
        data = self._toPost('PRIOR_AUTH_CAPTURE')
        response = self.conn.send(data)
        return self._fromPost(response)

    def auth_capture(self):
        data = self._toPost('AUTH_CAPTURE')
        response = self.conn.send(data)
        return self._fromPost(response)

    def credit(self):
        pass

    def void(self):
        data = self._toPost('VOID')
        response = self.conn.send(data)
        return self._fromPost(response)
示例#9
0
class Customer(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, PATH, 'text/xml')
        self.login = login
        self.key = key
        self.payment = []
        self.billto = []
        self.shipping = []
        self.amount = None
        self.customer_id = None
        self.request_id = None
        self.validation_mode = 'none'

    def set_amount(self, amount):
        self.amount = str(amount)

    def add_payment(self, card_num, card_exp, card_code=None):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception('card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment.append((TYPE_CREDIT, (card_num, tuple(card_exp), card_code)))

    def add_billto(self, first_name, last_name, company=None, address=None, city=None, state=None, zip=None, country=None):
        self.billto.append((first_name, last_name, company, address, city, state, zip, country))

    def add_shipping(self, first_name, last_name, company=None, address=None, city=None, state=None, zip=None, country=None):
        self.shipping.append((first_name, last_name, company, address, city, state, zip, country))

    def set_customer_id(self, customer_id):
        self.customer_id = customer_id

    def set_profile_id(self, profile_id):
        self.profile_id = profile_id

    def set_request_id(self, request_id):
        self.request_id = request_id

    def set_validation_mode(self, validation_mode):
        self.validation_mode = validation_mode

    def _toXml(self, requestType):
        rootElem = etree.Element(requestType, xmlns=ANET_XMLNS)
        authElem = etree.SubElement(rootElem, "merchantAuthentication")
        etree.SubElement(authElem, "name").text = self.login
        etree.SubElement(authElem, "transactionKey").text = self.key
        if self.reference_id:
            etree.SubElement(rootElem, 'refId').text = str(self.reference_id)
        if self.profile_id:
            etree.SubElement(rootElem, 'customerProfileId').text = str(self.profile_id)
        if requestType == 'createCustomerProfileRequest':
            profileElem = etree.SubElement(rootElem, 'profile')
            if self.customer_id:
                etree.SubElement(profileElem, 'merchantCustomerId').text = str(self.customer_id)
            profileElem = etree.SubElement(profileElem, 'paymentProfiles')
        else:
            profileElem = etree.SubElement(profileElem, 'paymentProfile')
        if self.payment or self.billto:
            if self.billto:
                for first_name, last_name, company, address, city, state, zip, country in self.billto:
                    billToElem = etree.SubElement(profileElem, 'billTo')
                    etree.SubElement(billToElem, 'firstName').text = first_name
                    etree.SubElement(billToElem, 'lastName').text = last_name
                    if company:
                        etree.SubElement(billToElem, 'company').text = company
                    if address:
                        etree.SubElement(billToElem, 'address').text = address
                    if city:
                        etree.SubElement(billToElem, 'city').text = city
                    if state:
                        etree.SubElement(billToElem, 'state').text = state
                    if zip:
                        etree.SubElement(billToElem, 'zip').text = zip
                    if country:
                        etree.SubElement(billToElem, 'country').text = country
            if self.payment:
                for type, cc_info in self.payment:
                    if type == TYPE_CREDIT:
                        (card_num, card_exp, card_code) = cc_info
                        credit = etree.SubElement(etree.SubElement(profileElem, 'payment'), 'creditCard')
                        etree.SubElement(credit, 'cardNumber').text = card_num
                        etree.SubElement(credit, 'expirationDate').text = '%s-%s' % card_exp
                        if card_code:
                            etree.SubElement(credit, 'cardCode').text = card_code
        if self.shipping:
            for first_name, last_name, company, address, city, state, zip, country in self.shipping:
                if requestType == 'createCustomerProfileRequest':
                    shippingElem = etree.SubElement(profileElem, 'shipToList')
                else:
                    shippingElem = etree.SubElement(rootElem, 'address')
                etree.SubElement(shippingElem, 'firstName').text = first_name
                etree.SubElement(shippingElem, 'lastName').text = last_name
                if company:
                    etree.SubElement(shippingElem, 'company').text = company
                if address:
                    etree.SubElement(shippingElem, 'address').text = address
                if city:
                    etree.SubElement(shippingElem, 'city').text = city
                if state:
                    etree.SubElement(shippingElem, 'state').text = state
                if zip:
                    etree.SubElement(shippingElem, 'zip').text = zip
                if country:
                    etree.SubElement(shippingElem, 'country').text = country
        etree.subElement(rootElem, 'validationMode').text = str(self.validation_mode)
        return etree.tostring(root, xml_declaration=True, encoding='utf-8')

    def _fromXml(self, response):
        #TODO: investigate why etree will not parse this document when this namespace definition is intact.
        # for now just remove it :-)
        response = response.replace(ANET_XMLNS, '')
        return CustomerResult(response)

    def create(self):
        xml = self._toXml('createCustomerProfileRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createPayment(self):
        xml = self._toXml('createCustomerPaymentProfileRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createShipping(self):
        xml = self._toXml('createCustomerShippingAddressRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createTransaction(self):
        xml = self._toXml('createCustomerProfileTransactionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)
示例#10
0
class Customer(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, PATH, 'text/xml')
        self.login = login
        self.key = key
        self.payment = []
        self.billto = []
        self.shipping = []
        self.amount = None
        self.customer_id = None
        self.request_id = None
        self.validation_mode = 'none'

    def set_amount(self, amount):
        self.amount = str(amount)

    def add_payment(self, card_num, card_exp, card_code=None):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception(
                'card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment.append(
            (TYPE_CREDIT, (card_num, tuple(card_exp), card_code)))

    def add_billto(self,
                   first_name,
                   last_name,
                   company=None,
                   address=None,
                   city=None,
                   state=None,
                   zip=None,
                   country=None):
        self.billto.append((first_name, last_name, company, address, city,
                            state, zip, country))

    def add_shipping(self,
                     first_name,
                     last_name,
                     company=None,
                     address=None,
                     city=None,
                     state=None,
                     zip=None,
                     country=None):
        self.shipping.append((first_name, last_name, company, address, city,
                              state, zip, country))

    def set_customer_id(self, customer_id):
        self.customer_id = customer_id

    def set_profile_id(self, profile_id):
        self.profile_id = profile_id

    def set_request_id(self, request_id):
        self.request_id = request_id

    def set_validation_mode(self, validation_mode):
        self.validation_mode = validation_mode

    def _toXml(self, requestType):
        rootElem = etree.Element(requestType, xmlns=ANET_XMLNS)
        authElem = etree.SubElement(rootElem, "merchantAuthentication")
        etree.SubElement(authElem, "name").text = self.login
        etree.SubElement(authElem, "transactionKey").text = self.key
        if self.reference_id:
            etree.SubElement(rootElem, 'refId').text = str(self.reference_id)
        if self.profile_id:
            etree.SubElement(rootElem,
                             'customerProfileId').text = str(self.profile_id)
        if requestType == 'createCustomerProfileRequest':
            profileElem = etree.SubElement(rootElem, 'profile')
            if self.customer_id:
                etree.SubElement(profileElem, 'merchantCustomerId').text = str(
                    self.customer_id)
            profileElem = etree.SubElement(profileElem, 'paymentProfiles')
        else:
            profileElem = etree.SubElement(profileElem, 'paymentProfile')
        if self.payment or self.billto:
            if self.billto:
                for first_name, last_name, company, address, city, state, zip, country in self.billto:
                    billToElem = etree.SubElement(profileElem, 'billTo')
                    etree.SubElement(billToElem, 'firstName').text = first_name
                    etree.SubElement(billToElem, 'lastName').text = last_name
                    if company:
                        etree.SubElement(billToElem, 'company').text = company
                    if address:
                        etree.SubElement(billToElem, 'address').text = address
                    if city:
                        etree.SubElement(billToElem, 'city').text = city
                    if state:
                        etree.SubElement(billToElem, 'state').text = state
                    if zip:
                        etree.SubElement(billToElem, 'zip').text = zip
                    if country:
                        etree.SubElement(billToElem, 'country').text = country
            if self.payment:
                for type, cc_info in self.payment:
                    if type == TYPE_CREDIT:
                        (card_num, card_exp, card_code) = cc_info
                        credit = etree.SubElement(
                            etree.SubElement(profileElem, 'payment'),
                            'creditCard')
                        etree.SubElement(credit, 'cardNumber').text = card_num
                        etree.SubElement(
                            credit, 'expirationDate').text = '%s-%s' % card_exp
                        if card_code:
                            etree.SubElement(credit,
                                             'cardCode').text = card_code
        if self.shipping:
            for first_name, last_name, company, address, city, state, zip, country in self.shipping:
                if requestType == 'createCustomerProfileRequest':
                    shippingElem = etree.SubElement(profileElem, 'shipToList')
                else:
                    shippingElem = etree.SubElement(rootElem, 'address')
                etree.SubElement(shippingElem, 'firstName').text = first_name
                etree.SubElement(shippingElem, 'lastName').text = last_name
                if company:
                    etree.SubElement(shippingElem, 'company').text = company
                if address:
                    etree.SubElement(shippingElem, 'address').text = address
                if city:
                    etree.SubElement(shippingElem, 'city').text = city
                if state:
                    etree.SubElement(shippingElem, 'state').text = state
                if zip:
                    etree.SubElement(shippingElem, 'zip').text = zip
                if country:
                    etree.SubElement(shippingElem, 'country').text = country
        etree.subElement(rootElem,
                         'validationMode').text = str(self.validation_mode)
        return etree.tostring(root, xml_declaration=True, encoding='utf-8')

    def _fromXml(self, response):
        #TODO: investigate why etree will not parse this document when this namespace definition is intact.
        # for now just remove it :-)
        response = response.replace(ANET_XMLNS, '')
        return CustomerResult(response)

    def create(self):
        xml = self._toXml('createCustomerProfileRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createPayment(self):
        xml = self._toXml('createCustomerPaymentProfileRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createShipping(self):
        xml = self._toXml('createCustomerShippingAddressRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def createTransaction(self):
        xml = self._toXml('createCustomerProfileTransactionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)
示例#11
0
class Recurring(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, PATH, 'text/xml')
        self.login = login
        self.key = key
        self.schedule = None
        self.amount = None
        self.trial = None
        self.payment = None
        self.customer = None
        self.subscription_id = None

    def set_schedule(self,
                     period=PERIOD_ONGOING,
                     start=None,
                     count=1,
                     unit=UNIT_MONTH):
        if start is None:
            start = datetime.datetime.now()
        self.schedule = (start, period, count, unit)

    def set_amount(self, amount):
        self.amount = str(amount)

    def set_trial(self, trialPeriod, trialAmount):
        self.trial = (trialPeriod, str(trialAmount))

    def set_credit(self, card_num, card_exp):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception(
                'card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment = (TYPE_CREDIT, (card_num, tuple(card_exp)))

    def set_customer(self,
                     first_name,
                     last_name,
                     company=None,
                     address=None,
                     city=None,
                     state=None,
                     zip=None,
                     country=None):
        self.customer = (first_name, last_name, company, address, city, state,
                         zip, country)

    def set_subscription_id(self, subscription_id):
        self.subscription_id = subscription_id

    def _toXml(self, requestType):
        root = etree.Element(requestType, xmlns=ANET_XMLNS)
        auth = etree.SubElement(root, "merchantAuthentication")
        etree.SubElement(auth, "name").text = self.login
        etree.SubElement(auth, "transactionKey").text = self.key
        if self.subscription_id:
            etree.SubElement(root,
                             'subscriptionId').text = str(self.subscription_id)
        if requestType != 'ARBCancelSubscriptionRequest':
            subscription = etree.SubElement(root, 'subscription')
            if self.schedule:
                (start, total, count, unit) = self.schedule
                schedule = etree.SubElement(subscription, 'paymentSchedule')
                interval = etree.SubElement(schedule, 'interval')
                etree.SubElement(interval, 'length').text = str(count)
                etree.SubElement(interval, 'unit').text = str(unit)
                etree.SubElement(schedule,
                                 'startDate').text = start.strftime('%Y-%m-%d')
                if self.trial:
                    total += self.trial[0]
                    etree.SubElement(schedule, 'trialOccurrences').text = str(
                        self.trial[0])
                etree.SubElement(schedule,
                                 'totalOccurrences').text = str(total)
            if self.amount:
                etree.SubElement(subscription,
                                 'amount').text = str(self.amount)
            if self.trial:
                etree.SubElement(subscription,
                                 'trialAmount').text = str(self.trial[1])
            if self.payment:
                type = self.payment[0]
                if type == TYPE_CREDIT:
                    (card_num, card_exp) = self.payment[1]
                    payment = etree.SubElement(subscription, 'payment')
                    credit = etree.SubElement(payment, 'creditCard')
                    etree.SubElement(credit, 'cardNumber').text = card_num
                    etree.SubElement(
                        credit, 'expirationDate').text = '%s-%s' % card_exp
            if self.customer:
                (first_name, last_name, company, address, city, state, zip,
                 country) = self.customer
                customer = etree.SubElement(subscription, 'billTo')
                etree.SubElement(customer, 'firstName').text = first_name
                etree.SubElement(customer, 'lastName').text = last_name
                if company:
                    etree.SubElement(customer, 'company').text = company
                if address:
                    etree.SubElement(customer, 'address').text = address
                if city:
                    etree.SubElement(customer, 'city').text = city
                if state:
                    etree.SubElement(customer, 'state').text = state
                if zip:
                    etree.SubElement(customer, 'zip').text = zip
                if country:
                    etree.SubElement(customer, 'country').text = country
        return etree.tostring(root, xml_declaration=True, encoding='utf-8')

    def _fromXml(self, response):
        #TODO: investigate why etree will not parse this document when this namespace definition is intact.
        # for now just remove it :-)
        response = response.replace(ANET_XMLNS, '')
        return RecurringResult(response)

    def create(self):
        xml = self._toXml('ARBCreateSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def update(self):
        xml = self._toXml('ARBUpdateSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def cancel(self):
        xml = self._toXml('ARBCancelSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)
示例#12
0
class Recurring(object):
    def __init__(self, host, login, key):
        self.conn = AuthorizeNet(host, PATH, 'text/xml')
        self.login = login
        self.key = key
        self.schedule = None
        self.amount = None
        self.trial = None
        self.payment = None
        self.customer = None
        self.subscription_id = None

    def set_schedule(self, period=PERIOD_ONGOING, start=None, count=1, unit=UNIT_MONTH):
        if start is None:
            start = datetime.datetime.now()
        self.schedule = (start, period, count, unit)

    def set_amount(self, amount):
        self.amount = str(amount)

    def set_trial(self, trialPeriod, trialAmount):
        self.trial = (trialPeriod, str(trialAmount))

    def set_credit(self, card_num, card_exp):
        if not isinstance(card_exp, (tuple, list)):
            raise Exception('card_exp must be a tuple or list!')
        if len(card_exp) != 2:
            raise Exception('card_exp must contain two items (year and month)!')
        if len(card_exp[0]) != 4:
            raise Exception('First item of card_exp must be year as YYYY!')
        if len(card_exp[1]) == 1:
            card_exp[1] = '0' + card_exp[1]
        elif len(card_exp[1]) > 2:
            raise Exception('Second item of card_exp must be month as MM!')
        self.payment = (TYPE_CREDIT, (card_num, tuple(card_exp)))

    def set_customer(self, first_name, last_name, company=None, address=None, city=None, state=None, zip=None, country=None):
        self.customer = (first_name, last_name, company, address, city, state, zip, country)

    def set_subscription_id(self, subscription_id):
        self.subscription_id = subscription_id

    def _toXml(self, requestType):
        root = etree.Element(requestType, xmlns=ANET_XMLNS)
        auth = etree.SubElement(root, "merchantAuthentication")
        etree.SubElement(auth, "name").text = self.login
        etree.SubElement(auth, "transactionKey").text = self.key
        if self.subscription_id:
            etree.SubElement(root, 'subscriptionId').text = str(self.subscription_id)
        if requestType != 'ARBCancelSubscriptionRequest':
            subscription = etree.SubElement(root, 'subscription')
            if self.schedule:
                (start, total, count, unit) = self.schedule
                schedule = etree.SubElement(subscription, 'paymentSchedule')
                interval = etree.SubElement(schedule, 'interval')
                etree.SubElement(interval, 'length').text = str(count)
                etree.SubElement(interval, 'unit').text = str(unit)
                etree.SubElement(schedule, 'startDate').text = start.strftime('%Y-%m-%d')
                if self.trial:
                    total += self.trial[0]
                    etree.SubElement(schedule, 'trialOccurrences').text = str(self.trial[0])
                etree.SubElement(schedule, 'totalOccurrences').text = str(total)
            if self.amount:
                etree.SubElement(subscription, 'amount').text = str(self.amount)
            if self.trial:
                etree.SubElement(subscription, 'trialAmount').text = str(self.trial[1])
            if self.payment:
                type = self.payment[0]
                if type == TYPE_CREDIT:
                    (card_num, card_exp) = self.payment[1]
                    payment = etree.SubElement(subscription, 'payment')
                    credit = etree.SubElement(payment, 'creditCard')
                    etree.SubElement(credit, 'cardNumber').text = card_num
                    etree.SubElement(credit, 'expirationDate').text = '%s-%s' % card_exp
            if self.customer:
                (first_name, last_name, company, address, city, state, zip, country) = self.customer
                customer = etree.SubElement(subscription, 'billTo')
                etree.SubElement(customer, 'firstName').text = first_name
                etree.SubElement(customer, 'lastName').text = last_name
                if company:
                    etree.SubElement(customer, 'company').text = company
                if address:
                    etree.SubElement(customer, 'address').text = address
                if city:
                    etree.SubElement(customer, 'city').text = city
                if state:
                    etree.SubElement(customer, 'state').text = state
                if zip:
                    etree.SubElement(customer, 'zip').text = zip
                if country:
                    etree.SubElement(customer, 'country').text = country
        return etree.tostring(root, xml_declaration=True, encoding='utf-8')

    def _fromXml(self, response):
        #TODO: investigate why etree will not parse this document when this namespace definition is intact.
        # for now just remove it :-)
        response = response.replace(ANET_XMLNS, '')
        return RecurringResult(response)

    def create(self):
        xml = self._toXml('ARBCreateSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def update(self):
        xml = self._toXml('ARBUpdateSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)

    def cancel(self):
        xml = self._toXml('ARBCancelSubscriptionRequest')
        response = self.conn.send(xml)
        return self._fromXml(response)