paddle_pay 0.0.1

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 (116) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +207 -0
  4. data/lib/paddle_pay.rb +40 -0
  5. data/lib/paddle_pay/configuration.rb +17 -0
  6. data/lib/paddle_pay/connection.rb +69 -0
  7. data/lib/paddle_pay/errors/paddle_pay_error.rb +54 -0
  8. data/lib/paddle_pay/models/alert/webhook.rb +14 -0
  9. data/lib/paddle_pay/models/product/coupon.rb +36 -0
  10. data/lib/paddle_pay/models/product/license.rb +14 -0
  11. data/lib/paddle_pay/models/product/pay_link.rb +14 -0
  12. data/lib/paddle_pay/models/product/payment.rb +15 -0
  13. data/lib/paddle_pay/models/product/product.rb +12 -0
  14. data/lib/paddle_pay/models/subscription/charge.rb +14 -0
  15. data/lib/paddle_pay/models/subscription/modifier.rb +24 -0
  16. data/lib/paddle_pay/models/subscription/payment.rb +25 -0
  17. data/lib/paddle_pay/models/subscription/plan.rb +19 -0
  18. data/lib/paddle_pay/models/subscription/user.rb +31 -0
  19. data/lib/paddle_pay/models/transaction/checkout.rb +13 -0
  20. data/lib/paddle_pay/models/transaction/order.rb +13 -0
  21. data/lib/paddle_pay/models/transaction/product.rb +13 -0
  22. data/lib/paddle_pay/models/transaction/subscription.rb +13 -0
  23. data/lib/paddle_pay/models/transaction/user.rb +13 -0
  24. data/lib/paddle_pay/util.rb +36 -0
  25. data/lib/paddle_pay/version.rb +5 -0
  26. data/test/spec/paddle_pay/configuration_spec.rb +24 -0
  27. data/test/spec/paddle_pay/connection_spec.rb +115 -0
  28. data/test/spec/paddle_pay/models/alert/webhook_spec.rb +41 -0
  29. data/test/spec/paddle_pay/models/product/coupon_spec.rb +98 -0
  30. data/test/spec/paddle_pay/models/product/license_spec.rb +33 -0
  31. data/test/spec/paddle_pay/models/product/pay_link_spec.rb +33 -0
  32. data/test/spec/paddle_pay/models/product/payment_spec.rb +31 -0
  33. data/test/spec/paddle_pay/models/product/product_spec.rb +42 -0
  34. data/test/spec/paddle_pay/models/subscription/charge_spec.rb +31 -0
  35. data/test/spec/paddle_pay/models/subscription/modifier_spec.rb +70 -0
  36. data/test/spec/paddle_pay/models/subscription/payment_spec.rb +68 -0
  37. data/test/spec/paddle_pay/models/subscription/plan_spec.rb +57 -0
  38. data/test/spec/paddle_pay/models/subscription/user_spec.rb +87 -0
  39. data/test/spec/paddle_pay/models/transaction/checkout_spec.rb +41 -0
  40. data/test/spec/paddle_pay/models/transaction/order_spec.rb +41 -0
  41. data/test/spec/paddle_pay/models/transaction/product_spec.rb +41 -0
  42. data/test/spec/paddle_pay/models/transaction/subscription_spec.rb +41 -0
  43. data/test/spec/paddle_pay/models/transaction/user_spec.rb +41 -0
  44. data/test/spec/paddle_pay/util_spec.rb +41 -0
  45. data/test/spec/paddle_pay/version_spec.rb +9 -0
  46. data/test/test_helper.rb +18 -0
  47. data/test/vcr_cassettes/paddle_pay/alert/webhook/test_0001_should_list_all_webhooks.yml +61 -0
  48. data/test/vcr_cassettes/paddle_pay/alert/webhook/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  49. data/test/vcr_cassettes/paddle_pay/alert/webhook/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  50. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0001_should_list_all_coupons.yml +60 -0
  51. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0001_should_raise_an_error_if_the_coupon_deletion_is_invalid.yml +61 -0
  52. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0001_should_raise_an_error_if_the_coupon_is_invalid.yml +61 -0
  53. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0001_should_return_updated_0_if_the_coupon_group_update_is_invalid.yml +62 -0
  54. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0001_should_return_updated_0_if_the_coupon_update_is_invalid.yml +62 -0
  55. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  56. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0002_should_return_coupon_codes_if_the_coupon_is_valid.yml +60 -0
  57. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0002_should_return_success_if_the_coupon_deletion_is_valid.yml +62 -0
  58. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0002_should_return_updated_0_if_the_coupon_group_update_is_valid.yml +62 -0
  59. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0002_should_return_updated_0_if_the_coupon_update_is_valid.yml +62 -0
  60. data/test/vcr_cassettes/paddle_pay/product/coupon/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  61. data/test/vcr_cassettes/paddle_pay/product/license/test_0001_should_raise_an_error_if_license_generation_request_is_invalid.yml +61 -0
  62. data/test/vcr_cassettes/paddle_pay/product/license/test_0002_should_return_a_license_code_if_license_generation_request_is_valid.yml +61 -0
  63. data/test/vcr_cassettes/paddle_pay/product/pay_link/test_0001_should_raise_an_error_if_pay_link_generation_request_is_invalid.yml +61 -0
  64. data/test/vcr_cassettes/paddle_pay/product/pay_link/test_0002_should_return_an_url_if_pay_link_generation_request_is_valid.yml +60 -0
  65. data/test/vcr_cassettes/paddle_pay/product/payment/test_0001_should_raise_an_error_if_the_payment_refund_is_invalid.yml +61 -0
  66. data/test/vcr_cassettes/paddle_pay/product/payment/test_0002_should_return_success_if_the_payment_refund_is_valid.yml +60 -0
  67. data/test/vcr_cassettes/paddle_pay/product/test_0001_should_list_all_products.yml +60 -0
  68. data/test/vcr_cassettes/paddle_pay/product/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  69. data/test/vcr_cassettes/paddle_pay/product/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  70. data/test/vcr_cassettes/paddle_pay/subscription/charge/test_0001_should_raise_an_error_if_the_charge_is_invalid.yml +61 -0
  71. data/test/vcr_cassettes/paddle_pay/subscription/charge/test_0002_should_return_invoice_id_if_the_charge_is_valid.yml +61 -0
  72. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0001_should_list_all_modifiers.yml +62 -0
  73. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0001_should_raise_an_error_if_the_modifier_deletion_is_invalid.yml +61 -0
  74. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0001_should_raise_an_error_if_the_modifier_is_invalid.yml +61 -0
  75. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  76. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0002_should_return_a_modifier_id_if_the_modifier_is_valid.yml +60 -0
  77. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0002_should_return_a_product_id_if_the_modifier_deletion_is_valid.yml +60 -0
  78. data/test/vcr_cassettes/paddle_pay/subscription/modifier/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  79. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0001_should_list_all_payments.yml +60 -0
  80. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0001_should_raise_an_error_if_the_payment_refund_is_invalid.yml +61 -0
  81. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0001_should_raise_an_error_if_the_payment_reschedule_is_invalid.yml +313 -0
  82. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  83. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0002_should_return_success_if_the_payment_refund_is_valid.yml +60 -0
  84. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0002_should_return_success_if_the_payment_reschedule_is_valid.yml +62 -0
  85. data/test/vcr_cassettes/paddle_pay/subscription/payment/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  86. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0001_should_list_all_plans.yml +60 -0
  87. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0001_should_raise_an_error_if_the_plan_is_invalid.yml +61 -0
  88. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0002_should_be_successful_if_the_plan_is_valid.yml +62 -0
  89. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  90. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0002_should_return_a_product_id_if_the_plan_is_valid.yml +62 -0
  91. data/test/vcr_cassettes/paddle_pay/subscription/plan/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  92. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0001_should_list_all_users.yml +61 -0
  93. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0001_should_raise_an_error_if_the_cancelation_is_invalid.yml +61 -0
  94. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0001_should_raise_an_error_if_the_subscription_update_is_invalid.yml +61 -0
  95. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0001_should_raise_an_error_if_the_subscription_update_preview_is_invalid.yml +61 -0
  96. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  97. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0002_should_return_a_subscription_id_if_the_subscription_update_is_valid.yml +60 -0
  98. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0002_should_return_a_subscription_id_if_the_subscription_update_preview_is_valid.yml +60 -0
  99. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0002_should_return_success_if_the_cancelation_is_valid.yml +62 -0
  100. data/test/vcr_cassettes/paddle_pay/subscription/user/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  101. data/test/vcr_cassettes/paddle_pay/transaction/checkout/test_0001_should_list_all_checkouts.yml +61 -0
  102. data/test/vcr_cassettes/paddle_pay/transaction/checkout/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  103. data/test/vcr_cassettes/paddle_pay/transaction/checkout/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  104. data/test/vcr_cassettes/paddle_pay/transaction/order/test_0001_should_list_all_orders.yml +61 -0
  105. data/test/vcr_cassettes/paddle_pay/transaction/order/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  106. data/test/vcr_cassettes/paddle_pay/transaction/order/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  107. data/test/vcr_cassettes/paddle_pay/transaction/product/test_0001_should_list_all_products.yml +62 -0
  108. data/test/vcr_cassettes/paddle_pay/transaction/product/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  109. data/test/vcr_cassettes/paddle_pay/transaction/product/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  110. data/test/vcr_cassettes/paddle_pay/transaction/subscription/test_0001_should_list_all_subscriptions.yml +61 -0
  111. data/test/vcr_cassettes/paddle_pay/transaction/subscription/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  112. data/test/vcr_cassettes/paddle_pay/transaction/subscription/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  113. data/test/vcr_cassettes/paddle_pay/transaction/user/test_0001_should_list_all_users.yml +62 -0
  114. data/test/vcr_cassettes/paddle_pay/transaction/user/test_0002_should_raise_an_error_if_no_vendor_id_is_present.yml +61 -0
  115. data/test/vcr_cassettes/paddle_pay/transaction/user/test_0003_should_raise_an_error_if_no_vendor_auth_code_is_present.yml +61 -0
  116. metadata +358 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d4b576ab1993da2a68d2157288909b5a32263c0e64fba65c8f590ade235e34e4
