amazon_flex_pay 0.9.14 → 0.10.0

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 CHANGED
@@ -7,7 +7,6 @@ task :default => :test
7
7
 
8
8
  desc 'Test the AmazonFlexPay plugin.'
9
9
  Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
10
  t.libs << 'test'
12
11
  t.pattern = 'test/**/*_test.rb'
13
12
  t.verbose = true
@@ -9,19 +9,35 @@ require 'active_support' # camelcase, underscore
9
9
  require 'active_support/inflector'
10
10
  require 'active_support/notifications'
11
11
 
12
- require 'amazon_flex_pay/signing'
13
- require 'amazon_flex_pay/model'
14
- require 'amazon_flex_pay/enumerations'
15
- require 'amazon_flex_pay/data_types'
12
+ require_relative 'amazon_flex_pay/util'
13
+ require_relative 'amazon_flex_pay/signature'
14
+ require_relative 'amazon_flex_pay/model'
15
+ require_relative 'amazon_flex_pay/enumerations'
16
+ require_relative 'amazon_flex_pay/data_types'
16
17
 
17
- require 'amazon_flex_pay/api'
18
- require 'amazon_flex_pay/pipelines'
18
+ require_relative 'amazon_flex_pay/api'
19
+ require_relative 'amazon_flex_pay/pipelines'
19
20
 
20
21
  module AmazonFlexPay
21
- VERSION = '0.9.14'
22
+ VERSION = '0.10.0'
22
23
  API_VERSION = '2011-09-20'
23
24
  PIPELINE_VERSION = '2009-01-09'
24
25
 
26
+ ENDPOINTS = {
27
+ :sandbox => {
28
+ :api => 'https://fps.sandbox.amazonaws.com/',
29
+ :cbui => 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start'
30
+ }.freeze,
31
+ :live => {
32
+ :api => 'https://fps.amazonaws.com/',
33
+ :cbui => 'https://authorize.payments.amazon.com/cobranded-ui/actions/start'
34
+ }.freeze
35
+ }
36
+
37
+ extend Util
38
+ extend AmazonFlexPay::API
39
+ extend AmazonFlexPay::Pipelines
40
+
25
41
  class << self
26
42
  attr_accessor :access_key
27
43
  attr_accessor :secret_key
@@ -30,7 +46,7 @@ module AmazonFlexPay
30
46
  #
31
47
  # Defaults to the sandbox unless you set it explicitly or call <tt>go_live!</tt>.
32
48
  def api_endpoint
33
- @api_endpoint ||= 'https://fps.sandbox.amazonaws.com/'
49
+ @api_endpoint ||= ENDPOINTS[:sandbox][:api]
34
50
  end
35
51
  attr_writer :api_endpoint
36
52
 
@@ -38,7 +54,7 @@ module AmazonFlexPay
38
54
  #
39
55
  # Defaults to the sandbox unless you set it explicitly or call <tt>go_live!</tt>.
40
56
  def pipeline_endpoint
41
- @pipeline_endpoint ||= 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start'
57
+ @pipeline_endpoint ||= ENDPOINTS[:sandbox][:cbui]
42
58
  end
43
59
  attr_writer :pipeline_endpoint
44
60
 
@@ -46,9 +62,14 @@ module AmazonFlexPay
46
62
  #
47
63
  # Call <tt>AmazonFlexPay.go_live!</tt> to enable live transactions and real money in this environment.
48
64
  def go_live!
49
- self.api_endpoint = 'https://fps.amazonaws.com/'
50
- self.pipeline_endpoint = 'https://authorize.payments.amazon.com/cobranded-ui/actions/start'
65
+ self.api_endpoint = ENDPOINTS[:live][:api]
66
+ self.pipeline_endpoint = ENDPOINTS[:live][:cbui]
51
67
  end
68
+
69
+ def sign(endpoint, params)
70
+ Signature.new(secret_key, endpoint, params).generate
71
+ end
72
+
52
73
  end
53
74
 
54
75
  end
@@ -1,21 +1,20 @@
1
- # load all api classes
2
- require 'amazon_flex_pay/api/base_request'
3
- Dir[File.dirname(__FILE__) + '/api/*'].each do |p| require "amazon_flex_pay/api/#{File.basename(p)}" end
1
+ require_relative 'api/base_request'
2
+ Dir[File.dirname(__FILE__) + '/api/*'].each do |p| require_relative "api/#{File.basename(p)}" end
4
3
 
