quickpay-ruby-client 1.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0db8d46e31a28416b4e0b7ade182b396ee10be52
4
- data.tar.gz: 9c4fd8fef2c3a3b64730ae8f62be8d9a00f71822
2
+ SHA256:
3
+ metadata.gz: 47a7b8b3bec59cf6276448d2e8eb29149288518b12d0df8e377fc10783bb6090
4
+ data.tar.gz: d80a3b9b3deda68bea662dd67a5937ea724a7aa58d44ec7fde61c74c588b9e43
5
5
  SHA512:
6
- metadata.gz: c2690337637c7f098400ce849070d70fd6dbddc18fd55d49b3a8d20ef3902009a56eb7954c5364193e5ec3430b6867a6d32eba992dd8218521fe5d635b5dc560
7
- data.tar.gz: f35af9f1e711344682fedb0540f7f58093c051dde49cef89fb6ed8786dcb8922558ee2c775e7c41406bdc051dafe84130f6c449fca29f9803c5f897fe41a59e4
6
+ metadata.gz: cadad5ea2172320dd9133e6e8534d08cc1475d1b3d8d66839686eebaeba74000e0b162f8332b118cc21794299970a3c938b199f85ceff6a5b44c37405164ffaa
7
+ data.tar.gz: c46b7f639b9f9359c53206a02583c5c593535601541cd8a75861666b943db5a629edfb7df58d6b25615450758b8ffa461bcb668a002b7022e511f7f2acd85ede
data/.gitignore CHANGED
@@ -1,9 +1,4 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
1
+ .bundle/
2
+ coverage/
3
+ pkg/
4
+ Gemfile.lock
data/.travis.yml CHANGED
@@ -1,8 +1,12 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.2
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
6
+ - 3.0
4
7
  cache: bundler
5
- script: bundle exec rspec --format documentation --color
8
+ before_script: wget -O ~/.rubocop.yml https://quickpay.github.io/development/.rubocop.yml
9
+ script: bundle exec rake
6
10
  notifications:
7
11
  slack:
8
12
  secure: SixeTgiVsOaeWyKwICxLJ0GLN/C9j6qW1ZdaEytIDuZaBAn9oArrRGkJiehFdlzcPUHwzMWC0vl9GQzyBhZ7dbq+B53QY1mH9LTb9A53Y2d1OO1kBjJAkC5Yprvpjm52+x889Dwlz0bfLETvLsC2ej0NZDvSSLKFjpZZIZMOWkg=
data/CHANGELOG.md CHANGED
@@ -1,23 +1,86 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.0
3
4
 
4
- ## Unreleased
5
+ ### Breaking changes
5
6
 
