smart_pay 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/README.md +43 -0
- data/Rakefile +26 -0
- data/lib/smart_pay.rb +21 -0
- data/lib/smart_pay/hmac_calculator.rb +28 -0
- data/lib/smart_pay/request.rb +25 -0
- data/lib/smart_pay/response.rb +22 -0
- data/lib/smart_pay/version.rb +4 -0
- data/test/request_test.rb +33 -0
- data/test/response_test.rb +20 -0
- metadata +109 -0
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
## SmartPay
|
2
|
+
|
3
|
+
Provides HMAC signing and verification when passing parameters
|
4
|
+
to and from Barclays SmartPay hosted payment pages.
|
5
|
+
|
6
|
+
More information can be found in the [SmartPay hosted payment process integration guide](http://www.barclaycard.com/smartpay/documentation/pdf/SmartPay_HPP_IntegrationGuide.pdf)
|
7
|
+
|
8
|
+
### Usage
|
9
|
+
```
|
10
|
+
req = SmartPay::Request.new("Kah942*$7sdp0)", {
|
11
|
+
:merchant_reference => "Internet Order 12345",
|
12
|
+
:payment_amount => 10000,
|
13
|
+
:currency_code => "GBP",
|
14
|
+
:ship_before_date => "2007-10-20",
|
15
|
+
:skin_code => "4aD37dJA",
|
16
|
+
:merchant_account => "TestMerchant",
|
17
|
+
:shopper_locale => "en_GB",
|
18
|
+
:order_data => "H4sIAAAAAAAAALMpsOPlCkssyswvLVZIz89PKVZIzEtRKE4tKstMTi3W4+Wy0S+wAwDOGUCXJgAAAA==",
|
19
|
+
:session_validity => "2007-10-11T11:00:00Z",
|
20
|
+
:merchant_signature => "yARtfsxD47jeXzOlEyZ0j3pg="
|
21
|
+
})
|
22
|
+
req.hmac_signature # => 'x58ZcRVL1H6y+XSeBGrySJ9ACVo=\n'
|
23
|
+
|
24
|
+
|
25
|
+
res = SmartPay::Response.new("Kah942*$7sdp0)", {
|
26
|
+
:merchant_reference => "Internet Order 12345",
|
27
|
+
:skin_code => "4aD37dJA",
|
28
|
+
:shopper_locale => "en_GB",
|
29
|
+
:auth_result => "AUTHORISED",
|
30
|
+
:psp_reference => "1211992213193029",
|
31
|
+
:merchant_sig => "ytt3QxWoEhAskUzUne0P5VA9lPw="
|
32
|
+
})
|
33
|
+
res.verified # => true
|
34
|
+
```
|
35
|
+
|
36
|
+
### Contributing
|
37
|
+
|
38
|
+
1. Fork it
|
39
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
41
|
+
4. Run the tests (`bundle exec rake`)
|
42
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
43
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
Bundler::GemHelper.install_tasks
|
10
|
+
|
11
|
+
require 'rake/testtask'
|
12
|
+
|
13
|
+
require 'gem_publisher'
|
14
|
+
Rake::TestTask.new(:test) do |t|
|
15
|
+
t.libs << 'lib'
|
16
|
+
t.libs << 'test'
|
17
|
+
t.pattern = 'test/**/*_test.rb'
|
18
|
+
t.verbose = false
|
19
|
+
end
|
20
|
+
|
21
|
+
task :publish_gem do |t|
|
22
|
+
gem = GemPublisher.publish_if_updated("smart_pay.gemspec", :rubygems)
|
23
|
+
puts "Published #{gem}" if gem
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :test
|
data/lib/smart_pay.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'smart_pay/request'
|
2
|
+
require 'smart_pay/response'
|
3
|
+
|
4
|
+
module SmartPay
|
5
|
+
|
6
|
+
def self.test_mode=(test_mode)
|
7
|
+
@@test_mode = test_mode
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.test_mode
|
11
|
+
!!@@test_mode
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.ordered_parameters(ordered_keys, parameters)
|
15
|
+
[].tap do |ary|
|
16
|
+
ordered_keys.each do |k|
|
17
|
+
ary << parameters[k] if parameters[k]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module SmartPay
|
5
|
+
class HmacCalculator
|
6
|
+
def initialize(psk, parameters)
|
7
|
+
@psk = psk
|
8
|
+
@parameters = parameters
|
9
|
+
end
|
10
|
+
|
11
|
+
def signature
|
12
|
+
raise_if_key_missing
|
13
|
+
hmac = OpenSSL::HMAC.digest('sha1', @psk, @parameters.join)
|
14
|
+
Base64.encode64(hmac)
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify(merchant_sig)
|
18
|
+
raise_if_key_missing
|
19
|
+
"#{merchant_sig}\n" == signature
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def raise_if_key_missing
|
25
|
+
raise "missing or empty pre-shared key" unless @psk && @psk.length > 0
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'hmac_calculator'
|
2
|
+
|
3
|
+
module SmartPay
|
4
|
+
class Request
|
5
|
+
|
6
|
+
TEST_URL = "https://test.barclaycardsmartpay.com/hpp/pay.shtml"
|
7
|
+
LIVE_URL = "https://live.barclaycardsmartpay.com/hpp/pay.shtml"
|
8
|
+
ORDERED_KEYS = [:payment_amount, :currency_code, :ship_before_date, :merchant_reference,
|
9
|
+
:skin_code, :merchant_account, :session_validity, :shopper_email, :shopper_reference,
|
10
|
+
:allowed_methods, :blocked_methods, :shopper_statement, :billing_address_type]
|
11
|
+
|
12
|
+
def initialize(shared_key, parameters = {})
|
13
|
+
@shared_key = shared_key
|
14
|
+
@parameters = SmartPay.ordered_parameters(ORDERED_KEYS, parameters)
|
15
|
+
end
|
16
|
+
|
17
|
+
def hmac_signature
|
18
|
+
SmartPay::HmacCalculator.new(@shared_key, @parameters).signature
|
19
|
+
end
|
20
|
+
|
21
|
+
def request_url
|
22
|
+
SmartPay.test_mode ? TEST_URL : LIVE_URL
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'hmac_calculator'
|
2
|
+
|
3
|
+
module SmartPay
|
4
|
+
class Response
|
5
|
+
|
6
|
+
attr_reader :parameters
|
7
|
+
|
8
|
+
ORDERED_KEYS = [:auth_result, :psp_reference, :merchant_reference,
|
9
|
+
:skin_code, :merchant_return_data]
|
10
|
+
|
11
|
+
def initialize(shared_key, parameters = {})
|
12
|
+
raise "Response signature not found" unless parameters.has_key?(:merchant_sig)
|
13
|
+
@shared_key = shared_key
|
14
|
+
@merchant_sig = parameters.delete(:merchant_sig)
|
15
|
+
@parameters = SmartPay.ordered_parameters(ORDERED_KEYS, parameters)
|
16
|
+
end
|
17
|
+
|
18
|
+
def verified
|
19
|
+
SmartPay::HmacCalculator.new(@shared_key, @parameters).verify(@merchant_sig)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe SmartPay::Request do
|
4
|
+
before do
|
5
|
+
SmartPay.test_mode = true
|
6
|
+
@shared_key = "Kah942*$7sdp0)"
|
7
|
+
@parameters = {
|
8
|
+
:merchant_reference => "Internet Order 12345",
|
9
|
+
:payment_amount => 10000,
|
10
|
+
:currency_code => "GBP",
|
11
|
+
:ship_before_date => "2007-10-20",
|
12
|
+
:skin_code => "4aD37dJA",
|
13
|
+
:merchant_account => "TestMerchant",
|
14
|
+
:shopper_locale => "en_GB",
|
15
|
+
:order_data => "H4sIAAAAAAAAALMpsOPlCkssyswvLVZIz89PKVZIzEtRKE4tKstMTi3W4+Wy0S+wAwDOGUCXJgAAAA==",
|
16
|
+
:session_validity => "2007-10-11T11:00:00Z",
|
17
|
+
:merchant_signature => "yARtfsxD47jeXzOlEyZ0j3pg="
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Based on example in http://www.barclaycard.com/smartpay/documentation/pdf/SmartPay_HPP_IntegrationGuide.pdf
|
22
|
+
it "should calculate the correct hmac signature" do
|
23
|
+
request = SmartPay::Request.new(@shared_key, @parameters)
|
24
|
+
assert_equal "x58ZcRVL1H6y+XSeBGrySJ9ACVo=\n", request.hmac_signature
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should use the appropriate request URL" do
|
28
|
+
SmartPay.test_mode = false
|
29
|
+
assert_equal SmartPay::Request::LIVE_URL, SmartPay::Request.new(nil).request_url
|
30
|
+
SmartPay.test_mode = true
|
31
|
+
assert_equal SmartPay::Request::TEST_URL, SmartPay::Request.new(nil).request_url
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe SmartPay::Response do
|
4
|
+
before do
|
5
|
+
SmartPay.test_mode = true
|
6
|
+
@shared_key = "Kah942*$7sdp0)"
|
7
|
+
@parameters = {
|
8
|
+
:merchant_reference => "Internet Order 12345",
|
9
|
+
:skin_code => "4aD37dJA",
|
10
|
+
:shopper_locale => "en_GB",
|
11
|
+
:auth_result => "AUTHORISED",
|
12
|
+
:psp_reference => "1211992213193029",
|
13
|
+
:merchant_sig => "ytt3QxWoEhAskUzUne0P5VA9lPw="
|
14
|
+
}
|
15
|
+
end
|
16
|
+
it "should verify the response parameters" do
|
17
|
+
response = SmartPay::Response.new(@shared_key, @parameters)
|
18
|
+
assert response.verified, "Merchant signature is incorrect"
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smart_pay
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Steve Laing
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rdoc
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.12'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.12'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 10.1.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 10.1.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: gem_publisher
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.0
|
62
|
+
description:
|
63
|
+
email: steve.laing@digital.cabinet-office.gov.uk
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- lib/smart_pay.rb
|
69
|
+
- lib/smart_pay/hmac_calculator.rb
|
70
|
+
- lib/smart_pay/version.rb
|
71
|
+
- lib/smart_pay/request.rb
|
72
|
+
- lib/smart_pay/response.rb
|
73
|
+
- Rakefile
|
74
|
+
- README.md
|
75
|
+
- test/request_test.rb
|
76
|
+
- test/response_test.rb
|
77
|
+
homepage:
|
78
|
+
licenses: []
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
hash: 3111097971645311082
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
hash: 3111097971645311082
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.8.23
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Ruby library for handling Barclaycard Smartpay requests and responses
|
107
|
+
test_files:
|
108
|
+
- test/request_test.rb
|
109
|
+
- test/response_test.rb
|