dbalatero-fpswax 0.0.1 → 0.0.2
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/Rakefile +1 -0
- data/VERSION.yml +1 -1
- data/lib/fpswax/mixins/hmac_signature.rb +1 -1
- data/lib/fpswax/pay_response.rb +34 -0
- data/lib/fpswax/response.rb +3 -3
- data/lib/fpswax/session.rb +59 -2
- data/lib/fpswax.rb +6 -0
- data/spec/fixtures/pay/cancelled.xml +2 -0
- data/spec/fixtures/pay/error.xml +2 -0
- data/spec/fixtures/pay/failure.xml +2 -0
- data/spec/fixtures/pay/pending.xml +2 -0
- data/spec/fixtures/pay/reserved.xml +2 -0
- data/spec/fixtures/pay/success.xml +2 -0
- data/spec/fpswax/mixins/hmac_signature_spec.rb +13 -0
- data/spec/fpswax/pay_response_spec.rb +44 -0
- data/spec/fpswax/response_spec.rb +5 -0
- data/spec/fpswax/session_spec.rb +41 -3
- data/spec/spec_helper.rb +11 -0
- metadata +24 -4
data/Rakefile
CHANGED
@@ -11,6 +11,7 @@ begin
|
|
11
11
|
gem.authors = ["David Balatero"]
|
12
12
|
|
13
13
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
gem.add_dependency('nokogiri', '>= 1.2.3')
|
14
15
|
end
|
15
16
|
rescue LoadError
|
16
17
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
data/VERSION.yml
CHANGED
@@ -6,7 +6,7 @@ module Fpswax
|
|
6
6
|
module HmacSignature
|
7
7
|
private
|
8
8
|
def generate_signature_for(params, secret_key)
|
9
|
-
query = params.sort_by { |k,v| k.downcase }
|
9
|
+
query = params.sort_by { |k,v| k.to_s.downcase }
|
10
10
|
digest = OpenSSL::Digest::Digest.new('sha1')
|
11
11
|
hmac = OpenSSL::HMAC.digest(digest, secret_key, query.to_s)
|
12
12
|
encoded = Base64.encode64(hmac).chomp
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fpswax
|
2
|
+
class PayResponse < Response
|
3
|
+
attr_reader :transaction_id
|
4
|
+
attr_reader :transaction_status
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
super(xml)
|
8
|
+
if valid?
|
9
|
+
@transaction_id = xml.css('PayResult TransactionId')[0].content rescue nil
|
10
|
+
@transaction_status = xml.css('PayResult TransactionStatus')[0].content rescue nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def cancelled?
|
15
|
+
@transaction_status == 'Cancelled'
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure?
|
19
|
+
@transaction_status == 'Failure'
|
20
|
+
end
|
21
|
+
|
22
|
+
def pending?
|
23
|
+
@transaction_status == 'Pending'
|
24
|
+
end
|
25
|
+
|
26
|
+
def reserved?
|
27
|
+
@transaction_status == 'Reserved'
|
28
|
+
end
|
29
|
+
|
30
|
+
def success?
|
31
|
+
@transaction_status == 'Success'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/fpswax/response.rb
CHANGED
@@ -10,14 +10,14 @@ module Fpswax
|
|
10
10
|
end
|
11
11
|
|
12
12
|
if @errors.empty?
|
13
|
-
@request_id = xml.css('RequestId')[0].content
|
13
|
+
@request_id = xml.css('RequestId')[0].content rescue nil
|
14
14
|
else
|
15
|
-
@request_id = xml.css('RequestID')[0].content
|
15
|
+
@request_id = xml.css('RequestID')[0].content rescue nil
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
def valid?
|
20
|
-
@errors.empty?
|
20
|
+
@request_id && @errors.empty?
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/fpswax/session.rb
CHANGED
@@ -7,16 +7,25 @@ module Fpswax
|
|
7
7
|
|
8
8
|
include Mixins::HmacSignature
|
9
9
|
|
10
|
+
attr_accessor :logger
|
11
|
+
|
10
12
|
def initialize(access_key, secret_key, sandbox = true)
|
11
13
|
@access_key = access_key
|
12
14
|
@secret_key = secret_key
|
13
15
|
@sandbox = sandbox
|
16
|
+
|
17
|
+
@logger = Logger.new(STDOUT)
|
18
|
+
@logger.level = Logger::WARN
|
14
19
|
end
|
15
20
|
|
16
21
|
def in_sandbox?
|
17
22
|
@sandbox
|
18
23
|
end
|
19
24
|
|
25
|
+
def fps_url
|
26
|
+
@sandbox ? 'https://fps.sandbox.amazonaws.com' : 'https://fps.amazonaws.com'
|
27
|
+
end
|
28
|
+
|
20
29
|
def api_version
|
21
30
|
API_VERSION
|
22
31
|
end
|
@@ -31,12 +40,60 @@ module Fpswax
|
|
31
40
|
validate_required?(params,
|
32
41
|
:CallerReference,
|
33
42
|
:SenderTokenId,
|
34
|
-
:TransactionAmount
|
43
|
+
:"TransactionAmount.CurrencyCode",
|
44
|
+
:"TransactionAmount.Value")
|
35
45
|
|
36
|
-
|
46
|
+
get_response(:Pay, PayResponse, params)
|
37
47
|
end
|
38
48
|
|
39
49
|
private
|
50
|
+
def get_response(action, response_klass, params)
|
51
|
+
add_params_for_request!(action, params)
|
52
|
+
response = self.class.post(fps_url,
|
53
|
+
:params => params)
|
54
|
+
|
55
|
+
@logger.debug("get_response") {
|
56
|
+
"Got XML response:\n#{response.body}"
|
57
|
+
}
|
58
|
+
|
59
|
+
response_klass.new(Nokogiri::XML(response.body))
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.post(url, options = {})
|
63
|
+
url = URI.parse(url) if url.is_a?(String)
|
64
|
+
conn = Net::HTTP.new(url.host, url.port)
|
65
|
+
if conn.port == 443
|
66
|
+
conn.use_ssl = true
|
67
|
+
end
|
68
|
+
|
69
|
+
req = Net::HTTP::Post.new(url.request_uri)
|
70
|
+
req.form_data = options[:params]
|
71
|
+
|
72
|
+
conn.start do |http|
|
73
|
+
http.request(req)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_params_for_request!(action, params)
|
78
|
+
# Required params for all requests:
|
79
|
+
# http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/CommonRequestParameters.html
|
80
|
+
params.merge!(:Action => action,
|
81
|
+
:AWSAccessKeyId => @access_key,
|
82
|
+
:SignatureVersion => 1,
|
83
|
+
:Timestamp => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
84
|
+
:Version => api_version)
|
85
|
+
|
86
|
+
# Generate an HMAC signature.
|
87
|
+
signature = generate_signature_for(params, @secret_key)
|
88
|
+
params[:Signature] = signature
|
89
|
+
|
90
|
+
@logger.debug('add_params_for_request!') do
|
91
|
+
"Params for request (#{action}): #{params.inspect}"
|
92
|
+
end
|
93
|
+
|
94
|
+
params
|
95
|
+
end
|
96
|
+
|
40
97
|
def validate_required?(hash, *args)
|
41
98
|
args.each do |arg|
|
42
99
|
raise(ParameterRequired, "This method requires #{arg} to be passed in!") if !hash[arg]
|
data/lib/fpswax.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
2
2
|
|
3
|
+
require 'logger'
|
3
4
|
require 'openssl'
|
4
5
|
require 'nokogiri'
|
6
|
+
require 'net/http'
|
7
|
+
require 'net/https'
|
8
|
+
require 'uri'
|
5
9
|
|
6
10
|
require 'fpswax/mixins/hmac_signature'
|
7
11
|
|
@@ -10,5 +14,7 @@ require 'fpswax/ipn_request'
|
|
10
14
|
require 'fpswax/response'
|
11
15
|
require 'fpswax/session'
|
12
16
|
|
17
|
+
require 'fpswax/pay_response'
|
18
|
+
|
13
19
|
module Fpswax
|
14
20
|
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><PayResult><TransactionId>145ST343M4FVUENSE545EV1BL7H6OU421QP</TransactionId><TransactionStatus>Cancelled</TransactionStatus></PayResult><ResponseMetadata><RequestId>49da36a0-732a-4180-b0dd-c22fe2e0dd0b:0</RequestId></ResponseMetadata></PayResponse>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><PayResult><TransactionId>145ST343M4FVUENSE545EV1BL7H6OU421QP</TransactionId><TransactionStatus>Failure</TransactionStatus></PayResult><ResponseMetadata><RequestId>49da36a0-732a-4180-b0dd-c22fe2e0dd0b:0</RequestId></ResponseMetadata></PayResponse>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><PayResult><TransactionId>145ST343M4FVUENSE545EV1BL7H6OU421QP</TransactionId><TransactionStatus>Pending</TransactionStatus></PayResult><ResponseMetadata><RequestId>49da36a0-732a-4180-b0dd-c22fe2e0dd0b:0</RequestId></ResponseMetadata></PayResponse>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><PayResult><TransactionId>145ST343M4FVUENSE545EV1BL7H6OU421QP</TransactionId><TransactionStatus>Reserved</TransactionStatus></PayResult><ResponseMetadata><RequestId>49da36a0-732a-4180-b0dd-c22fe2e0dd0b:0</RequestId></ResponseMetadata></PayResponse>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><PayResult><TransactionId>145ST343M4FVUENSE545EV1BL7H6OU421QP</TransactionId><TransactionStatus>Success</TransactionStatus></PayResult><ResponseMetadata><RequestId>49da36a0-732a-4180-b0dd-c22fe2e0dd0b:0</RequestId></ResponseMetadata></PayResponse>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Fpswax::Mixins::HmacSignature do
|
4
|
+
include Fpswax::Mixins::HmacSignature
|
5
|
+
|
6
|
+
describe "generate_signature_for" do
|
7
|
+
it "should accept symboled keys" do
|
8
|
+
lambda {
|
9
|
+
generate_signature_for({:key1 => 'ok'}, 'my key')
|
10
|
+
}.should_not raise_error
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Fpswax::PayResponse do
|
4
|
+
it "should be a Response" do
|
5
|
+
pay = Fpswax::PayResponse.new(mock_xml)
|
6
|
+
pay.should be_a_kind_of(Fpswax::Response)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should handle errors correctly" do
|
10
|
+
pay = Fpswax::PayResponse.new(fixture_raw_xml('pay/error.xml'))
|
11
|
+
pay.should_not be_valid
|
12
|
+
pay.errors.should have(1).thing
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "any pay response" do
|
16
|
+
before(:each) do
|
17
|
+
@pay = Fpswax::PayResponse.new(fixture_raw_xml('pay/pending.xml'))
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have its transaction status" do
|
21
|
+
@pay.transaction_status.should == 'Pending'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have its transaction ID" do
|
25
|
+
@pay.transaction_id.should == '145ST343M4FVUENSE545EV1BL7H6OU421QP'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
['cancelled', 'failure', 'pending', 'reserved', 'success'].each do |status|
|
30
|
+
describe "a pending pay response" do
|
31
|
+
before(:each) do
|
32
|
+
@pay = Fpswax::PayResponse.new(fixture_raw_xml("pay/#{status}.xml"))
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be valid" do
|
36
|
+
@pay.should be_valid
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be #{status}" do
|
40
|
+
@pay.send("#{status}?".to_sym).should be_true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -31,5 +31,10 @@ describe Fpswax::Response do
|
|
31
31
|
response = Fpswax::Response.new(xml)
|
32
32
|
response.should_not be_valid
|
33
33
|
end
|
34
|
+
|
35
|
+
it "should be false if there was no parsed request id" do
|
36
|
+
response = Fpswax::Response.new(mock_xml)
|
37
|
+
response.should_not be_valid
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
data/spec/fpswax/session_spec.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
3
|
describe Fpswax::Session do
|
4
|
+
before(:each) do
|
5
|
+
FakeWeb.clean_registry
|
6
|
+
end
|
7
|
+
|
4
8
|
describe "initialize" do
|
5
9
|
it "should take an access key, private key" do
|
6
10
|
lambda {
|
@@ -45,14 +49,18 @@ describe Fpswax::Session do
|
|
45
49
|
@valid_params = {
|
46
50
|
:CallerReference => 'a',
|
47
51
|
:SenderTokenId => 'b',
|
48
|
-
:TransactionAmount => '
|
52
|
+
:"TransactionAmount.CurrencyCode" => 'USD',
|
53
|
+
:"TransactionAmount.Value" => 'c'
|
49
54
|
}
|
50
55
|
end
|
51
56
|
|
52
57
|
it "should return a PayResponse" do
|
53
|
-
|
58
|
+
FakeWeb.register_uri(:post,
|
59
|
+
'https://fps.sandbox.amazonaws.com:443/',
|
60
|
+
:file => fixture_path('pay/success.xml'))
|
54
61
|
response = @session.pay(@valid_params)
|
55
|
-
response.should be_an_instance_of(PayResponse)
|
62
|
+
response.should be_an_instance_of(Fpswax::PayResponse)
|
63
|
+
response.should be_valid
|
56
64
|
end
|
57
65
|
|
58
66
|
describe "should validate parameters" do
|
@@ -72,5 +80,35 @@ describe Fpswax::Session do
|
|
72
80
|
}.should_not raise_error(Fpswax::Session::ParameterRequired)
|
73
81
|
end
|
74
82
|
end
|
83
|
+
|
84
|
+
describe "fps_url" do
|
85
|
+
it "should point at the production API if we are in production" do
|
86
|
+
session = Fpswax::Session.new('a', 'b', false)
|
87
|
+
session.should_not be_in_sandbox
|
88
|
+
session.fps_url.should == 'https://fps.amazonaws.com'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should point at the sandbox API if we aren't in production" do
|
92
|
+
session = Fpswax::Session.new('a', 'b', true)
|
93
|
+
session.should be_in_sandbox
|
94
|
+
session.fps_url.should == 'https://fps.sandbox.amazonaws.com'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "logger" do
|
99
|
+
before(:each) do
|
100
|
+
@session = Fpswax::Session.new('a', 'b')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return a logger object" do
|
104
|
+
@session.logger.should be_a_kind_of(Logger)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should be able to be set to something else" do
|
108
|
+
lambda {
|
109
|
+
@session.logger = Logger.new(STDOUT)
|
110
|
+
}.should_not raise_error
|
111
|
+
end
|
112
|
+
end
|
75
113
|
end
|
76
114
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,13 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
4
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
5
|
require 'fpswax'
|
6
6
|
|
7
|
+
begin
|
8
|
+
require 'fakeweb'
|
9
|
+
FakeWeb.allow_net_connect = false
|
10
|
+
rescue LoadError
|
11
|
+
abort "You need fakeweb installed to run specs. gem install fakeweb."
|
12
|
+
end
|
13
|
+
|
7
14
|
Spec::Runner.configure do |config|
|
8
15
|
|
9
16
|
end
|
@@ -15,3 +22,7 @@ end
|
|
15
22
|
def fixture_raw_xml(path)
|
16
23
|
Nokogiri::XML(File.read(fixture_path(path)))
|
17
24
|
end
|
25
|
+
|
26
|
+
def mock_xml
|
27
|
+
Nokogiri::XML("<id>2</id>")
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbalatero-fpswax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Balatero
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-25 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: nokogiri
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.3
|
24
|
+
version:
|
16
25
|
description:
|
17
26
|
email: david@bitwax.cd
|
18
27
|
executables: []
|
@@ -31,12 +40,21 @@ files:
|
|
31
40
|
- lib/fpswax/error.rb
|
32
41
|
- lib/fpswax/ipn_request.rb
|
33
42
|
- lib/fpswax/mixins/hmac_signature.rb
|
43
|
+
- lib/fpswax/pay_response.rb
|
34
44
|
- lib/fpswax/response.rb
|
35
45
|
- lib/fpswax/session.rb
|
46
|
+
- spec/fixtures/pay/cancelled.xml
|
47
|
+
- spec/fixtures/pay/error.xml
|
48
|
+
- spec/fixtures/pay/failure.xml
|
49
|
+
- spec/fixtures/pay/pending.xml
|
50
|
+
- spec/fixtures/pay/reserved.xml
|
51
|
+
- spec/fixtures/pay/success.xml
|
36
52
|
- spec/fixtures/raw/errors.xml
|
37
53
|
- spec/fixtures/raw/request_id.xml
|
38
54
|
- spec/fpswax/error_spec.rb
|
39
55
|
- spec/fpswax/ipn_request_spec.rb
|
56
|
+
- spec/fpswax/mixins/hmac_signature_spec.rb
|
57
|
+
- spec/fpswax/pay_response_spec.rb
|
40
58
|
- spec/fpswax/response_spec.rb
|
41
59
|
- spec/fpswax/session_spec.rb
|
42
60
|
- spec/spec_helper.rb
|
@@ -69,6 +87,8 @@ summary: A library for interfacing with Amazon FPS, without any "cleverness".
|
|
69
87
|
test_files:
|
70
88
|
- spec/fpswax/error_spec.rb
|
71
89
|
- spec/fpswax/ipn_request_spec.rb
|
90
|
+
- spec/fpswax/mixins/hmac_signature_spec.rb
|
91
|
+
- spec/fpswax/pay_response_spec.rb
|
72
92
|
- spec/fpswax/response_spec.rb
|
73
93
|
- spec/fpswax/session_spec.rb
|
74
94
|
- spec/spec_helper.rb
|