paddle 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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