amazon_pay_sdk_ruby 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,41 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'amazon_pay/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'amazon_pay_sdk_ruby'
7
+ spec.version = AmazonPay::VERSION
8
+ spec.authors = ['Everistus Olumese']
9
+ spec.email = ['everistusolumese@gmail.com']
10
+
11
+ spec.summary = 'AmazonPay Ruby SDK'
12
+ spec.description = 'AmazonPay Ruby SDK'
13
+ spec.homepage = 'https://github.com/bytenaija/amazon-pay-sdk-ruby'
14
+ spec.license = 'MIT'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
+
21
+ # spec.metadata["homepage_uri"] = spec.homepage
22
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
23
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
24
+ # else
25
+ # raise "RubyGems 2.0 or newer is required to protect against " \
26
+ # "public gem pushes."
27
+ # end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = 'exe'
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ['lib']
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.17'
39
+ spec.add_development_dependency 'rake', '~> 10.0'
40
+ spec.add_development_dependency 'rspec', '~> 3.0'
41
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'amazon_pay_sdk_ruby'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,53 @@
1
+ module AmazonPay
2
+ # Class for Amazon Web Store
3
+ class AmazonInStoreClient < AmazonPayClient
4
+ def initialize(config_args)
5
+ super(config_args)
6
+ end
7
+
8
+ # API to initiate a purchase with a merchant
9
+ # - Initiates a purchase with a merchant.
10
+ # @see //TODO Update Live URL
11
+ # @param {Hash} payload - The payload for the request
12
+ # @param {Hash} [headers=nil] - The headers for the request
13
+ #
14
+ def merchant_scan(payload: nil, headers: nil)
15
+ api_call(options: {
16
+ method: 'POST',
17
+ url_fragment: 'in-store/merchantScan',
18
+ payload: payload,
19
+ headers: headers
20
+ })
21
+ end
22
+
23
+ # API to create Charge to the buyer
24
+ # - Creates a charge to the buyer with the requested amount.
25
+ # @see //TODO Update Live URL
26
+ # @param {Hash} payload - The payload for the request
27
+ # @param {Hash} [headers=nil] - The headers for the request
28
+ #
29
+ def charge(payload: nil, headers: nil)
30
+ api_call(options: {
31
+ method: 'POST',
32
+ url_fragment: 'in-store/charge',
33
+ payload: payload,
34
+ headers: headers
35
+ })
36
+ end
37
+
38
+ # API to create a Refund to the buyer
39
+ # - Refunds an amount that was previously charged to the buyer.
40
+ # @see //TODO Update Live URL
41
+ # @param {Hash} payload - The payload for the request
42
+ # @param {Hash} [headers=nil] - The headers for the request
43
+ #
44
+ def refund(payload: nil, headers: nil)
45
+ api_call(options: {
46
+ method: 'POST',
47
+ url_fragment: 'in-store/refund',
48
+ payload: payload,
49
+ headers: headers
50
+ })
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,85 @@
1
+ require 'amazon_pay/client_helper'
2
+
3
+ module AmazonPay
4
+ class AmazonPayClient
5
+ def initialize(config_args)
6
+ @config_args = config_args.freeze
7
+ end
8
+
9
+ # API to process a request
10
+ # - Makes an API Call using the specified options.
11
+ # @param {Hash} options - The options to make the API Call
12
+ # @param {String} options.method - The HTTP request method
13
+ # @param {String} options.url_fragment - The URI for the API Call
14
+ # @param {String} [options.payload=nil] - The payload for the API Call
15
+ # @param {Hash} [options.headers=nil] - The headers for the API Call
16
+ # @param {Hash} [options.queryParams=nil] - The headers for the API Call
17
+
18
+ def api_call(options: {})
19
+ prepared_options = AmazonPay::ClientHelper.prepare_options(config_args: @config_args, options: options)
20
+ prepared_options[:headers] = AmazonPay::ClientHelper.sign_headers(config_args: @config_args, options: prepared_options)
21
+ AmazonPay::ClientHelper.invoke_api(config_args: @config_args, api_options: prepared_options)
22
+ end
23
+
24
+ # Signs the request headers
25
+ # - Signs the request provided and returns the signed headers Hash.
26
+ # @param {Hash} options - The options to make the API Call
27
+ # @param {String} options.method - The HTTP request method
28
+ # @param {String} options.url_fragment - The URI for the API Call
29
+ # @param {String} [options.payload=nil] - The payload for the API Call
30
+ # @param {Hash} [options.headers=nil] - The headers for the API Call
31
+
32
+ def get_signed_headers(options: {})
33
+ prepared_options = AmazonPay::ClientHelper.prepare_options(@config_args, options)
34
+ AmazonPay::ClientHelper.sign_headers(config_args: @config_args, options: prepared_options)
35
+ end
36
+
37
+ # Lets the solution provider get Authorization Token for their merchants if they are granted the delegation.
38
+ # - Please note that your solution provider account must have a pre-existing relationship (valid and active MWS authorization token) with the merchant account in order to use this function.
39
+ # @param {String} mws_auth_token - The mws_auth_token
40
+ # @param {String} merchant_id - The merchant_id
41
+ # @param {Hash} [headers=nil] - The headers for the request
42
+
43
+ def get_authorization_token(mws_auth_token: nil, merchant_id: nil, headers: nil)
44
+ api_call(options: {
45
+ method: 'GET',
46
+ url_fragment: "authorizationTokens/#{mws_auth_token}",
47
+ headers: headers,
48
+ query_params: {
49
+ merchantId: merchant_id
50
+ }
51
+ })
52
+ end
53
+
54
+ # Generates static signature for amazon.Pay.renderButton used by checkout.js.
55
+ # - Returns signature as string.
56
+ # @param {Hash} payload - The payload for the request
57
+ # @returns {String} signature
58
+
59
+ def generate_button_signature(payload: nil)
60
+ AmazonPay::ClientHelper.sign_payload(config_args: @config_args, payload: payload)
61
+ end
62
+
63
+ # Lets the solution provider make the DeliveryTrackers request with their auth token.
64
+ # - Lets you provide shipment tracking information to Amazon Pay so that Amazon Pay will
65
+ # be able to notify buyers on Alexa when shipments are delivered.
66
+ # @see https://developer.amazon.com/docs/amazon-pay-onetime/delivery-notifications.html#api-reference
67
+ # @param {Hash} payload - The payload for the request
68
+ # @param {String} payload.amazonOrderReferenceId - The Amazon Order Reference ID or Charge
69
+ # Permission Id associated with the order for which the shipments need
70
+ # to be tracked
71
+ # @param {String} payload.trackingNumber - The tracking number for the shipment provided by
72
+ # the shipping company
73
+ # @param {Hash} payload.carrierCode - The shipping company code used for delivering goods to the customer
74
+ # @param {Hash} [headers=nil] - The headers for the request
75
+
76
+ def delivery_trackers(payload: nil, headers: nil)
77
+ api_call(options: {
78
+ method: 'POST',
79
+ url_fragment: 'deliveryTrackers',
80
+ payload: payload,
81
+ headers: headers
82
+ })
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,215 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+
3
+ module AmazonPay
4
+ # Class for Amazon Web Store
5
+ class AmazonWebStoreClient < AmazonPayClient
6
+ def initialize(config_args)
7
+ super(config_args)
8
+ end
9
+
10
+ # API to get the Buyer Hash
11
+ # - Get Buyer details can include buyer ID, name, email address, postal code,
12
+ # and country code
13
+ # - when used with the Amazon.Pay.renderButton 'SignIn' productType and corresponding
14
+ # signInScopes
15
+ # @param {String} buyer_token - The checkout session Id
16
+ # @param {Hash} [headers=nil] - The headers for the request
17
+
18
+ def get_buyer(buyer_token: nil, headers: nil)
19
+ api_call(options:
20
+ {
21
+ method: 'GET',
22
+ url_fragment: "buyers/#{buyer_token}",
23
+ headers: headers
24
+ })
25
+ end
26
+
27
+ # API to create a CheckoutSession Hash
28
+ # - Creates a new CheckoutSession Hash.
29
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/checkout-session.html#create-checkout-session
30
+ # @param {Hash} payload - The payload for the request
31
+ # @param {Hash} headers - The headers for the request
32
+ def create_checkout_session(payload: nil, headers: nil)
33
+ api_call(options: {
34
+ method: 'POST',
35
+ url_fragment: 'checkoutSessions',
36
+ payload: payload,
37
+ headers: headers
38
+ })
39
+ end
40
+
41
+ # API to get the CheckoutSession Hash
42
+ # - Retrives details of a previously created CheckoutSession Hash.
43
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/checkout-session.html#get-checkout-session
44
+ # @param {String} checkout_session_id - The checkout session Id
45
+ # @param {Hash} [headers=nil] - The headers for the request
46
+ def get_checkout_session(checkout_session_id: nil, headers: nil)
47
+ api_call(options: {
48
+ method: 'GET',
49
+ url_fragment: "checkoutSessions/#{checkout_session_id}",
50
+ headers: headers
51
+ })
52
+ end
53
+
54
+ # API to update the CheckoutSession Hash
55
+ # - Updates a previously created CheckoutSession Hash.
56
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/checkout-session.html#update-checkout-session
57
+ # @param {String} checkout_session_id - The checkout session Id
58
+ # @param {Hash} payload - The payload for the request
59
+ # @param {Hash} [headers=nil] - The headers for the request
60
+ def update_checkout_session(checkout_session_id: nil, payload: nil, headers: nil)
61
+ api_call(options: {
62
+ method: 'PATCH',
63
+ url_fragment: "checkoutSessions/#{checkout_session_id}",
64
+ payload: payload,
65
+ headers: headers
66
+ })
67
+ end
68
+
69
+ # API to complete a Checkout Session
70
+ # - Confirms the completion of buyer checkout.
71
+ # @see //TODO Update Live URL
72
+ # @param {String} checkout_session_id - The checkout session Id
73
+ # @param {Hash} payload - The payload for the request
74
+ # @param {Hash} [headers=nil] - The headers for the request
75
+ def complete_checkout_session(checkout_session_id: nil, payload: nil, headers: nil)
76
+ api_call(options: {
77
+ method: 'POST',
78
+ url_fragment: "checkoutSessions/#{checkout_session_id}/complete",
79
+ payload: payload,
80
+ headers: headers
81
+ })
82
+ end
83
+
84
+ # API to get a ChargePermission Hash
85
+ # - Retrives details of a previously created ChargePermission Hash.
86
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge-permission.html#get-charge-permission
87
+ # @param {String} charge_permission_id - The charge permission Id
88
+ # @param {Hash} [headers=nil] - The headers for the request
89
+ def get_charge_permission(charge_permission_id: nil, headers: nil)
90
+ api_call(options: {
91
+ method: 'GET',
92
+ url_fragment: "chargePermissions/#{charge_permission_id}",
93
+ headers: headers
94
+ })
95
+ end
96
+
97
+ # API to update a ChargePermission Hash
98
+ # - Updates a previously created ChargePermission Hash.
99
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge-permission.html#update-charge-permission
100
+ # @param {String} charge_permission_id - The charge permission Id
101
+ # @param {Hash} payload - The payload for the request
102
+ # @param {Hash} [headers=nil] - The headers for the request
103
+ def update_charge_permission(charge_permission_id: nil, payload: nil, headers: nil)
104
+ api_call(options: {
105
+ method: 'PATCH',
106
+ url_fragment: "chargePermissions/#{charge_permission_id}",
107
+ payload: payload,
108
+ headers: headers
109
+ })
110
+ end
111
+
112
+ # API to close a ChargePermission Hash
113
+ # - Closes a perviously created ChargePermission Hash.
114
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge-permission.html#close-charge-permission
115
+ # @param {String} charge_permission_id - The charge permission Id
116
+ # @param {Hash} payload - The payload for the request
117
+ # @param {Hash} [headers=nil] - The headers for the request
118
+ def close_charge_permission(charge_permission_id: nil, payload: nil, headers: nil)
119
+ api_call(options: {
120
+ method: 'DELETE',
121
+ url_fragment: "chargePermissions/#{charge_permission_id}/close",
122
+ payload: payload,
123
+ headers: headers
124
+ })
125
+ end
126
+
127
+ # API to create a Charge Hash
128
+ # - Creates a new Charge Hash.
129
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge.html#create-charge
130
+ # @param {Hash} payload - The payload for the request
131
+ # @param {Hash} headers - The headers for the request
132
+ def create_charge(payload: nil, headers: nil)
133
+ api_call(options: {
134
+ method: 'POST',
135
+ url_fragment: 'charges',
136
+ payload: payload,
137
+ headers: headers
138
+ })
139
+ end
140
+
141
+ # API to get the Charge Hash
142
+ # - Retrieves a perviously created Charge Hash.
143
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge.html#get-charge
144
+ # @param {String} charge_id - The charge Id
145
+ # @param {Hash} [headers=nil] - The headers for the request
146
+ def get_charge(charge_id: nil, headers: nil)
147
+ api_call(options: {
148
+ method: 'GET',
149
+ url_fragment: "charges/#{charge_id}",
150
+ headers: headers
151
+ })
152
+ end
153
+
154
+ # API to create a captureCharge request
155
+ # - Captures an existing charge
156
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge.html#capture-charge
157
+ # @param {String} charge_id - The charge Id
158
+ # @param {Hash} payload - The payload for the request
159
+ # @param {Hash} [headers=nil] - The headers for the request
160
+
161
+ def capture_charge(charge_id: nil, payload: nil, headers: nil)
162
+ api_call(options: {
163
+ method: 'POST',
164
+ url_fragment: "charges/#{charge_id}/capture",
165
+ payload: payload,
166
+ headers: headers
167
+ })
168
+ end
169
+
170
+ # API to create a cancelCharge request
171
+ # - Cancels an existing charge.
172
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/charge.html#cancel-charge
173
+ # @param {String} charge_id - The charge Id
174
+ # @param {Hash} payload - The payload for the request
175
+ # @param {Hash} [headers=nil] - The headers for the request
176
+
177
+ def cancel_charge(charge_id: nil, payload: nil, headers: nil)
178
+ api_call(options: {
179
+ method: 'DELETE',
180
+ url_fragment: "charges/#{charge_id}/cancel",
181
+ payload: payload,
182
+ headers: headers
183
+ })
184
+ end
185
+
186
+ # API to create a Refund Hash
187
+ # - Generates a refund.
188
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/refund.html#create-refund
189
+ # @param {Hash} payload - The payload for the request
190
+ # @param {Hash} headers - The headers for the request
191
+
192
+ def create_refund(payload: nil, headers: nil)
193
+ api_call(options: {
194
+ method: 'POST',
195
+ url_fragment: 'refunds',
196
+ payload: payload,
197
+ headers: headers
198
+ })
199
+ end
200
+
201
+ # API to get a Refund Hash
202
+ # - Retreives details of an existing refund.
203
+ # @see https://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-api-v2/refund.html#get-refund
204
+ # @param {String} refundId - The refund Id
205
+ # @param {Hash} [headers=nil] - The headers for the request
206
+
207
+ def get_refund(refund_id: nil, headers: nil)
208
+ api_call(options: {
209
+ method: 'GET',
210
+ url_fragment: "refunds/#{refund_id}",
211
+ headers: headers
212
+ })
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,185 @@
1
+ # rubocop:disable Metrics/MethodLength, Metrics/ClassLength, Metrics/AbcSize
2
+
3
+ require 'openssl'
4
+ require 'base64'
5
+ require 'json'
6
+ require 'time'
7
+ require 'date'
8
+ require 'net/http'
9
+ require 'amazon_pay/constants'
10
+
11
+ module AmazonPay
12
+ # All the helper files
13
+ class ClientHelper
14
+ def self.fetch_timestamp
15
+ Time.now.utc.iso8601
16
+ end
17
+
18
+ def self.fetch_api_endpoint_base_url(config_args: {})
19
+ if config_args[:overrideServiceUrl]&.length&.positive?
20
+ config_args[:overrideServiceUrl]
21
+ else
22
+ region = config_args[:region].downcase.to_sym
23
+ region_map = AmazonPay::CONSTANTS[:REGION_MAP][region].to_sym
24
+
25
+ AmazonPay::CONSTANTS[:API_ENDPOINTS][region_map]
26
+ end
27
+ end
28
+
29
+ def self.invoke_api(config_args: {}, api_options: {})
30
+ options = {
31
+ method: api_options[:method],
32
+ json: false,
33
+ headers: api_options[:headers],
34
+ url: "https://#{fetch_api_endpoint_base_url(config_args: config_args)}/#{api_options[:url_fragment]}"\
35
+ "#{fetch_query_string(request_params: api_options[:query_params])}",
36
+ body: api_options[:payload]
37
+ }
38
+
39
+ retry_logic(options: options, count: 1)
40
+ end
41
+
42
+ def self.fetch_query_string(request_params: nil)
43
+ return "?#{fetch_parameters_as_string(request_params: request_params)}" if request_params
44
+
45
+ ''
46
+ end
47
+
48
+ def self.fetch_parameters_as_string(request_params: nil)
49
+ return '' if request_params.nil?
50
+
51
+ query_params = []
52
+ request_params.map do |key, value|
53
+ query_params << "#{key}=#{CGI.escape(value)}"
54
+ end
55
+ query_params.join('&')
56
+ end
57
+
58
+ def self.prepare_options(config_args: {}, options: {})
59
+ options[:headers] ||= {}
60
+
61
+ # if user doesn't pass in a string, assume it's a JS Hash and convert it to a JSON string
62
+ unless options[:payload].is_a?(String) || options[:payload].nil?
63
+ options[:payload] = JSON.generate(options[:payload])
64
+ end
65
+
66
+ options[:url_fragment] = if config_args[:sandbox] == true || config_args[:sandbox] == 'true'
67
+ "sandbox/#{AmazonPay::CONSTANTS[:API_VERSION]}/#{options[:url_fragment]}"
68
+ else
69
+ "live/#{AmazonPay::CONSTANTS[:API_VERSION]}/#{options[:url_fragment]}"
70
+ end
71
+
72
+ options
73
+ end
74
+
75
+ def self.sign(private_key: nil, data: nil)
76
+ sign_hash = OpenSSL::Digest.new('SHA256')
77
+ priv = OpenSSL::PKey::RSA.new(private_key)
78
+ signature = priv.sign_pss(sign_hash, data, salt_length: 20, mgf1_hash: 'SHA256')
79
+ Base64.strict_encode64(signature)
80
+ end
81
+
82
+ def self.retry_logic(options: {}, count: 0)
83
+ response = send_request(options: options, count: count)
84
+ return response if count > AmazonPay::CONSTANTS[:RETRIES]
85
+
86
+ return response unless response.nil?
87
+
88
+ count += 1
89
+ retry_logic(options: options, count: count)
90
+ end
91
+
92
+ def self.send_request(options: {}, count: 0)
93
+ delay_time = count == 1 ? 0 : (2**(count - 1)).seconds
94
+ sleep(delay_time)
95
+ begin
96
+ uri = URI(options[:url])
97
+
98
+ http = Net::HTTP.new(uri.host, uri.port)
99
+ http.use_ssl = true
100
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
101
+
102
+ case options[:method].to_sym
103
+ when :GET
104
+ response = http.get(uri, options[:headers])
105
+ when :DELETE
106
+ response = http.delete(uri.request_uri, options[:headers])
107
+ when :POST
108
+ request = Net::HTTP::Post.new(uri.path, options[:headers])
109
+ request.body = options[:body]
110
+ response = http.request(request)
111
+ when :PATCH
112
+ request = Net::HTTP::Patch.new(uri.path, options[:headers])
113
+ request.body = options[:body]
114
+ response = http.request(request)
115
+ end
116
+ JSON.parse(response.body)
117
+ rescue StandardError
118
+ nil
119
+ end
120
+ end
121
+
122
+ # Expected options:
123
+ # options[:method]
124
+ # options[:url_fragment]
125
+ # options[:payload]
126
+ # options[:headers]
127
+
128
+ def self.sign_headers(config_args: {}, options: {})
129
+ headers = options[:headers] || {}
130
+ headers['x-amz-pay-region'] = 'us'
131
+ headers['x-amz-pay-host'] = fetch_api_endpoint_base_url(config_args: config_args)
132
+ headers['x-amz-pay-date'] = fetch_timestamp
133
+ headers['content-type'] = 'application/json'
134
+ headers['accept'] = 'application/json'
135
+ headers[
136
+ 'user-agent'
137
+ ] = "amazon-pay-api-sdk-ruby/#{AmazonPay::CONSTANTS[:SDK_VERSION]} (Ruby/#{RUBY_VERSION}; #{RUBY_PLATFORM})"
138
+
139
+ lower_case_sorted_header_keys = headers.keys.sort.map(&:downcase)
140
+ signed_headers = lower_case_sorted_header_keys.join(';')
141
+
142
+ payload = options[:payload]
143
+
144
+ if payload.nil? || options[:url_fragment].include?('/account-management/'\
145
+ "#{AmazonPay::CONSTANTS[:API_VERSION]}/accounts")
146
+ payload = '' # do not sign payload for payment critical data APIs
147
+ end
148
+
149
+ canonical_request =
150
+ options[:method] + "\n/" +
151
+ options[:url_fragment] + "\n" +
152
+ fetch_parameters_as_string(request_params: options[:query_params]) +
153
+ "\n"
154
+
155
+ lower_case_sorted_header_keys.each do |item|
156
+ str = item.downcase + ':' + headers[item] + "\n"
157
+
158
+ canonical_request += str
159
+ end
160
+
161
+ canonical_request += "\n" + signed_headers + "\n" +
162
+ OpenSSL::Digest::SHA256.hexdigest(payload)
163
+
164
+ string_to_sign =
165
+ AmazonPay::CONSTANTS[:AMAZON_SIGNATURE_ALGORITHM] +
166
+ "\n" +
167
+ OpenSSL::Digest::SHA256.hexdigest(canonical_request)
168
+
169
+ signature = sign(private_key: config_args[:private_key], data: string_to_sign)
170
+
171
+ headers['authorization'] = "#{AmazonPay::CONSTANTS[:AMAZON_SIGNATURE_ALGORITHM]} "\
172
+ "PublicKeyId=#{config_args[:public_key_id]}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
173
+
174
+ headers
175
+ end
176
+
177
+ def self.sign_payload(config_args: nil, payload: nil)
178
+ # if user doesn't pass in a string, assume it's a JS Hash and convert it to a JSON string
179
+ payload = JSON.generate(payload) unless payload.is_a?(String)
180
+ string_to_sign = AmazonPay::CONSTANTS[:AMAZON_SIGNATURE_ALGORITHM] + "\n" +
181
+ OpenSSL::Digest::SHA256.hexdigest(payload)
182
+ sign(private_key: config_args[:private_key], data: string_to_sign)
183
+ end
184
+ end
185
+ end