paddle 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +67 -2
  5. data/README.md +51 -3
  6. data/lib/paddle/classic/client.rb +0 -1
  7. data/lib/paddle/classic/resource.rb +1 -1
  8. data/lib/paddle/classic/resources/charges.rb +1 -3
  9. data/lib/paddle/classic/resources/coupons.rb +6 -8
  10. data/lib/paddle/classic/resources/licenses.rb +1 -3
  11. data/lib/paddle/classic/resources/modifiers.rb +4 -6
  12. data/lib/paddle/classic/resources/pay_links.rb +0 -2
  13. data/lib/paddle/classic/resources/payments.rb +3 -5
  14. data/lib/paddle/classic/resources/plans.rb +2 -4
  15. data/lib/paddle/classic/resources/products.rb +0 -2
  16. data/lib/paddle/classic/resources/transactions.rb +0 -2
  17. data/lib/paddle/classic/resources/users.rb +7 -9
  18. data/lib/paddle/classic/resources/webhooks.rb +0 -2
  19. data/lib/paddle/client.rb +36 -46
  20. data/lib/paddle/collection.rb +12 -0
  21. data/lib/paddle/configuration.rb +1 -3
  22. data/lib/paddle/error.rb +123 -0
  23. data/lib/paddle/models/address.rb +1 -5
  24. data/lib/paddle/models/adjustment.rb +1 -5
  25. data/lib/paddle/models/business.rb +1 -5
  26. data/lib/paddle/models/customer.rb +1 -5
  27. data/lib/paddle/models/discount.rb +1 -5
  28. data/lib/paddle/models/event.rb +0 -4
  29. data/lib/paddle/models/event_type.rb +0 -4
  30. data/lib/paddle/models/notification.rb +0 -4
  31. data/lib/paddle/models/notification_setting.rb +1 -5
  32. data/lib/paddle/models/price.rb +1 -5
  33. data/lib/paddle/models/pricing_preview.rb +1 -5
  34. data/lib/paddle/models/product.rb +1 -5
  35. data/lib/paddle/models/report.rb +2 -6
  36. data/lib/paddle/models/subscription.rb +3 -7
  37. data/lib/paddle/models/transaction.rb +4 -8
  38. data/lib/paddle/object.rb +22 -1
  39. data/lib/paddle/version.rb +1 -1
  40. data/lib/paddle.rb +2 -2
  41. data/paddle.gemspec +3 -3
  42. metadata +8 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0c36c67374aa35e91a2497199311888ef26eb0265cd14dddf57f535e7dabb6e
4
- data.tar.gz: 287d3e39a116eb4b19bba68baaa0772c67306e0f47249c81c815a29ab5a82f0f
3
+ metadata.gz: fd93d2c8220b972ffa99dc9134c9ae6a1dd4da4051d63d363f825f4130be5965
4
+ data.tar.gz: 4e6f0566db66650772cef15c976d229221cf3292b8a60f044ac22cfe91f81d70
5
5
  SHA512:
6
- metadata.gz: 30ab0451e76ea879e948373553f707359e9847f92f9a06a1d962dad8f327e471d89858b505e27e7e030570db5413d161943b6aa29b7efe68dc26cdb9723bad7b
7
- data.tar.gz: 10fd334a894063e6f14c69fb9e03d1931e9153877037b786cc127fec82d2ba4d0cf992ec1441ca4550ae469dcf444e8abf64404f4478573e28f834ab00d745e5
6
+ metadata.gz: 51904dcd27cdc1272ffffe94397ab53756a07cf0de48071d8e4b4830efd51533965296dd7f0b74667e6a0be0f9f6dd3ec2fbba6dda6f2b512983ab01be0e4096
7
+ data.tar.gz: aedd0b4538ed33115788157c00e18b06c83da69ac0491fa1f62f69ecf5c77cebc9e27c9f8e9aa51bfd23bf13a94f67a97f8657bd7a29d3b42bc4a2c9bb41d311
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ # Omakase Ruby styling for Rails
2
+ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
3
+
4
+ # Overwrite or add rules to create your own house style
5
+ #
6
+ # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
7
+ # Layout/SpaceInsideArrayLiteralBrackets:
8
+ # Enabled: false
9
+
10
+ Rails/RefuteMethods:
11
+ Enabled: false
data/Gemfile CHANGED
@@ -9,5 +9,5 @@ gem "rake", "~> 13.0"
9
9
 