6
- ### Features:
7
+ The interface has been changed to (https://github.com/QuickPay/quickpay-ruby-client/pull/36):
7
8
 
8
- (your contribution here)
9
+ - always return an array for all request types (incl. when adding the `raw: true` option)
10
+ - order the array as `[body, status, headers]` (was `[status, body, headers]`
11
+ - always parse JSON body unless the `raw: true` option is set
9
12
 
10
- ### Bugfixes
13
+ The reasoning is that we almost always want the `body`, but in some case we want `status`and/or `headers` as well. Before we had to set the `raw: true` option, but then a JSON body would not be parsed.
11
14
 
12
- (your contribution here)
15
+ ```ruby
16
+ body, = client.get("/ping")
17
+ body, status, = client.get("/ping")
18
+ body, status, headers = client.get("/ping")
19
+ body, status, headers = client.get("/ping", raw: true)
20
+ ```
21
+
22
+ ### New features
23
+
24
+ #### Blocks
25
+
26
+ You can now pass a block to a request (https://github.com/QuickPay/quickpay-ruby-client/pull/32):
27
+
28
+ ```ruby
29
+ msg = client.get("/ping") do |body, status, headers, error|
30
+ case error
31
+ when nil
32
+ body["msg"]
33
+ when QuickPay::API::NotFound
34
+ nil
35
+ else
36
+ raise error
37
+ end
38
+ end
39
+ ```
40
+
41
+ #### Verbose errors
42
+
43
+ The `QuickPay::API::Error` now includes the request that yielded the error - for example:
44
+
45
+ ```
46
+ #<QuickPay::API::Error::NotFound:
47
+ status=404,
48
+ body="404 Not Found",
49
+ headers={"Server"=>"nginx", "Date"=>"Sun, 21 Mar 2021 09:10:12 GMT", "Connection"=>"keep-alive", "X-Cascade"=>"pass", "Vary"=>"Origin"}
50
+ request=#<struct QuickPay::API::Client::Request
51
+ method=:post,
52
+ path="/payments",
53
+ body="{\"currency\":\"DKK\",\"order_id\":\"1212\"}",
54
+ headers={"User-Agent"=>"quickpay-ruby-client, v2.0.3", "Accept-Version"=>"v10", "Content-Type"=>"application/json"},
55
+ query=nil>>
56
+ ```
57
+
58
+ ## v2.0.3
59
+
60
+ * Add the possibility of settins options for JSON parser
61
+
62
+ ## v2.0.2
63
+
64
+ * Update excon dependency for CVE-2019-16779 (prognostikos)
65
+
66
+ ## v2.0.1
67
+
68
+ * More verbose `#to_s`/`#inspect` on errors
69
+
70
+ ## v2.0.0
71
+
72
+ * This is a total rewrite and while the code is cleaner, simpler and faster, it does present some **breaking changes compared to v1.X.X**:
73
+ * The client now accepts arguements `username` instead of `password` and `api_key` has been removed. To authenticate with an API key, simply set `password: <key>` and omit username.
74
+ * The request methods now accepts request body as an named option (`client.post(<endpoint>, body: { amount: 100 })`) rather than a hash of body params (`client.post(<endpoint>, amount: 100)`).
75
+ * Replace the following dependencies - which reduces the total number of dependencies to 5 (was 27):
76
+ * HTTParty => Excon (https://github.com/excon/excon) - which luckily means no more partying hard.
77
+ * Rspec => Minitest
13
78
 
14
79
  ## v1.2.0 (2016-10-25)
15
80
 
16
- - Can now HEAD (https://github.com/QuickPay/quickpay-ruby-client/pull/21)
81
+ * Can now HEAD (https://github.com/QuickPay/quickpay-ruby-client/pull/21)
17
82
 
18
83
  ## v1.1.0 (2016-01-11)
19
84
 
20
- ### Features:
21
-
22
- - Send options to the underlaying HTTParty (https://github.com/QuickPay/quickpay-ruby-client/pull/16)
23
- - Be able to upload files (https://github.com/QuickPay/quickpay-ruby-client/pull/17<Paste>)
85
+ * Send options to the underlaying HTTParty (https://github.com/QuickPay/quickpay-ruby-client/pull/16)
86
+ * Be able to upload files (https://github.com/QuickPay/quickpay-ruby-client/pull/17<Paste>)
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in quickpay-ruby-client.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,20 +1,26 @@
1
- quickpay-ruby-client
2
- ======================
1
+ # QuickPay::API::Client
2
+
3
3
  [![Build Status](https://travis-ci.org/QuickPay/quickpay-ruby-client.svg)](https://travis-ci.org/QuickPay/quickpay-ruby-client)
4
4
 
5
- `quickpay-ruby-client` is a official client for [QuickPay API](http://tech.quickpay.net/api). The Quickpay API enables you to accept payments in a secure and reliable manner. This gem currently support QuickPay `v10` api.
5
+ The `quickpay-ruby-client` gem is a official client for [QuickPay API](https://learn.quickpay.net/tech-talk/api). The Quickpay API enables you to accept payments in a secure and reliable manner.
6
+
7
+ This gem currently support QuickPay `v10` api.
6
8
 
7
9
  ## Installation
8
10
 
9
11
  Add to your Gemfile
10
-
11
- $ gem 'quickpay-ruby-client'
12
+
13
+ ```ruby
14
+ gem "quickpay-ruby-client"
15
+ ```
12
16
 
13
17
  or install from Rubygems:
14
-
15
- $ gem install quickpay-ruby-client
16
-
17
- It is currently tested with Ruby ( >= 2.1.x)
18
+
19
+ ```
20
+ $ gem install quickpay-ruby-client
21
+ ```
22
+
23
+ It is currently tested with Ruby ( >= 2.5.x)
18
24
 
19
25
  * MRI
20
26
  * Rubinius (2.0)
@@ -25,63 +31,122 @@ Before doing anything you should register yourself with QuickPay and get access
25
31
 
26
32
  ### Create a new API client
27
33
 
28
- First you should create a client instance that is anonymous or authorized with `api_key` or login credentials provided by QuickPay.
34
+ First you should create a client instance that is anonymous or authorized with your API key or login credentials provided by QuickPay.
29
35
 
30
36
  To initialise an anonymous client:
31
37
 
32
- ```
33
- require 'quickpay/api/client'
38
+ ```ruby
39
+ require "quickpay/api/client"
34
40
  client = QuickPay::API::Client.new
35
41
  ```
36
42
 
37
- To initialise a client with QuickPay Api Key:
43
+ To initialise a client with QuickPay API Key:
38
44
 
39
- ```
40
- require 'quickpay/api/client'
41
- client = QuickPay::API::Client.new(api_key: ENV['QUICKPAY_API_KEY'])
45
+ ```ruby
46
+ require "quickpay/api/client"
47
+ client = QuickPay::API::Client.new(password: ENV["QUICKPAY_API_KEY"])
42
48
  ```
43
49
 
44
50
  Or you can provide login credentials like:
45
51
 
46
- ```
47
- require 'quickpay/api/client'
48
- client = QuickPay::API::Client.new(email: ENV['QUICKPAY_LOGIN'], password: ENV['QUICKPAY_PASSWORD'])
52
+ ```ruby
53
+ require "quickpay/api/client"
54
+ client = QuickPay::API::Client.new(username: ENV["QUICKPAY_LOGIN"], password: ENV["QUICKPAY_PASSWORD"])
49
55
  ```
50
56
 
51
- To pass request specific headers:
57
+ You can also set some connection specific options (default values shown):
52
58
 
59
+ ```ruby
60
+ client = QuickPay::API::Client.new(
61
+ options: {
62
+ read_timeout: 60,
63
+ write_timeout: 60,
64
+ connect_timeout: 60,
65
+ json_opts: { symbolize_names: false }
66
+ }
67
+ )
53
68
  ```
54
- client = Quickpay::API::Client.new({ email: ENV['QUICKPAY_LOGIN'], password: ENV['QUICKPAY_PASSWORD'] },
55
- :headers => { 'QuickPay-Callback-URL' => 'https://webshop.com' })
56
- ```
57
69
 
70
+ ### Sending request
71
+
72
+ You can afterwards call any method described in QuickPay API with corresponding http method and endpoint. These methods are supported currently: `get`, `post`, `put`, `patch`, `delete` and `head`.
73
+
74
+ Any request will return an array in the form `[body, status, headers]`:
58
75
 
59
- ### API Calls
76
+ ```ruby
77
+ # Shortest form when interested in the response body only
78
+ body, = client.get("/ping")
79
+ puts body.inspect
60
80
 
61
- You can afterwards call any method described in QuickPay api with corresponding http method and endpoint. These methods are supported currently: `get`, `post`, `put`, `patch` and `delete`.
81
+ # Get all response information
82
+ body, status, headers = client.get("/ping")
83
+ puts body.inspect, status.inspect, headers.inspect
62
84
 
63
85
  ```
64
- client.get("/activity").each do |activity|
65
- puts activity["id"]
66
- end
67
86
 
87
+ You can also do requests in block form:
88
+
89
+ ```ruby
90
+ client.get("/ping") do |body, status, headers|
91
+ puts body.inspect
92
+ end
68
93
  ```
69
94
 
70
- If you want raw http response, headers Please add `:raw => true` parameter:
95
+ It is even possible to pass the `QuickPay::API::Error` to the block as the 4th parameter to be able to handle the errors that _would_ have otherwise been raised. This parameter is nil when the response is a success.
71
96
 
97
+ ```ruby
98
+ # the error is not raised but passed to the block as the fourth parameter
99
+ client.get("/ping") do |body, status, headers, error|
100
+ case error
101
+ when nil
102
+ body[:id]
103
+ when QuickPay::API::NotFound
104
+ nil
105
+ else
106
+ raise error
107
+ end
108
+ end
109
+
110
+ # will raise `QuickPay::API::Error::NotFound` since the fourth block param is not defined
111
+ client.get("/non-existing-path") do |body, status, headers| do
112
+ end
72
113
  ```
73
- status, body, headers = client.get("/activity", :raw => true)
114
+
115
+ If you want raw http response body, you can add `:raw => true` parameter:
116
+
117
+ ```ruby
118
+ body, status, headers = client.get("/ping", raw: true)
74
119
 
75
120
  if status == 200
76
- JSON.parse(body).each do |activity|
77
- puts activity["id"]
78
- end
121
+ puts JSON.parse(body).inspect
79
122
  else
80
- puts "Error: #{body}"
123
+ # do something else
81
124
  end
82
125
 
83
126
  ```
84
127
 
128
+ Beyond the endpoint, the client accepts the following options (default values shown):
129
+
130
+ * `body: ""`
131
+ * `headers: {}`
132
+ * `query: {}`
133
+ * `raw: false`
134
+ * `json_opts: nil`
135
+
136
+ Full example:
137
+
138
+ ```ruby
139
+ response, = client.post(
140
+ "/payments/1/capture",
141
+ body: { amount: 100 }.to_json,
142
+ headers: { "Content-Type" => "application/json" },
143
+ query: { "synchronized" => "" },
144
+ raw: false,
145
+ json_opts: { symbolize_names: true }
146
+ )
147
+
148
+ ```
149
+
85
150
  ### Handling API exceptions
86
151
 
87
152
  By default `(get|post|patch|put|delete)` will return JSON parsed body on success (i.e. `2xx` response code) otherwise it will raise appropriate error. Your code should handle the errors appropriately. Following error codes are supported currently:
@@ -90,7 +155,7 @@ By default `(get|post|patch|put|delete)` will return JSON parsed body on success
90
155
  Response status | Error |
91
156
  ----------------| ----------|
92
157
  `400` | `QuickPay::API::BadRequest`
93
- `401` | `QuickPay::API::Unauthorized`
158
+ `401` | `QuickPay::API::Unauthorized`
94
159
  `402` | `QuickPay::API::PaymentRequired`
95
160
  `403` | `QuickPay::API::Forbidden`
96
161
  `404` | `QuickPay::API::NotFound`
@@ -98,26 +163,43 @@ Response status | Error |
98
163
  `406` | `QuickPay::API::NotAcceptable`
99
164
  `409` | `QuickPay::API::Conflict`
100
165
  `500` | `QuickPay::API::ServerError`
166
+ `502` | `QuickPay::API::BadGateway`
167
+ `503` | `QuickPay::API::ServiceUnavailable`
168
+ `504` | `QuickPay::API::GatewayTimeout`
101
169
 
102
170
  All exceptions inherits `QuickPay::API::Error`, so you can listen for any api error like:
103
171
 
104
- ```
172
+ ```ruby
105
173
  begin
106
- client.post("/payments", :currency => :DKK, :order_id => '1212')
107
- ...
174
+ client.post("/payments", body: { currency: "DKK", order_id: "1212" }, headers: { "Content-Type" => "application/json" })
108
175
  rescue QuickPay::API::Error => e
109
- puts e.body
176
+ puts e.inspect
110
177
  end
111
178
  ```
112
179
 
113
- You can read more about api responses at [http://tech.quickpay.net/api/](http://tech.quickpay.net/api).
180
+ Example error object:
181
+
182
+ ```
183
+ #<QuickPay::API::Error::NotFound:
184
+ status=404,
185
+ body="404 Not Found",
186
+ headers={"Server"=>"nginx", "Date"=>"Sun, 21 Mar 2021 09:10:12 GMT", "Connection"=>"keep-alive", "X-Cascade"=>"pass", "Vary"=>"Origin"}
187
+ request=#<struct QuickPay::API::Client::Request
188
+ method=:post,
189
+ path="/payments",
190
+ body="{\"currency\":\"DKK\",\"order_id\":\"1212\"}",
191
+ headers={"User-Agent"=>"quickpay-ruby-client, v2.0.3", "Accept-Version"=>"v10", "Content-Type"=>"application/json"},
192
+ query=nil>>
193
+ ```
194
+
195
+ You can read more about QuickPay API responses at [https://learn.quickpay.net/tech-talk/api](https://learn.quickpay.net/tech-talk/api).
114
196
 
115
197
  ## Contributions
116
198
 
117
199
  To contribute:
118
200
 
119
- 1. Write a spec that fails
120
- 2. Fix spec by adding/changing code
201
+ 1. Write a test that fails
202
+ 2. Fix test by adding/changing code
121
203
  3. Add feature or bugfix to changelog in the "Unreleased" section
122
204
  4. Submit a pull request
123
205
  5. World is now a better place! :)
@@ -125,5 +207,5 @@ To contribute:
125
207
  ### Running the specs
126
208
 
127
209
  ```
128
- bundle exec rspec
210
+ $ bundle exec rake test
129
211
  ```
data/Rakefile CHANGED
@@ -1 +1,33 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require "rubocop/rake_task"
4
+
5
+ task default: :test
6
+
7
+ desc "Open an irb/pry session"
8
+ task :console do
9
+ exec "bin/console"
10
+ end
11
+
12
+ namespace :test do
13
+ RuboCop::RakeTask.new
14
+
15
+ task :opts do
16
+ ENV["TESTOPTS"] = "--verbose"
17
+ end
18
+
19
+ desc "Run tests"
20
+ task :specs do |t|
21
+ Rake::TestTask.new(t.name) do |tt|
22
+ tt.libs << "."
23
+ tt.test_files = Dir.glob("test/*.rb")
24
+ tt.warning = false
25
+ end
26
+ end
27
+
28
+ desc "Run tests with verbose output"
29
+ task verbose: %i[opts test]
30
+ end
31
+
32
+ desc "Run test suite"
33
+ task test: ["test:specs", "test:rubocop"]
data/bin/console ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ ENV["APP_KIND"] = "console"
3
+ APP_ROOT = File.realdirpath(File.expand_path("..", __dir__))
4
+ $LOAD_PATH.unshift(APP_ROOT)
5
+
6
+ require "irb"
7
+ require "lib/quickpay/api/client"
8
+
9
+ CLIENT = QuickPay::API::Client.new
10
+
11
+ ARGV.clear
12
+ IRB.start
@@ -1,34 +1,81 @@
1
- require 'quickpay'
2
- require 'quickpay/api/request'
3
- require 'quickpay/api/errors'
1
+ require "excon"
2
+ require "json"
3
+ require "quickpay/api/error"
4
+ require "quickpay/api/version"
4
5
 
5
6
  module QuickPay
6
- class << self
7
- attr_accessor :base_uri
8
- end
9
-
10
7
  module API
11
8
  class Client
12
- attr_accessor :options
13
-
14
- def initialize(auth_params = {}, opts = {})
15
- opts[:secret] ||= extract_auth(auth_params)
16
- opts[:base_uri] ||= (QuickPay.base_uri || QuickPay::BASE_URI)
9
+ DEFAULT_HEADERS = {
10
+ "User-Agent" => "quickpay-ruby-client, v#{QuickPay::API::VERSION}",
11
+ "Accept-Version" => "v10"
12
+ }.freeze
13
+
14
+ Request = Struct.new(:method, :path, :body, :headers, :query) # rubocop:disable Lint/StructNewOverride
15
+
16
+ def initialize(username: nil, password: nil, base_uri: "https://api.quickpay.net", options: {})
17
+ opts = {
18
+ read_timeout: options.fetch(:read_timeout, 60),
19
+ write_timeout: options.fetch(:write_timeout, 60),
20
+ connect_timeout: options.fetch(:connect_timeout, 60),
21
+ json_opts: options.fetch(:json_opts, nil)
22
+ }
17
23
 
18
- @options = opts.dup
24
+ opts[:username] = Excon::Utils.escape_uri(username) if username
25
+ opts[:password] = Excon::Utils.escape_uri(password) if password
26
+
27
+ @connection = Excon.new(base_uri, opts)
19
28
  end
20
-
21
- def extract_auth params
22
- if params[:email] and params[:password]
23
- "#{params[:email]}:#{params[:password]}"
24
- elsif params[:api_key]
25
- ":#{params[:api_key]}"
29
+
30
+ %i[get post patch put delete head].each do |method|
31
+ define_method(method) do |path, **options, &block|
32
+ headers = DEFAULT_HEADERS.merge(options.fetch(:headers, {}))
33
+ body = begin
34
+ data = options.fetch(:body, "")
35
+ if headers["Content-Type"] == "application/json" && data.instance_of?(Hash)
36
+ data.to_json
37
+ else
38
+ data
39
+ end
40
+ end
41
+
42
+ req = Request.new(
43
+ method,
44
+ path,
45
+ scrub_body(body.dup, headers["Content-Type"]),
46
+ headers,
47
+ options.fetch(:query, {})
48
+ ).freeze
49
+
50
+ res = @connection.request(**req.to_h)
51
+ error = QuickPay::API::Error.by_status_code(res.status, res.body, res.headers, req)
52
+
53
+ if !options.fetch(:raw, false) && res.headers["Content-Type"] =~ %r{application/json}
54
+ res.body = JSON.parse(res.body, options[:json_opts] || @connection.data[:json_opts])
55
+ end
56
+
57
+ if block
58
+ # Raise error if not specified as fourth block parameter
59
+ raise error if error && block.parameters.size < 4
60
+
61
+ block.call(res.body, res.status, res.headers, error)
62
+ else
63
+ raise error if error
64
+
65
+ [res.body, res.status, res.headers]
66
+ end
26
67
  end
27
68
  end
28
69
 
29
- [:get, :post, :patch, :put, :delete, :head].each do |method|
30
- define_method(method) do |*args|
31
- Request.new(options).request(method, *args)
70
+ private
71
+
72
+ def scrub_body(body, content_type)
73
+ return "" if body.to_s.empty?
74
+
75
+ if ["application/json", "application/x-www-form-urlencoded"].include?(content_type)
76
+ body
77
+ else
78
+ "<scrubbed for Content-Type #{content_type}>"
32
79
  end
33
80
  end
34
81
  end
@@ -0,0 +1,68 @@
1
+ module QuickPay
2
+ module API
3
+ class Error < StandardError
4
+ class BadRequest < Error; end
5
+
6
+ class Unauthorized < Error; end
7
+
8
+ class PaymentRequired < Error; end
9
+
10
+ class Forbidden < Error; end
11
+
12
+ class NotFound < Error; end
13
+
14
+ class MethodNotAllowed < Error; end
15
+
16
+ class NotAcceptable < Error; end
17
+
18
+ class Conflict < Error; end
19
+
20
+ class TooManyRequest < Error; end
21
+
22
+ class InternalServerError < Error; end
23
+
24
+ class BadGateway < Error; end
25
+
26
+ class ServiceUnavailable < Error; end
27
+
28
+ class GatewayTimeout < Error; end
29
+
30
+ CLASS_MAP = {
31
+ 400 => BadRequest,
32
+ 401 => Unauthorized,
33
+ 402 => PaymentRequired,
34
+ 403 => Forbidden,
35
+ 404 => NotFound,
36
+ 405 => MethodNotAllowed,
37
+ 406 => NotAcceptable,
38
+ 409 => Conflict,
39
+ 429 => TooManyRequest,
40
+ 500 => InternalServerError,
41
+ 502 => BadGateway,
42
+ 503 => ServiceUnavailable,
43
+ 504 => GatewayTimeout
44
+ }.freeze
45
+
46
+ attr_reader :status, :body, :headers, :request
47
+
48
+ def initialize(status, body, headers, request)
49
+ @status = status
50
+ @body = body
51
+ @headers = headers
52
+ @request = request
53
+ end
54
+
55
+ def to_s
56
+ "#<#{self.class}: status=#{status}, body=#{body.inspect}, " \
57
+ "headers=#{headers.inspect} request=#{request.inspect}>"
58
+ end
59
+ alias_method :inspect, :to_s
60
+
61
+ def self.by_status_code(status, body, headers, request)
62
+ return if (200..399).cover? status
63
+
64
+ CLASS_MAP.fetch(status, QuickPay::API::Error).new(status, body, headers, request)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,7 +1,5 @@
1
-
2
1
  module QuickPay
3
2
  module API
4
- class Conflict < Error
5
- end
3
+ VERSION = "3.0.0".freeze
6
4
  end
7
5
  end
@@ -1,16 +1,17 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("lib", __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'quickpay/version'
3
+ require "quickpay/api/version"
5
4
 
6
5
  Gem::Specification.new do |spec|
6
+ spec.required_ruby_version = ">= 2.5.0" # rubocop:disable Gemspec/RequiredRubyVersion
7
+
7
8
  spec.name = "quickpay-ruby-client"
8
- spec.version = QuickPay::VERSION
9
+ spec.version = QuickPay::API::VERSION
9
10
  spec.authors = ["QuickPay Developers"]
10
11
  spec.email = ["support@quickpay.net"]
11
12
 
12
13
  spec.summary = "Ruby client for QuickPay API"
13
- spec.description = "Embed QuickPay's secure payments directly into your Ruby applications. more at https://tech.quickpay.net"
14
+ spec.description = "Embed QuickPay's secure payments directly into your Ruby applications. Learn more at https://tech.quickpay.net"
14
15
  spec.homepage = "https://github.com/QuickPay/quickpay-ruby-client"
15
16
  spec.license = "MIT"
16
17
 
@@ -19,11 +20,13 @@ Gem::Specification.new do |spec|
19
20
  spec.require_paths = ["lib"]
20
21
 
21
22
  spec.add_development_dependency "bundler"
22
- spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_development_dependency "rspec", "~> 3.2"
24
- spec.add_development_dependency "rspec-mocks"
25
- spec.add_development_dependency "webmock", "~> 1.24"
26
- spec.add_development_dependency "pry-byebug"
23
+ spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rubocop"
27
+ spec.add_development_dependency "simplecov"
28
+ spec.add_development_dependency "simplecov-console"
27
29
 
28
- spec.add_dependency "httmultiparty", "~> 0.3.16"
30
+ spec.add_dependency "excon", "~> 0.79.0"
31
+ spec.add_dependency "json", "~> 2.5.0"
29
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickpay-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - QuickPay Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-25 00:00:00.000000000 Z
11
+ date: 2021-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,35 +25,35 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.2'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.2'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec-mocks
56
+ name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,21 +67,21 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: webmock
70
+ name: rubocop
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.24'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.24'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: pry-byebug
84
+ name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,21 +95,49 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: httmultiparty
98
+ name: simplecov-console
99
99
  requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: excon
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.79.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
100
121
  requirements:
101
122
  - - "~>"
102
123
  - !ruby/object:Gem::Version
103
- version: 0.3.16
124
+ version: 0.79.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: json
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 2.5.0
104
132
  type: :runtime
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
- version: 0.3.16
138
+ version: 2.5.0
111
139
  description: Embed QuickPay's secure payments directly into your Ruby applications.
112
- more at https://tech.quickpay.net
140
+ Learn more at https://tech.quickpay.net
113
141
  email:
114
142
  - support@quickpay.net
115
143
  executables: []
@@ -117,30 +145,16 @@ extensions: []
117
145
  extra_rdoc_files: []
118
146
  files:
119
147
  - ".gitignore"
120
- - ".rspec"
121
148
  - ".travis.yml"
122
149
  - CHANGELOG.md
123
150
  - Gemfile
124
151
  - LICENSE.txt
125
152
  - README.md
126
153
  - Rakefile
127
- - lib/quickpay.rb
154
+ - bin/console
128
155
  - lib/quickpay/api/client.rb
129
- - lib/quickpay/api/errors.rb
130
- - lib/quickpay/api/errors/bad_request.rb
131
- - lib/quickpay/api/errors/conflict.rb
132
- - lib/quickpay/api/errors/forbidden.rb
133
- - lib/quickpay/api/errors/method_not_allowed.rb
134
- - lib/quickpay/api/errors/not_acceptable.rb
135
- - lib/quickpay/api/errors/not_found.rb
136
- - lib/quickpay/api/errors/payment_required.rb
137
- - lib/quickpay/api/errors/quickpay_error.rb
138
- - lib/quickpay/api/errors/server_error.rb
139
- - lib/quickpay/api/errors/unauthorized.rb
140
- - lib/quickpay/api/request.rb
141
- - lib/quickpay/constants.rb
142
- - lib/quickpay/logger.rb
143
- - lib/quickpay/version.rb
156
+ - lib/quickpay/api/error.rb
157
+ - lib/quickpay/api/version.rb
144
158
  - quickpay-ruby-client.gemspec
145
159
  homepage: https://github.com/QuickPay/quickpay-ruby-client
146
160
  licenses:
@@ -154,15 +168,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
168
  requirements:
155
169
  - - ">="
156
170
  - !ruby/object:Gem::Version
157
- version: '0'
171
+ version: 2.5.0
158
172
  required_rubygems_version: !ruby/object:Gem::Requirement
159
173
  requirements:
160
174
  - - ">="
161
175
  - !ruby/object:Gem::Version
162
176
  version: '0'
163
177
  requirements: []
164
- rubyforge_project:
165
- rubygems_version: 2.6.6
178
+ rubygems_version: 3.1.2
166
179
  signing_key:
167
180
  specification_version: 4
168
181
  summary: Ruby client for QuickPay API
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/lib/quickpay.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'json'
2
- require 'quickpay/version'
3
- require 'quickpay/logger'
4
- require 'quickpay/constants'
@@ -1,10 +0,0 @@
1
-
2
- [:quickpay_error, :bad_request, :unauthorized, :payment_required,
3
- :forbidden, :not_found, :method_not_allowed, :not_acceptable,
4
- :conflict, :server_error].each do |err_code|
5
- require "quickpay/api/errors/#{err_code}"
6
- end
7
-
8
-
9
-
10
-
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class BadRequest < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class Forbidden < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class MethodNotAllowed < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class NotAcceptable < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class NotFound < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class PaymentRequired < Error
5
- end
6
- end
7
- end
@@ -1,13 +0,0 @@
1
- module QuickPay
2
- module API
3
- class Error < StandardError
4
- attr_reader :code, :status, :body
5
-
6
- def initialize(code, status, body)
7
- @code = code
8
- @status = status
9
- @body = body
10
- end
11
- end
12
- end
13
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class ServerError < Error
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
-
2
- module QuickPay
3
- module API
4
- class Unauthorized < Error
5
- end
6
- end
7
- end
@@ -1,98 +0,0 @@
1
- require 'httmultiparty'
2
-
3
- module QuickPay
4
- module API
5
- class Request
6
- include HTTMultiParty
7
-
8
- attr_reader :options, :secret
9
-
10
- def initialize (options = {})
11
- @options = options.dup
12
- @secret = @options.delete(:secret)
13
- self.class.base_uri(options[:base_uri] || BASE_URI)
14
- end
15
-
16
- def request method, path, data = {}
17
- raw = data.delete(:raw)
18
- req_headers = headers.merge(data.delete(:headers) || {})
19
-
20
- http_options = options.dup
21
- if data.any? { |_key, value| value.is_a?(File) }
22
- http_options[:body] = data
23
- http_options[:detect_mime_type] = true
24
- else
25
- case method
26
- when :get, :delete, :head
27
- http_options[:query] = data
28
- when :post, :patch, :put
29
- http_options[:body] = data.to_json
30
- req_headers["Content-Type"] = "application/json"
31
- end
32
- end
33
-
34
- http_options[:headers] = headers.merge(req_headers)
35
- QuickPay.logger.debug { "#{method.to_s.upcase} #{base_uri}#{path} #{http_options}" }
36
- create_response(raw, self.class.send(method, path, http_options))
37
- end
38
-
39
- def create_response raw, res
40
- if raw
41
- [res.code, res.body, res.headers]
42
- else
43
- response = res.parsed_response
44
- raise_error(response, res.code) if res.code >= 400
45
- response
46
- end
47
- end
48
-
49
- def raise_error body, status
50
- code = API_STATUS_CODES[status].to_s
51
- args = [code, status, body]
52
-
53
- klass =
54
- begin
55
- require "quickpay/api/errors/#{code}"
56
- class_name = code.split('_').map(&:capitalize).join('')
57
- QuickPay::API.const_get(class_name)
58
- rescue LoadError, NameError
59
- QuickPay::API::Error
60
- end
61
-
62
- fail klass.new(*args), error_description(body)
63
- end
64
-
65
- private
66
-
67
- def base_uri
68
- self.class.default_options[:base_uri]
69
- end
70
-
71
- def error_description msg
72
- msg
73
- end
74
-
75
- def headers
76
- heads = {
77
- 'User-Agent' => user_agent,
78
- 'Accept-Version' => "v#{QuickPay::API_VERSION}"
79
- }
80
- heads['Authorization'] = "Basic #{authorization}" if secret != nil
81
- heads
82
- end
83
-
84
- def user_agent
85
- user_agent = "quickpay-ruby-client, v#{QuickPay::VERSION}"
86
- user_agent += ", #{RUBY_VERSION}, #{RUBY_PLATFORM}, #{RUBY_PATCHLEVEL}"
87
- if defined?(RUBY_ENGINE)
88
- user_agent += ", #{RUBY_ENGINE}"
89
- end
90
- user_agent
91
- end
92
-
93
- def authorization
94
- Base64.strict_encode64(secret)
95
- end
96
- end
97
- end
98
- end
@@ -1,21 +0,0 @@
1
-
2
- module QuickPay
3
- BASE_URI = 'https://api.quickpay.net'
4
- API_VERSION = 10
5
-
6
- API_STATUS_CODES = {
7
- 200 => :ok,
8
- 201 => :created,
9
- 202 => :accepted,
10
- 400 => :bad_request,
11
- 401 => :unauthorized,
12
- 402 => :payment_required,
13
- 403 => :forbidden,
14
- 404 => :not_found,
15
- 405 => :method_not_allowed,
16
- 406 => :not_acceptable,
17
- 409 => :conflict,
18
- 500 => :server_error
19
- }
20
- end
21
-
@@ -1,16 +0,0 @@
1
- require 'logger'
2
-
3
- module QuickPay
4
- class << self
5
- attr_writer :logger
6
-
7
- def logger
8
- @logger ||= lambda {
9
- logger = Logger.new($stdout)
10
- logger.level = Logger::INFO
11
- logger
12
- }.call
13
- end
14
-
15
- end
16
- end
@@ -1,3 +0,0 @@
1
- module QuickPay
2
- VERSION = "1.2.0"
3
- end