forked from vcatalano/py-authorize
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
60 changed files
with
5,891 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,10 @@ | ||
*.py[cod] | ||
|
||
# C extensions | ||
*.so | ||
*.py[co] | ||
.DS_Store | ||
docs/_build/ | ||
build/ | ||
dist/ | ||
Authorize.egg-info/ | ||
PyAuthorize.egg-info/ | ||
|
||
# Packages | ||
*.egg | ||
*.egg-info | ||
dist | ||
build | ||
eggs | ||
parts | ||
bin | ||
var | ||
sdist | ||
develop-eggs | ||
.installed.cfg | ||
lib | ||
lib64 | ||
|
||
# Installer logs | ||
pip-log.txt | ||
|
||
# Unit test / coverage reports | ||
.coverage | ||
.tox | ||
nosetests.xml | ||
|
||
# Translations | ||
*.mo | ||
|
||
# Mr Developer | ||
.mr.developer.cfg | ||
.project | ||
.pydevproject |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from authorize.configuration import Configuration | ||
from authorize.address import Address | ||
from authorize.bank_account import BankAccount | ||
from authorize.batch import Batch | ||
from authorize.credit_card import CreditCard | ||
from authorize.customer import Customer | ||
from authorize.environment import Environment | ||
from authorize.exceptions import AuthorizeError | ||
from authorize.exceptions import AuthorizeConnectionError | ||
from authorize.exceptions import AuthorizeResponseError | ||
from authorize.exceptions import AuthorizeInvalidError | ||
from authorize.recurring import Recurring | ||
from authorize.transaction import Transaction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from authorize import Configuration | ||
|
||
|
||
class Address(object): | ||
|
||
@staticmethod | ||
def create(customer_id, params={}): | ||
return Configuration.api.address.create(customer_id, params) | ||
|
||
@staticmethod | ||
def details(customer_id, address_id): | ||
return Configuration.api.address.details(customer_id, address_id) | ||
|
||
@staticmethod | ||
def update(customer_id, address_id, params={}): | ||
return Configuration.api.address.update(customer_id, address_id, params) | ||
|
||
@staticmethod | ||
def delete(customer_id, address_id): | ||
return Configuration.api.address.delete(customer_id, address_id) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import xml.etree.cElementTree as E | ||
|
||
from authorize.apis.base_api import BaseAPI | ||
from authorize.schemas import AddressSchema | ||
from authorize.xml_data import * | ||
|
||
|
||
class AddressAPI(BaseAPI): | ||
|
||
def create(self, customer_id, params={}): | ||
address = self._deserialize(AddressSchema(), params) | ||
return self.api._make_call(self._create_request(customer_id, address)) | ||
|
||
def details(self, customer_id, address_id): | ||
return self.api._make_call(self._details_request(customer_id, address_id)) | ||
|
||
def update(self, customer_id, address_id, params={}): | ||
address = self._deserialize(AddressSchema(), params) | ||
return self.api._make_call(self._update_request(customer_id, address_id, address)) | ||
|
||
def delete(self, customer_id, address_id): | ||
self.api._make_call(self._delete_request(customer_id, address_id)) | ||
|
||
# The following methods generate the XML for the corresponding API calls. | ||
# This makes unit testing each of the calls easier. | ||
def _create_request(self, customer_id, address={}): | ||
return self._make_xml('createCustomerShippingAddressRequest', customer_id, None, params=address) | ||
|
||
def _details_request(self, customer_id, address_id): | ||
request = self.api._base_request('getCustomerShippingAddressRequest') | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
E.SubElement(request, 'customerAddressId').text = address_id | ||
return request | ||
|
||
def _update_request(self, customer_id, address_id, address={}): | ||
return self._make_xml('updateCustomerShippingAddressRequest', customer_id, address_id, params=address) | ||
|
||
def _delete_request(self, customer_id, address_id): | ||
request = self.api._base_request('deleteCustomerShippingAddressRequest') | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
E.SubElement(request, 'customerAddressId').text = address_id | ||
return request | ||
|
||
def _make_xml(self, method, customer_id=None, address_id=None, params={}): | ||
request = self.api._base_request(method) | ||
|
||
if customer_id: | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
|
||
address_data = create_address('address', params) | ||
|
||
if address_id: | ||
E.SubElement(address_data, 'customerAddressId').text = address_id | ||
|
||
request.append(address_data) | ||
|
||
return request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import urllib2 | ||
import xml.etree.cElementTree as E | ||
|
||
from urllib2 import HTTPError | ||
|
||
from authorize.apis.address_api import AddressAPI | ||
from authorize.apis.credit_card_api import CreditCardAPI | ||
from authorize.apis.customer_api import CustomerAPI | ||
from authorize.apis.bank_account_api import BankAccountAPI | ||
from authorize.apis.batch_api import BatchAPI | ||
from authorize.apis.recurring_api import RecurringAPI | ||
from authorize.apis.transaction_api import TransactionAPI | ||
from authorize.exceptions import AuthorizeConnectionError | ||
from authorize.exceptions import AuthorizeResponseError | ||
from authorize.response_parser import parse_response | ||
from authorize.xml_data import * | ||
|
||
E.register_namespace('', 'AnetApi/xml/v1/schema/AnetApiSchema.xsd') | ||
|
||
|
||
class AuthorizeAPI(object): | ||
|
||
def __init__(self, config): | ||
"""Allow for multiple instances of the Authorize API.""" | ||
self.config = config | ||
self.customer = CustomerAPI(self) | ||
self.credit_card = CreditCardAPI(self) | ||
self.bank_account = BankAccountAPI(self) | ||
self.address = AddressAPI(self) | ||
self.recurring = RecurringAPI(self) | ||
self.batch = BatchAPI(self) | ||
self.transaction = TransactionAPI(self) | ||
|
||
@property | ||
def client_auth(self): | ||
"""Generate an XML element with client auth data populated.""" | ||
if not hasattr(self, '_client_auth'): | ||
self._client_auth = E.Element('merchantAuthentication') | ||
E.SubElement(self._client_auth, 'name').text = self.config.login_id | ||
E.SubElement(self._client_auth, 'transactionKey').text = self.config.transaction_key | ||
return self._client_auth | ||
|
||
def _base_request(self, method): | ||
"""Factory method for generating the base XML requests.""" | ||
request = E.Element(method) | ||
request.set('xmlns', 'AnetApi/xml/v1/schema/AnetApiSchema.xsd') | ||
request.append(self.client_auth) | ||
return request | ||
|
||
def _make_call(self, call): | ||
"""Make a call to the Authorize.net server with the XML.""" | ||
try: | ||
request = urllib2.Request(self.config.environment, E.tostring(call)) | ||
request.add_header('Content-Type', 'text/xml') | ||
response = urllib2.urlopen(request).read() | ||
response = E.fromstring(response) | ||
result = parse_response(response) | ||
except HTTPError, e: | ||
return AuthorizeConnectionError('Error processing XML request.') | ||
|
||
# Throw an exception for invalid calls. This makes error handling | ||
# easier. | ||
if result.messages.result_code != 'Ok': | ||
error = result.messages.message | ||
e = AuthorizeResponseError('%s: %s' % (error.code, error.text)) | ||
e.full_response = result | ||
raise e | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from authorize.apis.payment_profile_api import PaymentProfileAPI | ||
from authorize.schemas import CreateBankAccountSchema | ||
from authorize.xml_data import * | ||
|
||
|
||
class BankAccountAPI(PaymentProfileAPI): | ||
|
||
def create(self, customer_id, params={}): | ||
card = self._deserialize(CreateBankAccountSchema(), params) | ||
return self.api._make_call(self._create_request(customer_id, card)) | ||
|
||
def update(self, customer_id, payment_id, params={}): | ||
card = self._deserialize(CreateBankAccountSchema(), params) | ||
return self.api._make_call(self._update_request(customer_id, payment_id, card)) | ||
|
||
# The following methods generate the XML for the corresponding API calls. | ||
# This makes unit testing each of the calls easier. | ||
def _create_request(self, customer_id, card={}): | ||
return self._make_xml('createCustomerPaymentProfileRequest', customer_id, None, params=card) | ||
|
||
def _update_request(self, customer_id, payment_id, card={}): | ||
return self._make_xml('updateCustomerPaymentProfileRequest', customer_id, payment_id, params=card) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import colander | ||
|
||
from authorize.exceptions import AuthorizeInvalidError | ||
|
||
|
||
class BaseAPI(object): | ||
|
||
def __init__(self, api): | ||
self.api = api | ||
self.config = api.config | ||
|
||
def _deserialize(self, schema, params={}): | ||
try: | ||
deserialized = schema.deserialize(params) | ||
except colander.Invalid as e: | ||
raise AuthorizeInvalidError(e) | ||
return deserialized |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import xml.etree.cElementTree as E | ||
|
||
from authorize.apis.base_api import BaseAPI | ||
from authorize.schemas import ListBatchSchema | ||
from authorize.xml_data import * | ||
|
||
|
||
class BatchAPI(BaseAPI): | ||
|
||
def details(self, batch_id): | ||
return self.api._make_call(self._details_request(batch_id)) | ||
|
||
def list(self, params={}): | ||
batch = self._deserialize(ListBatchSchema(), params) | ||
return self.api._make_call(self._list_request(batch)) | ||
|
||
# The following methods generate the XML for the corresponding API calls. | ||
# This makes unit testing each of the calls easier. | ||
def _details_request(self, batch_id): | ||
request = self.api._base_request('getBatchStatisticsRequest') | ||
E.SubElement(request, 'batchId').text = batch_id | ||
return request | ||
|
||
def _list_request(self, params={}): | ||
request = self.api._base_request('getSettledBatchListRequest') | ||
E.SubElement(request, 'includeStatistics').text = 'true' | ||
if 'start' in params: | ||
E.SubElement(request, 'firstSettlementDate').text = params['start'] | ||
if 'end' in params: | ||
E.SubElement(request, 'lastSettlementDate').text = params['end'] | ||
return request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from authorize.apis.payment_profile_api import PaymentProfileAPI | ||
from authorize.schemas import CreateCreditCardSchema | ||
from authorize.schemas import ValidateCreditCardSchema | ||
from authorize.xml_data import * | ||
|
||
|
||
class CreditCardAPI(PaymentProfileAPI): | ||
|
||
def create(self, customer_id, params={}): | ||
card = self._deserialize(CreateCreditCardSchema(), params) | ||
return self.api._make_call(self._create_request(customer_id, card)) | ||
|
||
def update(self, customer_id, payment_id, params={}): | ||
card = self._deserialize(CreateCreditCardSchema(), params) | ||
return self.api._make_call(self._update_request(customer_id, payment_id, card)) | ||
|
||
def validate(self, customer_id, payment_id, params={}): | ||
card = self._deserialize(ValidateCreditCardSchema(), params) | ||
return self.api._make_call(self._validate_request(customer_id, payment_id, card)) | ||
|
||
# The following methods generate the XML for the corresponding API calls. | ||
# This makes unit testing each of the calls easier. | ||
def _create_request(self, customer_id, card={}): | ||
return self._make_xml('createCustomerPaymentProfileRequest', customer_id, None, params=card) | ||
|
||
def _update_request(self, customer_id, payment_id, card={}): | ||
return self._make_xml('updateCustomerPaymentProfileRequest', customer_id, payment_id, params=card) | ||
|
||
def _validate_request(self, customer_id, payment_id, card={}): | ||
request = self.api._base_request('validateCustomerPaymentProfileRequest') | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
E.SubElement(request, 'customerPaymentProfileId').text = payment_id | ||
|
||
if 'address_id' in card: | ||
E.SubElement(request, 'customerShippingAddressId').text = card['address_id'] | ||
|
||
if 'card_code' in card: | ||
E.SubElement(request, 'cardCode').text = str(card['card_code']) | ||
|
||
E.SubElement(request, 'validationMode').text = card['validation_mode'] | ||
|
||
return request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import xml.etree.cElementTree as E | ||
|
||
from authorize.apis.base_api import BaseAPI | ||
from authorize.schemas import CustomerBaseSchema | ||
from authorize.schemas import CreateCustomerSchema | ||
from authorize.xml_data import * | ||
|
||
|
||
class CustomerAPI(BaseAPI): | ||
|
||
def create(self, params={}): | ||
customer = self._deserialize(CreateCustomerSchema().bind(), params) | ||
return self.api._make_call(self._create_request(customer)) | ||
|
||
def details(self, customer_id): | ||
return self.api._make_call(self._details_request(customer_id)) | ||
|
||
def update(self, customer_id, params={}): | ||
customer = self._deserialize(CustomerBaseSchema().bind(), params) | ||
return self.api._make_call(self._update_request(customer_id, customer)) | ||
|
||
def delete(self, customer_id): | ||
return self.api._make_call(self._delete_request(customer_id)) | ||
|
||
def list(self): | ||
return self.api._make_call(self.api._base_request('getCustomerProfileIdsRequest')) | ||
|
||
# The following methods generate the XML for the corresponding API calls. | ||
# This makes unit testing each of the calls easier. | ||
def _create_request(self, customer={}): | ||
request = self.api._base_request('createCustomerProfileRequest') | ||
profile = create_profile(customer) | ||
|
||
payment_profiles = E.Element('paymentProfiles') | ||
|
||
# We are only concerned about payment profile information if a | ||
# payment method is included | ||
if 'credit_card' in customer or 'bank_account' in customer: | ||
# Customer type | ||
if 'customer_type' in customer: | ||
E.SubElement(payment_profiles, 'customerType').text = customer['customer_type'] | ||
|
||
# Customer billing information | ||
if 'billing' in customer: | ||
payment_profiles.append(create_address('billTo', customer['billing'])) | ||
|
||
# Payment method | ||
payment = E.SubElement(payment_profiles, 'payment') | ||
if 'credit_card' in customer: | ||
payment.append(create_card(customer['credit_card'])) | ||
else: | ||
payment.append(create_account(customer['bank_account'])) | ||
profile.append(payment_profiles) | ||
|
||
# Customer shipping information | ||
if 'shipping' in customer: | ||
profile.append(create_address('shipToList', customer['shipping'])) | ||
|
||
request.append(profile) | ||
|
||
return request | ||
|
||
def _details_request(self, customer_id): | ||
request = self.api._base_request('getCustomerProfileRequest') | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
return request | ||
|
||
def _update_request(self, customer_id, customer): | ||
request = self.api._base_request('updateCustomerProfileRequest') | ||
profile = create_profile(customer) | ||
E.SubElement(profile, 'customerProfileId').text = customer_id | ||
request.append(profile) | ||
return request | ||
|
||
def _delete_request(self, customer_id): | ||
request = self.api._base_request('deleteCustomerProfileRequest') | ||
E.SubElement(request, 'customerProfileId').text = customer_id | ||
return request |
Oops, something went wrong.