Created
November 4, 2010 17:29
-
-
Save telent/662821 to your computer and use it in GitHub Desktop.
Talking to Sagepay Reporting & Admin API from Ruby
This file contains hidden or 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
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