5
4
  module AmazonFlexPay
6
- class << self
5
+ module API
7
6
  # Cancels a transaction.
8
7
  #
9
8
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/Cancel.html
10
9
  def cancel(transaction_id, options = {})
11
- API::Cancel.new(options.merge(:transaction_id => transaction_id)).submit
10
+ submit Cancel.new(options.merge(:transaction_id => transaction_id))
12
11
  end
13
12
 
14
13
  # Cancels a token.
15
14
  #
16
15
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/CancelToken.html
17
16
  def cancel_token(token_id, options = {})
18
- API::CancelToken.new(options.merge(:token_id => token_id)).submit
17
+ submit CancelToken.new(options.merge(:token_id => token_id))
19
18
  end
20
19
 
21
20
  # Searches through transactions on your account. Helpful if you want to compare vs your own records,
@@ -23,21 +22,21 @@ module AmazonFlexPay
23
22
  #
24
23
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetAccountActivity.html
25
24
  def get_account_activity(start_date, end_date, options = {})
26
- API::GetAccountActivity.new(options.merge(:start_date => start_date, :end_date => end_date)).submit
25
+ submit GetAccountActivity.new(options.merge(:start_date => start_date, :end_date => end_date))
27
26
  end
28
27
 
29
28
  # Gets your Amazon Payments account balance.
30
29
  #
31
30
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetAccountBalance.html
32
31
  def get_account_balance
33
- API::GetAccountBalance.new.submit
32
+ submit GetAccountBalance.new
34
33
  end
35
34
 
36
35
  # Returns the status of a recipient's Amazon account.
37
36
  #
38
37
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/GetRecipientVerificationStatus.html
39
38
  def get_recipient_verification_status(recipient_token_id)
40
- API::GetRecipientVerificationStatus.new(:recipient_token_id => recipient_token_id).submit
39
+ submit GetRecipientVerificationStatus.new(:recipient_token_id => recipient_token_id)
41
40
  end
42
41
 
43
42
  # Returns information about a token's state from a caller reference.
@@ -48,21 +47,21 @@ module AmazonFlexPay
48
47
  #
49
48
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/GetTokensByCaller.html
50
49
  def get_token_by_caller_reference(ref)
51
- API::GetTokenByCaller.new(:caller_reference => ref).submit
50
+ submit GetTokenByCaller.new(:caller_reference => ref)
52
51
  end
53
52
 
54
53
  # Returns information about a token's state from a token id.
55
54
  #
56
55
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/GetTokensByCaller.html
57
56
  def get_token_by_id(id)
58
- API::GetTokenByCaller.new(:token_id => id).submit
57
+ submit GetTokenByCaller.new(:token_id => id)
59
58
  end
60
59
 
61
60
  # Returns information about how much of the token has been used, and what remains.
62
61
  #
63
62
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetTokenUsage.html
64
63
  def get_token_usage(id)
65
- API::GetTokenUsage.new(:token_id => id).submit
64
+ submit GetTokenUsage.new(:token_id => id)
66
65
  end
67
66
 
68
67
  # Returns all of your tokens. Note that when you send someone through a recipient pipeline, that registers
@@ -74,7 +73,7 @@ module AmazonFlexPay
74
73
  #
75
74
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetTokens.html
76
75
  def get_tokens(options = {})
77
- API::GetTokens.new(options).submit
76
+ submit GetTokens.new(options)
78
77
  end
79
78
 
80
79
  # Returns all of Amazon's details about a transaction, such as its status and when it began and finished
@@ -82,7 +81,7 @@ module AmazonFlexPay
82
81
  #
83
82
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetTransaction.html
84
83
  def get_transaction(id)
85
- API::GetTransaction.new(:transaction_id => id).submit
84
+ submit GetTransaction.new(:transaction_id => id)
86
85
  end
87
86
 
88
87
  # Returns the current status of the transaction. Note that this information is also available from
@@ -90,7 +89,7 @@ module AmazonFlexPay
90
89
  #
91
90
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAccountManagementGuide/GetTransactionStatus.html
92
91
  def get_transaction_status(id)
93
- API::GetTransactionStatus.new(:transaction_id => id).submit
92
+ submit GetTransactionStatus.new(:transaction_id => id)
94
93
  end
95
94
 
96
95
  # Begins a Pay request for a sender token. If you are not also the recipient (this is a three-party marketplace
