cardia 0.0.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/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +28 -0
- data/README.txt +8 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/cardia/credit_card_transaction.rb +207 -0
- data/lib/cardia/customer.rb +15 -0
- data/lib/cardia/merchant.rb +23 -0
- data/lib/cardia/order.rb +37 -0
- data/lib/cardia/transaction_status.rb +60 -0
- data/lib/cardia/version.rb +9 -0
- data/lib/cardia.rb +19 -0
- data/lib/credit_card.rb +189 -0
- data/lib/enum.rb +78 -0
- data/lib/validateable.rb +80 -0
- data/log/debug.log +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +27 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_cardia.rb +11 -0
- data/test/test_credit_card_transaction.rb +76 -0
- data/test/test_helper.rb +33 -0
- data/test/test_transaction_status.rb +15 -0
- metadata +80 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Marius Mårnes Mathiesen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
lib/cardia.rb
|
9
|
+
lib/cardia/credit_card_transaction.rb
|
10
|
+
lib/cardia/customer.rb
|
11
|
+
lib/cardia/merchant.rb
|
12
|
+
lib/cardia/order.rb
|
13
|
+
lib/cardia/transaction_status.rb
|
14
|
+
lib/cardia/version.rb
|
15
|
+
lib/credit_card.rb
|
16
|
+
lib/enum.rb
|
17
|
+
lib/validateable.rb
|
18
|
+
log/debug.log
|
19
|
+
script/destroy
|
20
|
+
script/generate
|
21
|
+
setup.rb
|
22
|
+
tasks/deployment.rake
|
23
|
+
tasks/environment.rake
|
24
|
+
tasks/website.rake
|
25
|
+
test/test_cardia.rb
|
26
|
+
test/test_credit_card_transaction.rb
|
27
|
+
test/test_helper.rb
|
28
|
+
test/test_transaction_status.rb
|
data/README.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
= Cardia
|
2
|
+
Implements payments through Norwegian payment gateway Cardia's Cardia Service.
|
3
|
+
|
4
|
+
See Cardia::CreditCardTransaction for example usage
|
5
|
+
|
6
|
+
== Other sources of information
|
7
|
+
* Cardia's own documentation is available at http://www.cardia.no/Resource/Documentation/Services/Cardia.Services.Card.pdf
|
8
|
+
* SOAP interface description: https://secure.cardia.no/service/card/transaction/1.2/transaction.asmx
|
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'cardia/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Marius Mårnes Mathiesen' # can also be an array of Authors
|
4
|
+
EMAIL = "marius.mathiesen@gmail.com"
|
5
|
+
DESCRIPTION = "provides credit card payments through Cardia"
|
6
|
+
GEM_NAME = 'cardia' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'cardia' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
|
11
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
12
|
+
@config = nil
|
13
|
+
RUBYFORGE_USERNAME = "zmalltalker"
|
14
|
+
def rubyforge_username
|
15
|
+
unless @config
|
16
|
+
begin
|
17
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
18
|
+
rescue
|
19
|
+
puts <<-EOS
|
20
|
+
ERROR: No rubyforge config file found: #{@config_file}"
|
21
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
22
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
23
|
+
EOS
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
REV = nil
|
32
|
+
# UNCOMMENT IF REQUIRED:
|
33
|
+
# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
|
34
|
+
VERS = Cardia::VERSION::STRING + (REV ? ".#{REV}" : "")
|
35
|
+
RDOC_OPTS = ['--quiet', '--title', 'cardia documentation',
|
36
|
+
"--opname", "index.html",
|
37
|
+
"--line-numbers",
|
38
|
+
"--main", "README",
|
39
|
+
"--inline-source"]
|
40
|
+
|
41
|
+
class Hoe
|
42
|
+
def extra_deps
|
43
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
44
|
+
@extra_deps
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Generate all the Rake tasks
|
49
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
50
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
51
|
+
p.author = AUTHOR
|
52
|
+
p.description = DESCRIPTION
|
53
|
+
p.email = EMAIL
|
54
|
+
p.summary = DESCRIPTION
|
55
|
+
p.url = HOMEPATH
|
56
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
57
|
+
p.test_globs = ["test/**/test_*.rb"]
|
58
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
59
|
+
|
60
|
+
# == Optional
|
61
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\\n\\n")
|
62
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
63
|
+
|
64
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
69
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
|
+
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
16
|
+
|
17
|
+
require 'cardia'
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module Cardia
|
2
|
+
|
3
|
+
# This class represents a credit card transaction against Cardia
|
4
|
+
# These are created at Cardia using one of the register methods:
|
5
|
+
# - register, which keeps the control with us (we dont redirect the user away), but gives the merchant full responsibility
|
6
|
+
# - register_3d, which forces our user into foreign territory, hopefully returning to us afterwards; but limits the merchants liabilities
|
7
|
+
#
|
8
|
+
# == Minimal usage example
|
9
|
+
# require 'cardia'
|
10
|
+
#
|
11
|
+
# customer = Cardia::Customer.new("John","Doe")
|
12
|
+
# amount = 1000
|
13
|
+
# order = Cardia::Order.new(amount, "My test order")
|
14
|
+
# order.customer = customer
|
15
|
+
# merchant = Cardia::Merchant.test_merchant
|
16
|
+
# transaction = Cardia::CreditCardTransaction.with_http_connection(order)
|
17
|
+
# transaction.merchant = merchant
|
18
|
+
#
|
19
|
+
# card = ActiveMerchant::Billing::CreditCard.valid_card_for_testing
|
20
|
+
#
|
21
|
+
# status = transaction.register(card)
|
22
|
+
#
|
23
|
+
class CreditCardTransaction
|
24
|
+
|
25
|
+
attr_reader :order, :verification_address
|
26
|
+
attr_reader :merchant
|
27
|
+
|
28
|
+
def initialize(an_order, http_connection) #:nodoc:
|
29
|
+
@order= an_order
|
30
|
+
@http = http_connection
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new instance. Send along your Order as the parameter, see Billing::Order for methods that should be implemented in your order
|
34
|
+
def self.with_http_connection(an_order)
|
35
|
+
http = Net::HTTP.new(self.server_name,"443")
|
36
|
+
http.use_ssl = true
|
37
|
+
return self.new(an_order, http)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Send along the Cardia::Merchant that the payment is for
|
41
|
+
def merchant=(a_merchant)
|
42
|
+
@merchant = a_merchant
|
43
|
+
end
|
44
|
+
|
45
|
+
def invoke_transaction_web_service(method, values) #:nodoc:
|
46
|
+
doc = do_invoke_web_service("/Service/Card/Transaction/1.2/Transaction.asmx/",
|
47
|
+
method,
|
48
|
+
values)
|
49
|
+
status_code = doc.root.elements["StatusCode"].text.to_i
|
50
|
+
return status_code, doc
|
51
|
+
end
|
52
|
+
|
53
|
+
def invoke_teller_web_service(method, values) #:nodoc:
|
54
|
+
doc = do_invoke_web_service("/Service/Card/Mpi/TellerMpi/1.2/TellerMpi.asmx/", method, values)
|
55
|
+
status_code = doc.root.elements["ResponseCode"].text.to_i
|
56
|
+
return status_code, doc
|
57
|
+
end
|
58
|
+
|
59
|
+
# Implements the vanilla plain calls to Cardia
|
60
|
+
def invoke(method, values) #:nodoc:
|
61
|
+
status, doc = invoke_transaction_web_service(method, values)
|
62
|
+
return status
|
63
|
+
end
|
64
|
+
|
65
|
+
# Register the payment, keeping our user with us
|
66
|
+
def register_with_doc(a_credit_card) #:nodoc:
|
67
|
+
raise "Invalid credit card" unless a_credit_card.valid?
|
68
|
+
params =
|
69
|
+
{
|
70
|
+
:merchantToken => @merchant.token,
|
71
|
+
:userToken => @order.customer.token,
|
72
|
+
:merchantReference => @order.reference,
|
73
|
+
:store => store_name,
|
74
|
+
:orderDescription => @order.description,
|
75
|
+
:cardNumber => a_credit_card.number,
|
76
|
+
:expiryDate => a_credit_card.expires,
|
77
|
+
:cvc2Code => a_credit_card.verification_value,
|
78
|
+
:currencyCode => "NOK",
|
79
|
+
:instanceId => "",
|
80
|
+
:amount => @order.amount.to_i, # croaks on floating point
|
81
|
+
:purchaseDate => Date.today.strftime("%Y-%m-%d"),
|
82
|
+
:isOnHold => "true",
|
83
|
+
:isPreRegistered => "false"
|
84
|
+
}
|
85
|
+
opts = []
|
86
|
+
params.each{|k,v| opts<<"#{k}=#{v}"}
|
87
|
+
|
88
|
+
values = opts.join("&")
|
89
|
+
method = "RegisterCardTransaction"
|
90
|
+
status, doc = invoke_transaction_web_service(method, values)
|
91
|
+
return status, doc
|
92
|
+
end
|
93
|
+
|
94
|
+
# Register the transaction with Cardia. Once this has been done, the amount is reserved on the users credit card, given that the the returned status says so...
|
95
|
+
def register(a_credit_card)
|
96
|
+
status, doc = register_with_doc(a_credit_card)
|
97
|
+
return status
|
98
|
+
end
|
99
|
+
|
100
|
+
def wait_until_approved #:nodoc:
|
101
|
+
(1..10).each do |n|
|
102
|
+
status = check_status
|
103
|
+
if status == TransactionStatus.approved
|
104
|
+
yield
|
105
|
+
return
|
106
|
+
end
|
107
|
+
puts n
|
108
|
+
sleep(2)
|
109
|
+
end
|
110
|
+
raise "Out of retries, Order not approved"
|
111
|
+
end
|
112
|
+
|
113
|
+
def http_connection
|
114
|
+
@http
|
115
|
+
end
|
116
|
+
|
117
|
+
def do_invoke_web_service(base_url, method, values) #:nodoc:
|
118
|
+
http = http_connection
|
119
|
+
url = base_url + method
|
120
|
+
response, body = http.post(url, values, {"Content-Type" => "application/x-www-form-urlencoded"})
|
121
|
+
response.value
|
122
|
+
return REXML::Document.new(response.body)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Register using 3DSecure. After doing this, we should redirect the customer to the location stored in @verification_address
|
126
|
+
def register_3d(a_credit_card, success_url, failure_url)
|
127
|
+
raise "No verification code supplied" if a_credit_card.verification_value.nil?
|
128
|
+
params = {
|
129
|
+
:merchantToken => @merchant.token,
|
130
|
+
:applicationIdentifier => "", # not in use
|
131
|
+
:cardNumber => a_credit_card.number,
|
132
|
+
:expiryDate => a_credit_card.expires,
|
133
|
+
:cv2Code => a_credit_card.verification_value,
|
134
|
+
:merchantReference => @order.reference,
|
135
|
+
:successfulTransactionUrl => CGI::escape(success_url),
|
136
|
+
:unsuccessfulTransactionUrl => CGI::escape(failure_url),
|
137
|
+
:authorizedNotAuthenticatedUrl => "", # not in use
|
138
|
+
:currencyCode => "NOK",
|
139
|
+
:amount => @order.amount.to_i,
|
140
|
+
:isOnHold => "true",
|
141
|
+
:paymentType => a_credit_card.payment_type
|
142
|
+
}
|
143
|
+
opts = []
|
144
|
+
params.each{|k,v| opts << "#{k}=#{v}"}
|
145
|
+
values = opts.join("&")
|
146
|
+
status, doc = invoke_teller_web_service("PrepareTransaction", values)
|
147
|
+
unless status == 1
|
148
|
+
raise doc.root.elements["Error"].text
|
149
|
+
end
|
150
|
+
address = doc.root.elements["Address"].text
|
151
|
+
guid = doc.root.elements["ReferenceGuid"].text
|
152
|
+
@verification_address = "#{address}?preparationGuid=#{guid}"
|
153
|
+
return @verification_address
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
# Cancels a transaction. A good practice is probably to have a before_destroy filter in your order that does this
|
158
|
+
def void
|
159
|
+
return invoke("VoidTransaction", "merchantToken=#{@merchant.token}&userToken=#{@order.customer.token}&merchantReference=#{@order.reference}")
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
# Credits the transaction. This is bank-speak for reversing it; giving the customer a full refund
|
164
|
+
# If you want to, you can supply the amount manually
|
165
|
+
def credit(amount=nil)
|
166
|
+
amount = @order.amount if amount.nil?
|
167
|
+
return invoke("CreditTransaction", "merchantToken=#{@merchant.token}&amount=#{amount}&merchantReference=#{@order.reference}")
|
168
|
+
end
|
169
|
+
alias_method :refund, :credit
|
170
|
+
|
171
|
+
# This method confirms payments that are "on hold". Cardia calls this RevertOnHold
|
172
|
+
def confirm!
|
173
|
+
return invoke_transaction_web_service("RevertOnHoldTransaction", "merchantToken=#{@merchant.token}&merchantReference=#{@order.reference}")
|
174
|
+
end
|
175
|
+
|
176
|
+
# This method changes the amount on a transaction
|
177
|
+
# You should probably investigate about the terms around this before actually using it
|
178
|
+
def change_amount(new_amount)
|
179
|
+
return invoke("ChangeAmount", "merchantToken=#{@merchant.token}&amount=#{new_amount}&merchantReference=#{@order.reference}")
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the transaction status as a Cardia::TransactionStatus instance
|
183
|
+
def check_status
|
184
|
+
status, doc = invoke_transaction_web_service("ReturnTransactionStatus", "merchantToken=#{@merchant.token}&merchantReference=#{@order.reference}")
|
185
|
+
response_code = doc.root.elements["ResponseCode"].text
|
186
|
+
currency_code = doc.root.elements["CurrencyCode"].text
|
187
|
+
recurring_code = doc.root.elements["RecurringCode"].text
|
188
|
+
amt = doc.root.elements["Amount"]
|
189
|
+
s = TransactionStatus.new(status)
|
190
|
+
unless amt.nil?
|
191
|
+
s.amount = Money.kroner(amt.text.to_i)
|
192
|
+
end
|
193
|
+
s.response_code = response_code.to_i
|
194
|
+
s.currency_code = currency_code
|
195
|
+
s.recurring_code = recurring_code
|
196
|
+
return s
|
197
|
+
end
|
198
|
+
|
199
|
+
def store_name #:nodoc:
|
200
|
+
"AS Juks og Bedrag"
|
201
|
+
end
|
202
|
+
|
203
|
+
def self.server_name #:nodoc:
|
204
|
+
"secure.cardia.no"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Cardia
|
2
|
+
|
3
|
+
# A very basic Customer, you probably want to roll your own
|
4
|
+
class Customer
|
5
|
+
def initialize(first_name, last_name)
|
6
|
+
@first_name, @last_name = first_name, last_name
|
7
|
+
end
|
8
|
+
|
9
|
+
# You need to generate a unique token identifying your Customer
|
10
|
+
def token
|
11
|
+
"867B5C54-B763-4D7C-B180-8766A5505656"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cardia
|
2
|
+
|
3
|
+
# A merchant is the entity who requests payments/transactions. It is identified by a merchant token, which you'll get from Cardia
|
4
|
+
class Merchant
|
5
|
+
attr_accessor :token
|
6
|
+
class << self
|
7
|
+
|
8
|
+
# The test merchant. Using this merchant, no transactions are done for real.
|
9
|
+
def test_merchant
|
10
|
+
m = self.new
|
11
|
+
m.token = "CF4B6B54-6C28-4FA3-86B0-E9A347D75C6C"
|
12
|
+
m
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create an instance with your real token
|
16
|
+
def with_token(a_token)
|
17
|
+
m = self.new
|
18
|
+
m.token = a_token
|
19
|
+
m
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/cardia/order.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Cardia
|
2
|
+
# This is the very minimum that's required in order for and Order to function. You probably have your own...
|
3
|
+
# For home baked order classes, you need to implement methods listed below
|
4
|
+
class Order
|
5
|
+
attr_reader :amount, :description, :reference
|
6
|
+
attr_accessor :customer, :status
|
7
|
+
|
8
|
+
# Creates an instance: Parameters:
|
9
|
+
# * +amount+: The amount as an integer
|
10
|
+
# * +description+: Give a describing name (not used for much...)
|
11
|
+
def initialize(amount, description)
|
12
|
+
@amount,@description = amount, description
|
13
|
+
@reference = rand(10000)
|
14
|
+
end
|
15
|
+
|
16
|
+
# You need to provide a reference that's guaranteed to be unique for your merchant
|
17
|
+
def reference
|
18
|
+
@reference
|
19
|
+
end
|
20
|
+
|
21
|
+
def compute_access_key #:nodoc:
|
22
|
+
"ello"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Callback that's called when an order is confirmed
|
26
|
+
def be_confirmed
|
27
|
+
@status = Status.confirmed
|
28
|
+
end
|
29
|
+
|
30
|
+
class Status #:nodoc:
|
31
|
+
def self.confirmed
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Cardia
|
2
|
+
# Wrapper around the result of the ReturnTransactionStatus call to Cardia
|
3
|
+
class TransactionStatus < Enum
|
4
|
+
attr_accessor :amount, :response_code, :currency_code, :recurring_code
|
5
|
+
map :approved, 1, "Transaction is approved"
|
6
|
+
map :not_approved, 2, "Transaction not approved"
|
7
|
+
map :not_registered, 3, "No transaction registered"
|
8
|
+
map :error, 4, "General error"
|
9
|
+
map :void, 5, "Transaction is approved, but voided afterwards."
|
10
|
+
|
11
|
+
# Explains the current status
|
12
|
+
def explanation
|
13
|
+
if self.response_success?
|
14
|
+
return description
|
15
|
+
end
|
16
|
+
return "#{response_message}, #{description}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Whether the transaction was successful
|
20
|
+
def response_success?
|
21
|
+
response_code == 0
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the response code as a human readable text
|
25
|
+
def response_message
|
26
|
+
result = response_code_to_string[response_code]
|
27
|
+
if result.nil?
|
28
|
+
result = "Unknown response code %s" % response_code
|
29
|
+
end
|
30
|
+
return result
|
31
|
+
end
|
32
|
+
|
33
|
+
def response_code_to_string #:nodoc:
|
34
|
+
result = {
|
35
|
+
0 => "Success",
|
36
|
+
6 => "Invalid card number",
|
37
|
+
7 => "Card is hot listed (known card used for fraud)",
|
38
|
+
17 => "Card is expired",
|
39
|
+
18 => "Invalid expiry date",
|
40
|
+
19 => "Card number is not valid",
|
41
|
+
22 => "Card type is not registered for merchant",
|
42
|
+
|
43
|
+
45 => "Amount exceeds allowed amount",
|
44
|
+
|
45
|
+
46 => "Amount is below minimum amount",
|
46
|
+
|
47
|
+
54 => "Card can not be used for internet purchases",
|
48
|
+
|
49
|
+
69 => "The bank do not authorise the payment (authorisation not OK)",
|
50
|
+
74 => "Card is rejected",
|
51
|
+
|
52
|
+
75 => "Not authorised"}
|
53
|
+
[25, 26, 27, 28, 29, 31].each do |each|
|
54
|
+
result[each] = "Card can not be used for internet purchases"
|
55
|
+
end
|
56
|
+
return result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/lib/cardia.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
require 'validateable'
|
5
|
+
require 'cgi'
|
6
|
+
require 'credit_card'
|
7
|
+
require 'rexml/document'
|
8
|
+
require 'enum'
|
9
|
+
require 'cardia/credit_card_transaction'
|
10
|
+
require 'cardia/customer'
|
11
|
+
require 'cardia/merchant'
|
12
|
+
require 'cardia/order'
|
13
|
+
require 'cardia/transaction_status'
|
14
|
+
require 'cardia/version'
|
15
|
+
$:.unshift File.dirname(__FILE__)
|
16
|
+
|
17
|
+
module Cardia
|
18
|
+
|
19
|
+
end
|