#! /usr/bin/env python from AuthorizeNetCodes import Login, Password, TransKey, GatewayURL, DefaultFieldSep, FieldEncapsulationChar, TestMode from pprint import pprint import pycurl,string,csv,sys import cStringIO # can use StringIO if the faster C version isn't available on your platform __title__="PyCC" __version__="0.1" __author__="Carl Paetzel" __license__="BSD-style" # (useful modifications are requested) __website__="http://pycc.sf.net/" __doc__=""" This is a basic authorize.net API In order to use this, you have to have a valid login and transaction key from authorize.net USAGE: see end of file (or run this script) You should create a file called AuthorizeNetCodes.py in the same directory containing the following: # Configuration file for AuthorizeNet.py Login="megacorp" # authorize.net login Password="" # authorize.net password (not needed and not recommended -- use transaction key instead) TransKey="basjdbkjash218789213" # secret transaction key as set in merchant interface GatewayURL='https://secure.authorize.net/gateway/transact.dll' # gateway to POST the transaction to TestMode='TRUE' # TRUE or FALSE """ TRUE=1 FALSE=0 class AuthNet: def __init__(self): " this shows all the data fields that might be useful " self.data={ 'test_request':TestMode, 'delim_data': 'TRUE', 'delim_char': ',', 'encap_char': '"', # 'relay_response': 'FALSE', # a value of FALSE is required for AIM # important fields 'version': '3.1', # version 3.1 = credit card verification number can be included 'login': Login, 'tran_key': TransKey, 'password': Password, 'amount': '', # include tax 'card_num': '', # for testing 'exp_date': '', # for testing 'type': 'AUTH_CAPTURE', # AUTH_CAPTURE, etc 'method': 'CC', # CC or ECHECK 'card_code': '', # card verification code from front or back of card (3 or 4 digits) 'recurring_billing': '', # [YES,NO] indicates whther this is a recurring billing. does this have anything to do with ARB? 'auth_code': '', # authorization code for a previous transaction from another gateway # REQUIRED BY WELLS FARGO SECURE SOURCE 'first_name': '', 'last_name': '', 'company': '', 'address': '', 'city': '', 'state': '', 'zip': '', 'country': '', 'phone': '', 'fax': '', 'email': '', 'customer_ip': '', 'customer_organization_type': '', # [I]ndividual or [B]usiness # # Everything below is optional unless using echeck (see echeck section) # # Useful to do reporting within Authorize.net's tools: 'cust_id': '', 'email_customer': '', # should confirmation email be sent to customer [TRUE|FALSE] or follow value in merchant interface 'merchant_email': '', # additional email addresses to send merchant's copy of customer confirmation email to (on top of ones listed in merchant interface) 'invoice_num': '', 'description': '', # SELDOM-USED FIELDS 'trans_id': '', # id of a previous transaction from this gateway (for example, refund) 'authentication_indicator': '', # ECI for VISA or UCAF for MC. Only used for VISA with Wells Fargo SS 'cardholder_authentication_value': '', # Valid CAVV, AVV, or UCAF. Only used for VISA with WF # Physical shipment (fulfillment) only: 'ship_to_first_name': '', 'ship_to_last_name': '', 'ship_to_company': '', 'ship_to_address': '', 'ship_to_city': '', 'ship_to_state': '', 'ship_to_zip': '', 'ship_to_country': '', # Level 2 Data 'po_duty': '', 'tax': '', 'tax_exempt': '', 'freight': '', 'duty': '', # E-Check fields 'bank_name': '', # Name of bank at which account is maintained 'bank_aba_code': '', # ABA routing number 'bank_acct_num': '', # Bank Account Number 'bank_acct_type': '', # Type of Account ? Checking, Business Checking or Savings 'bank_acct_name': '', # Name under which the account is maintained at the bank 'type': '', # Type of transaction (AUTH_CAPTURE, CREDIT) 'echeck_type': '', # Type of eCheck.Net transaction (CCD, PPD, TEL, WEB) 'customer_tax_id': '', # 9 digits, SSN or TIN. Either DL or this is needed for echeck 'drivers_license_num': '', # 50 digits } self.rawoutput='' # initialize the rawoutput variable or append_to_buf can't work def execute(self): " execute a transaction and set self.response with response from authorize.net " post_string='&'.join(map("x_%s=%r".__mod__,self.data.iteritems())) # print post_string # sys.exit(0) post_string=post_string.replace(" ","+") post_string=post_string.replace('"','') # double quotes break the csv output and aren't needed anyway c=pycurl.Curl() c.setopt(c.URL, GatewayURL) c.setopt(c.POST, TRUE) c.setopt(c.SSL_VERIFYPEER, TRUE) # c.setopt(c.RETURNTRANSFER, TRUE) c.setopt(c.POSTFIELDS, post_string) c.setopt(c.WRITEFUNCTION, self.append_to_buf) c.perform() c.close() results=self.rawoutput.replace("\\'","'") # First, create the StringIO object, then the csv reader object # using the StringIO object. sf = cStringIO.StringIO() csvReader = csv.reader(sf) # Now, write a CSV string out to the StringIO object. sf.write(results) # We have to seek the StringIO pseudo-file back to its start. sf.seek(0,0) # Now read in the same data via the csv reader object. self.response = csvReader.next() self.status=self.response[0] self.error=self.response[3] self.approvalcode=self.response[4] def dump_response_code_fields(self): "important note: authorize.net starts their counting of these fields from one, but we start our counting from 0!" print "important note: authorize.net starts their counting of these fields from one, but we start our counting from 0!" for i in range(len(self.response)): if i<7 or i>36: print str(i)+": "+str(self.response[i]) def append_to_buf(self,buf): " helper function for the setopt function " self.rawoutput=self.rawoutput+buf def testAuthNet(): " how you might use this class " # (all transactions will be approved in test mode) authnet=AuthNet() authnet.data.update( { # some sample data: 'amount': '.19', # include tax 'card_num': '4007000000027', # a real fake credit card (passes checksum tests) for testing 'exp_date': '0307', # for testing 'type': 'AUTH_CAPTURE', # AUTH_CAPTURE, etc 'method': 'CC', # CC or ECHECK 'card_code': '', # card verification code from front or back of card (3 or 4 digits) # REQUIRED BY WELLS FARGO SECURE SOURCE (and good idea anyway for fraud checks) 'first_name': 'John', 'last_name': 'Doe', 'company': 'MegaWidgets Corp', 'address': "1133 Westchester's Avenue, Suite 333", # single quote and comma test 'city': '"Almost" White Plains', # double quote test -- (they get stripped) 'state': 'NY', 'zip': '10604', 'country': 'USA', 'phone': '888-839-9289', 'fax': '866-722-9226', 'email': 'notanymore@MegaWidgetsCorp.com', 'customer_ip': '10.1.0.1', 'customer_organization_type': 'B', # [I]ndividual or [B]usiness }) authnet.execute() return authnet # if executed from command line, test a sample transaction authnet=testAuthNet() # authnet.dump_response_code_fields() print authnet.data['first_name']+' '+authnet.data['last_name']+', your transaction ', if authnet.status == '1': print 'was approved. Your approval code is '+authnet.approvalcode if authnet.status == '2': print 'was declined.' if authnet.status == '3': print 'has an error: ' + authnet.error if authnet.status == '4': print 'was held for manual review.'