@@ -100,11 +99,11 @@ module AmazonFlexPay
100
99
  #
101
100
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/Pay.html
102
101
  def pay(value, currency, sender_token_id, caller_reference, options = {})
103
- API::Pay.new(options.merge(
102
+ submit Pay.new(options.merge(
104
103
  :transaction_amount => {:value => value, :currency_code => currency},
105
104
  :sender_token_id => sender_token_id,
106
105
  :caller_reference => caller_reference
107
- )).submit
106
+ ))
108
107
  end
109
108
 
110
109
  # Begins a Reserve request for the sender token. Very similar to <tt>pay</tt>.
@@ -113,11 +112,11 @@ module AmazonFlexPay
113
112
  #
114
113
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/Reserve.html
115
114
  def reserve(value, currency, sender_token_id, caller_reference, options = {})
116
- API::Reserve.new(options.merge(
115
+ submit Reserve.new(options.merge(
117
116
  :transaction_amount => {:value => value, :currency_code => currency},
118
117
  :sender_token_id => sender_token_id,
119
118
  :caller_reference => caller_reference
120
- )).submit
119
+ ))
121
120
  end
122
121
 
123
122
  # Refunds a transaction. By default it will refund the entire transaction, but you can
@@ -127,7 +126,7 @@ module AmazonFlexPay
127
126
  #
128
127
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/Refund.html
129
128
  def refund(transaction_id, caller_reference, options = {})
130
- API::Refund.new(options.merge(:transaction_id => transaction_id, :caller_reference => caller_reference)).submit
129
+ submit Refund.new(options.merge(:transaction_id => transaction_id, :caller_reference => caller_reference))
131
130
  end
132
131
 
133
132
  # If you have a Reserve transaction, use this to Settle (capture) it.
@@ -136,7 +135,7 @@ module AmazonFlexPay
136
135
  #
137
136
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/Settle.html
138
137
  def settle(transaction_id, options = {})
139
- API::Settle.new(options.merge(:reserve_transaction_id => transaction_id)).submit
138
+ submit Settle.new(options.merge(:reserve_transaction_id => transaction_id))
140
139
  end
141
140
 
142
141
  # This is how you verify IPNs and pipeline responses.
@@ -154,7 +153,35 @@ module AmazonFlexPay
154
153
  #
155
154
  # Please use <tt>verify_request</tt> instead to make sure the URL and params remain properly formatted.
156
155
  def verify_signature(url, params)
157
- API::VerifySignature.new(:url_end_point => url, :http_parameters => params).submit
156
+ submit VerifySignature.new(:url_end_point => url, :http_parameters => params)
157
+ end
158
+
159
+ protected
160
+
161
+ # This compiles an API request object into a URL, sends it to Amazon, and processes
162
+ # the response.
163
+ def submit(request)
164
+ url = request.to_url
165
+ ActiveSupport::Notifications.instrument("amazon_flex_pay.api", :action => request.action_name, :request => url) do |payload|
166
+ begin
167
+ http = RestClient.get(url)
168
+
169
+ payload[:response] = http.body
170
+ payload[:code] = http.code
171
+
172
+ response = request.class::Response.from_xml(http.body)
173
+ response.request = request
174
+ response
175
+
176
+ rescue RestClient::BadRequest, RestClient::Unauthorized, RestClient::Forbidden => e
177
+ payload[:response] = e.http_body
178
+ payload[:code] = e.http_code
179
+
180
+ er = AmazonFlexPay::API::BaseRequest::ErrorResponse.from_xml(e.response.body)
181
+ klass = AmazonFlexPay::API.const_get(er.errors.first.code)
182
+ raise klass.new(er.errors.first.code, er.errors.first.message, er.request_id, request)
183
+ end
184
+ end
158
185
  end
159
186
  end
160
187
  end
@@ -1,45 +1,30 @@
1
1
  module AmazonFlexPay::API #:nodoc:
2
2
  class BaseRequest < AmazonFlexPay::Model
