Skip to content

crooksey/pyPaymentSense

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pyPaymentSense

Python code to interact with the Payment Sense API, including full validation for all variables. Works with python 2/3.

The package can be install with:

$ pip install pypaymentsense

For a usage example see below:

# coding: utf-8
import datetime
import pytz
import requests
import pypaymentsense
from pypaymentsense import build_hash, get_paymenturl

# Lets build a POST request

#######################################
# These variables are always required #
#######################################
post_addr = "https://mms.paymentsensegateway.com/Pages/PublicPages/PaymentForm.aspx"
# Note, the below details are obtained from Payment Snese once you have setup
# an account, and will be sent in TWO seperate emails when you first register
PreSharedKey = "YOUR-PSK-HERE"
MerchantID = "YOUR-MERCHANT-ID"
Password = "YOUR=PASSWORD-HERE"
# no decimal point in values, e.g. 34120 is 341.20
Amount = "34120"
# 826 is GBP
# Full list can be found here:
# http://developers.paymentsense.co.uk/hosted-integration-resources/
CurrencyCode = "826"
# Echo certain information back to the server so you can display on your
# callback page
EchoAVSCheckResult = False
EchoCardType = False
# Anything you want here
OrderID = "test Order416"
# SALE or PREAUTH
TransactionType = "SALE"
# The url the user will be returned to once payment has been made/declined
# It is a good idea to inlcude some JS code on this page to show the 
# user the results of the payment
CallbackURL = "http://example.com/your_callback"
# Self explanitory variables
EmailAddressEditable = True
PhoneNumberEditable = False
CV2Mandatory = True
Address1Mandatory = True
CityMandatory = False
PostCodeMandatory = True
StateMandatory = False
CountryMandatory = False
ResultDeliveryMethod="SERVER_PULL"
PaymentFormDisplaysResult = True
EchoCV2CheckResult = False
EchoThreeDSecureAuthenticationCheckResult = False
# Non required variables, we define these now to enable the full building
# of the URL, they can be passed as NONE if you do not want to include them
# in the post
ServerResultURL = None
OrderDescription= "Example Description"
CustomerName = "John Smith"
Address1 = "15 Faithfull Street"
Address2 = None
Address3 = None
Address4 = None
City = "Chichester"
State = "West Sussex"
PostCode = "XX2 5AW"
# List of country codes can be found here:
# http://developers.paymentsense.co.uk/hosted-integration-resources/
CountryCode = None
EmailAddress = "[email protected]"
PhoneNumber = "01243 774626"

# Now we need to set our timezone
datetime_tz = datetime.datetime.now(pytz.timezone("Europe/London"))

payment_url = get_paymenturl(
			PreSharedKey=PreSharedKey, MerchantID=MerchantID,
			Password=Password, Amount=Amount,
			CurrencyCode=CurrencyCode, 
			EchoAVSCheckResult=EchoAVSCheckResult,
			EchoCardType=EchoCardType, OrderID=OrderID,
			TransactionType=TransactionType, CallbackURL=CallbackURL,
			EmailAddressEditable=EmailAddressEditable,
			PhoneNumberEditable=PhoneNumberEditable,
			CV2Mandatory=CV2Mandatory,
			Address1Mandatory=Address1Mandatory,
			CityMandatory=CityMandatory,
			PostCodeMandatory=PostCodeMandatory,
			StateMandatory=StateMandatory, 
			CountryMandatory=CountryMandatory,
			ResultDeliveryMethod=ResultDeliveryMethod,
			PaymentFormDisplaysResult=PaymentFormDisplaysResult,
			EchoCV2CheckResult= EchoCV2CheckResult,
			EchoThreeDSecureAuthenticationCheckResult=\
				EchoThreeDSecureAuthenticationCheckResult,
			ServerResultURL=ServerResultURL,
			OrderDescription=OrderDescription,
			CustomerName=CustomerName,
			Address1=Address1,
			Address2=Address2,
			Address3=Address3,
			Address4=Address4,
			City=City,
			State=State,
			PostCode=PostCode,
			CountryCode=CountryCode,
			EmailAddress=EmailAddress,
			PhoneNumber=PhoneNumber,
			datetime_tz=datetime_tz,
			post_addr=post_addr
			)
print ("Genearated Url: " + payment_url)

For this example we will use the SERVER_PULL method, what this does is, after a successful payment, certain details are passed back to your server, you then send these details back to paymentsense as a request. The request response contains the details of the transaction, for example your callback view would have the following code:

import urllib
PreSharedKey = "YOUR-PSK-HERE"
Password = "YOUR-PASSWORD-HERE"
'''
This code works in pyramid + django, flask users should use the following
to perform a GET request:
hashdigest = request.args.get('HashDigest')
'''
# Get required variables from the URL string
hashdigest = request.GET['HashDigest']
merchantid = request.GET['MerchantID']
crossreference = request.GET['CrossReference']
orderid = request.GET['OrderID']
post_addr = "https://mms.paymentsensegateway.com/Pages/PublicPages/PaymentFormResultHandler.ashx"
data = {
    'MerchantID': merchantid,
    'Password': Password,
    'CrossReference': crossreference,
    }
# Send request to payment sense 
r = requests.post(post_addr, data=data)
# Result is the .text
url_raw =  r.text
# Test if start of string StatusCode=0 (12 chars)
# The response returned via the callback will contain the variable StatusCode
# twice, if the first instance of the string shows a 0, this indicates the
# transaction is valid, and will contain data regarding the transaction.
url_test = url_raw[0:12]
trans_ok = "StatusCode=0"
trans_ok_len = len(trans_ok)

if url_test == trans_ok:
    url_clean = url_raw[trans_ok_len:]
    url_decode = urllib.parse.unquote(url_clean)
    # Remove the first instance of StatusCode in the string, we no longer 
    # need it
else:
    # Else the first StatusCode comes back as 30, this indicates the 
    # transaction is not legit and we then need to format the data
    # differently, we just need to replace the spaces with "+"
    url_decode = url_raw.replace(" ", "+")
# Yes, we can all agree that the API that returns different data with the 
# same variable name is awful design, but we can thank paymentsense for
# their great design here. As the response further in will also contain 
# StatusCode again, this will show if the transaction has been approved
# or declined.
# You now have a url string (variable url_deconde) E.g. Var1=abc&VAR2=def, 
# pass this to another view for processing.

Now you have a URL string, you can pass this to the view used to show the payment, results, in this view you would have code similar to:

'''
This code works in pyramid + django, flask users should use the following
to perform a GET request:
status_code = request.args.get('StatusCode')
'''
# Here we will access the URL string passed from the previous view

if int(request.GET['StatusCode']) == 0:
    payment['result'] = "Approved"
    result_logo = True
else:
    payment['result'] = "Declined"
    result_logo = False

amount_raw = Decimal(request.GET['Amount'])
amount = amount_raw / 100

order_desc = request.GET['OrderDescription']

# create a dict with the results in
payment = {}
payment['result'] = result
payment['amount'] = amount
payment['card_type'] = request.GET['CardType']
payment['auth_code'] = request.GET['Message']
payment['order_desc'] = request.GET['OrderDescription']
payment['trade_name_str'] = trade_name_str
payment['trans_ref'] = request.GET['OrderID']
payment['cardholder_name'] = request.GET['CustomerName']

# You can then return the payment dict to the template for rendering

Notes: Still current as of 5th June 2019

About

Python code to interact with the Payment Sense API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages