Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Talking to Sagepay Reporting & Admin API from Ruby
require 'patron'
require 'time'
require 'active_support/core_ext/hash.rb'
require 'digest/md5'
require 'nokogiri'
module SagePay;end
class SagePay::Admin
def initialize(args)
@sess = Patron::Session.new
@sess.timeout = args[:timeout] || 10
@sess.base_url = args[:base_url] || "https://live.sagepay.com/access/"
@sess.headers['User-Agent'] = 'Can o Worms/0.1'
@sess.headers['Content-Type'] = 'application/x-www-form-urlencoded'
@vendor=args[:vendor]
@username=args[:username]
@password=args[:password]
@verbose=args[:verbose]
end
def send_rq(contents)
opts={:root=>'V',:skip_instruct=>true,:indent=>0}
data=contents.merge({
:vendor=>@vendor,
:user=>@username,
:password=>@password
})
# the authentication method in use here was clearly designed by
# someone who did not "get" xml. It is whitespace-sensitive,
# so the only sane thing to do is not to generate any.
# https://support.sagepay.com/forum/Topic11669-39-1.aspx
string=(data.to_xml(opts).delete "\n").gsub(/^<V>(.+)<\/V>$/,'\1')
digest = Digest::MD5.hexdigest(string)
string=string.gsub(%r{<password>.*</password>},
"<signature>#{digest}</signature>")
print ">> #{string}\n" if @verbose
r=Nokogiri.XML(@sess.post("access.htm",
"XML=<vspaccess>"+string+"</vspaccess>").body)
print "<< #{r}" if @verbose
r
end
def get_transaction_list(args={})
offset=args[:startrow] || 0
limit=args[:endrow] || nil
Enumerator.new do |yielder|
cursor=offset
loop do
doc=
send_rq({
:command=>"getTransactionList",
:startdate=>args[:startdate].strftime("%d/%m/%Y %H:%M:%S"),
:enddate=>args[:enddate].strftime("%d/%m/%Y %H:%M:%S"),
:includeaddresses=>(args[:includeaddresses] ? "YES": :"NO"),
:startrow=>cursor.to_s,
:sorttype=>"ByDate", # or "ByVendorTxCode"
:sortorder=>"ASC"
})
error= doc.css('vspaccess errorcode').first.content.to_i
if(error.zero?)
totalrows=doc.css('vspaccess transactions totalrows').first.content.to_i
if limit.nil? then limit=totalrows end
endrow=doc.css('vspaccess transactions endrow').first.content.to_i
doc.css('vspaccess transactions transaction').each do |tx|
hash={}
tx.children.each do |k|
hash[k.node_name.to_sym]=k.content
end
if ! hash[:rownumber].empty? then
yielder.yield hash
end
end
else
raise doc.css('vspaccess error').first.content
end
if endrow >= limit then
break
else
cursor=endrow+1
end
end
end
end
end
### and here is example code for using it
sagepay=SagePay::Admin.new(:vendor=>"vendorname",
:username=>"username",
:password=>"very secret",
:verbose=>false,
:timeout=>30
)
start=Time.parse("2010-10-29 08:58:00")
sagepay.get_transaction_list(:includeaddresses=>true,
:startdate=>start,
:enddate=>start+1800).each do |tx|
if (tx[:result] != "SUCCESS") then
warn tx
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.