3
- # This compiles an API request object into a URL, sends it to Amazon, and processes
4
- # the response.
5
- def submit
6
- url = AmazonFlexPay.api_endpoint + '?' + AmazonFlexPay.query_string(self.to_params)
7
- ActiveSupport::Notifications.instrument("amazon_flex_pay.api", :action => action_name, :request => url) do |payload|
8
- begin
9
- http = RestClient.get(url)
10
-
11
- payload[:response] = http.body
12
- payload[:code] = http.code
13
-
14
- response = self.class::Response.from_xml(http.body)
15
- response.request = self
16
- response
17
-
18
- rescue RestClient::BadRequest, RestClient::Unauthorized, RestClient::Forbidden => e
19
- payload[:response] = e.http_body
20
- payload[:code] = e.http_code
3
+ def to_url
4
+ AmazonFlexPay.api_endpoint + '?' + self.to_param
5
+ end
21
6
 
22
- er = ErrorResponse.from_xml(e.response.body)
23
- klass = AmazonFlexPay::API.const_get(er.errors.first.code)
24
- raise klass.new(er.errors.first.code, er.errors.first.message, er.request_id, self)
25
- end
26
- end
7
+ def to_param
8
+ params = to_hash.merge(
9
+ 'AWSAccessKeyId' => AmazonFlexPay.access_key,
10
+ 'Timestamp' => format_value(Time.now),
11
+ 'SignatureVersion' => 2,
12
+ 'SignatureMethod' => 'HmacSHA256'
13
+ )
14
+ params['Signature'] = AmazonFlexPay.sign(AmazonFlexPay.api_endpoint, params)
15
+ AmazonFlexPay::Util.query_string(params)
27
16
  end
28
17
 
29
18
  # Converts the API request object into parameters and signs them.