4
+ data.tar.gz: 055e96a399e3b98a508ff638506bb44383fc05020258202447d314ffc7d1a402
5
+ SHA512:
6
+ metadata.gz: 4d4abed1bfa549c2fc8c50522c462d65ed0a82a92b046e9b72663556e90d5f16f07a17d61f8dc127b9a6b963a03bcc098a12c233f488372d16b4666b40ae120f
7
+ data.tar.gz: 5f82a368c69a8231840ecf002702ab0e44ec9e8e38f3ff8cf25135dd4e1a6da8bb41ba1215bf8147799afc442f85f63f83455116edfd7cad6e6bc88348beeeee
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2020 Nicolas Metzger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,207 @@
1
+ # PaddlePay
2
+
3
+ A Ruby wrapper for the paddle.com API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'paddle_pay'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ ## Configuration
18
+
19
+ Configure the gem with the credentials obtained from the Paddle Dashboard
20
+
21
+ ```ruby
22
+ PaddlePay.configure do |config|
23
+ config.vendor_id = 'YOUR VENDOR ID'
24
+ config.vendor_auth_code = 'YOUR VENDOR AUTH CODE'
25
+ end
26
+ ```
27
+ ## Usage
28
+
29
+ ### Product
30
+ List all published one-time products associated with your account:
31
+ ```ruby
32
+ PaddlePay::Product.list(filters = {}, options = {})
33
+ ```
34
+
35
+ ##### Coupons
36
+ Return any available coupons valid for a specified one-time product or subscription plan:
37
+ ```ruby
38
+ product_id = 123456
39
+ PaddlePay::Product::Coupon.list(product_id, options = {})
40
+ ```
41
+
42
+ Create a new coupon for the given product or a checkout:
43
+ ```ruby
44
+ attributes = { coupon_type: 'checkout', discount_type: 'percentage', discount_amount: '20', allowed_uses: 10 }
45
+ PaddlePay::Product::Coupon.create(attributes, options = {})
46
+ ```
47
+
48
+ Delete a given coupon and prevent it from being further used:
49
+ ```ruby
50
+ coupon_code = 'ABCDEFG'
51
+ product_id = 123456
52
+ PaddlePay::Product::Coupon.delete(coupon_code, product_id, options = {})
53
+ ```
54
+
55
+ Updating a single coupon code:
56
+ ```ruby
57
+ coupon_code = 'ABCDEFG'
58
+ attributes = { allowed_uses: 10 }
59
+ PaddlePay::Product::Coupon.update_code(coupon_code, attributes = {}, options = {})
60
+ ```
61
+
62
+ Updating a group of coupons:
63
+ ```ruby
64
+ group = 'GROUP123'
65
+ attributes = { allowed_uses: 10 }
66
+ PaddlePay::Product::Coupon.update_group(group, attributes = {}, options = {})
67
+ ```
68
+
69
+ ##### Pay Links
70
+ Set custom attributes for a one-time or subscription checkout link:
71
+ ```ruby
72
+ attributes = { product_id: '123456' }
73
+ PaddlePay::Product::PayLink.generate(attributes, options = {})
74
+ ```
75
+
76
+ ##### Payments
77
+ Request a refund for a one-time payment, either in full or partial:
78
+ ```ruby
79
+ order_id = 123456
80
+ PaddlePay::Product::Payment.refund(order_id, attributes = {}, options = {})
81
+ ```
82
+
83
+ ### Subscription
84
+
85
+ ##### Plans
86
+ List all of the available subscription plans:
87
+ ```ruby
88
+ PaddlePay::Subscription::Plan.list(filters = {}, options = {})
89
+ ```
90
+
91
+ Create a new subscription billing plan:
92
+ ```ruby
93
+ attributes = { plan_name: 'Test', plan_trial_days: 30, plan_length: 1, plan_type: 'month', main_currency_code: 'USD', recurring_price_usd: '5.00' }
94
+ PaddlePay::Subscription::Plan.create(attributes, options = {})
95
+ ```
96
+
97
+ ##### Subscription Users
98
+ List all users subscribed to any of your subscription plans:
99
+ ```ruby
100
+ PaddlePay::Subscription::User.list(filters = {}, options = {})
101
+ ```
102
+
103
+ Cancel the specified subscription:
104
+ ```ruby
105
+ subscription_id = 1234567
106
+ PaddlePay::Subscription::User.cancel(subscription_id, options = {})
107
+ ```
108
+
109
+ Update the quantity, price, and/or plan of a user’s subscription:
110
+ ```ruby
111
+ subscription_id = 1234567
112
+ attributes = { recurring_price: '10.00', currency: 'USD', quantity: 1, plan_id: 12345 }
113
+ PaddlePay::Subscription::User.update(subscription_id, attributes, options = {})
114
+ ```
115
+
116
+ Get a preview of subscription changes before they are committed:
117
+ ```ruby
118
+ PaddlePay::Subscription::User.preview_update(subscription_id, attributes, options = {})
119
+ ```
120
+ ##### Modifiers
121
+ List all the subscription modifiers:
122
+ ```ruby
123
+ PaddlePay::Subscription::Modifier.list(filters = {}, options = {})
124
+ ```
125
+
126
+ Add a modifier to a recurring subscription:
127
+ ```ruby
128
+ attributes = { subscription_id: 1234567, modifier_amount: '1.00', modifier_description: 'Test' }
129
+ PaddlePay::Subscription::Modifier.create(attributes, options = {})
130
+ ```
131
+
132
+ Delete an existing subscription price modifier:
133
+ ```ruby
134
+ modifier_id = 12345
135
+ PaddlePay::Subscription::Modifier.delete(modifier_id, options = {})
136
+ ```
137
+
138
+ ##### Payments
139
+ List all paid and upcoming (unpaid) payments:
140
+ ```ruby
141
+ PaddlePay::Subscription::Payment.list(filters = {}, options = {})
142
+ ```
143
+ Change the due date on an upcoming subscription payment:
144
+ ```ruby
145
+ payment_id = 123456
146
+ date = '2020-12-31' # in format YYYY-MM-DD
147
+ PaddlePay::Subscription::Payment.reschedule(payment_id, date, options = {})
148
+ ```
149
+
150
+ Request a refund for a subscription payment, either in full or partial:
151
+ ```ruby
152
+ order_id = 123456
153
+ PaddlePay::Subscription::Payment.refund(order_id, attributes = {}, options = {})
154
+ ```
155
+
156
+ ##### One-off Charges
157
+ Make immediate one-time charges on top of an existing subscription:
158
+ ```ruby
159
+ subscription_id = 1234567
160
+ amount = '5.00'
161
+ charge_name = 'Test'
162
+ PaddlePay::Subscription::Charge.create(subscription_id, amount, charge_name, options = {})
163
+ ```
164
+
165
+ ### Alert
166
+
167
+ ##### Webhooks
168
+ Retrieve past events and alerts that Paddle has sent to webhooks on your account:
169
+ ```ruby
170
+ PaddlePay::Alert::Webhook.history(filters = {}, options = {})
171
+ ```
172
+
173
+ ### Transaction
174
+ Retrieve transactions for related entities within Paddle:
175
+ ##### Checkout
176
+ ```ruby
177
+ id = '123456'
178
+ PaddlePay::Transaction::Checkout.list(id, options = {})
179
+ ```
180
+ ##### Order
181
+ ```ruby
182
+ id = '123456'
183
+ PaddlePay::Transaction::Order.list(id, options = {})
184
+ ```
185
+ ##### Product
186
+ ```ruby
187
+ id = '123456'
188
+ PaddlePay::Transaction::Product.list(id, options = {})
189
+ ```
190
+ ##### Subscription
191
+ ```ruby
192
+ id = '123456'
193
+ PaddlePay::Transaction::Subscription.list(id, options = {})
194
+ ```
195
+ ##### User
196
+ ```ruby
197
+ id = '123456'
198
+ PaddlePay::Transaction::User.list(id, options = {})
199
+ ```
200
+
201
+ ## Development
202
+
203
+ Check out the repository and run `bin/setup` to install dependencies. For configuration run `mv .env.template .env` and set your credentials in the required fields. After that, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt.
204
+
205
+ ## License
206
+
207
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+
6
+ require_relative 'paddle_pay/configuration'
7
+ require_relative 'paddle_pay/connection'
8
+ require_relative 'paddle_pay/util'
9
+ require_relative 'paddle_pay/version'
10
+ require_relative 'paddle_pay/errors/paddle_pay_error'
11
+ require_relative 'paddle_pay/models/alert/webhook'
12
+ require_relative 'paddle_pay/models/product/coupon'
13
+ require_relative 'paddle_pay/models/product/license'
14
+ require_relative 'paddle_pay/models/product/pay_link'
15
+ require_relative 'paddle_pay/models/product/payment'
16
+ require_relative 'paddle_pay/models/product/product'
17
+ require_relative 'paddle_pay/models/subscription/charge'
18
+ require_relative 'paddle_pay/models/subscription/modifier'
19
+ require_relative 'paddle_pay/models/subscription/payment'
20
+ require_relative 'paddle_pay/models/subscription/plan'
21
+ require_relative 'paddle_pay/models/subscription/user'
22
+ require_relative 'paddle_pay/models/transaction/checkout'
23
+ require_relative 'paddle_pay/models/transaction/order'
24
+ require_relative 'paddle_pay/models/transaction/product'
25
+ require_relative 'paddle_pay/models/transaction/subscription'
26
+ require_relative 'paddle_pay/models/transaction/user'
27
+
28
+ module PaddlePay
29
+ class << self
30
+ attr_writer :config
31
+ end
32
+
33
+ def self.configure
34
+ yield(config) if block_given?
35
+ end
36
+
37
+ def self.config
38
+ @config ||= PaddlePay::Configuration.new
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaddlePay
4
+ class Configuration
5
+ attr_reader :vendors_url
6
+ attr_reader :vendor_auth_code
7
+ attr_reader :vendor_id
8
+
9
+ def initialize
10
+ @vendors_url = 'https://vendors.paddle.com/api'
11
+ end
12
+
13
+ attr_writer :vendor_auth_code
14
+
15
+ attr_writer :vendor_id
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaddlePay
4
+ module Connection
5
+ class << self
6
+ def request(url, options = {})
7
+ request_url = PaddlePay.config.vendors_url
8
+ params = options.delete(:params) || {}
9
+ headers = options.delete(:headers) || {}
10
+ body = options.delete(:body) || {}
11
+
12
+ conn = Faraday.new(url: request_url) do |faraday|
13
+ faraday.request :url_encoded
14
+ faraday.response :raise_error
15
+ faraday.adapter :net_http
16
+ end
17
+
18
+ begin
19
+ response = conn.post(url, config.merge(body)) do |req|
20
+ req.params.merge!(params)
21
+ req.headers.merge!(headers)
22
+ end
23
+ result = parse(response)
24
+ unless result['success']
25
+ raise PaddlePayError.new(result['error']['message'], result['error']['code'])
26
+ end
27
+
28
+ PaddlePay::Util.convert_hash_keys(result['response'])
29
+ rescue Faraday::BadRequestError => e
30
+ raise BadRequestError.new(e.response[:body], e.response[:status])
31
+ rescue Faraday::UnauthorizedError => e
32
+ raise UnauthorizedError.new(e.response[:body], e.response[:status])
33
+ rescue Faraday::ForbiddenError => e
34
+ raise ForbiddenError.new(e.response[:body], e.response[:status])
35
+ rescue Faraday::ResourceNotFound => e
36
+ raise ResourceNotFoundError.new(e.response[:body], e.response[:status])
37
+ rescue Faraday::ProxyAuthError => e
38
+ raise ProxyAuthError.new(e.response[:body], e.response[:status])
39
+ rescue Faraday::ConflictError => e
40
+ raise ConflictError.new(e.response[:body], e.response[:status])
41
+ rescue Faraday::UnprocessableEntityError => e
42
+ raise UnprocessableEntityError.new(e.response[:body], e.response[:status])
43
+ rescue Faraday::TimeoutError => e
44
+ raise TimeoutError, 'The connection has timed out'
45
+ rescue Faraday::ConnectionFailed => e
46
+ raise ConnectionError, 'The connection failed'
47
+ rescue Faraday::ServerError => e
48
+ raise ServerError.new(e.response[:body], e.response[:status])
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def parse(response)
55
+ JSON.parse(response.body)
56
+ rescue JSON::ParserError
57
+ raise ParseError, "Invalid response object from API: #{response.body.inspect} " \
58
+ "(HTTP response code was #{response.status})"
59
+ end
60
+
61
+ def config
62
+ {
63
+ vendor_id: PaddlePay.config.vendor_id,
64
+ vendor_auth_code: PaddlePay.config.vendor_auth_code
65
+ }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # based off of stripe gem: https://github.com/stripe/stripe-ruby
4
+ module PaddlePay
5
+ class PaddlePayError < StandardError
6
+ attr_reader :code
7
+ attr_reader :message
8
+
9
+ def initialize(message, code = nil)
10
+ super("#{message} #{'(Code ' + code.to_s + ')' if code}")
11
+ @code = code
12
+ @message = message
13
+ end
14
+ end
15
+
16
+ class ClientError < PaddlePayError
17
+ end
18
+
19
+ class BadRequestError < ClientError
20
+ end
21
+
22
+ class UnauthorizedError < ClientError
23
+ end
24
+
25
+ class ForbiddenError < ClientError
26
+ end
27
+
28
+ class ResourceNotFoundError < ClientError
29
+ end
30
+
31
+ class ProxyAuthError < ClientError
32
+ end
33
+
34
+ class ConflictError < ClientError
35
+ end
36
+
37
+ class UnprocessableEntityError < ClientError
38
+ end
39
+
40
+ class ServerError < PaddlePayError
41
+ end
42
+
43
+ class LimitExceededError < ServerError
44
+ end
45
+
46
+ class ConnectionError < ServerError
47
+ end
48
+
49
+ class TimeoutError < ServerError
50
+ end
51
+
52
+ class ParseError < ServerError
53
+ end
54
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaddlePay
4
+ module Alert
5
+ module Webhook
6
+ class << self
7
+ def history(filters = {}, options = {})
8
+ options.merge!({ body: filters }) if filters.is_a?(::Hash)
9
+ Connection.request('2.0/alert/webhooks', options)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaddlePay
4
+ module Product
5
+ module Coupon
6
+ class << self
7
+ def list(product_id, options = {})
8
+ options.merge!({ body: { product_id: product_id } })
9
+ Connection.request('2.0/product/list_coupons', options)
10
+ end
11
+
12
+ def create(attributes, options = {})
13
+ options.merge!({ body: attributes }) if attributes.is_a?(::Hash)
14
+ Connection.request('2.1/product/create_coupon', options)
15
+ end
16
+
17
+ def delete(coupon_code, product_id, options = {})
18
+ options.merge!({ body: { coupon_code: coupon_code, product_id: product_id } })
19
+ Connection.request('2.0/product/delete_coupon', options)
20
+ end
21
+
22
+ def update_code(coupon_code, attributes = {}, options = {})
23
+ attributes.merge!(coupon_code: coupon_code)
24
+ options.merge!({ body: attributes })
25
+ Connection.request('2.1/product/update_coupon', options)
26
+ end
27
+
28
+ def update_group(group, attributes = {}, options = {})
29
+ attributes.merge!(group: group)
30
+ options.merge!({ body: attributes })
31
+ Connection.request('2.1/product/update_coupon', options)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end