realex 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +52 -0
- data/Rakefile +34 -0
- data/lib/real_ex/address.rb +15 -0
- data/lib/real_ex/card.rb +23 -0
- data/lib/real_ex/client.rb +35 -0
- data/lib/real_ex/config.rb +7 -0
- data/lib/real_ex/initializer.rb +24 -0
- data/lib/real_ex/recurring.rb +151 -0
- data/lib/real_ex/response.rb +38 -0
- data/lib/real_ex/transaction.rb +171 -0
- data/lib/realex.rb +20 -0
- data/realex.gemspec +68 -0
- data/spec/address_spec.rb +26 -0
- data/spec/card_spec.rb +27 -0
- data/spec/config_spec.rb +11 -0
- data/spec/real_ex_spec.rb +23 -0
- data/spec/recurring_spec.rb +52 -0
- data/spec/response_spec.rb +70 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/transaction_spec.rb +132 -0
- metadata +83 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# RealEx library for interfacing with www.realexpayments.com #
|
2
|
+
|
3
|
+
This is a Ruby library for interfacing with the RealEx API ( http://www.realexpayments.com )
|
4
|
+
|
5
|
+
## Basic Usage ##
|
6
|
+
|
7
|
+
require 'realex'
|
8
|
+
|
9
|
+
RealEx::Config.shared_secret = 'YOUR SHARED SECRET'
|
10
|
+
RealEx::Config.merchant_id = 'YOUR MERCHANT ID'
|
11
|
+
|
12
|
+
card = RealEx::Card.new(:number => '4***************', :cvv => '509', :expiry_date => '0822', :cardholder_name => 'Paul Campbell', :type => 'VISA')
|
13
|
+
|
14
|
+
transaction = RealEx::Authorization.new(
|
15
|
+
:customer_number => 1234, :variable_reference => 1234,
|
16
|
+
:card => card, :amount => 500, :order_id => 12345, :currency => 'EUR', :autosettle => true)
|
17
|
+
|
18
|
+
transaction.comments << "Here's a comment"
|
19
|
+
|
20
|
+
transaction.to_xml
|
21
|
+
|
22
|
+
transaction.shipping_address = RealEx::Address.new(:type => 'shipping', :code => 'Postal Code', :country => 'Country')
|
23
|
+
|
24
|
+
transaction.billing_address = RealEx::Address.new(:type => 'billing', :code => 'Postal Code', :country => 'Country')
|
25
|
+
|
26
|
+
transaction.authorize!
|
27
|
+
|
28
|
+
## Manual Request Type ##
|
29
|
+
|
30
|
+
transaction.manual = true
|
31
|
+
transaction.authcode = '12345'
|
32
|
+
|
33
|
+
transaction.authorize!
|
34
|
+
|
35
|
+
|
36
|
+
## Recurring payments ##
|
37
|
+
|
38
|
+
payer = RealEx::Recurring::Payer.new(:type => 'Business', :reference => 'boom', :title => 'Mr.', :firstname => 'Paul', :lastname => 'Campbell', :company => 'Hyper Tiny')
|
39
|
+
|
40
|
+
payer.address = RealEx::Address.new(:street => '64 Dame Street', :city => 'Dublin', :county => 'Dublin', :post_code => 'Dublin 3', :country => 'Ireland', :country_code => 'IE', :phone_numbers => { :home => '1234', :work => '1234', :fax => '1234', :mobile => '1234'}, :email => 'paul@rslw.com')
|
41
|
+
|
42
|
+
payer.save!
|
43
|
+
|
44
|
+
recurring_card = RealEx::Recurring::Card.new(:payer => payer, :reference => 'paulcampbell')
|
45
|
+
|
46
|
+
recurring_card.card = card
|
47
|
+
|
48
|
+
recurring_card.save
|
49
|
+
|
50
|
+
transaction = RealEx::Recurring::Authorization.new(:amount => 500, :payer => payer, :order_id => order_id)
|
51
|
+
|
52
|
+
transaction.authorize!
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc 'Run the specs'
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
9
|
+
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
10
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
PKG_FILES = FileList[
|
14
|
+
'[a-zA-Z]*',
|
15
|
+
'lib/**/*',
|
16
|
+
'rails/**/*'
|
17
|
+
]
|
18
|
+
|
19
|
+
begin
|
20
|
+
require 'jeweler'
|
21
|
+
Jeweler::Tasks.new do |gemspec|
|
22
|
+
gemspec.name = "realex"
|
23
|
+
gemspec.summary = "Ruby interface to http://realexpayments.com"
|
24
|
+
gemspec.description = "A Ruby library to make use of the payments API at http://realexpayments.com"
|
25
|
+
gemspec.email = "paul@rslw.com"
|
26
|
+
gemspec.homepage = "http://github.com/paulca/realex"
|
27
|
+
gemspec.authors = ["Paul Campbell"]
|
28
|
+
gemspec.version = "0.1.1"
|
29
|
+
end
|
30
|
+
rescue LoadError
|
31
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
32
|
+
end
|
33
|
+
|
34
|
+
Jeweler::GemcutterTasks.new
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RealEx
|
2
|
+
class Address
|
3
|
+
include Initializer
|
4
|
+
attributes :street, :city, :county
|
5
|
+
attributes :post_code, :country, :country_code, :phone_numbers, :email
|
6
|
+
|
7
|
+
[1,2,3].each do |line|
|
8
|
+
class_eval do
|
9
|
+
define_method("line#{line}") do
|
10
|
+
street.split("\n")[line - 1]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/real_ex/card.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module RealEx
|
2
|
+
class Card
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
attributes :number, :cvv, :expiry_date, :cardholder_name, :type, :issue_number
|
6
|
+
|
7
|
+
# The luhn check is a check to see if a credit card
|
8
|
+
# is actually a credit card or not
|
9
|
+
def passes_luhn_check?
|
10
|
+
odd = true
|
11
|
+
luhn = number.to_s.gsub(/\D/,'').reverse.split('').collect { |d|
|
12
|
+
d = d.to_i
|
13
|
+
d *= 2 if odd = !odd
|
14
|
+
d > 9 ? d - 9 : d
|
15
|
+
}.inject(0) { |sum,number| sum + number }
|
16
|
+
luhn % 10 == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def clean_name
|
20
|
+
cardholder_name.gsub(/[^a-zA-Z0-9 ]/, '')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RealEx
|
2
|
+
class Client
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def timestamp
|
6
|
+
Time.now.strftime('%Y%m%d%H%M%S')
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_hash(hash_string_items)
|
10
|
+
first_hash = Digest::SHA1.hexdigest(hash_string_items.join('.'))
|
11
|
+
Digest::SHA1.hexdigest("#{first_hash}.#{RealEx::Config.shared_secret}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_xml(type, &block)
|
15
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
16
|
+
xml.instruct!
|
17
|
+
xml.request(:timestamp => timestamp, :type => type) { |r| block.call(r) }
|
18
|
+
xml.target!
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(url,xml)
|
22
|
+
h = Net::HTTP.new('epage.payandshop.com', 443)
|
23
|
+
h.use_ssl = true
|
24
|
+
response = h.request_post(url, xml)
|
25
|
+
result = Hpricot.XML(response.body)
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse(response)
|
30
|
+
status = (response/:result).inner_html
|
31
|
+
raise RealExError, "#{(response/:message).inner_html} (#{status})" unless status == "00"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RealEx
|
2
|
+
module Initializer
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
# this blatantly ripped from jnunemaker's Twitter gem. Thanks John!
|
9
|
+
module ClassMethods
|
10
|
+
# creates the attributes class variable and creates each attribute's accessor methods
|
11
|
+
def attributes(*attrs)
|
12
|
+
@@attributes = attrs
|
13
|
+
@@attributes.each { |a| attr_accessor a }
|
14
|
+
end
|
15
|
+
|
16
|
+
# read method for attributes class variable
|
17
|
+
def self.attributes; @@attributes end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(setters = {})
|
21
|
+
setters.each { |k, v| send("#{k}=", v) } unless setters.nil?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module RealEx
|
2
|
+
module Recurring
|
3
|
+
|
4
|
+
class Transaction < RealEx::Transaction
|
5
|
+
def authorize!
|
6
|
+
RealEx::Response.new_from_xml(RealEx::Client.call('/epage-remote-plugins.cgi', to_xml))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Payer < Transaction
|
11
|
+
attributes :type, :reference, :title, :firstname, :lastname, :address, :company, :comments
|
12
|
+
attributes :update
|
13
|
+
|
14
|
+
def request_type
|
15
|
+
@request_type = update == true ? 'payer-edit' : 'payer-new'
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_xml
|
19
|
+
super do |per|
|
20
|
+
per.payer(:type => type, :ref => reference) do |payer|
|
21
|
+
payer.title title
|
22
|
+
payer.firstname firstname
|
23
|
+
payer.lastname lastname
|
24
|
+
payer.company company
|
25
|
+
payer.address do |add|
|
26
|
+
add.line1 address.line1
|
27
|
+
add.line1 address.line2
|
28
|
+
add.line3 address.line3
|
29
|
+
add.city address.city
|
30
|
+
add.county address.county
|
31
|
+
add.postcode address.post_code
|
32
|
+
add.country(address.country, :country_code => address.country_code)
|
33
|
+
end
|
34
|
+
payer.phonenumbers do |numbers|
|
35
|
+
numbers.home address.phone_numbers[:home]
|
36
|
+
numbers.work address.phone_numbers[:work]
|
37
|
+
numbers.fax address.phone_numbers[:fax]
|
38
|
+
numbers.mobile address.phone_numbers[:mobile]
|
39
|
+
end
|
40
|
+
payer.email address.email
|
41
|
+
if !comments.empty?
|
42
|
+
payer.comments do |c|
|
43
|
+
comments.each_with_index do |i,comment|
|
44
|
+
c.comment(comment, :id => i + 1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# 20030516175919.yourmerchantid.uniqueid…smithj01
|
53
|
+
def hash
|
54
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, '', '', reference])
|
55
|
+
end
|
56
|
+
|
57
|
+
def save!
|
58
|
+
authorize!
|
59
|
+
end
|
60
|
+
|
61
|
+
def update!
|
62
|
+
self.update = true
|
63
|
+
authorize!
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
class Card < Transaction
|
69
|
+
attributes :card, :payer, :update, :reference
|
70
|
+
|
71
|
+
def request_type
|
72
|
+
@request_type = update == true ? 'eft-update-expiry-date' : 'card-new'
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_xml
|
76
|
+
super do |per|
|
77
|
+
per.card do |c|
|
78
|
+
c.ref reference
|
79
|
+
c.payerref payer.reference
|
80
|
+
c.number card.number
|
81
|
+
c.expdate card.expiry_date
|
82
|
+
c.chname card.cardholder_name
|
83
|
+
c.type card.type
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# 20030516181127.yourmerchantid.uniqueid…smithj01.John Smith.498843******9991
|
89
|
+
def hash
|
90
|
+
if update == true
|
91
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, payer.reference, reference,card.expiry_date])
|
92
|
+
else
|
93
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, '', '', payer.reference,card.cardholder_name,card.number])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def save!
|
98
|
+
authorize!
|
99
|
+
end
|
100
|
+
|
101
|
+
def update!
|
102
|
+
self.update = true
|
103
|
+
authorize!
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
class Authorization < Transaction
|
109
|
+
attributes :payer, :reference, :customer_number, :variable_reference, :product_id
|
110
|
+
attributes :billing_address, :shipping_address
|
111
|
+
|
112
|
+
def request_type
|
113
|
+
'receipt-in'
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_xml
|
117
|
+
super do |per|
|
118
|
+
per.amount(amount, :currency => currency)
|
119
|
+
per.payerref payer.reference
|
120
|
+
per.paymentmethod reference
|
121
|
+
if customer_number or variable_reference or billing_address or shipping_address
|
122
|
+
per.tssinfo do |t|
|
123
|
+
t.custnum customer_number if customer_number
|
124
|
+
t.varref variable_reference if variable_reference
|
125
|
+
t.prodid product_id if product_id
|
126
|
+
if billing_address
|
127
|
+
t.address :type => 'billing' do |a|
|
128
|
+
a.code billing_address.post_code
|
129
|
+
a.country billing_address.country
|
130
|
+
end
|
131
|
+
end
|
132
|
+
if shipping_address
|
133
|
+
t.address :type => 'shipping' do |a|
|
134
|
+
a.code shipping_address.post_code
|
135
|
+
a.country shipping_address.country
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# timesttimestamp.merchantid.orderid.amount.currency.payerref
|
144
|
+
def hash
|
145
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, amount, currency, payer.reference])
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RealEx
|
2
|
+
class Response
|
3
|
+
class CardIssuer
|
4
|
+
include Initializer
|
5
|
+
attributes :bank, :country, :countrycode, :region
|
6
|
+
end
|
7
|
+
|
8
|
+
include Initializer
|
9
|
+
|
10
|
+
attributes :timestamp, :result, :message, :orderid, :merchantid, :account, :cvnresult, :avspostcoderesponse, :pasref, :timetaken, :authtimetaken, :batchid, :avsaddressresponse, :cardissuer
|
11
|
+
|
12
|
+
def self.new_from_xml(xml)
|
13
|
+
parsed_xml = xml.kind_of?(String) ? Hpricot.XML(xml) : xml
|
14
|
+
r = new
|
15
|
+
r.timestamp = (parsed_xml).at('response')['timestamp'] if (parsed_xml).at('response')
|
16
|
+
r.result = (parsed_xml).at('result').inner_html if (parsed_xml).at('result')
|
17
|
+
r.message = (parsed_xml).at('message').inner_html if (parsed_xml).at('message')
|
18
|
+
r.orderid = (parsed_xml).at('orderid').inner_html if (parsed_xml).at('orderid')
|
19
|
+
r.merchantid = (parsed_xml).at('merchantid').inner_html if (parsed_xml).at('merchantid')
|
20
|
+
r.account = (parsed_xml).at('account').inner_html if (parsed_xml).at('account')
|
21
|
+
r.cvnresult = (parsed_xml).at('cvnresult').inner_html if (parsed_xml).at('cvnresult')
|
22
|
+
r.avspostcoderesponse = (parsed_xml).at('avspostcoderesponse').inner_html if (parsed_xml).at('avspostcoderesponse')
|
23
|
+
r.avsaddressresponse = (parsed_xml).at('avsaddressresponse').inner_html if (parsed_xml).at('avsaddressresponse')
|
24
|
+
r.batchid = (parsed_xml).at('batchid').inner_html if (parsed_xml).at('batchid')
|
25
|
+
r.pasref = (parsed_xml).at('pasref').inner_html if (parsed_xml).at('pasref')
|
26
|
+
r.timetaken = (parsed_xml).at('timetaken').inner_html if (parsed_xml).at('timetaken')
|
27
|
+
r.authtimetaken = (parsed_xml).at('authtimetaken').inner_html if (parsed_xml).at('authtimetaken')
|
28
|
+
if cardissuer = (parsed_xml).at('cardissuer')
|
29
|
+
r.cardissuer = CardIssuer.new()
|
30
|
+
r.cardissuer.bank = cardissuer.at('bank').inner_html
|
31
|
+
r.cardissuer.country = cardissuer.at('country').inner_html
|
32
|
+
r.cardissuer.countrycode = cardissuer.at('countrycode').inner_html
|
33
|
+
r.cardissuer.region = cardissuer.at('region').inner_html
|
34
|
+
end
|
35
|
+
r
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module RealEx
|
2
|
+
class Transaction
|
3
|
+
include Initializer
|
4
|
+
attributes :card, :amount, :order_id, :currency, :autosettle, :variable_reference
|
5
|
+
attr_accessor :comments
|
6
|
+
attr_accessor :authcode, :pasref
|
7
|
+
|
8
|
+
REQUEST_TYPES = ['auth', 'manual', 'offline', 'tss', 'payer-new', 'payer-edit', 'card-new', 'eft-update-expiry-date']
|
9
|
+
|
10
|
+
def initialize(hash = {})
|
11
|
+
super(hash)
|
12
|
+
self.comments ||= []
|
13
|
+
self.autosettle ||= true
|
14
|
+
self.currency ||= RealEx::Config.currency || 'EUR'
|
15
|
+
end
|
16
|
+
|
17
|
+
def request_type
|
18
|
+
self.class.name.split('::').last.downcase
|
19
|
+
end
|
20
|
+
|
21
|
+
def autosettle?
|
22
|
+
autosettle
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_xml(&block)
|
26
|
+
xml = RealEx::Client.build_xml(request_type) do |r|
|
27
|
+
r.merchantid RealEx::Config.merchant_id
|
28
|
+
r.orderid order_id
|
29
|
+
r.authcode authcode if authcode
|
30
|
+
r.pasref pasref if pasref
|
31
|
+
r.account RealEx::Config.account
|
32
|
+
if block_given?
|
33
|
+
block.call(r)
|
34
|
+
end
|
35
|
+
if !comments.empty?
|
36
|
+
r.comments do |c|
|
37
|
+
comments.each_with_index do |index,comment|
|
38
|
+
c.comment(comment, :id => index)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
r.sha1hash hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def hash
|
47
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, '', '', ''])
|
48
|
+
end
|
49
|
+
|
50
|
+
def authorize!
|
51
|
+
RealEx::Response.new_from_xml(RealEx::Client.call('/epage-remote.cgi', to_xml))
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class Authorization < Transaction
|
57
|
+
attributes :shipping_address, :billing_address, :customer_number, :product_id, :customer_ip_address
|
58
|
+
attributes :offline, :manual
|
59
|
+
|
60
|
+
def initialize(hash = {})
|
61
|
+
super(hash)
|
62
|
+
self.manual ||= false
|
63
|
+
self.offline ||= false
|
64
|
+
end
|
65
|
+
|
66
|
+
REQUEST_TYPES.each do |type|
|
67
|
+
class_eval do
|
68
|
+
define_method("#{type}=") do |boolean| # def manual=(boolean)
|
69
|
+
self.request_type = type if boolean # self.request_type = 'manual' if boolean
|
70
|
+
end # end
|
71
|
+
|
72
|
+
define_method("#{type}?") do # def manual?
|
73
|
+
request_type == type # request_type == 'manual'
|
74
|
+
end # end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def request_type
|
79
|
+
@request_type ||= 'auth'
|
80
|
+
end
|
81
|
+
|
82
|
+
def request_type=(type)
|
83
|
+
@request_type = type if REQUEST_TYPES.include?(type)
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_xml
|
87
|
+
super do |r|
|
88
|
+
r.amount(amount, :currency => currency) unless offline?
|
89
|
+
if !offline?
|
90
|
+
r.card do |c|
|
91
|
+
c.number card.number
|
92
|
+
c.expdate card.expiry_date
|
93
|
+
c.chname card.clean_name
|
94
|
+
c.type card.type
|
95
|
+
end
|
96
|
+
r.autosettle :flag => autosettle? ? '1' : '0'
|
97
|
+
r.tssinfo do |t|
|
98
|
+
t.custnum customer_number if customer_number
|
99
|
+
t.varref variable_reference if variable_reference
|
100
|
+
t.prodid product_id if product_id
|
101
|
+
t.custipaddress customer_ip_address if customer_ip_address
|
102
|
+
if billing_address
|
103
|
+
t.address :type => 'billing' do |a|
|
104
|
+
a.code billing_address.post_code
|
105
|
+
a.country billing_address.country
|
106
|
+
end
|
107
|
+
end
|
108
|
+
if shipping_address
|
109
|
+
t.address :type => 'shipping' do |a|
|
110
|
+
a.code shipping_address.post_code
|
111
|
+
a.country shipping_address.country
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def hash
|
120
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, (amount unless offline?), (currency unless offline?), (card.number unless offline?)])
|
121
|
+
end
|
122
|
+
|
123
|
+
def rebate!
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
def void!
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
def settle!
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
class Void < Transaction
|
138
|
+
end
|
139
|
+
|
140
|
+
class Settle < Transaction
|
141
|
+
end
|
142
|
+
|
143
|
+
class Rebate < Transaction
|
144
|
+
|
145
|
+
attr_accessor :refund_password
|
146
|
+
|
147
|
+
def refund_hash
|
148
|
+
Digest::SHA1.hexdigest((refund_password || RealEx::Config.refund_password || ''))
|
149
|
+
end
|
150
|
+
|
151
|
+
def to_xml(&block)
|
152
|
+
super do |per|
|
153
|
+
per.amount(amount, :currency => currency)
|
154
|
+
per.autosettle :flag => autosettle? ? '1' : '0'
|
155
|
+
per.refundhash refund_hash
|
156
|
+
if !comments.empty?
|
157
|
+
per.comments do |c|
|
158
|
+
comments.each_with_index do |index,comment|
|
159
|
+
c.comment(comment, :id => index)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def hash
|
168
|
+
RealEx::Client.build_hash([RealEx::Client.timestamp, RealEx::Config.merchant_id, order_id, amount, currency, ''])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
data/lib/realex.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rio'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'hpricot'
|
4
|
+
require 'net/https'
|
5
|
+
require 'builder'
|
6
|
+
|
7
|
+
$:.unshift(File.dirname(__FILE__))
|
8
|
+
require 'real_ex/initializer'
|
9
|
+
require 'real_ex/config'
|
10
|
+
require 'real_ex/client'
|
11
|
+
|
12
|
+
require 'real_ex/address'
|
13
|
+
require 'real_ex/card'
|
14
|
+
require 'real_ex/transaction'
|
15
|
+
require 'real_ex/response'
|
16
|
+
require 'real_ex/recurring'
|
17
|
+
|
18
|
+
module RealEx
|
19
|
+
class UnknownError < StandardError; end
|
20
|
+
end
|
data/realex.gemspec
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{realex}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Paul Campbell"]
|
12
|
+
s.date = %q{2010-02-24}
|
13
|
+
s.description = %q{A Ruby library to make use of the payments API at http://realexpayments.com}
|
14
|
+
s.email = %q{paul@rslw.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"README.md",
|
21
|
+
"Rakefile",
|
22
|
+
"lib/real_ex/address.rb",
|
23
|
+
"lib/real_ex/card.rb",
|
24
|
+
"lib/real_ex/client.rb",
|
25
|
+
"lib/real_ex/config.rb",
|
26
|
+
"lib/real_ex/initializer.rb",
|
27
|
+
"lib/real_ex/recurring.rb",
|
28
|
+
"lib/real_ex/response.rb",
|
29
|
+
"lib/real_ex/transaction.rb",
|
30
|
+
"lib/realex.rb",
|
31
|
+
"realex.gemspec",
|
32
|
+
"spec/address_spec.rb",
|
33
|
+
"spec/card_spec.rb",
|
34
|
+
"spec/config_spec.rb",
|
35
|
+
"spec/real_ex_spec.rb",
|
36
|
+
"spec/recurring_spec.rb",
|
37
|
+
"spec/response_spec.rb",
|
38
|
+
"spec/spec.opts",
|
39
|
+
"spec/spec_helper.rb",
|
40
|
+
"spec/transaction_spec.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/paulca/realex}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.5}
|
46
|
+
s.summary = %q{Ruby interface to http://realexpayments.com}
|
47
|
+
s.test_files = [
|
48
|
+
"spec/address_spec.rb",
|
49
|
+
"spec/card_spec.rb",
|
50
|
+
"spec/config_spec.rb",
|
51
|
+
"spec/real_ex_spec.rb",
|
52
|
+
"spec/recurring_spec.rb",
|
53
|
+
"spec/response_spec.rb",
|
54
|
+
"spec/spec_helper.rb",
|
55
|
+
"spec/transaction_spec.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
63
|
+
else
|
64
|
+
end
|
65
|
+
else
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx::Address" do
|
4
|
+
before do
|
5
|
+
@address = RealEx::Address.new(
|
6
|
+
:post_code => '1234',
|
7
|
+
:country => 'Ireland',
|
8
|
+
:street => "99 Street view,\nholleraino\npicksville"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should just save the attributes" do
|
13
|
+
@address.post_code.should == '1234'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should just save the attributes" do
|
17
|
+
@address.country.should == 'Ireland'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have line1 line2 and line3" do
|
21
|
+
@address.line1.should == "99 Street view,"
|
22
|
+
@address.line2.should == "holleraino"
|
23
|
+
@address.line3.should == "picksville"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/spec/card_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx::Card" do
|
4
|
+
before do
|
5
|
+
@card = RealEx::Card.new(
|
6
|
+
:number => '4111111111111111',
|
7
|
+
:cvv => '509',
|
8
|
+
:expiry_date => '0802',
|
9
|
+
:cardholder_name => 'Paul Campbell',
|
10
|
+
:type => 'VISA',
|
11
|
+
:issue_number => nil
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should just save the attributes" do
|
16
|
+
@card.number.should == '4111111111111111'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should pass the luhn check" do
|
20
|
+
@card.passes_luhn_check?.should == true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should fail the luhn check if it's an invalid card" do
|
24
|
+
@card.number = '1234'
|
25
|
+
@card.passes_luhn_check?.should == false
|
26
|
+
end
|
27
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx::Config" do
|
4
|
+
before do
|
5
|
+
RealEx::Config.shared_secret = "He's actually a woman"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should set the shared_secret" do
|
9
|
+
RealEx::Config.shared_secret.should == "He's actually a woman"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx" do
|
4
|
+
|
5
|
+
# before do
|
6
|
+
# @card = RealEx::Cart
|
7
|
+
#
|
8
|
+
# RealEx::Connection
|
9
|
+
# RealEx::Card
|
10
|
+
# RealEx::Transaction
|
11
|
+
# RealEx::Refund
|
12
|
+
# RealEx::Recurring::Payer
|
13
|
+
# RealEx::Recurring::Card
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# it "should set the shared secret" do
|
17
|
+
# RealEx.shared_secret.should == "He's a woman"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# it "should set the merchant_id" do
|
21
|
+
# RealEx.merchant_id.should == '123456'
|
22
|
+
# end
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx::Recurring" do
|
4
|
+
before do
|
5
|
+
RealEx::Config.merchant_id = 'paul'
|
6
|
+
RealEx::Config.shared_secret = "He's not dead, he's just asleep!"
|
7
|
+
RealEx::Config.account = 'internet'
|
8
|
+
|
9
|
+
@card = RealEx::Card.new(
|
10
|
+
:number => '4111111111111111',
|
11
|
+
:cvv => '509',
|
12
|
+
:expiry_date => '0802',
|
13
|
+
:cardholder_name => 'Paul Campbell',
|
14
|
+
:type => 'VISA',
|
15
|
+
:issue_number => nil
|
16
|
+
)
|
17
|
+
@payer = RealEx::Recurring::Payer.new(:type => 'Business', :reference => 'boom', :title => 'Mr.', :firstname => 'Paul', :lastname => 'Campbell', :company => 'Contrast')
|
18
|
+
@payer.address = RealEx::Address.new(:street => 'My house', :city => 'Dublin', :county => 'Dublin', :post_code => 'Dublin 2', :country => 'Ireland', :country_code => 'IE',
|
19
|
+
:phone_numbers => { :home => '1', :work => '2', :fax => '3', :mobile => '4'}, :email => 'paul@contrast.ie')
|
20
|
+
@card = RealEx::Recurring::Card.new(:payer => @payer, :card => @card, :reference => 'billabong')
|
21
|
+
@transaction = RealEx::Recurring::Authorization.new(
|
22
|
+
:payer => @payer,
|
23
|
+
:amount => 500,
|
24
|
+
:order_id => 1234,
|
25
|
+
:currency => 'EUR',
|
26
|
+
:autosettle => true
|
27
|
+
)
|
28
|
+
RealEx::Client.stub!(:timestamp).and_return('20090326160218')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create tasty XML for the payer" do
|
32
|
+
@payer.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"payer-new\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid></orderid>\n <account>internet</account>\n <payer type=\"Business\" ref=\"boom\">\n <title>Mr.</title>\n <firstname>Paul</firstname>\n <lastname>Campbell</lastname>\n <company>Contrast</company>\n <address>\n <line1>My house</line1>\n <line1></line1>\n <line3></line3>\n <city>Dublin</city>\n <county>Dublin</county>\n <postcode>Dublin 2</postcode>\n <country country_code=\"IE\">Ireland</country>\n </address>\n <phonenumbers>\n <home>1</home>\n <work>2</work>\n <fax>3</fax>\n <mobile>4</mobile>\n </phonenumbers>\n <email>paul@contrast.ie</email>\n </payer>\n <sha1hash>7e97b1b743c2599b6c1fd0c5515d369d8372df15</sha1hash>\n</request>\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should create tasty XML for the payer update" do
|
36
|
+
@payer.update = true
|
37
|
+
@payer.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"payer-edit\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid></orderid>\n <account>internet</account>\n <payer type=\"Business\" ref=\"boom\">\n <title>Mr.</title>\n <firstname>Paul</firstname>\n <lastname>Campbell</lastname>\n <company>Contrast</company>\n <address>\n <line1>My house</line1>\n <line1></line1>\n <line3></line3>\n <city>Dublin</city>\n <county>Dublin</county>\n <postcode>Dublin 2</postcode>\n <country country_code=\"IE\">Ireland</country>\n </address>\n <phonenumbers>\n <home>1</home>\n <work>2</work>\n <fax>3</fax>\n <mobile>4</mobile>\n </phonenumbers>\n <email>paul@contrast.ie</email>\n </payer>\n <sha1hash>7e97b1b743c2599b6c1fd0c5515d369d8372df15</sha1hash>\n</request>\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should create lovely XML for the card" do
|
41
|
+
@card.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"card-new\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid></orderid>\n <account>internet</account>\n <card>\n <ref>billabong</ref>\n <payerref>boom</payerref>\n <number>4111111111111111</number>\n <expdate>0802</expdate>\n <chname>Paul Campbell</chname>\n <type>VISA</type>\n </card>\n <sha1hash>24dc62271ccaddc59082b4db45c80b0241f630f7</sha1hash>\n</request>\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create lovely XML for the card update" do
|
45
|
+
@card.update = true
|
46
|
+
@card.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"eft-update-expiry-date\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid></orderid>\n <account>internet</account>\n <card>\n <ref>billabong</ref>\n <payerref>boom</payerref>\n <number>4111111111111111</number>\n <expdate>0802</expdate>\n <chname>Paul Campbell</chname>\n <type>VISA</type>\n </card>\n <sha1hash>a97a52b7e5afa2980f4298251c2b8b836fd82331</sha1hash>\n</request>\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should create tasty XML for the authorization" do
|
50
|
+
@transaction.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"receipt-in\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>1234</orderid>\n <account>internet</account>\n <amount currency=\"EUR\">500</amount>\n <payerref>boom</payerref>\n <paymentmethod></paymentmethod>\n <sha1hash>ec3afd1714b4473210c2b1eda0c6675bd13c411b</sha1hash>\n</request>\n"
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
# <?xml version="1.0" ?>
|
3
|
+
# <response timestamp="20090326164411">
|
4
|
+
# <result>501</result>
|
5
|
+
# <message>This transaction (1234) has already been processed! If you feel this is incorrect please contact the merchant!</message>
|
6
|
+
# <orderid>1234</orderid>
|
7
|
+
# </response>
|
8
|
+
describe "RealEx::Response" do
|
9
|
+
before do
|
10
|
+
@response = RealEx::Response.new_from_xml(%Q[<?xml version="1.0" ?>
|
11
|
+
<response timestamp="20090326164411">
|
12
|
+
<result>501</result>
|
13
|
+
<message>This transaction (1234) has already been processed! If you feel this is incorrect please contact the merchant!</message>
|
14
|
+
<orderid>1234</orderid>
|
15
|
+
</response>])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should build the object" do
|
19
|
+
@response.timestamp.should == '20090326164411'
|
20
|
+
@response.result.should == '501'
|
21
|
+
@response.message.should == 'This transaction (1234) has already been processed! If you feel this is incorrect please contact the merchant!'
|
22
|
+
@response.orderid.should == '1234'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "RealEx::Response" do
|
27
|
+
before do
|
28
|
+
@response = RealEx::Response.new_from_xml(%Q[<?xml version="1.0" encoding="UTF-8" ?>
|
29
|
+
<response timestamp="20090326171616">
|
30
|
+
<merchantid>test</merchantid>
|
31
|
+
<account>Realex</account>
|
32
|
+
<orderid>12345</orderid>
|
33
|
+
<authcode>171616</authcode>
|
34
|
+
<result>00</result>
|
35
|
+
<cvnresult>U</cvnresult>
|
36
|
+
<avspostcoderesponse>U</avspostcoderesponse>
|
37
|
+
<avsaddressresponse>U</avsaddressresponse>
|
38
|
+
<batchid>136</batchid>
|
39
|
+
<message>[ test system ] Authorised 171616</message>
|
40
|
+
<pasref>12380877763476</pasref>
|
41
|
+
<timetaken>1</timetaken>
|
42
|
+
<authtimetaken>0</authtimetaken>
|
43
|
+
<cardissuer>
|
44
|
+
<bank>AIB BANK</bank>
|
45
|
+
<country>IRELAND</country>
|
46
|
+
<countrycode>IE</countrycode>
|
47
|
+
<region>EUR</region>
|
48
|
+
</cardissuer>])
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should build the object" do
|
52
|
+
@response.timestamp.should == '20090326171616'
|
53
|
+
@response.merchantid.should == 'test'
|
54
|
+
@response.account.should == 'Realex'
|
55
|
+
@response.orderid.should == '12345'
|
56
|
+
@response.cardissuer.bank.should == 'AIB BANK'
|
57
|
+
@response.cvnresult.should == 'U'
|
58
|
+
@response.cvnresult.should == 'U'
|
59
|
+
@response.avspostcoderesponse.should == 'U'
|
60
|
+
@response.avsaddressresponse.should == 'U'
|
61
|
+
@response.batchid.should == '136'
|
62
|
+
@response.message.should == '[ test system ] Authorised 171616'
|
63
|
+
@response.pasref.should == '12380877763476'
|
64
|
+
@response.timetaken.should == '1'
|
65
|
+
@response.authtimetaken.should == '0'
|
66
|
+
@response.cardissuer.country.should == 'IRELAND'
|
67
|
+
@response.cardissuer.countrycode.should == 'IE'
|
68
|
+
@response.cardissuer.region.should == 'EUR'
|
69
|
+
end
|
70
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
gem 'rspec'
|
6
|
+
require 'spec'
|
7
|
+
end
|
8
|
+
|
9
|
+
dir = File.dirname(__FILE__)
|
10
|
+
|
11
|
+
$:.unshift(File.join(dir, '/../lib/'))
|
12
|
+
require dir + '/../lib/real_ex'
|
13
|
+
|
14
|
+
|
15
|
+
def stdout_for(&block)
|
16
|
+
# Inspired by http://www.ruby-forum.com/topic/58647
|
17
|
+
old_stdout = $stdout
|
18
|
+
$stdout = StringIO.new
|
19
|
+
yield
|
20
|
+
output = $stdout.string
|
21
|
+
$stdout = old_stdout
|
22
|
+
output
|
23
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "RealEx::Transaction" do
|
4
|
+
before do
|
5
|
+
RealEx::Config.merchant_id = 'paul'
|
6
|
+
RealEx::Config.shared_secret = "She's a man!"
|
7
|
+
RealEx::Config.account = 'internet'
|
8
|
+
|
9
|
+
@card = RealEx::Card.new(
|
10
|
+
:number => '4111111111111111',
|
11
|
+
:cvv => '509',
|
12
|
+
:expiry_date => '0802',
|
13
|
+
:cardholder_name => 'Paul Campbell',
|
14
|
+
:type => 'VISA',
|
15
|
+
:issue_number => nil
|
16
|
+
)
|
17
|
+
@transaction = RealEx::Authorization.new(
|
18
|
+
:card => @card,
|
19
|
+
:amount => 500,
|
20
|
+
:order_id => 1234,
|
21
|
+
:currency => 'EUR',
|
22
|
+
:autosettle => true
|
23
|
+
)
|
24
|
+
RealEx::Client.stub!(:timestamp).and_return('20090326160218')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should set up the card" do
|
28
|
+
@transaction.card.should == @card
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow setting comments" do
|
32
|
+
@transaction.comments << "This is a comment"
|
33
|
+
@transaction.comments.should == ["This is a comment"]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should build the xml" do
|
37
|
+
@transaction.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"auth\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>1234</orderid>\n <account>internet</account>\n <amount currency=\"EUR\">500</amount>\n <card>\n <number>4111111111111111</number>\n <expdate>0802</expdate>\n <chname>Paul Campbell</chname>\n <type>VISA</type>\n </card>\n <autosettle flag=\"1\"/>\n <tssinfo>\n </tssinfo>\n <sha1hash>d979885b0a296469d85ada0f08c5577d857142a0</sha1hash>\n</request>\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "with addresses" do
|
41
|
+
before do
|
42
|
+
@transaction.shipping_address = RealEx::Address.new(:post_code => 'Shipping Code', :country => 'Shipping Country')
|
43
|
+
@transaction.billing_address = RealEx::Address.new(:post_code => 'Biling Code', :country => 'Billing Country')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should add the addresses into the xml" do
|
47
|
+
@transaction.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"auth\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>1234</orderid>\n <account>internet</account>\n <amount currency=\"EUR\">500</amount>\n <card>\n <number>4111111111111111</number>\n <expdate>0802</expdate>\n <chname>Paul Campbell</chname>\n <type>VISA</type>\n </card>\n <autosettle flag=\"1\"/>\n <tssinfo>\n <address type=\"billing\">\n <code>Biling Code</code>\n <country>Billing Country</country>\n </address>\n <address type=\"shipping\">\n <code>Shipping Code</code>\n <country>Shipping Country</country>\n </address>\n </tssinfo>\n <sha1hash>d979885b0a296469d85ada0f08c5577d857142a0</sha1hash>\n</request>\n"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "actually going through" do
|
52
|
+
|
53
|
+
it "should parse the response" do
|
54
|
+
RealEx::Client.should_receive(:call).and_return(Hpricot.XML('yay'))
|
55
|
+
@transaction.authorize!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "a manual request type" do
|
60
|
+
before do
|
61
|
+
@transaction.manual = true
|
62
|
+
@transaction.authcode = '123456'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should allow a manual request" do
|
66
|
+
@transaction.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"manual\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>1234</orderid>\n <authcode>123456</authcode>\n <account>internet</account>\n <amount currency=\"EUR\">500</amount>\n <card>\n <number>4111111111111111</number>\n <expdate>0802</expdate>\n <chname>Paul Campbell</chname>\n <type>VISA</type>\n </card>\n <autosettle flag=\"1\"/>\n <tssinfo>\n </tssinfo>\n <sha1hash>d979885b0a296469d85ada0f08c5577d857142a0</sha1hash>\n</request>\n"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "an offline request type" do
|
71
|
+
before do
|
72
|
+
@transaction.offline = true
|
73
|
+
@transaction.authcode = '123456'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should allow an offline request" do
|
77
|
+
@transaction.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"offline\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>1234</orderid>\n <authcode>123456</authcode>\n <account>internet</account>\n <sha1hash>c01440492e678c7793cc7a221617384dec6d9ea1</sha1hash>\n</request>\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "a bit of meta" do
|
82
|
+
it "should allow setting and getting of manual= and manual?" do
|
83
|
+
@transaction.manual = true
|
84
|
+
@transaction.manual?.should == true
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow setting and getting of offline= and offline?" do
|
88
|
+
@transaction.offline = true
|
89
|
+
@transaction.offline?.should == true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "RealEx::Rebate" do
|
96
|
+
before do
|
97
|
+
RealEx::Config.merchant_id = 'paul'
|
98
|
+
RealEx::Config.shared_secret = "She's a man!"
|
99
|
+
RealEx::Config.account = 'internet'
|
100
|
+
RealEx::Config.refund_password = ''
|
101
|
+
@rebate = RealEx::Rebate.new(
|
102
|
+
:order_id => '12345',
|
103
|
+
:pasref => '23455',
|
104
|
+
:authcode => '123123123',
|
105
|
+
:amount => 500
|
106
|
+
)
|
107
|
+
RealEx::Client.stub!(:timestamp).and_return('20090326160218')
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should create some tasty xml" do
|
111
|
+
@rebate.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"rebate\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>12345</orderid>\n <authcode>123123123</authcode>\n <pasref>23455</pasref>\n <account>internet</account>\n <amount currency=\"EUR\">500</amount>\n <autosettle flag=\"1\"/>\n <refundhash>da39a3ee5e6b4b0d3255bfef95601890afd80709</refundhash>\n <sha1hash>be2f8fdc84c32d8d77ab6fae7896c10530d9d80c</sha1hash>\n</request>\n"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "RealEx::Void" do
|
116
|
+
before do
|
117
|
+
RealEx::Config.merchant_id = 'paul'
|
118
|
+
RealEx::Config.shared_secret = "She's a man!"
|
119
|
+
RealEx::Config.account = 'internet'
|
120
|
+
RealEx::Config.refund_password = ''
|
121
|
+
@void = RealEx::Void.new(
|
122
|
+
:order_id => '12345',
|
123
|
+
:pasref => '23455',
|
124
|
+
:authcode => '123123123'
|
125
|
+
)
|
126
|
+
RealEx::Client.stub!(:timestamp).and_return('20090326160218')
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should create some tasty xml" do
|
130
|
+
@void.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<request type=\"void\" timestamp=\"20090326160218\">\n <merchantid>paul</merchantid>\n <orderid>12345</orderid>\n <authcode>123123123</authcode>\n <pasref>23455</pasref>\n <account>internet</account>\n <sha1hash>16b04c4e989c413a54da8585266f6087cedccb0b</sha1hash>\n</request>\n"
|
131
|
+
end
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: realex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Campbell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-24 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A Ruby library to make use of the payments API at http://realexpayments.com
|
17
|
+
email: paul@rslw.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.md
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- lib/real_ex/address.rb
|
29
|
+
- lib/real_ex/card.rb
|
30
|
+
- lib/real_ex/client.rb
|
31
|
+
- lib/real_ex/config.rb
|
32
|
+
- lib/real_ex/initializer.rb
|
33
|
+
- lib/real_ex/recurring.rb
|
34
|
+
- lib/real_ex/response.rb
|
35
|
+
- lib/real_ex/transaction.rb
|
36
|
+
- lib/realex.rb
|
37
|
+
- realex.gemspec
|
38
|
+
- spec/address_spec.rb
|
39
|
+
- spec/card_spec.rb
|
40
|
+
- spec/config_spec.rb
|
41
|
+
- spec/real_ex_spec.rb
|
42
|
+
- spec/recurring_spec.rb
|
43
|
+
- spec/response_spec.rb
|
44
|
+
- spec/spec.opts
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
- spec/transaction_spec.rb
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/paulca/realex
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --charset=UTF-8
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.5
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Ruby interface to http://realexpayments.com
|
75
|
+
test_files:
|
76
|
+
- spec/address_spec.rb
|
77
|
+
- spec/card_spec.rb
|
78
|
+
- spec/config_spec.rb
|
79
|
+
- spec/real_ex_spec.rb
|
80
|
+
- spec/recurring_spec.rb
|
81
|
+
- spec/response_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- spec/transaction_spec.rb
|