10
10
  gem "minitest", "~> 5.0"
11
11
  gem "dotenv"
12
-
13
12
  gem "vcr"
13
+ gem "rubocop-rails-omakase", require: false
data/Gemfile.lock CHANGED
@@ -1,22 +1,86 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paddle (2.2.0)
4
+ paddle (2.3.0)
5
5
  faraday (~> 2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ activesupport (7.1.3.4)
11
+ base64
12
+ bigdecimal
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ connection_pool (>= 2.2.5)
15
+ drb
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ mutex_m
19
+ tzinfo (~> 2.0)
20
+ ast (2.4.2)
10
21
  base64 (0.1.1)
22
+ bigdecimal (3.1.8)
23
+ concurrent-ruby (1.3.3)
24
+ connection_pool (2.4.1)
11
25
  dotenv (2.7.6)
26
+ drb (2.2.1)
12
27
  faraday (2.7.11)
13
28
  base64
14
29
  faraday-net_http (>= 2.0, < 3.1)
15
30
  ruby2_keywords (>= 0.0.4)
16
31
  faraday-net_http (3.0.2)
32
+ i18n (1.14.5)
33
+ concurrent-ruby (~> 1.0)
34
+ json (2.7.2)
35
+ language_server-protocol (3.17.0.3)
17
36
  minitest (5.19.0)
18
- rake (13.0.6)
37
+ mutex_m (0.2.0)
38
+ parallel (1.25.1)
39
+ parser (3.3.3.0)
40
+ ast (~> 2.4.1)
41
+ racc
42
+ racc (1.8.0)
43
+ rack (3.1.7)
44
+ rainbow (3.1.1)
45
+ rake (13.2.1)
46
+ regexp_parser (2.9.2)
47
+ rexml (3.3.0)
48
+ strscan
49
+ rubocop (1.64.1)
50
+ json (~> 2.3)
51
+ language_server-protocol (>= 3.17.0)
52
+ parallel (~> 1.10)
53
+ parser (>= 3.3.0.2)
54
+ rainbow (>= 2.2.2, < 4.0)
55
+ regexp_parser (>= 1.8, < 3.0)
56
+ rexml (>= 3.2.5, < 4.0)
57
+ rubocop-ast (>= 1.31.1, < 2.0)
58
+ ruby-progressbar (~> 1.7)
59
+ unicode-display_width (>= 2.4.0, < 3.0)
60
+ rubocop-ast (1.31.3)
61
+ parser (>= 3.3.1.0)
62
+ rubocop-minitest (0.35.0)
63
+ rubocop (>= 1.61, < 2.0)
64
+ rubocop-ast (>= 1.31.1, < 2.0)
65
+ rubocop-performance (1.21.0)
66
+ rubocop (>= 1.48.1, < 2.0)
67
+ rubocop-ast (>= 1.31.1, < 2.0)
68
+ rubocop-rails (2.25.0)
69
+ activesupport (>= 4.2.0)
70
+ rack (>= 1.1)
71
+ rubocop (>= 1.33.0, < 2.0)
72
+ rubocop-ast (>= 1.31.1, < 2.0)
73
+ rubocop-rails-omakase (1.0.0)
74
+ rubocop
75
+ rubocop-minitest
76
+ rubocop-performance
77
+ rubocop-rails
78
+ ruby-progressbar (1.13.0)
19
79
  ruby2_keywords (0.0.5)
80
+ strscan (3.1.0)
81
+ tzinfo (2.0.6)
82
+ concurrent-ruby (~> 1.0)
83
+ unicode-display_width (2.5.0)
20
84
  vcr (6.2.0)
21
85
 
22
86
  PLATFORMS
@@ -27,6 +91,7 @@ DEPENDENCIES
27
91
  minitest (~> 5.0)
28
92
  paddle!
29
93
  rake (~> 13.0)
94
+ rubocop-rails-omakase
30
95
  vcr
31
96
 
32
97
  BUNDLED WITH
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Paddle Ruby Library
2
2
 
3
- A Ruby library for the Paddle APIs, both Classic and Billing.
3
+ The easiest and most complete Ruby library for the Paddle APIs, both Classic and Billing.
4
4
 
5
5
  ## Installation
6
6
 
@@ -33,10 +33,57 @@ Paddle.configure do |config|
33
33
  end
34
34
  ```
35
35
 
36
+ ### Resources
37
+
38
+ The gem maps as closely as we can to the Paddle API so you can easily convert API examples to gem code.
39
+
40
+ Responses are created as objects like `Paddle::Product`. Having types like `Paddle::Product` is handy for understanding what
41
+ type of object you're working with. They're built using OpenStruct so you can easily access data in a Ruby-ish way.
42
+
43
+ ### Pagination
44
+
45
+ Some of the endpoints return pages of results. The result object will have a `data` key to access the results.
46
+
47
+ An example of using collections, including pagination:
48
+
49
+ ```ruby
50
+ results = Paddle::Product.list(per_page: 10)
51
+ #=> Paddle::Collection
52
+
53
+ results.total
54
+ #=> 10
55
+
56
+ results.data
57
+ #=> [#<Paddle::Product>, #<Paddle::Product>]
58
+
59
+ results.each do |result|
60
+ puts result.id
61
+ end
62
+
63
+ results.first
64
+ #=> #<Paddle::Product>
65
+
66
+ results.last
67
+ #=> #<Paddle::Product>
68
+
69
+ # Retrieve the next page
70
+ Paddle::Product.list(per_page: 10, after: "abc123")
71
+ #=> Paddle::Collection
72
+ ```
73
+
36
74
  ### Caveats
37
75
 
38
- The Paddle API doesn't take `nil` values for optional parameters. If you want to
39
- remove a value, you'll need to pass `"null"` instead.
76
+ >[!NOTE]
77
+ >
78
+ > The Paddle API doesn't take `nil` values for optional parameters. If you want to remove a value, you'll need to pass `"null"` instead.
79
+
80
+ ### Updating records
81
+
82
+ For API endpoints that support it, you can use the `update` method to update a record, like so:
83
+
84
+ ```ruby
85
+ Paddle::Product.retrieve(id: "pro_abc123").update(name: "My New Name")
86
+ ```
40
87
 
41
88
  ### Products
42
89
 
@@ -128,6 +175,7 @@ Paddle::Customer.list(email: "me@mydomain.com")
128
175
 
129
176
  # Create a customer
130
177
  # https://developer.paddle.com/api-reference/customers/create-customer
178
+ # Returns a Paddle::ConflictError if the email is already used on Paddle
131
179
  Paddle::Customer.create(email: "myemail@mydomain.com", name: "Customer Name")
132
180
 
133
181
  # Retrieve a customer
@@ -1,7 +1,6 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class Client
4
-
5
4
  BASE_URL = "https://vendors.paddle.com/api"
6
5
  SANDBOX_BASE_URL = "https://sandbox-vendors.paddle.com/api"
7
6
 
@@ -14,7 +14,7 @@ module Paddle
14
14
  # end
15
15
 
16
16
  def post_request(url, body: {}, headers: {})
17
- attrs = {vendor_id: client.vendor_id, vendor_auth_code: client.vendor_auth_code}
17
+ attrs = { vendor_id: client.vendor_id, vendor_auth_code: client.vendor_auth_code }
18
18
  handle_response client.connection.post(url, attrs.merge(body), headers)
19
19
  end
20
20
 
@@ -1,13 +1,11 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class ChargesResource < Resource
4
-
5
4
  def create(subscription_id:, amount:, charge_name:)
6
- attrs = {amount: amount, charge_name: charge_name}
5
+ attrs = { amount: amount, charge_name: charge_name }
7
6
  response = post_request("2.0/subscription/#{subscription_id}/charge", body: attrs)
8
7
  Charge.new(response.body["response"])
9
8
  end
10
-
11
9
  end
12
10
  end
13
11
  end
@@ -1,33 +1,31 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class CouponsResource < Resource
4
-
5
4
  def list(product_id:)
6
- response = post_request("2.0/product/list_coupons", body: {product_id: product_id})
5
+ response = post_request("2.0/product/list_coupons", body: { product_id: product_id })
7
6
  Collection.from_response(response, type: Coupon)
8
7
  end
9
8
 
10
9
  def create(coupon_type:, discount_type:, discount_amount:, **params)
11
- attrs = {coupon_type: coupon_type, discount_type: discount_type, discount_amount: discount_amount}
10
+ attrs = { coupon_type: coupon_type, discount_type: discount_type, discount_amount: discount_amount }
12
11
 
13
12
  response = post_request("2.1/product/create_coupon", body: attrs.merge(params))
14
13
 
15
14
  coupons = response.body["response"]["coupon_codes"]
16
15
 
17
- coupons.map {|c| Paddle::Coupon.new(code: c)}
16
+ coupons.map { |c| Paddle::Coupon.new(code: c) }
18
17
  end
19
18
 
20
19
  def delete(coupon_code:, product_id:)
21
- attrs = {coupon_code: coupon_code, product_id: product_id}
20
+ attrs = { coupon_code: coupon_code, product_id: product_id }
22
21
  response = post_request("2.0/product/delete_coupon", body: attrs)
23
- return true if response.success?
22
+ true if response.success?
24
23
  end
25
24
 
26
25
  def update(**params)
27
26
  response = post_request("2.1/product/update_coupon", body: params)
28
- return true if response.success?
27
+ true if response.success?
29
28
  end
30
-
31
29
  end
32
30
  end
33
31
  end
@@ -1,15 +1,13 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class LicensesResource < Resource
4
-
5
4
  def generate(product_id:, allowed_uses:, **params)
6
- attrs = {product_id: product_id, allowed_uses: allowed_uses}
5
+ attrs = { product_id: product_id, allowed_uses: allowed_uses }
7
6
 
8
7
  response = post_request("2.0/product/generate_license", body: attrs.merge(params))
9
8
 
10
9
  License.new(response.body["response"]) if response.success?
11
10
  end
12
-
13
11
  end
14
12
  end
15
13
  end
@@ -1,26 +1,24 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class ModifiersResource < Resource
4
-
5
4
  def list(**params)
6
5
  response = post_request("2.0/subscription/modifiers", body: params)
7
6
  Collection.from_response(response, type: Modifier)
8
7
  end
9
8
 
10
9
  def create(subscription_id:, modifier_amount:, **params)
11
- attrs = {subscription_id: subscription_id, modifier_amount: modifier_amount}
10
+ attrs = { subscription_id: subscription_id, modifier_amount: modifier_amount }
12
11
  create_response = post_request("2.0/subscription/modifiers/create", body: attrs.merge(params))
13
12
 
14
- response = post_request("2.0/subscription/modifiers", body: {subscription_id: subscription_id} )
13
+ response = post_request("2.0/subscription/modifiers", body: { subscription_id: subscription_id })
15
14
  Collection.from_response(response, type: Modifier)
16
15
  end
17
16
 
18
17
  def delete(modifier_id:)
19
- attrs = {modifier_id: modifier_id}
18
+ attrs = { modifier_id: modifier_id }
20
19
  response = post_request("2.0/subscription/modifiers/delete", body: attrs)
21
- return true if response.success?
20
+ true if response.success?
22
21
  end
23
-
24
22
  end
25
23
  end
26
24
  end
@@ -1,13 +1,11 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class PayLinksResource < Resource
4
-
5
4
  def generate(**params)
6
5
  response = post_request("2.0/product/generate_pay_link", body: params)
7
6
 
8
7
  PayLink.new(response.body["response"]) if response.success?
9
8
  end
10
-
11
9
  end
12
10
  end
13
11
  end
@@ -1,24 +1,22 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class PaymentsResource < Resource
4
-
5
4
  def list(**params)
6
5
  response = post_request("2.0/subscription/payments", body: params)
7
6
  Collection.from_response(response, type: Payment)
8
7
  end
9
8
 
10
9
  def reschedule(payment_id:, date:)
11
- attrs = {payment_id: payment_id, date: date}
10
+ attrs = { payment_id: payment_id, date: date }
12
11
  response = post_request("2.0/subscription/payments_reschedule", body: attrs)
13
- return true if response.success?
12
+ true if response.success?
14
13
  end
15
14
 
16
15
  def refund(order_id:, **params)
17
- attrs = {order_id: order_id}
16
+ attrs = { order_id: order_id }
18
17
  response = post_request("2.0/payment/refund", body: attrs.merge(params))
19
18
  PaymentRefund.new(response.body["response"])
20
19
  end
21
-
22
20
  end
23
21
  end
24
22
  end
@@ -1,21 +1,19 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class PlansResource < Resource
4
-
5
4
  def list
6
5
  response = post_request("2.0/subscription/plans")
7
6
  Collection.from_response(response, type: Plan)
8
7
  end
9
8
 
10
9
  def create(name:, type:, **params)
11
- attrs = {plan_name: name, plan_type: type}
10
+ attrs = { plan_name: name, plan_type: type }
12
11
  create_response = post_request("2.0/subscription/plans_create", body: attrs.merge(params))
13
12
 
14
13
  # After creating the Plan, because it doesn't return the whole record, grab it from the API and return that
15
- response = post_request("2.0/subscription/plans", body: {plan: create_response.body["response"]["product_id"]} )
14
+ response = post_request("2.0/subscription/plans", body: { plan: create_response.body["response"]["product_id"] })
16
15
  Plan.new(response.body.dig("response")[0]) if response.success?
17
16
  end
18
-
19
17
  end
20
18
  end
21
19
  end
@@ -1,12 +1,10 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class ProductsResource < Resource
4
-
5
4
  def list
6
5
  response = post_request("2.0/product/get_products")
7
6
  Collection.from_response(response, type: Product, key: "products")
8
7
  end
9
-
10
8
  end
11
9
  end
12
10
  end
@@ -1,12 +1,10 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class TransactionsResource < Resource
4
-
5
4
  def list(entity:, id:)
6
5
  response = post_request("2.0/#{entity}/#{id}/transactions")
7
6
  Collection.from_response(response, type: Transaction)
8
7
  end
9
-
10
8
  end
11
9
  end
12
10
  end
@@ -1,42 +1,40 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class UsersResource < Resource
4
-
5
4
  def list(**params)
6
5
  response = post_request("2.0/subscription/users", body: params)
7
6
  Collection.from_response(response, type: User)
8
7
  end
9
8
 
10
9
  def update(subscription_id:, **params)
11
- attrs = {subscription_id: subscription_id}
10
+ attrs = { subscription_id: subscription_id }
12
11
  response = post_request("2.0/subscription/users/update", body: attrs.merge(params))
13
12
  User.new(response.body["response"]) if response.success?
14
13
  end
15
14
 
16
15
  def pause(subscription_id:, **params)
17
- attrs = {subscription_id: subscription_id, pause: true}
16
+ attrs = { subscription_id: subscription_id, pause: true }
18
17
  response = post_request("2.0/subscription/users/update", body: attrs.merge(params))
19
18
  User.new(response.body["response"]) if response.success?
20
19
  end
21
20
 
22
21
  def unpause(subscription_id:, **params)
23
- attrs = {subscription_id: subscription_id, pause: false}
22
+ attrs = { subscription_id: subscription_id, pause: false }
24
23
  response = post_request("2.0/subscription/users/update", body: attrs.merge(params))
25
24
  User.new(response.body["response"]) if response.success?
26
25
  end
27
26
 
28
27
  def update_postcode(subscription_id:, postcode:)
29
- attrs = {subscription_id: subscription_id, postcode: postcode}
28
+ attrs = { subscription_id: subscription_id, postcode: postcode }
30
29
  response = post_request("2.0/subscription/users/postcode", body: attrs)
31
- return true if response.success?
30
+ true if response.success?
32
31
  end
33
32
 
34
33
  def cancel(subscription_id:)
35
- attrs = {subscription_id: subscription_id}
34
+ attrs = { subscription_id: subscription_id }
36
35
  response = post_request("2.0/subscription/users_cancel", body: attrs)
37
- return true if response.success?
36
+ true if response.success?
38
37
  end
39
-
40
38
  end
41
39
  end
42
40
  end
@@ -1,12 +1,10 @@
1
1
  module Paddle
2
2
  module Classic
3
3
  class WebhooksResource < Resource
4
-
5
4
  def list(**params)
6
5
  response = post_request("2.0/alert/webhooks", body: params)
7
6
  Collection.from_response(response, type: Webhook, key: "data")
8
7
  end
9
-
10
8
  end
11
9
  end
12
10
  end
data/lib/paddle/client.rb CHANGED
@@ -1,72 +1,62 @@
1
+ require "faraday"
2
+
1
3
  module Paddle
2
4
  class Client
3
-
4
5
  class << self
5
-
6
6
  def connection
7
- @connection ||= Faraday.new(Paddle.config.url) do |conn|
8
- conn.request :authorization, :Bearer, Paddle.config.api_key
9
-
10
- conn.headers = {
11
- "User-Agent" => "paddle/v#{VERSION} (github.com/deanpcmad/paddle)",
12
- "Paddle-Version" => Paddle.config.version.to_s
13
- }
14
-
15
- conn.request :json
16
-
17
- conn.response :json, content_type: "application/json"
18
- end
7
+ @connection ||= create_connection
19
8
  end
20
9
 
21
-
22
10
  def get_request(url, params: {}, headers: {})
23
- handle_response connection.get(url, params, headers)
11
+ handle_response(connection.get(url, params, headers))
24
12
  end
25
13
 
26
14
  def post_request(url, body: {}, headers: {})
27
- handle_response connection.post(url, body, headers)
15
+ handle_response(connection.post(url, body, headers))
28
16
  end
29
17
 
30
18
  def patch_request(url, body:, headers: {})
31
- handle_response connection.patch(url, body, headers)
19
+ handle_response(connection.patch(url, body, headers))
32
20
  end
33
21
 
34
22
  def delete_request(url, headers: {})
35
- handle_response connection.delete(url, headers)
23
+ handle_response(connection.delete(url, headers))
36
24
  end
37
25
 
38
- def handle_response(response)
39
- case response.status
40
- when 400
41
- raise Error, "Error 400: Your request was malformed. '#{response.body["error"]["code"]}'"
42
- when 401
43
- raise Error, "Error 401: You did not supply valid authentication credentials. '#{response.body["error"]}'"
44
- when 403
45
- raise Error, "Error 403: You are not allowed to perform that action. '#{response.body["error"]["code"]}'"
46
- when 404
47
- raise Error, "Error 404: No results were found for your request. '#{response.body["error"]["code"]}'"
48
- when 409
49
- raise Error, "Error 409: Your request was a conflict. '#{response.body["error"]["code"]}'"
50
- when 429
51
- raise Error, "Error 429: Your request exceeded the API rate limit. '#{response.body["error"]["code"]}'"
52
- when 500
53
- raise Error, "Error 500: We were unable to perform the request due to server-side problems. '#{response.body["error"]["code"]}'"
54
- when 503
55
- raise Error, "Error 503: You have been rate limited for sending more than 20 requests per second. '#{response.body["error"]["code"]}'"
56
- when 501
57
- raise Error, "Error 501: This resource has not been implemented. '#{response.body["error"]["code"]}'"
58
- when 204
59
- return true
60
- end
26
+ private
61
27
 
62
- if response.body && response.body["error"]
63
- raise Error, "Error #{response.body["error"]["code"]} - #{response.body["errors"]["message"]}"
28
+ def create_connection
29
+ Faraday.new(Paddle.config.url) do |conn|
30
+ conn.request :authorization, :Bearer, Paddle.config.api_key
31
+ conn.headers = default_headers
32
+ conn.request :json
33
+ conn.response :json
64
34
  end
35
+ end
65
36
 
66
- response
37
+ def default_headers
38
+ {
39
+ "User-Agent" => "paddle/v#{VERSION} (github.com/deanpcmad/paddle)",
40
+ "Paddle-Version" => Paddle.config.version.to_s
41
+ }
67
42
  end
68
43
 
69
- end
44
+ def handle_response(response)
45
+ return true if response.status == 204
46
+ return response unless error?(response)
70
47
 
48
+ raise_error(response)
49
+ end
50
+
51
+ def error?(response)
52
+ [ 400, 401, 403, 404, 409, 429, 500, 501, 503 ].include?(response.status) ||
53
+ response.body&.key?("error")
54
+ end
55
+
56
+ def raise_error(response)
57
+ error = Paddle::ErrorFactory.create(response.body, response.status)
58
+ raise error if error
59
+ end
60
+ end
71
61
  end
72
62
  end
@@ -23,5 +23,17 @@ module Paddle
23
23
  @data = data
24
24
  @total = total
25
25
  end
26
+
27
+ def each(&block)
28
+ data.each(&block)
29
+ end
30
+
31
+ def first
32
+ data.first
33
+ end
34
+
35
+ def last
36
+ data.last
37
+ end
26
38
  end
27
39
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Paddle
4
4
  class Configuration
5
-
6
5
  attr_reader :environment
7
6
 
8
7
  attr_accessor :version
@@ -15,7 +14,7 @@ module Paddle
15
14
 
16
15
  def environment=(env)
17
16
  env = env.nil? ? :production : env.to_sym
18
- unless [:development, :sandbox, :production].include?(env)
17
+ unless [ :development, :sandbox, :production ].include?(env)
19
18
  raise ArgumentError, "#{env.inspect} is not a valid environment"
20
19
  end
21
20
  @environment = env
@@ -29,6 +28,5 @@ module Paddle
29
28
  "https://sandbox-api.paddle.com"
30
29
  end
31
30
  end
32
-
33
31
  end
34
32
  end