amazon_pay_sdk_ruby 2.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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +35 -0
- data/LICENSE.txt +21 -0
- data/README.md +478 -0
- data/Rakefile +6 -0
- data/amazon_pay_sdk_ruby.gemspec +41 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/amazon_pay/amazon_in_store_client.rb +53 -0
- data/lib/amazon_pay/amazon_pay_client.rb +85 -0
- data/lib/amazon_pay/amazon_web_store_client.rb +215 -0
- data/lib/amazon_pay/client_helper.rb +185 -0
- data/lib/amazon_pay/constants.rb +23 -0
- data/lib/amazon_pay/version.rb +3 -0
- data/lib/amazon_pay_sdk_ruby.rb +12 -0
- metadata +104 -0
data/Rakefile
ADDED
@@ -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
|
data/bin/console
ADDED
@@ -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__)
|
data/bin/setup
ADDED
@@ -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
|