diff --git a/README.rst b/README.rst
index be69438..06c92f2 100644
--- a/README.rst
+++ b/README.rst
@@ -43,7 +43,7 @@ Here is a simple example of a basic credit card transaction.
Documentation
-------------
-Please visit the `Github Page`_ page for full documentation.
+Please visit the `Github Page`_ for full documentation.
.. _Github Page: http://vcatalano.github.io/py-authorize/index.html
diff --git a/authorize/__init__.py b/authorize/__init__.py
index fd3c489..525e3c4 100644
--- a/authorize/__init__.py
+++ b/authorize/__init__.py
@@ -1,3 +1,5 @@
+import xml.etree.ElementTree as E
+
from authorize.configuration import Configuration
from authorize.address import Address
from authorize.bank_account import BankAccount
@@ -11,3 +13,13 @@
from authorize.exceptions import AuthorizeInvalidError
from authorize.recurring import Recurring
from authorize.transaction import Transaction
+
+
+# Monkeypatch the ElementTree module so that we can use CDATA element types
+E._original_serialize_xml = E._serialize_xml
+def _serialize_xml(write, elem, *args):
+ if elem.tag == '![CDATA[':
+ write('' % elem.text)
+ return
+ return E._original_serialize_xml(write, elem, *args)
+E._serialize_xml = E._serialize['xml'] = _serialize_xml
\ No newline at end of file
diff --git a/authorize/apis/transaction_api.py b/authorize/apis/transaction_api.py
index 9d66a48..b577adb 100644
--- a/authorize/apis/transaction_api.py
+++ b/authorize/apis/transaction_api.py
@@ -1,5 +1,10 @@
import xml.etree.cElementTree as E
+try:
+ import urllib.parse as urllib
+except:
+ import urllib
+
from authorize.apis.base_api import BaseAPI
from authorize.schemas import AIMTransactionSchema
from authorize.schemas import CIMTransactionSchema
@@ -88,6 +93,13 @@ def _cim_base_request(self, xact_type, xact={}):
if 'recurring' in xact:
E.SubElement(xact_type, 'recurringBilling').text = str(xact['recurring']).lower()
+ if 'extra_options' in xact:
+ extra_options = {}
+ if 'customer_ip' in xact['extra_options']:
+ extra_options['x_customer_ip'] = xact['extra_options']['customer_ip']
+ options = E.SubElement(request, 'extraOptions')
+ E.SubElement(options, '![CDATA[').text = urllib.urlencode(extra_options)
+
return request
def _aim_base_request(self, xact_type, xact={}):
@@ -131,6 +143,10 @@ def _aim_base_request(self, xact_type, xact={}):
if 'shipping' in xact:
xact_elem.append(create_address('shipTo', xact['shipping']))
+ if 'extra_options' in xact:
+ if 'customer_ip' in xact['extra_options']:
+ E.SubElement(xact_elem, 'customerIP').text = xact['extra_options']['customer_ip']
+
return request
def _settle_request(self, transaction_id):
diff --git a/authorize/schemas.py b/authorize/schemas.py
index 41e2393..faa8c76 100644
--- a/authorize/schemas.py
+++ b/authorize/schemas.py
@@ -163,9 +163,6 @@ class CustomerSchema(AddressSchema):
customer_id = colander.SchemaNode(colander.String(),
validator=colander.Length(max=20),
missing=colander.drop)
- # customer_ip = colander.SchemaNode(colander.String(),
- # validator=colander.Length(max=20),
- # missing=colander.drop)
class CreateCustomerSchema(CustomerBaseSchema, CustomerTypeSchema):
@@ -228,6 +225,12 @@ class OrderSchema(colander.MappingSchema):
missing=colander.drop)
+class ExtraOptions(colander.MappingSchema):
+ customer_ip = colander.SchemaNode(colander.String(),
+ validator=colander.Length(max=39),
+ missing=colander.drop)
+
+
class TransactionBaseSchema(colander.MappingSchema):
line_items = LineItemsSchema(validator=colander.Length(max=30),
missing=colander.drop)
@@ -262,6 +265,7 @@ class CIMTransactionSchema(CIMBaseSchema, TransactionBaseSchema):
validator=colander.Regex(
r'^[0-9]{3,4}$', 'The card code is invalid'),
missing=colander.drop)
+ extra_options = ExtraOptions(missing=colander.drop)
class AIMTransactionSchema(TransactionBaseSchema):
diff --git a/authorize/xml_data.py b/authorize/xml_data.py
index 696d930..0957943 100644
--- a/authorize/xml_data.py
+++ b/authorize/xml_data.py
@@ -128,4 +128,4 @@ def prettify(elem):
"""Return a pretty-printed XML string for the Element."""
rough_string = E.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
- return reparsed.toprettyxml(indent=" ").strip()
+ return reparsed.toprettyxml(indent=' ').strip()
diff --git a/docs/transaction.rst b/docs/transaction.rst
index cf31e5f..55830b4 100644
--- a/docs/transaction.rst
+++ b/docs/transaction.rst
@@ -114,7 +114,11 @@ Full Example
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
+ 'recurring': True,
})
result.transaction_response.trans_id
@@ -228,7 +232,11 @@ Full Transactions with Bank Accounts
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
+ 'recurring': True,
})
result.transaction_response.trans_id
@@ -309,7 +317,11 @@ Full Transactions Example with CIM Data
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
- 'tax_exempt': False,
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
+ 'tax_exempt': False,,
+ 'recurring': True,
})
result.transaction_response.trans_id
diff --git a/tests/test_live_transaction.py b/tests/test_live_transaction.py
index 02dfef8..aedde45 100644
--- a/tests/test_live_transaction.py
+++ b/tests/test_live_transaction.py
@@ -81,6 +81,9 @@
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
'recurring': True,
}
@@ -135,6 +138,9 @@
'name': 'The amount for duty',
'description': 'I can''t believe you would pay for duty',
},
+ 'extra_options': {
+ 'customer_ip': 'fe80::f4b6:2a88:70fa:f09f',
+ },
'tax_exempt': False,
'recurring': True,
'card_code': '443',
@@ -214,6 +220,9 @@
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
'recurring': True,
}
diff --git a/tests/test_transaction_api.py b/tests/test_transaction_api.py
index befd2e8..43aeef4 100644
--- a/tests/test_transaction_api.py
+++ b/tests/test_transaction_api.py
@@ -56,6 +56,9 @@
'name': 'The amount for duty',
'description': 'I can''t believe you would pay for duty',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
'recurring': True,
'card_code': '443',
@@ -135,6 +138,9 @@
'name': 'UPS 2-Day Shipping',
'description': 'Handle with care',
},
+ 'extra_options': {
+ 'customer_ip': '100.0.0.1',
+ },
'tax_exempt': False,
'recurring': True,
}
@@ -206,6 +212,8 @@
true
+
+
'''
@@ -299,6 +307,7 @@
520-123-4567
520-456-7890
+ 100.0.0.1
'''