30
- def to_params
31
- params = self.to_hash.merge(
19
+ def to_hash
20
+ super.merge(
32
21
  'Action' => action_name,
33
- 'AWSAccessKeyId' => AmazonFlexPay.access_key,
34
- 'Version' => AmazonFlexPay::API_VERSION,
35
- 'Timestamp' => format_value(Time.now)
22
+ 'Version' => AmazonFlexPay::API_VERSION
36
23
  )
24
+ end
37
25
 
38
- params['SignatureVersion'] = 2
39
- params['SignatureMethod'] = 'HmacSHA256'
40
- params['Signature'] = AmazonFlexPay.signature(AmazonFlexPay.api_endpoint, params)
41
-
42
- params
26
+ def action_name #:nodoc:
27
+ self.class.to_s.split('::').last
43
28
  end
44
29
 
45
30
  class BaseResponse < AmazonFlexPay::Model
@@ -77,12 +62,5 @@ module AmazonFlexPay::API #:nodoc:
77
62
  attribute :message
78
63
  end
79
64
  end
80
-
81
-
82
- protected
83
-
84
- def action_name #:nodoc:
85
- self.class.to_s.split('::').last
86
- end
87
65
  end
88
66
  end
@@ -1,15 +1,15 @@
1
- require 'amazon_flex_pay/pipelines/base'
2
- Dir[File.dirname(__FILE__) + '/pipelines/*'].each do |p| require "amazon_flex_pay/pipelines/#{File.basename(p)}" end
1
+ require_relative 'pipelines/base'
2
+ Dir[File.dirname(__FILE__) + '/pipelines/*'].each do |p| require_relative "pipelines/#{File.basename(p)}" end
3
3
 
4
4
  module AmazonFlexPay
5
- class << self
5
+ module Pipelines
6
6
  # Creates a pipeline that may be used to change the payment method of a token.
7
7
  #
8
8
  # Note that this does not allow changing a token's limits or recipients or really anything but the method.
9
9
  #
10
10
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/EditTokenPipeline.html
11
- def edit_token_pipeline(caller_reference, options = {})
12
- AmazonFlexPay::Pipelines::EditToken.new(options.merge(:caller_reference => caller_reference))
11
+ def edit_token_pipeline(caller_reference, return_url, options = {})
12
+ cbui EditToken.new(options.merge(:caller_reference => caller_reference, :return_url => return_url))
13
13
  end
14
14
 
15
15
  # Creates a pipeline that will authorize you to send money _from_ the user multiple times.
@@ -18,15 +18,15 @@ module AmazonFlexPay
18
18
  # you only plan to collect from the token once.
19
19
  #
20
20
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/MultiUsePipeline.html
21
- def multi_use_pipeline(caller_reference, options = {})
22
- AmazonFlexPay::Pipelines::MultiUse.new(options.merge(:caller_reference => caller_reference))
21
+ def multi_use_pipeline(caller_reference, return_url, options = {})
22
+ cbui MultiUse.new(options.merge(:caller_reference => caller_reference, :return_url => return_url))
23
23
  end
24
24
 
25
25
  # Creates a pipeline that will authorize you to send money _to_ the user.
26
26
  #
27
27
  # See http://docs.amazonwebservices.com/AmazonFPS/latest/FPSAdvancedGuide/CBUIapiMerchant.html
28
- def recipient_pipeline(caller_reference, options = {})
29
- AmazonFlexPay::Pipelines::Recipient.new(options.merge(:caller_reference => caller_reference))
28
+ def recipient_pipeline(caller_reference, return_url, options = {})
29
+ cbui Recipient.new(options.merge(:caller_reference => caller_reference, :return_url => return_url))
30
30
  end
31
31
 
32
32
  # Creates a pipeline that will authorize you to send money _from_ the user one time.
@@ -34,8 +34,14 @@ module AmazonFlexPay
34
34
  # Note that if this payment fails, you must create another pipeline to get another token.
35
35
  #
36
36
  # See http://docs.amazonwebservices.com/AmazonFPS/2010-08-28/FPSBasicGuide/SingleUsePipeline.html
37
- def single_use_pipeline(caller_reference, options = {})
38
- AmazonFlexPay::Pipelines::SingleUse.new(options.merge(:caller_reference => caller_reference))
37
+ def single_use_pipeline(caller_reference, return_url, options = {})
38
+ cbui SingleUse.new(options.merge(:caller_reference => caller_reference, :return_url => return_url))
39
+ end
40
+
41
+ protected
42
+
43
+ def cbui(pipeline)
44
+ pipeline.to_url
39
45
  end
40
46
  end
41
47
  end
@@ -1,29 +1,32 @@
1
1
  module AmazonFlexPay::Pipelines #:nodoc:
2
2
  class Base < AmazonFlexPay::Model
3
+ attribute :'returnURL' # required
3
4
  attribute :caller_reference # required
4
5
  attribute :cobranding_style
5
6
  attribute :cobranding_url
6
7
  attribute :website_description
7
8
 
8
9
  # Returns a full redirectable URL for this pipeline.
9
- def url(return_url)
10
- AmazonFlexPay.pipeline_endpoint + '?' + AmazonFlexPay.query_string(to_params(return_url))
10
+ def to_url
11
+ AmazonFlexPay.pipeline_endpoint + '?' + self.to_param
11
12
  end
12
13
 
13
14
  # Converts the Pipeline object into parameters and signs them.
14
- def to_params(return_url)
15
- params = self.to_hash.merge(
16
- 'pipelineName' => pipeline_name,
15
+ def to_param
16
+ params = to_hash.merge(
17
17
  'callerKey' => AmazonFlexPay.access_key,
18
- 'version' => AmazonFlexPay::PIPELINE_VERSION,
19
- 'returnURL' => return_url
18
+ 'signatureVersion' => 2,
19
+ 'signatureMethod' => 'HmacSHA256'
20
20
  )
21
+ params['signature'] = AmazonFlexPay.sign(AmazonFlexPay.pipeline_endpoint, params)
22
+ AmazonFlexPay::Util.query_string(params)
23
+ end
21
24
 
22
- params['signatureVersion'] = 2
23
- params['signatureMethod'] = 'HmacSHA256'
24
- params['signature'] = AmazonFlexPay.signature(AmazonFlexPay.pipeline_endpoint, params)
25
-
26
- params
25
+ def to_hash
26
+ super().merge(
27
+ 'pipelineName' => pipeline_name,
28
+ 'version' => AmazonFlexPay::PIPELINE_VERSION
29
+ )
27
30
  end
28
31
 
29
32
  protected
@@ -0,0 +1,24 @@
1
+ module AmazonFlexPay
2
+ # Generates a signature for the given URL and parameters.
3
+ class Signature
4
+ def initialize(secret_key, endpoint, params)
5
+ @secret_key, @endpoint, @params = secret_key, endpoint, params
6
+ end
7
+
8
+ def generate
9
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, @secret_key, signable)).strip
10
+ end
11
+
12
+ private
13
+
14
+ def signable
15
+ uri = URI.parse(@endpoint)
16
+ [
17
+ 'GET',
18
+ uri.host,
19
+ uri.path,
20
+ AmazonFlexPay::Util.query_string(@params)
21
+ ].join("\n")
22
+ end
23
+ end
24
+ end