Skip to content

Instantly share code, notes, and snippets.

@neilbradley
Created October 11, 2017 14:25
Show Gist options
  • Save neilbradley/b5b7d0621065f08a2abf7703bced9ee0 to your computer and use it in GitHub Desktop.
Save neilbradley/b5b7d0621065f08a2abf7703bced9ee0 to your computer and use it in GitHub Desktop.
sharedapps/eway/payment.py
import os, logging
import requests
import json
from django.conf import settings
RESPONSE_CODES = {
'F7000': "Undefined Fraud",
'V5000': "Undefined System",
'A0000': "Undefined Approved",
'A2000': "Transaction Approved",
'A2008': "Honour With Identification",
'A2010': "Approved For Partial Amount",
'A2011': "Approved VIP",
'A2016': "Approved Update Track 3",
'V6000': "Undefined Validation",
'V6001': "Invalid Request CustomerIP",
'V6002': "Invalid Request DeviceID",
'V6011': "Invalid Payment Amount",
'V6012': "Invalid Payment InvoiceDescription",
'V6013': "Invalid Payment InvoiceNumber",
'V6014': "Invalid Payment InvoiceReference",
'V6015': "Invalid Payment CurrencyCode",
'V6016': "Payment Required",
'V6017': "Payment CurrencyCode Required",
'V6018': "Unknown Payment CurrencyCode",
'V6021': "Cardholder Name Required",
'V6022': "Card Number Required",
'V6023': "CVN Required",
'V6031': "Invalid Card Number",
'V6032': "Invalid CVN",
'V6033': "Invalid Expiry Date",
'V6034': "Invalid Issue Number",
'V6035': "Invalid Start Date",
'V6036': "Invalid Month",
'V6037': "Invalid Year",
'V6040': "Invalid Token Customer Id",
'V6041': "Customer Required",
'V6042': "Customer First Name Required",
'V6043': "Customer Last Name Required",
'V6044': "Customer Country Code Required",
'V6045': "Customer Title Required",
'V6046': "Token Customer ID Required",
'V6047': "RedirectURL Required",
'V6051': "Invalid Customer First Name",
'V6052': "Invalid Customer Last Name",
'V6053': "Invalid Customer Country Code",
'V6054': "Invalid Customer Email",
'V6055': "Invalid Customer Phone",
'V6056': "Invalid Customer Mobile",
'V6057': "Invalid Customer Fax",
'V6058': "Invalid Customer Title",
'V6059': "Redirect URL Invalid",
'V6060': "Redirect URL Invalid",
'V6061': "Invalid Customer Reference",
'V6062': "Invalid Customer CompanyName",
'V6063': "Invalid Customer JobDescription",
'V6064': "Invalid Customer Street1",
'V6065': "Invalid Customer Street2",
'V6066': "Invalid Customer City",
'V6067': "Invalid Customer State",
'V6068': "Invalid Customer Postalcode",
'V6069': "Invalid Customer Email",
'V6070': "Invalid Customer Phone",
'V6071': "Invalid Customer Mobile",
'V6072': "Invalid Customer Comments",
'V6073': "Invalid Customer Fax",
'V6074': "Invalid Customer Url",
'V6075': "Invalid ShippingAddress FirstName",
'V6076': "Invalid ShippingAddress LastName",
'V6077': "Invalid ShippingAddress Street1",
'V6078': "Invalid ShippingAddress Street2",
'V6079': "Invalid ShippingAddress City",
'V6080': "Invalid ShippingAddress State",
'V6081': "Invalid ShippingAddress PostalCode",
'V6082': "Invalid ShippingAddress Email",
'V6083': "Invalid ShippingAddress Phone",
'V6084': "Invalid ShippingAddress Country",
'V6091': "Unknown Country Code",
'V6092': "Undefined Error - clarify meaning of this error",
'V6100': "Invalid ProcessRequest name",
'V6101': "Invalid ProcessRequest ExpiryMonth",
'V6102': "Invalid ProcessRequest ExpiryYear",
'V6103': "Invalid ProcessRequest StartMonth",
'V6104': "Invalid ProcessRequest StartYear",
'V6105': "Invalid ProcessRequest IssueNumber",
'V6106': "Invalid ProcessRequest CVN",
'V6107': "Invalid ProcessRequest AccessCode",
'V6108': "Invalid ProcessRequest CustomerHostAddress",
'V6109': "Invalid ProcessRequest UserAgent",
'V6110': "Invalid ProcessRequest Number",
'D4401': "Refer to Issuer",
'D4402': "Refer to Issuer, special",
'D4403': "No Merchant",
'D4404': "Pick Up Card",
'D4405': "Do Not Honour",
'D4406': "Error",
'D4407': "Pick Up Card, Special",
'D4409': "Request In Progress",
'D4412': "Invalid Transaction",
'D4413': "Invalid Amount",
'D4414': "Invalid Card Number",
'D4415': "No Issuer",
'D4419': "Re-enter Last Transaction",
'D4421': "No Method Taken",
'D4422': "Suspected Malfunction",
'D4423': "Unacceptable Transaction Fee",
'D4425': "Unable to Locate Record On File",
'D4430': "Format Error",
'D4431': "Bank Not Supported By Switch",
'D4433': "Expired Card, Capture",
'D4434': "Suspected Fraud, Retain Card",
'D4435': "Card Acceptor, Contact Acquirer, Retain Card",
'D4436': "Restricted Card, Retain Card",
'D4437': "Contact Acquirer Security Department, Retain Card",
'D4438': "PIN Tries Exceeded, Capture",
'D4439': "No Credit Account",
'D4440': "Function Not Supported",
'D4441': "Lost Card",
'D4442': "No Universal Account",
'D4443': "Stolen Card",
'D4444': "No Investment Account",
'D4451': "Insufficient Funds",
'D4452': "No Cheque Account",
'D4453': "No Savings Account",
'D4454': "Expired Card",
'D4455': "Incorrect PIN",
'D4456': "No Card Record",
'D4457': "Function Not Permitted to Cardholder",
'D4458': "Function Not Permitted to Terminal",
'D4460': "Acceptor Contact Acquirer",
'D4461': "Exceeds Withdrawal Limit",
'D4462': "Restricted Card",
'D4463': "Security Violation",
'D4464': "Original Amount Incorrect",
'D4466': "Acceptor Contact Acquirer, Security",
'D4467': "Capture Card",
'D4475': "PIN Tries Exceeded",
'D4482': "CVV Validation Error",
'D4490': "Cutoff In Progress",
'D4491': "Card Issuer Unavailable",
'D4492': "Unable To Route Transaction",
'D4493': "Cannot Complete, Violation Of The Law",
'D4494': "Duplicate Transaction",
'D4496': "System Error",
'S5000': 'System Error',
'S5011': 'PayPal Connection Error',
'S5012': 'PayPal Settings Error'
}
class Payment(object):
"""
The eway payment class
"""
data = {
"Customer": {
"Reference": "",
"Title": "",
"FirstName": "",
"LastName": "",
"CompanyName": "",
"JobDescription": "",
"Street1": "",
"Street2": "",
"City": "",
"State": "",
"PostalCode": "",
"Country": "", # e.g nz
"Phone": "",
"Mobile": ""
},
"ShippingAddress": {
"FirstName": "",
"LastName": "",
"Street1": "",
"Street2": "",
"City": "",
"State": "",
"Country": "",
"PostalCode": "",
"Phone": ""
},
"Payment": {
"TotalAmount": 0,
"InvoiceNumber": "",
},
"RedirectUrl": "http://au.cloudninehair.com/shop/confirmation/",
"CancelUrl":"http://au.cloudninehair.com/shop/checkout/",
"Method": "ProcessPayment",
"TransactionType": "Purchase" # Purchase, MOTO or Recurring - we'll only use Purchase
}
def __init__(self, *args, **kwargs):
self.api_key = getattr(settings, 'EWAY_API_KEY', None)
self.username = getattr(settings, 'EWAY_USERNAME', None)
self.password = getattr(settings, 'EWAY_PASSWORD', None)
if getattr(settings, 'EWAY_SANDBOX', False):
self.url = 'https://api.sandbox.ewaypayments.com/'
else:
self.url = 'https://api.ewaypayments.com/'
def data_from_order(self, order):
"""Store the cloud nine form data in the local data collection """
self.data['Customer']['Reference'] = order.account.id
self.data['Customer']['Title'] = ''
self.data['Customer']['FirstName'] = order.account.user.first_name
self.data['Customer']['LastName'] = order.account.user.last_name
self.data['Customer']['CompanyName'] = ''
self.data['Customer']['JobDescription'] = ''
self.data['Customer']['Street1'] = order.account.default_address.line1
self.data['Customer']['Street2'] = order.account.default_address.line2
self.data['Customer']['City'] = order.account.default_address.city
self.data['Customer']['State'] = order.account.default_address.county
self.data['Customer']['PostalCode'] = order.account.default_address.postcode
self.data['Customer']['Country'] = order.account.default_address.country.iso_code
self.data['Customer']['Phone'] = order.account.telephone
self.data['Customer']['Email'] = order.account.user.email
self.data['Customer']['Mobile'] = ''
self.data['ShippingAddress']['FirstName'] = order.account.user.first_name
self.data['ShippingAddress']['LastName'] = order.account.user.last_name
self.data['ShippingAddress']['Street1'] = order.delivery_address.line1
self.data['ShippingAddress']['Street2'] = order.delivery_address.line2
self.data['ShippingAddress']['City'] = order.delivery_address.city
self.data['ShippingAddress']['State'] = order.delivery_address.county
self.data['ShippingAddress']['Country'] = order.delivery_address.country.iso_code
self.data['ShippingAddress']['PostalCode'] = order.delivery_address.postcode
self.data['ShippingAddress']['Phone'] = order.delivery_address.account.telephone
self.data['Payment']['TotalAmount'] = int(order.total*100)
self.data['Payment']['InvoiceNumber'] = order.order_number
def create_access_code(self, order):
self.data_from_order(order)
#data = self.make_request('AccessCodes', self.data)
data = self.make_request('CreateAccessCode.json', self.data)
return (data['AccessCode'], data['FormActionURL'],) if not self.errors else (None, None,)
def make_request(self, url, data):
""" Do an API request to eway """
if data:
resp = requests.post(os.path.join(self.url, url), data=json.dumps(data), auth=(self.api_key, self.password))
else:
resp = requests.get(os.path.join(self.url, url), auth=(self.api_key, self.password))
if resp.status_code == 200:
out = resp.json()
if out['Errors']:
self.errors = [RESPONSE_CODES[code].replace('ProcessRequest ', '') for code in out['Errors'].split(",")]
else:
self.errors = []
return out
else:
raise Exception("Unhandled none 200 response code from eway: %d / %s" % (resp.status_code, resp.content,) )
def get_access_code_result(self, access_code):
data = self.make_request('AccessCode/%s' % access_code, {})
if data['ResponseMessage']:
self.errors = [RESPONSE_CODES[code] for code in data['ResponseMessage'].split(",")]
return data['TransactionStatus'], data['AuthorisationCode'], data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment