stripe 3.2.0 → 5.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +10 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +80 -0
  5. data/.rubocop_todo.yml +33 -0
  6. data/.travis.yml +9 -7
  7. data/.vscode/extensions.json +7 -0
  8. data/.vscode/settings.json +8 -0
  9. data/CHANGELOG.md +876 -0
  10. data/CODE_OF_CONDUCT.md +77 -0
  11. data/Gemfile +21 -21
  12. data/History.txt +1 -678
  13. data/README.md +195 -53
  14. data/Rakefile +18 -12
  15. data/VERSION +1 -1
  16. data/bin/stripe-console +5 -3
  17. data/lib/stripe/api_operations/create.rb +3 -1
  18. data/lib/stripe/api_operations/delete.rb +26 -2
  19. data/lib/stripe/api_operations/list.rb +3 -12
  20. data/lib/stripe/api_operations/nested_resource.rb +72 -0
  21. data/lib/stripe/api_operations/request.rb +33 -15
  22. data/lib/stripe/api_operations/save.rb +18 -9
  23. data/lib/stripe/api_resource.rb +60 -10
  24. data/lib/stripe/connection_manager.rb +159 -0
  25. data/lib/stripe/error_object.rb +94 -0
  26. data/lib/stripe/errors.rb +39 -19
  27. data/lib/stripe/instrumentation.rb +82 -0
  28. data/lib/stripe/list_object.rb +54 -22
  29. data/lib/stripe/multipart_encoder.rb +131 -0
  30. data/lib/stripe/oauth.rb +22 -14
  31. data/lib/stripe/object_types.rb +96 -0
  32. data/lib/stripe/{account.rb → resources/account.rb} +72 -34
  33. data/lib/stripe/resources/account_link.rb +9 -0
  34. data/lib/stripe/resources/alipay_account.rb +34 -0
  35. data/lib/stripe/{apple_pay_domain.rb → resources/apple_pay_domain.rb} +4 -2
  36. data/lib/stripe/resources/application_fee.rb +13 -0
  37. data/lib/stripe/resources/application_fee_refund.rb +30 -0
  38. data/lib/stripe/{balance.rb → resources/balance.rb} +3 -1
  39. data/lib/stripe/{balance_transaction.rb → resources/balance_transaction.rb} +3 -5
  40. data/lib/stripe/resources/bank_account.rb +42 -0
  41. data/lib/stripe/{bitcoin_receiver.rb → resources/bitcoin_receiver.rb} +6 -5
  42. data/lib/stripe/resources/bitcoin_transaction.rb +15 -0
  43. data/lib/stripe/resources/capability.rb +33 -0
  44. data/lib/stripe/resources/card.rb +37 -0
  45. data/lib/stripe/resources/charge.rb +22 -0
  46. data/lib/stripe/resources/checkout/session.rb +12 -0
  47. data/lib/stripe/{country_spec.rb → resources/country_spec.rb} +3 -5
  48. data/lib/stripe/{coupon.rb → resources/coupon.rb} +4 -2
  49. data/lib/stripe/resources/credit_note.rb +32 -0
  50. data/lib/stripe/resources/credit_note_line_item.rb +7 -0
  51. data/lib/stripe/resources/customer.rb +35 -0
  52. data/lib/stripe/resources/customer_balance_transaction.rb +30 -0
  53. data/lib/stripe/resources/discount.rb +7 -0
  54. data/lib/stripe/resources/dispute.rb +21 -0
  55. data/lib/stripe/resources/ephemeral_key.rb +19 -0
  56. data/lib/stripe/{event.rb → resources/event.rb} +3 -1
  57. data/lib/stripe/resources/exchange_rate.rb +9 -0
  58. data/lib/stripe/resources/file.rb +34 -0
  59. data/lib/stripe/resources/file_link.rb +11 -0
  60. data/lib/stripe/resources/invoice.rb +73 -0
  61. data/lib/stripe/{invoice_item.rb → resources/invoice_item.rb} +4 -2
  62. data/lib/stripe/{invoice_line_item.rb → resources/invoice_line_item.rb} +3 -1
  63. data/lib/stripe/resources/issuing/authorization.rb +33 -0
  64. data/lib/stripe/resources/issuing/card.rb +24 -0
  65. data/lib/stripe/resources/issuing/card_details.rb +9 -0
  66. data/lib/stripe/resources/issuing/cardholder.rb +13 -0
  67. data/lib/stripe/resources/issuing/dispute.rb +13 -0
  68. data/lib/stripe/resources/issuing/transaction.rb +12 -0
  69. data/lib/stripe/resources/login_link.rb +14 -0
  70. data/lib/stripe/resources/mandate.rb +7 -0
  71. data/lib/stripe/resources/order.rb +32 -0
  72. data/lib/stripe/{order_return.rb → resources/order_return.rb} +3 -5
  73. data/lib/stripe/resources/payment_intent.rb +42 -0
  74. data/lib/stripe/resources/payment_method.rb +32 -0
  75. data/lib/stripe/resources/payout.rb +22 -0
  76. data/lib/stripe/resources/person.rb +31 -0
  77. data/lib/stripe/{plan.rb → resources/plan.rb} +3 -1
  78. data/lib/stripe/{product.rb → resources/product.rb} +5 -3
  79. data/lib/stripe/resources/radar/early_fraud_warning.rb +11 -0
  80. data/lib/stripe/resources/radar/value_list.rb +14 -0
  81. data/lib/stripe/resources/radar/value_list_item.rb +13 -0
  82. data/lib/stripe/{recipient.rb → resources/recipient.rb} +5 -6
  83. data/lib/stripe/resources/recipient_transfer.rb +7 -0
  84. data/lib/stripe/{refund.rb → resources/refund.rb} +3 -1
  85. data/lib/stripe/resources/reporting/report_run.rb +12 -0
  86. data/lib/stripe/resources/reporting/report_type.rb +12 -0
  87. data/lib/stripe/resources/reversal.rb +29 -0
  88. data/lib/stripe/resources/review.rb +20 -0
  89. data/lib/stripe/resources/setup_intent.rb +32 -0
  90. data/lib/stripe/resources/sigma/scheduled_query_run.rb +15 -0
  91. data/lib/stripe/{sku.rb → resources/sku.rb} +5 -3
  92. data/lib/stripe/resources/source.rb +46 -0
  93. data/lib/stripe/resources/source_transaction.rb +7 -0
  94. data/lib/stripe/resources/subscription.rb +25 -0
  95. data/lib/stripe/resources/subscription_item.rb +25 -0
  96. data/lib/stripe/resources/subscription_schedule.rb +32 -0
  97. data/lib/stripe/resources/tax_id.rb +26 -0
  98. data/lib/stripe/resources/tax_rate.rb +11 -0
  99. data/lib/stripe/resources/terminal/connection_token.rb +11 -0
  100. data/lib/stripe/resources/terminal/location.rb +14 -0
  101. data/lib/stripe/resources/terminal/reader.rb +14 -0
  102. data/lib/stripe/{three_d_secure.rb → resources/three_d_secure.rb} +3 -1
  103. data/lib/stripe/{token.rb → resources/token.rb} +3 -1
  104. data/lib/stripe/resources/topup.rb +22 -0
  105. data/lib/stripe/resources/transfer.rb +26 -0
  106. data/lib/stripe/resources/usage_record.rb +7 -0
  107. data/lib/stripe/resources/usage_record_summary.rb +7 -0
  108. data/lib/stripe/resources/webhook_endpoint.rb +12 -0
  109. data/lib/stripe/resources.rb +79 -0
  110. data/lib/stripe/singleton_api_resource.rb +10 -4
  111. data/lib/stripe/stripe_client.rb +658 -337
  112. data/lib/stripe/stripe_object.rb +248 -126
  113. data/lib/stripe/stripe_response.rb +55 -21
  114. data/lib/stripe/util.rb +145 -187
  115. data/lib/stripe/version.rb +3 -1
  116. data/lib/stripe/webhook.rb +27 -16
  117. data/lib/stripe.rb +139 -90
  118. data/stripe.gemspec +26 -14
  119. data/test/openapi/README.md +9 -0
  120. data/test/stripe/account_link_test.rb +18 -0
  121. data/test/stripe/account_test.rb +311 -101
  122. data/test/stripe/alipay_account_test.rb +21 -1
  123. data/test/stripe/api_operations_test.rb +57 -8
  124. data/test/stripe/api_resource_test.rb +359 -271
  125. data/test/stripe/apple_pay_domain_test.rb +26 -11
  126. data/test/stripe/application_fee_refund_test.rb +10 -8
  127. data/test/stripe/application_fee_test.rb +49 -3
  128. data/test/stripe/balance_test.rb +4 -2
  129. data/test/stripe/balance_transaction_test.rb +20 -0
  130. data/test/stripe/bank_account_test.rb +11 -11
  131. data/test/stripe/capability_test.rb +45 -0
  132. data/test/stripe/charge_test.rb +25 -18
  133. data/test/stripe/checkout/session_test.rb +41 -0
  134. data/test/stripe/connection_manager_test.rb +163 -0
  135. data/test/stripe/country_spec_test.rb +6 -4
  136. data/test/stripe/coupon_test.rb +29 -10
  137. data/test/stripe/credit_note_test.rb +90 -0
  138. data/test/stripe/customer_balance_transaction_test.rb +37 -0
  139. data/test/stripe/customer_card_test.rb +13 -17
  140. data/test/stripe/customer_test.rb +161 -49
  141. data/test/stripe/dispute_test.rb +19 -8
  142. data/test/stripe/ephemeral_key_test.rb +23 -14
  143. data/test/stripe/errors_test.rb +32 -9
  144. data/test/stripe/exchange_rate_test.rb +20 -0
  145. data/test/stripe/file_link_test.rb +41 -0
  146. data/test/stripe/file_test.rb +87 -0
  147. data/test/stripe/instrumentation_test.rb +74 -0
  148. data/test/stripe/invoice_item_test.rb +31 -18
  149. data/test/stripe/invoice_line_item_test.rb +3 -1
  150. data/test/stripe/invoice_test.rb +158 -39
  151. data/test/stripe/issuing/authorization_test.rb +72 -0
  152. data/test/stripe/issuing/card_test.rb +62 -0
  153. data/test/stripe/issuing/cardholder_test.rb +53 -0
  154. data/test/stripe/issuing/dispute_test.rb +45 -0
  155. data/test/stripe/issuing/transaction_test.rb +48 -0
  156. data/test/stripe/list_object_test.rb +120 -88
  157. data/test/stripe/login_link_test.rb +16 -14
  158. data/test/stripe/mandate_test.rb +14 -0
  159. data/test/stripe/multipart_encoder_test.rb +130 -0
  160. data/test/stripe/oauth_test.rb +69 -50
  161. data/test/stripe/order_return_test.rb +7 -5
  162. data/test/stripe/order_test.rb +39 -14
  163. data/test/stripe/payment_intent_test.rb +107 -0
  164. data/test/stripe/payment_method_test.rb +84 -0
  165. data/test/stripe/payout_test.rb +18 -9
  166. data/test/stripe/person_test.rb +46 -0
  167. data/test/stripe/plan_test.rb +67 -19
  168. data/test/stripe/product_test.rb +28 -14
  169. data/test/stripe/radar/early_fraud_warning_test.rb +22 -0
  170. data/test/stripe/radar/value_list_item_test.rb +48 -0
  171. data/test/stripe/radar/value_list_test.rb +61 -0
  172. data/test/stripe/recipient_test.rb +27 -13
  173. data/test/stripe/refund_test.rb +11 -9
  174. data/test/stripe/reporting/report_run_test.rb +33 -0
  175. data/test/stripe/reporting/report_type_test.rb +22 -0
  176. data/test/stripe/reversal_test.rb +12 -10
  177. data/test/stripe/review_test.rb +27 -0
  178. data/test/stripe/setup_intent_test.rb +84 -0
  179. data/test/stripe/sigma/scheduled_query_run_test.rb +22 -0
  180. data/test/stripe/sku_test.rb +24 -12
  181. data/test/stripe/source_test.rb +70 -19
  182. data/test/stripe/stripe_client_test.rb +867 -326
  183. data/test/stripe/stripe_object_test.rb +284 -182
  184. data/test/stripe/stripe_response_test.rb +73 -24
  185. data/test/stripe/subscription_item_test.rb +47 -15
  186. data/test/stripe/subscription_schedule_test.rb +82 -0
  187. data/test/stripe/subscription_test.rb +41 -19
  188. data/test/stripe/tax_id_test.rb +31 -0
  189. data/test/stripe/tax_rate_test.rb +43 -0
  190. data/test/stripe/terminal/connection_token_test.rb +16 -0
  191. data/test/stripe/terminal/location_test.rb +68 -0
  192. data/test/stripe/terminal/reader_test.rb +62 -0
  193. data/test/stripe/three_d_secure_test.rb +4 -2
  194. data/test/stripe/topup_test.rb +62 -0
  195. data/test/stripe/transfer_test.rb +55 -8
  196. data/test/stripe/usage_record_summary_test.rb +29 -0
  197. data/test/stripe/util_test.rb +173 -84
  198. data/test/stripe/webhook_endpoint_test.rb +59 -0
  199. data/test/stripe/webhook_test.rb +21 -17
  200. data/test/stripe_mock.rb +78 -0
  201. data/test/stripe_test.rb +6 -15
  202. data/test/test_data.rb +28 -26
  203. data/test/test_helper.rb +48 -29
  204. metadata +183 -70
  205. data/lib/stripe/alipay_account.rb +0 -22
  206. data/lib/stripe/application_fee.rb +0 -22
  207. data/lib/stripe/application_fee_refund.rb +0 -20
  208. data/lib/stripe/bank_account.rb +0 -30
  209. data/lib/stripe/bitcoin_transaction.rb +0 -11
  210. data/lib/stripe/card.rb +0 -27
  211. data/lib/stripe/charge.rb +0 -82
  212. data/lib/stripe/customer.rb +0 -79
  213. data/lib/stripe/dispute.rb +0 -17
  214. data/lib/stripe/ephemeral_key.rb +0 -18
  215. data/lib/stripe/file_upload.rb +0 -33
  216. data/lib/stripe/invoice.rb +0 -29
  217. data/lib/stripe/login_link.rb +0 -9
  218. data/lib/stripe/order.rb +0 -29
  219. data/lib/stripe/payout.rb +0 -18
  220. data/lib/stripe/recipient_transfer.rb +0 -6
  221. data/lib/stripe/reversal.rb +0 -20
  222. data/lib/stripe/source.rb +0 -23
  223. data/lib/stripe/subscription.rb +0 -33
  224. data/lib/stripe/subscription_item.rb +0 -14
  225. data/lib/stripe/transfer.rb +0 -18
  226. data/test/api_stub_helpers.rb +0 -0
  227. data/test/stripe/bitcoin_receiver_test.rb +0 -67
  228. data/test/stripe/bitcoin_transaction_test.rb +0 -19
  229. data/test/stripe/file_upload_test.rb +0 -66
  230. data/test/stripe/recipient_card_test.rb +0 -44
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Stripe Ruby Library [![Build Status](https://travis-ci.org/stripe/stripe-ruby.svg?branch=master)](https://travis-ci.org/stripe/stripe-ruby)
1
+ # Stripe Ruby Library
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/stripe.svg)](https://badge.fury.io/rb/stripe)
4
+ [![Build Status](https://travis-ci.org/stripe/stripe-ruby.svg?branch=master)](https://travis-ci.org/stripe/stripe-ruby)
5
+ [![Coverage Status](https://coveralls.io/repos/github/stripe/stripe-ruby/badge.svg?branch=master)](https://coveralls.io/github/stripe/stripe-ruby?branch=master)
2
6
 
3
7
  The Stripe Ruby library provides convenient access to the Stripe API from
4
8
  applications written in the Ruby language. It includes a pre-defined set of
@@ -8,11 +12,9 @@ API.
8
12
 
9
13
  The library also provides other features. For example:
10
14
 
11
- * Easy configuration path for fast setup and use.
12
- * Helpers for pagination.
13
- * Tracking of "fresh" values in API resources so that partial updates can be
14
- executed.
15
- * Built-in mechanisms for the serialization of parameters according to the
15
+ - Easy configuration path for fast setup and use.
16
+ - Helpers for pagination.
17
+ - Built-in mechanisms for the serialization of parameters according to the
16
18
  expectations of Stripe's API.
17
19
 
18
20
  ## Documentation
@@ -24,15 +26,19 @@ See the [Ruby API docs](https://stripe.com/docs/api/ruby#intro).
24
26
  You don't need this source code unless you want to modify the gem. If you just
25
27
  want to use the package, just run:
26
28
 
27
- gem install stripe
29
+ ```sh
30
+ gem install stripe
31
+ ```
28
32
 
29
33
  If you want to build the gem from source:
30
34
 
31
- gem build stripe.gemspec
35
+ ```sh
36
+ gem build stripe.gemspec
37
+ ```
32
38
 
33
39
  ### Requirements
34
40
 
35
- * Ruby 2.0+.
41
+ - Ruby 2.3+.
36
42
 
37
43
  ### Bundler
38
44
 
@@ -40,7 +46,7 @@ If you are installing via bundler, you should be sure to use the https rubygems
40
46
  source in your Gemfile, as any gems fetched over http could potentially be
41
47
  compromised in transit and alter the code of gems fetched securely over https:
42
48
 
43
- ``` ruby
49
+ ```ruby
44
50
  source 'https://rubygems.org'
45
51
 
46
52
  gem 'rails'
@@ -53,17 +59,15 @@ The library needs to be configured with your account's secret key which is
53
59
  available in your [Stripe Dashboard][api-keys]. Set `Stripe.api_key` to its
54
60
  value:
55
61
 
56
- ``` ruby
62
+ ```ruby
57
63
  require "stripe"
58
64
  Stripe.api_key = "sk_test_..."
59
65
 
60
- # list charges
61
- Stripe::Charge.list()
66
+ # list customers
67
+ Stripe::Customer.list()
62
68
 
63
- # retrieve single charge
64
- Stripe::Charge.retrieve(
65
- "ch_18atAXCdGbJFKhCuBAa4532Z",
66
- )
69
+ # retrieve single customer
70
+ Stripe::Customer.retrieve("cus_123456789")
67
71
  ```
68
72
 
69
73
  ### Per-request Configuration
@@ -72,52 +76,110 @@ For apps that need to use multiple keys during the lifetime of a process, like
72
76
  one that uses [Stripe Connect][connect], it's also possible to set a
73
77
  per-request key and/or account:
74
78
 
75
- ``` ruby
79
+ ```ruby
76
80
  require "stripe"
77
81
 
78
- Stripe::Charge.list(
82
+ Stripe::Customer.list(
79
83
  {},
80
- :api_key => "sk_test_...",
81
- :stripe_account => "acct_..."
84
+ {
85
+ api_key: "sk_test_...",
86
+ stripe_account: "acct_...",
87
+ stripe_version: "2018-02-28",
88
+ }
89
+ )
90
+
91
+ Stripe::Customer.retrieve(
92
+ "cus_123456789",
93
+ {
94
+ api_key: "sk_test_...",
95
+ stripe_account: "acct_...",
96
+ stripe_version: "2018-02-28",
97
+ }
98
+ )
99
+
100
+ Stripe::Customer.retrieve(
101
+ {
102
+ id: "cus_123456789",
103
+ expand: %w(balance_transaction)
104
+ },
105
+ {
106
+ stripe_version: "2018-02-28",
107
+ api_key: "sk_test_...",
108
+ }
82
109
  )
83
110
 
84
- Stripe::Charge.retrieve(
85
- "ch_18atAXCdGbJFKhCuBAa4532Z",
86
- :api_key => "sk_test_...",
87
- :stripe_account => "acct_..."
111
+ Stripe::Customer.capture(
112
+ "cus_123456789",
113
+ {},
114
+ {
115
+ stripe_version: "2018-02-28",
116
+ api_key: "sk_test_...",
117
+ }
88
118
  )
89
119
  ```
90
120
 
91
- ### Configuring a Client
121
+ Keep in mind that there are different method signatures depending on the action:
122
+
123
+ - When operating on a collection (e.g. `.list`, `.create`) the method signature is
124
+ `method(params, opts)`.
125
+ - When operating on resource (e.g. `.capture`, `.update`) the method signature is
126
+ `method(id, params, opts)`.
127
+ - One exception is that `retrieve`, despite being an operation on a resource, has the signature
128
+ `retrieve(id, opts)`. In addition, it will accept a Hash for the `id` param but will extract the
129
+ `id` key out and use the others as options.
130
+
131
+ ### Accessing a response object
92
132
 
93
- While a default HTTP client is used by default, it's also possible to have the
94
- library use any client supported by [Faraday][faraday] by initializing a
95
- `Stripe::StripeClient` object and giving it a connection:
133
+ Get access to response objects by initializing a client and using its `request`
134
+ method:
96
135
 
97
- ``` ruby
98
- conn = Faraday.new
99
- client = Stripe::StripeClient.new(conn)
100
- charge, resp = client.request do
101
- Stripe::Charge.retrieve(
102
- "ch_18atAXCdGbJFKhCuBAa4532Z",
103
- )
136
+ ```ruby
137
+ client = Stripe::StripeClient.new
138
+ customer, resp = client.request do
139
+ Stripe::Customer.retrieve("cus_123456789",)
104
140
  end
105
141
  puts resp.request_id
106
142
  ```
107
143
 
144
+ ### Configuring a proxy
145
+
146
+ A proxy can be configured with `Stripe.proxy`:
147
+
148
+ ```ruby
149
+ Stripe.proxy = "https://user:pass@example.com:1234"
150
+ ```
151
+
152
+ ### Configuring an API Version
153
+
154
+ By default, the library will use the API version pinned to the account making
155
+ a request. This can be overridden with this global option:
156
+
157
+ ```ruby
158
+ Stripe.api_version = "2018-02-28"
159
+ ```
160
+
161
+ See [versioning in the API reference][versioning] for more information.
162
+
108
163
  ### Configuring CA Bundles
109
164
 
110
165
  By default, the library will use its own internal bundle of known CA
111
166
  certificates, but it's possible to configure your own:
112
167
 
113
- Stripe.ca_bundle_path = "path/to/ca/bundle"
168
+ ```ruby
169
+ Stripe.ca_bundle_path = "path/to/ca/bundle"
170
+ ```
114
171
 
115
172
  ### Configuring Automatic Retries
116
173
 
117
- The library can be configured to automatically retry requests that fail due to
118
- an intermittent network problem:
174
+ You can enable automatic retries on requests that fail due to a transient
175
+ problem by configuring the maximum number of retries:
119
176
 
120
- Stripe.max_network_retries = 2
177
+ ```ruby
178
+ Stripe.max_network_retries = 2
179
+ ```
180
+
181
+ Various errors can trigger a retry, like a connection error or a timeout, and
182
+ also certain API responses like HTTP status `409 Conflict`.
121
183
 
122
184
  [Idempotency keys][idempotency-keys] are added to requests to guarantee that
123
185
  retries are safe.
@@ -126,8 +188,8 @@ retries are safe.
126
188
 
127
189
  Open and read timeouts are configurable:
128
190
 
129
- ```java
130
- Stripe.open_timeout = 30 // in seconds
191
+ ```ruby
192
+ Stripe.open_timeout = 30 # in seconds
131
193
  Stripe.read_timeout = 80
132
194
  ```
133
195
 
@@ -144,49 +206,129 @@ production use, but `debug` is also available for more verbosity.
144
206
  There are a few options for enabling it:
145
207
 
146
208
  1. Set the environment variable `STRIPE_LOG` to the value `debug` or `info`:
147
- ```
209
+
210
+ ```sh
148
211
  $ export STRIPE_LOG=info
149
212
  ```
150
213
 
151
214
  2. Set `Stripe.log_level`:
152
- ``` ruby
153
- Stripe.log_level = "info"
215
+
216
+ ```ruby
217
+ Stripe.log_level = Stripe::LEVEL_INFO
154
218
  ```
155
219
 
220
+ ### Instrumentation
221
+
222
+ The library has various hooks that user code can tie into by passing a block to
223
+ `Stripe::Instrumentation.subscribe` to be notified about specific events.
224
+
225
+ #### `request_begin`
226
+
227
+ Invoked when an HTTP request starts. Receives `RequestBeginEvent` with the
228
+ following properties:
229
+
230
+ - `method`: HTTP method. (`Symbol`)
231
+ - `path`: Request path. (`String`)
232
+ - `user_data`: A hash on which users can set arbitrary data, and which will be
233
+ passed through to `request_end` invocations. This could be used, for example,
234
+ to assign unique IDs to each request, and it'd work even if many requests are
235
+ running in parallel. All subscribers share the same object for any particular
236
+ request, so they must be careful to use unique keys that will not conflict
237
+ with other subscribers. (`Hash`)
238
+
239
+ #### `request_end`
240
+
241
+ Invoked when an HTTP request finishes, regardless of whether it terminated with
242
+ a success or error. Receives `RequestEndEvent` with the following properties:
243
+
244
+ - `duration`: Request duration in seconds. (`Float`)
245
+ - `http_status`: HTTP response code (`Integer`) if available, or `nil` in case
246
+ of a lower level network error.
247
+ - `method`: HTTP method. (`Symbol`)
248
+ - `num_retries`: The number of retries. (`Integer`)
249
+ - `path`: Request path. (`String`)
250
+ - `user_data`: A hash on which users may have set arbitrary data in
251
+ `request_begin`. See above for more information. (`Hash`)
252
+
253
+ #### Example
254
+
255
+ For example:
256
+
257
+ ```ruby
258
+ Stripe::Instrumentation.subscribe(:request_end) do |request_event|
259
+ tags = {
260
+ method: request_event.method,
261
+ resource: request_event.path.split("/")[2],
262
+ code: request_event.http_status,
263
+ retries: request_event.num_retries
264
+ }
265
+ StatsD.distribution('stripe_request', request_event.duration, tags: tags)
266
+ end
267
+ ```
268
+
156
269
  ### Writing a Plugin
157
270
 
158
271
  If you're writing a plugin that uses the library, we'd appreciate it if you
159
272
  identified using `#set_app_info`:
160
273
 
161
- Stripe.set_app_info("MyAwesomePlugin", version: "1.2.34", url: "https://myawesomeplugin.info");
274
+ ```ruby
275
+ Stripe.set_app_info("MyAwesomePlugin", version: "1.2.34", url: "https://myawesomeplugin.info");
276
+ ```
162
277
 
163
278
  This information is passed along when the library makes calls to the Stripe
164
279
  API.
165
280
 
281
+ ### Request latency telemetry
282
+
283
+ By default, the library sends request latency telemetry to Stripe. These
284
+ numbers help Stripe improve the overall latency of its API for all users.
285
+
286
+ You can disable this behavior if you prefer:
287
+
288
+ ```ruby
289
+ Stripe.enable_telemetry = false
290
+ ```
291
+
166
292
  ## Development
167
293
 
168
294
  The test suite depends on [stripe-mock], so make sure to fetch and run it from a
169
295
  background terminal ([stripe-mock's README][stripe-mock] also contains
170
296
  instructions for installing via Homebrew and other methods):
171
297
 
172
- go get -u github.com/stripe/stripe-mock
173
- stripe-mock
298
+ ```sh
299
+ go get -u github.com/stripe/stripe-mock
300
+ stripe-mock
301
+ ```
174
302
 
175
303
  Run all tests:
176
304
 
177
- bundle exec rake
305
+ ```sh
306
+ bundle exec rake test
307
+ ```
178
308
 
179
309
  Run a single test suite:
180
310
 
181
- bundle exec ruby -Ilib/ test/stripe/util_test.rb
311
+ ```sh
312
+ bundle exec ruby -Ilib/ test/stripe/util_test.rb
313
+ ```
182
314
 
183
315
  Run a single test:
184
316
 
185
- bundle exec ruby -Ilib/ test/stripe/util_test.rb -n /should.convert.names.to.symbols/
317
+ ```sh
318
+ bundle exec ruby -Ilib/ test/stripe/util_test.rb -n /should.convert.names.to.symbols/
319
+ ```
320
+
321
+ Run the linter:
322
+
323
+ ```sh
324
+ bundle exec rake rubocop
325
+ ```
186
326
 
187
327
  Update bundled CA certificates from the [Mozilla cURL release][curl]:
188
328
 
189
- bundle exec rake update_certs
329
+ ```sh
330
+ bundle exec rake update_certs
331
+ ```
190
332
 
191
333
  Update the bundled [stripe-mock] by editing the version number found in
192
334
  `.travis.yml`.
@@ -194,9 +336,9 @@ Update the bundled [stripe-mock] by editing the version number found in
194
336
  [api-keys]: https://dashboard.stripe.com/account/apikeys
195
337
  [connect]: https://stripe.com/connect
196
338
  [curl]: http://curl.haxx.se/docs/caextract.html
197
- [faraday]: https://github.com/lostisland/faraday
198
339
  [idempotency-keys]: https://stripe.com/docs/api/ruby#idempotent_requests
199
340
  [stripe-mock]: https://github.com/stripe/stripe-mock
341
+ [versioning]: https://stripe.com/docs/api/ruby#versioning
200
342
 
201
343
  <!--
202
344
  # vim: set tw=79:
data/Rakefile CHANGED
@@ -1,31 +1,37 @@
1
- require 'rake/testtask'
1
+ # frozen_string_literal: true
2
2
 
3
- task :default => [:test]
3
+ require "rake/testtask"
4
+ require "rubocop/rake_task"
5
+
6
+ task default: %i[test rubocop]
4
7
 
5
8
  Rake::TestTask.new do |t|
6
- t.pattern = './test/**/*_test.rb'
9
+ t.pattern = "./test/**/*_test.rb"
7
10
  end
8
11
 
12
+ RuboCop::RakeTask.new
13
+
9
14
  desc "Update bundled certs"
10
15
  task :update_certs do
11
- require "faraday"
16
+ require "net/http"
17
+ require "uri"
12
18
 
13
19
  fetch_file "https://curl.haxx.se/ca/cacert.pem",
14
- File.expand_path("../lib/data/ca-certificates.crt", __FILE__)
20
+ ::File.expand_path("../lib/data/ca-certificates.crt", __FILE__)
15
21
  end
16
22
 
17
23
  #
18
24
  # helpers
19
25
  #
20
26
 
21
- def fetch_file(url, dest)
22
- File.open(dest, 'w') do |file|
23
- resp = Faraday.get(url)
24
- unless resp.status == 200
25
- abort("bad response when fetching: #{url}\n" \
26
- "Status #{resp.status}: #{resp.body}")
27
+ def fetch_file(uri, dest)
28
+ ::File.open(dest, "w") do |file|
29
+ resp = Net::HTTP.get_response(URI.parse(uri))
30
+ unless resp.code.to_i == 200
31
+ abort("bad response when fetching: #{uri}\n" \
32
+ "Status #{resp.code}: #{resp.body}")
27
33
  end
28
34
  file.write(resp.body)
29
- puts "Successfully fetched: #{url}"
35
+ puts "Successfully fetched: #{uri}"
30
36
  end
31
37
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.0
1
+ 5.16.0
data/bin/stripe-console CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'irb'
4
- require 'irb/completion'
3
+ # frozen_string_literal: true
5
4
 
6
- require "#{File.dirname(__FILE__)}/../lib/stripe"
5
+ require "irb"
6
+ require "irb/completion"
7
+
8
+ require "#{::File.dirname(__FILE__)}/../lib/stripe"
7
9
 
8
10
  # Config IRB to enable --simple-prompt and auto indent
9
11
  IRB.conf[:PROMPT_MODE] = :SIMPLE
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stripe
2
4
  module APIOperations
3
5
  module Create
4
- def create(params={}, opts={})
6
+ def create(params = {}, opts = {})
5
7
  resp, opts = request(:post, resource_url, params, opts)
6
8
  Util.convert_to_stripe_object(resp.data, opts)
7
9
  end
@@ -1,11 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stripe
2
4
  module APIOperations
3
5
  module Delete
4
- def delete(params={}, opts={})
5
- opts = Util.normalize_opts(opts)
6
+ module ClassMethods
7
+ # Deletes an API resource
8
+ #
9
+ # Deletes the identified resource with the passed in parameters.
10
+ #
11
+ # ==== Attributes
12
+ #
13
+ # * +id+ - ID of the resource to delete.
14
+ # * +params+ - A hash of parameters to pass to the API
15
+ # * +opts+ - A Hash of additional options (separate from the params /
16
+ # object values) to be added to the request. E.g. to allow for an
17
+ # idempotency_key to be passed in the request headers, or for the
18
+ # api_key to be overwritten. See {APIOperations::Request.request}.
19
+ def delete(id, params = {}, opts = {})
20
+ resp, opts = request(:delete, "#{resource_url}/#{id}", params, opts)
21
+ Util.convert_to_stripe_object(resp.data, opts)
22
+ end
23
+ end
24
+
25
+ def delete(params = {}, opts = {})
6
26
  resp, opts = request(:delete, resource_url, params, opts)
7
27
  initialize_from(resp.data, opts)
8
28
  end
29
+
30
+ def self.included(base)
31
+ base.extend(ClassMethods)
32
+ end
9
33
  end
10
34
  end
11
35
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stripe
2
4
  module APIOperations
3
5
  module List
4
- def list(filters={}, opts={})
6
+ def list(filters = {}, opts = {})
5
7
  opts = Util.normalize_opts(opts)
6
8
 
7
9
  resp, opts = request(:get, resource_url, filters, opts)
@@ -9,20 +11,9 @@ module Stripe
9
11
 
10
12
  # set filters so that we can fetch the same limit, expansions, and
11
13
  # predicates when accessing the next and previous pages
12
- #
13
- # just for general cleanliness, remove any paging options
14
14
  obj.filters = filters.dup
15
- obj.filters.delete(:ending_before)
16
- obj.filters.delete(:starting_after)
17
-
18
15
  obj
19
16
  end
20
-
21
- # The original version of #list was given the somewhat unfortunate name of
22
- # #all, and this alias allows us to maintain backward compatibility (the
23
- # choice was somewhat misleading in the way that it only returned a single
24
- # page rather than all objects).
25
- alias :all :list
26
17
  end
27
18
  end
28
19
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stripe
4
+ module APIOperations
5
+ # Adds methods to help manipulate a subresource from its parent resource so
6
+ # that it's possible to do so from a static context (i.e. without a
7
+ # pre-existing collection of subresources on the parent).
8
+ #
9
+ # For example, a transfer gains the static methods for reversals so that the
10
+ # methods `.create_reversal`, `.retrieve_reversal`, `.update_reversal`,
11
+ # etc. all become available.
12
+ module NestedResource
13
+ def nested_resource_class_methods(resource, path: nil, operations: nil,
14
+ resource_plural: nil)
15
+ resource_plural ||= "#{resource}s"
16
+ path ||= resource_plural
17
+
18
+ raise ArgumentError, "operations array required" if operations.nil?
19
+
20
+ resource_url_method = :"#{resource}s_url"
21
+
22
+ define_singleton_method(resource_url_method) do |id, nested_id = nil|
23
+ url = "#{resource_url}/#{CGI.escape(id)}/#{CGI.escape(path)}"
24
+ url += "/#{CGI.escape(nested_id)}" unless nested_id.nil?
25
+ url
26
+ end
27
+
28
+ operations.each do |operation|
29
+ case operation
30
+ when :create
31
+ define_singleton_method(:"create_#{resource}") \
32
+ do |id, params = {}, opts = {}|
33
+ url = send(resource_url_method, id)
34
+ resp, opts = request(:post, url, params, opts)
35
+ Util.convert_to_stripe_object(resp.data, opts)
36
+ end
37
+ when :retrieve
38
+ define_singleton_method(:"retrieve_#{resource}") \
39
+ do |id, nested_id, opts = {}|
40
+ url = send(resource_url_method, id, nested_id)
41
+ resp, opts = request(:get, url, {}, opts)
42
+ Util.convert_to_stripe_object(resp.data, opts)
43
+ end
44
+ when :update
45
+ define_singleton_method(:"update_#{resource}") \
46
+ do |id, nested_id, params = {}, opts = {}|
47
+ url = send(resource_url_method, id, nested_id)
48
+ resp, opts = request(:post, url, params, opts)
49
+ Util.convert_to_stripe_object(resp.data, opts)
50
+ end
51
+ when :delete
52
+ define_singleton_method(:"delete_#{resource}") \
53
+ do |id, nested_id, params = {}, opts = {}|
54
+ url = send(resource_url_method, id, nested_id)
55
+ resp, opts = request(:delete, url, params, opts)
56
+ Util.convert_to_stripe_object(resp.data, opts)
57
+ end
58
+ when :list
59
+ define_singleton_method(:"list_#{resource_plural}") \
60
+ do |id, params = {}, opts = {}|
61
+ url = send(resource_url_method, id)
62
+ resp, opts = request(:get, url, params, opts)
63
+ Util.convert_to_stripe_object(resp.data, opts)
64
+ end
65
+ else
66
+ raise ArgumentError, "Unknown operation: #{operation.inspect}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,13 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stripe
2
4
  module APIOperations
3
5
  module Request
4
6
  module ClassMethods
5
- OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :client, :stripe_account, :stripe_version]
7
+ def request(method, url, params = {}, opts = {})
8
+ params ||= {}
6
9
 
7
- def request(method, url, params={}, opts={})
10
+ error_on_invalid_params(params)
8
11
  warn_on_opts_in_params(params)
9
12
 
10
13
  opts = Util.normalize_opts(opts)
14
+ error_on_non_string_user_opts(opts)
15
+
11
16
  opts[:client] ||= StripeClient.active_client
12
17
 
13
18
  headers = opts.clone
@@ -25,23 +30,38 @@ module Stripe
25
30
  # Hash#select returns an array before 1.9
26
31
  opts_to_persist = {}
27
32
  opts.each do |k, v|
28
- if OPTS_KEYS_TO_PERSIST.include?(k)
29
- opts_to_persist[k] = v
30
- end
33
+ opts_to_persist[k] = v if Util::OPTS_PERSISTABLE.include?(k)
31
34
  end
32
35
 
33
36
  [resp, opts_to_persist]
34
37
  end
35
38
 
36
- private
39
+ private def error_on_non_string_user_opts(opts)
40
+ Util::OPTS_USER_SPECIFIED.each do |opt|
41
+ next unless opts.key?(opt)
42
+
43
+ val = opts[opt]
44
+ next if val.nil?
45
+ next if val.is_a?(String)
46
+
47
+ raise ArgumentError,
48
+ "request option '#{opt}' should be a string value " \
49
+ "(was a #{val.class})"
50
+ end
51
+ end
52
+
53
+ private def error_on_invalid_params(params)
54
+ return if params.nil? || params.is_a?(Hash)
37
55
 
38
- KNOWN_OPTS = Set[:api_key, :idempotency_key, :stripe_account, :stripe_version]
39
- private_constant :KNOWN_OPTS
56
+ raise ArgumentError,
57
+ "request params should be either a Hash or nil " \
58
+ "(was a #{params.class})"
59
+ end
40
60
 
41
- def warn_on_opts_in_params(params)
42
- KNOWN_OPTS.each do |opt|
43
- if params.has_key?(opt)
44
- $stderr.puts("WARNING: #{opt} should be in opts instead of params.")
61
+ private def warn_on_opts_in_params(params)
62
+ Util::OPTS_USER_SPECIFIED.each do |opt|
63
+ if params.key?(opt)
64
+ warn("WARNING: '#{opt}' should be in opts instead of params.")
45
65
  end
46
66
  end
47
67
  end
@@ -51,9 +71,7 @@ module Stripe
51
71
  base.extend(ClassMethods)
52
72
  end
53
73
 
54
- protected
55
-
56
- def request(method, url, params={}, opts={})
74
+ protected def request(method, url, params = {}, opts = {})
57
75
  opts = @opts.merge(Util.normalize_opts(opts))
58
76
  self.class.request(method, url, params, opts)
59
77
  end