bank_audi 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +7 -0
- data/README.markdown +27 -0
- data/Rakefile +1 -0
- data/bank_audi.gemspec +29 -0
- data/config/bank_audi.yml +4 -0
- data/lib/bank_audi.rb +137 -0
- data/lib/bank_audi/version.rb +3 -0
- data/spec/bank_audi_spec.rb +142 -0
- data/spec/spec_helper.rb +6 -0
- metadata +57 -0
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
BANK AUDI
|
2
|
+
=========
|
3
|
+
|
4
|
+
Bank Audi is the largest bank of Lebanon. This gem help to integrate with bank system
|
5
|
+
(Audi Virtual Payment Client. It is similiar to PayPal)
|
6
|
+
|
7
|
+
MAIN STEPS
|
8
|
+
----------
|
9
|
+
|
10
|
+
1. Merchant Form Submission
|
11
|
+
2. Pre-Payment Process
|
12
|
+
3. Payment Process
|
13
|
+
4. Merchant Response Code
|
14
|
+
|
15
|
+
|
16
|
+
BASIC MOMENTS
|
17
|
+
-------------
|
18
|
+
|
19
|
+
1. Request create `BankAudi::Request.new(attributes)`.
|
20
|
+
2. Attributes as secret_code, access_code, merchant, url (where you create request) you
|
21
|
+
should set in config/bank_audi.yml
|
22
|
+
3. You should set :merchant_txn_ref, order_info, amount & return_url
|
23
|
+
4. You can update update request `request.attributes = {}; request.amount = 100;`
|
24
|
+
5. Get request url (with params) `request.full_url`
|
25
|
+
6. Response create `BankAudi::Response.new(attributes)`
|
26
|
+
7. Check valid of response `response.valid?` (The invalid reason are bad secure hash & bad response code)
|
27
|
+
8. You can get messafe of errors if your object (request or response) is invalid? `object.errors`
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bank_audi.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "bank_audi/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "bank_audi"
|
7
|
+
s.version = BankAudi::VERSION
|
8
|
+
s.authors = ["m.yermolovich"]
|
9
|
+
s.email = ["m.yermolovich@dev1team.net"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{BANK AUDI (operations with money)}
|
12
|
+
s.description = %q{
|
13
|
+
Bank Audi is Lebanon's largest bank.
|
14
|
+
And this gem created to help some
|
15
|
+
make money transactions & integration
|
16
|
+
with its system.
|
17
|
+
}
|
18
|
+
|
19
|
+
s.rubyforge_project = "bank_audi"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
|
26
|
+
# specify any dependencies here; for example:
|
27
|
+
# s.add_development_dependency "rspec"
|
28
|
+
# s.add_runtime_dependency "rest-client"
|
29
|
+
end
|
data/lib/bank_audi.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require "bank_audi/version"
|
2
|
+
require 'active_support/all'
|
3
|
+
require 'yaml'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module BankAudi
|
7
|
+
OPTIONS = YAML.load_file('config/bank_audi.yml')
|
8
|
+
|
9
|
+
class Request
|
10
|
+
attr_reader :secret_code, :access_code, :merchant, :url, :errors
|
11
|
+
attr_accessor :merchant_txn_ref, :order_info, :amount, :return_url
|
12
|
+
alias :merchant_id :merchant
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@secret_code, @access_code, @merchant, @url =
|
16
|
+
OPTIONS['secret_code'], OPTIONS['access_code'], OPTIONS['merchant'], OPTIONS['url']
|
17
|
+
@merchant_txn_ref, @order_info, @amount, @return_url =
|
18
|
+
options[:merchant_txn_ref], options[:order_info], options[:amount], options[:return_url]
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid?
|
22
|
+
@errors = {}
|
23
|
+
attributes_names.each do |attribute|
|
24
|
+
if self.send(attribute).blank?
|
25
|
+
@errors[attribute] = "can't be blank"
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def invalid?
|
32
|
+
!valid?
|
33
|
+
end
|
34
|
+
|
35
|
+
def full_url
|
36
|
+
return nil if invalid?
|
37
|
+
params = String.new
|
38
|
+
{ 'accessCode' => @access_code, 'merchTxnRef' => @merchant_txn_ref, 'merchant' => @merchant,
|
39
|
+
'orderInfo' => @order_info, 'amount' => @amount, 'returnURL' => @return_url }.each do |name, value|
|
40
|
+
params << '&' if params.present?
|
41
|
+
params << (CGI::escape(name) + '=' + CGI::escape(value.to_s))
|
42
|
+
end
|
43
|
+
params << '&vpc_SecureHash=' + vpc_secure_hash.to_s
|
44
|
+
@url + '?' + params
|
45
|
+
end
|
46
|
+
|
47
|
+
def attributes
|
48
|
+
value = {}
|
49
|
+
attributes_names.each do |attribute|
|
50
|
+
value[attribute.to_sym] = self.send(attribute)
|
51
|
+
end
|
52
|
+
value
|
53
|
+
end
|
54
|
+
|
55
|
+
def attributes=(value = {})
|
56
|
+
value.each do |name, attr_value|
|
57
|
+
self.send("#{name}=", attr_value)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def attributes_names
|
63
|
+
%w(secret_code access_code merchant url merchant_txn_ref order_info amount return_url)
|
64
|
+
end
|
65
|
+
|
66
|
+
def vpc_secure_hash
|
67
|
+
Digest::MD5.hexdigest(@secret_code.to_s + @access_code.to_s + @amount.to_s + @merchant_txn_ref.to_s +
|
68
|
+
@merchant.to_s + @order_info.to_s + @return_url.to_s).upcase
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Response
|
73
|
+
attr_reader :secret_code, :errors
|
74
|
+
attr_accessor :attributes
|
75
|
+
|
76
|
+
def initialize(options = {})
|
77
|
+
@secret_code, @attributes = OPTIONS['secret_code'], HashWithIndifferentAccess.new(options)
|
78
|
+
end
|
79
|
+
|
80
|
+
def attributes=(options = {})
|
81
|
+
@attributes = HashWithIndifferentAccess.new(options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def valid?
|
85
|
+
@errors = {}
|
86
|
+
valid_vpc_txn_response_code? && valid_vpc_secure_hash?
|
87
|
+
end
|
88
|
+
|
89
|
+
def vpc_secure_hash
|
90
|
+
(@attributes[:vpc_secure_hash] || @attributes[:vpc_SecureHash]).upcase
|
91
|
+
end
|
92
|
+
|
93
|
+
def vpc_txn_response_code
|
94
|
+
@attributes[:vpc_txn_response_code] || @attributes[:vpc_TxnResponseCode]
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def valid_vpc_secure_hash?
|
99
|
+
params = @attributes.select { |k,v| !%w(vpc_secure_hash vpc_SecureHash).include?(k.to_s) }
|
100
|
+
vpc_secure_hash_params = @secret_code
|
101
|
+
sort_keys(params.keys).each do |key|
|
102
|
+
vpc_secure_hash_params += @attributes[key].to_s
|
103
|
+
end
|
104
|
+
if Digest::MD5.hexdigest(vpc_secure_hash_params).upcase == vpc_secure_hash
|
105
|
+
true
|
106
|
+
else
|
107
|
+
@errors[:vpc_secure_hash] = 'invalid'
|
108
|
+
false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def valid_vpc_txn_response_code?
|
113
|
+
if vpc_txn_response_code == '0'
|
114
|
+
true
|
115
|
+
else
|
116
|
+
@errors[:vpc_txn_response_code] = "bad code = #{vpc_txn_response_code}"
|
117
|
+
false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def sort_keys(keys)
|
122
|
+
keys.sort do |a,b|
|
123
|
+
size = [a.length, b.length].min
|
124
|
+
compare = 0
|
125
|
+
size.times do |i|
|
126
|
+
compare = (a[i] <=> b[i])
|
127
|
+
break if compare != 0
|
128
|
+
end
|
129
|
+
if compare != 0
|
130
|
+
compare
|
131
|
+
else
|
132
|
+
(a.length < b.length) ? 1 : -1
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BankAudi do
|
4
|
+
describe 'Request' do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@request = BankAudi::Request.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid(request)
|
11
|
+
request.merchant_txn_ref, request.order_info, request.amount, request.return_url =
|
12
|
+
'merchant-txn-ref', 'order-info', 100, 'http://www.google.com'
|
13
|
+
request
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should initialize with default attributes' do
|
17
|
+
[:secret_code, :access_code, :merchant, :url].each do |attribute|
|
18
|
+
@request.send(attribute).should_not be_blank
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should initialize with options' do
|
23
|
+
request = BankAudi::Request.new :merchant_txn_ref => 'merchant-txn-ref', :order_info => 'order-info',
|
24
|
+
:amount => 100, :return_url => 'http://www.google.com'
|
25
|
+
[:merchant_txn_ref, :order_info, :amount, :return_url].each do |attribute|
|
26
|
+
request.send(attribute).should_not be_blank
|
27
|
+
end
|
28
|
+
request.should be_valid
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'merchant_id is synonym of merchant' do
|
32
|
+
@request.merchant_id.should eq(@request.merchant)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should valid' do
|
36
|
+
valid(@request).should be_valid
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should invalid' do
|
40
|
+
@request.should_not be_valid
|
41
|
+
[:merchant_txn_ref, :order_info, :amount, :return_url].each do |attribute|
|
42
|
+
request = valid(@request)
|
43
|
+
request.send("#{attribute}=", nil)
|
44
|
+
request.should_not be_valid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should return errors (method errors)' do
|
49
|
+
request = valid(@request)
|
50
|
+
request.amount = nil
|
51
|
+
request.should_not be_valid
|
52
|
+
request.errors.first.should_not be_blank
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return full url' do
|
56
|
+
url = valid(@request).full_url
|
57
|
+
params = CGI::parse(url)
|
58
|
+
params['vpc_SecureHash'].first.should eq('A37A981709D939C0E04B640E26677471')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should return attributes (method attributes)' do
|
62
|
+
default_attributes = {
|
63
|
+
:secret_code => 'XXXXXX', :access_code => 'XXXXXX', :merchant => 'XXXXXX',
|
64
|
+
:url => 'https://gw1.audicards.com/TPGWeb/payment/prepayment.action'
|
65
|
+
}
|
66
|
+
|
67
|
+
@request.attributes.should eq(
|
68
|
+
default_attributes.merge(:merchant_txn_ref => nil, :order_info => nil, :amount => nil,
|
69
|
+
:return_url => nil)
|
70
|
+
)
|
71
|
+
|
72
|
+
valid(@request).attributes.should eq(
|
73
|
+
default_attributes.merge(:merchant_txn_ref => 'merchant-txn-ref', :order_info => 'order-info',
|
74
|
+
:amount => 100, :return_url => 'http://www.google.com')
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set attirubtes (method attributes=)' do
|
79
|
+
@request.attributes = { :merchant_txn_ref => 'merchant-txn-ref', :order_info => 'order-info',
|
80
|
+
:amount => 100, :return_url => 'http://www.google.com' }
|
81
|
+
@request.attributes.should eq(
|
82
|
+
valid(@request).attributes
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'Responce' do
|
88
|
+
|
89
|
+
before :each do
|
90
|
+
@response = BankAudi::Response.new
|
91
|
+
end
|
92
|
+
|
93
|
+
def valid(response)
|
94
|
+
response.attributes = { :access_code => 'XXXXXX', :amount => 100, :merchant_txn_ref => 'merchant-txn-ref',
|
95
|
+
:merchant => 'XXXXXX', :order_info => 'order-info', :return_url => 'http://www.google.com',
|
96
|
+
:vpc_secure_hash => 'B2384E5659611034CFFC95842C66A4BA', :vpc_txn_response_code => '0' }
|
97
|
+
response
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should initialize with default attributes' do
|
101
|
+
[:secret_code].each do |attribute|
|
102
|
+
@response.send(attribute).should_not be_blank
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should initialize with options' do
|
107
|
+
response = BankAudi::Response.new :some_attribute => 'some-attribute'
|
108
|
+
response.attributes.should_not be_blank
|
109
|
+
response.attributes.should eq({ 'some_attribute' => 'some-attribute' })
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should be valid' do
|
113
|
+
valid(@response).should be_valid
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should be invalid' do
|
117
|
+
@response.should_not be_valid
|
118
|
+
|
119
|
+
response = valid(@response)
|
120
|
+
response.attributes[:vpc_txn_response_code] = 'M'
|
121
|
+
response.should_not be_valid
|
122
|
+
|
123
|
+
response = valid(@response)
|
124
|
+
response.attributes[:amount] = 200
|
125
|
+
response.should_not be_valid
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should return errors (method errors)' do
|
129
|
+
response = valid(@response)
|
130
|
+
response.attributes[:vpc_txn_response_code] = 'Y'
|
131
|
+
response.should_not be_valid
|
132
|
+
response.errors.first.should_not be_blank
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should return value by different key type (string or symbol)' do
|
136
|
+
response = valid(@response)
|
137
|
+
response.attributes['vpc_txn_response_code'].should_not be_blank
|
138
|
+
response.attributes[:vpc_txn_response_code].should_not be_blank
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bank_audi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- m.yermolovich
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! "\n Bank Audi is Lebanon's largest bank.\n And
|
15
|
+
this gem created to help some\n make money transactions & integration\n
|
16
|
+
\ with its system.\n "
|
17
|
+
email:
|
18
|
+
- m.yermolovich@dev1team.net
|
19
|
+
executables: []
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- .gitignore
|
24
|
+
- Gemfile
|
25
|
+
- README.markdown
|
26
|
+
- Rakefile
|
27
|
+
- bank_audi.gemspec
|
28
|
+
- config/bank_audi.yml
|
29
|
+
- lib/bank_audi.rb
|
30
|
+
- lib/bank_audi/version.rb
|
31
|
+
- spec/bank_audi_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
homepage: ''
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project: bank_audi
|
53
|
+
rubygems_version: 1.8.24
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: BANK AUDI (operations with money)
|
57
|
+
test_files: []
|