epopia-stripe-ruby-mock 2.5.8

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 (171) hide show
  1. checksums.yaml +7 -0
  2. data/.env +2 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +12 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +413 -0
  9. data/Rakefile +14 -0
  10. data/bin/stripe-mock-server +19 -0
  11. data/lib/stripe_mock.rb +95 -0
  12. data/lib/stripe_mock/api/account_balance.rb +14 -0
  13. data/lib/stripe_mock/api/bank_tokens.rb +13 -0
  14. data/lib/stripe_mock/api/card_tokens.rb +13 -0
  15. data/lib/stripe_mock/api/client.rb +41 -0
  16. data/lib/stripe_mock/api/conversion_rate.rb +14 -0
  17. data/lib/stripe_mock/api/debug.rb +11 -0
  18. data/lib/stripe_mock/api/errors.rb +65 -0
  19. data/lib/stripe_mock/api/global_id_prefix.rb +22 -0
  20. data/lib/stripe_mock/api/instance.rb +38 -0
  21. data/lib/stripe_mock/api/live.rb +15 -0
  22. data/lib/stripe_mock/api/server.rb +39 -0
  23. data/lib/stripe_mock/api/test_helpers.rb +24 -0
  24. data/lib/stripe_mock/api/webhooks.rb +88 -0
  25. data/lib/stripe_mock/client.rb +127 -0
  26. data/lib/stripe_mock/data.rb +1193 -0
  27. data/lib/stripe_mock/data/list.rb +73 -0
  28. data/lib/stripe_mock/error_queue.rb +27 -0
  29. data/lib/stripe_mock/errors/closed_client_connection_error.rb +9 -0
  30. data/lib/stripe_mock/errors/server_timeout_error.rb +12 -0
  31. data/lib/stripe_mock/errors/stripe_mock_error.rb +15 -0
  32. data/lib/stripe_mock/errors/uninitialized_instance_error.rb +9 -0
  33. data/lib/stripe_mock/errors/unstarted_state_error.rb +9 -0
  34. data/lib/stripe_mock/errors/unsupported_request_error.rb +4 -0
  35. data/lib/stripe_mock/instance.rb +237 -0
  36. data/lib/stripe_mock/request_handlers/accounts.rb +86 -0
  37. data/lib/stripe_mock/request_handlers/balance.rb +17 -0
  38. data/lib/stripe_mock/request_handlers/balance_transactions.rb +37 -0
  39. data/lib/stripe_mock/request_handlers/cards.rb +35 -0
  40. data/lib/stripe_mock/request_handlers/charges.rb +177 -0
  41. data/lib/stripe_mock/request_handlers/country_spec.rb +22 -0
  42. data/lib/stripe_mock/request_handlers/coupons.rb +35 -0
  43. data/lib/stripe_mock/request_handlers/customers.rb +137 -0
  44. data/lib/stripe_mock/request_handlers/disputes.rb +35 -0
  45. data/lib/stripe_mock/request_handlers/ephemeral_key.rb +13 -0
  46. data/lib/stripe_mock/request_handlers/events.rb +21 -0
  47. data/lib/stripe_mock/request_handlers/external_accounts.rb +55 -0
  48. data/lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb +14 -0
  49. data/lib/stripe_mock/request_handlers/helpers/card_helpers.rb +127 -0
  50. data/lib/stripe_mock/request_handlers/helpers/charge_helpers.rb +16 -0
  51. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +17 -0
  52. data/lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb +49 -0
  53. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +119 -0
  54. data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +44 -0
  55. data/lib/stripe_mock/request_handlers/invoice_items.rb +45 -0
  56. data/lib/stripe_mock/request_handlers/invoices.rb +177 -0
  57. data/lib/stripe_mock/request_handlers/orders.rb +80 -0
  58. data/lib/stripe_mock/request_handlers/payment_intents.rb +203 -0
  59. data/lib/stripe_mock/request_handlers/payment_methods.rb +112 -0
  60. data/lib/stripe_mock/request_handlers/payouts.rb +32 -0
  61. data/lib/stripe_mock/request_handlers/plans.rb +42 -0
  62. data/lib/stripe_mock/request_handlers/products.rb +43 -0
  63. data/lib/stripe_mock/request_handlers/recipients.rb +60 -0
  64. data/lib/stripe_mock/request_handlers/refunds.rb +91 -0
  65. data/lib/stripe_mock/request_handlers/sources.rb +55 -0
  66. data/lib/stripe_mock/request_handlers/subscription_items.rb +36 -0
  67. data/lib/stripe_mock/request_handlers/subscriptions.rb +296 -0
  68. data/lib/stripe_mock/request_handlers/tax_rates.rb +36 -0
  69. data/lib/stripe_mock/request_handlers/tokens.rb +75 -0
  70. data/lib/stripe_mock/request_handlers/transfers.rb +65 -0
  71. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +32 -0
  72. data/lib/stripe_mock/server.rb +93 -0
  73. data/lib/stripe_mock/test_strategies/base.rb +81 -0
  74. data/lib/stripe_mock/test_strategies/live.rb +40 -0
  75. data/lib/stripe_mock/test_strategies/mock.rb +27 -0
  76. data/lib/stripe_mock/util.rb +44 -0
  77. data/lib/stripe_mock/version.rb +4 -0
  78. data/lib/stripe_mock/webhook_fixtures/account.application.deauthorized.json +12 -0
  79. data/lib/stripe_mock/webhook_fixtures/account.external_account.created.json +27 -0
  80. data/lib/stripe_mock/webhook_fixtures/account.external_account.deleted.json +27 -0
  81. data/lib/stripe_mock/webhook_fixtures/account.external_account.updated.json +27 -0
  82. data/lib/stripe_mock/webhook_fixtures/account.updated.json +26 -0
  83. data/lib/stripe_mock/webhook_fixtures/balance.available.json +25 -0
  84. data/lib/stripe_mock/webhook_fixtures/charge.dispute.closed.json +22 -0
  85. data/lib/stripe_mock/webhook_fixtures/charge.dispute.created.json +22 -0
  86. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_reinstated.json +88 -0
  87. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_withdrawn.json +88 -0
  88. data/lib/stripe_mock/webhook_fixtures/charge.dispute.updated.json +25 -0
  89. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +56 -0
  90. data/lib/stripe_mock/webhook_fixtures/charge.refunded.json +69 -0
  91. data/lib/stripe_mock/webhook_fixtures/charge.succeeded.json +55 -0
  92. data/lib/stripe_mock/webhook_fixtures/charge.updated.json +58 -0
  93. data/lib/stripe_mock/webhook_fixtures/coupon.created.json +23 -0
  94. data/lib/stripe_mock/webhook_fixtures/coupon.deleted.json +23 -0
  95. data/lib/stripe_mock/webhook_fixtures/customer.created.json +54 -0
  96. data/lib/stripe_mock/webhook_fixtures/customer.deleted.json +42 -0
  97. data/lib/stripe_mock/webhook_fixtures/customer.discount.created.json +28 -0
  98. data/lib/stripe_mock/webhook_fixtures/customer.discount.deleted.json +28 -0
  99. data/lib/stripe_mock/webhook_fixtures/customer.discount.updated.json +43 -0
  100. data/lib/stripe_mock/webhook_fixtures/customer.source.created.json +32 -0
  101. data/lib/stripe_mock/webhook_fixtures/customer.source.deleted.json +32 -0
  102. data/lib/stripe_mock/webhook_fixtures/customer.source.updated.json +36 -0
  103. data/lib/stripe_mock/webhook_fixtures/customer.subscription.created.json +66 -0
  104. data/lib/stripe_mock/webhook_fixtures/customer.subscription.deleted.json +65 -0
  105. data/lib/stripe_mock/webhook_fixtures/customer.subscription.trial_will_end.json +65 -0
  106. data/lib/stripe_mock/webhook_fixtures/customer.subscription.updated.json +78 -0
  107. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +57 -0
  108. data/lib/stripe_mock/webhook_fixtures/invoice.created.json +71 -0
  109. data/lib/stripe_mock/webhook_fixtures/invoice.payment_failed.json +105 -0
  110. data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +112 -0
  111. data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +74 -0
  112. data/lib/stripe_mock/webhook_fixtures/invoiceitem.created.json +21 -0
  113. data/lib/stripe_mock/webhook_fixtures/invoiceitem.deleted.json +21 -0
  114. data/lib/stripe_mock/webhook_fixtures/invoiceitem.updated.json +24 -0
  115. data/lib/stripe_mock/webhook_fixtures/plan.created.json +20 -0
  116. data/lib/stripe_mock/webhook_fixtures/plan.deleted.json +20 -0
  117. data/lib/stripe_mock/webhook_fixtures/plan.updated.json +23 -0
  118. data/lib/stripe_mock/webhook_fixtures/transfer.created.json +89 -0
  119. data/lib/stripe_mock/webhook_fixtures/transfer.failed.json +89 -0
  120. data/lib/stripe_mock/webhook_fixtures/transfer.paid.json +89 -0
  121. data/lib/stripe_mock/webhook_fixtures/transfer.updated.json +92 -0
  122. data/lib/trollop.rb +782 -0
  123. data/spec/_dummy/webhooks/dummy.event.json +6 -0
  124. data/spec/api/instance_spec.rb +30 -0
  125. data/spec/fixtures/create_refund.yml +126 -0
  126. data/spec/fixtures/stripe_webhooks/account.updated.json +7 -0
  127. data/spec/fixtures/stripe_webhooks/custom.account.updated.json +5 -0
  128. data/spec/instance_spec.rb +100 -0
  129. data/spec/integration_examples/charge_token_examples.rb +51 -0
  130. data/spec/integration_examples/customer_card_examples.rb +42 -0
  131. data/spec/integration_examples/prepare_error_examples.rb +38 -0
  132. data/spec/list_spec.rb +140 -0
  133. data/spec/readme_spec.rb +75 -0
  134. data/spec/server_spec.rb +139 -0
  135. data/spec/shared_stripe_examples/account_examples.rb +96 -0
  136. data/spec/shared_stripe_examples/balance_examples.rb +11 -0
  137. data/spec/shared_stripe_examples/balance_transaction_examples.rb +63 -0
  138. data/spec/shared_stripe_examples/bank_examples.rb +229 -0
  139. data/spec/shared_stripe_examples/bank_token_examples.rb +59 -0
  140. data/spec/shared_stripe_examples/card_examples.rb +307 -0
  141. data/spec/shared_stripe_examples/card_token_examples.rb +185 -0
  142. data/spec/shared_stripe_examples/charge_examples.rb +510 -0
  143. data/spec/shared_stripe_examples/country_specs_examples.rb +18 -0
  144. data/spec/shared_stripe_examples/coupon_examples.rb +85 -0
  145. data/spec/shared_stripe_examples/customer_examples.rb +453 -0
  146. data/spec/shared_stripe_examples/dispute_examples.rb +98 -0
  147. data/spec/shared_stripe_examples/ephemeral_key_examples.rb +17 -0
  148. data/spec/shared_stripe_examples/error_mock_examples.rb +162 -0
  149. data/spec/shared_stripe_examples/external_account_examples.rb +170 -0
  150. data/spec/shared_stripe_examples/extra_features_examples.rb +36 -0
  151. data/spec/shared_stripe_examples/invoice_examples.rb +524 -0
  152. data/spec/shared_stripe_examples/invoice_item_examples.rb +69 -0
  153. data/spec/shared_stripe_examples/payment_intent_examples.rb +131 -0
  154. data/spec/shared_stripe_examples/payment_method_examples.rb +175 -0
  155. data/spec/shared_stripe_examples/payout_examples.rb +68 -0
  156. data/spec/shared_stripe_examples/plan_examples.rb +194 -0
  157. data/spec/shared_stripe_examples/product_example.rb +65 -0
  158. data/spec/shared_stripe_examples/recipient_examples.rb +118 -0
  159. data/spec/shared_stripe_examples/refund_examples.rb +472 -0
  160. data/spec/shared_stripe_examples/subscription_examples.rb +1148 -0
  161. data/spec/shared_stripe_examples/subscription_items_examples.rb +75 -0
  162. data/spec/shared_stripe_examples/tax_rate_examples.rb +42 -0
  163. data/spec/shared_stripe_examples/transfer_examples.rb +130 -0
  164. data/spec/shared_stripe_examples/validation_examples.rb +19 -0
  165. data/spec/shared_stripe_examples/webhook_event_examples.rb +261 -0
  166. data/spec/spec_helper.rb +58 -0
  167. data/spec/stripe_mock_spec.rb +123 -0
  168. data/spec/support/stripe_examples.rb +42 -0
  169. data/spec/util_spec.rb +121 -0
  170. data/stripe-ruby-mock.gemspec +27 -0
  171. metadata +344 -0
@@ -0,0 +1,296 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Subscriptions
4
+
5
+ def Subscriptions.included(klass)
6
+ klass.add_handler 'get /v1/subscriptions', :retrieve_subscriptions
7
+ klass.add_handler 'post /v1/subscriptions', :create_subscription
8
+ klass.add_handler 'get /v1/subscriptions/(.*)', :retrieve_subscription
9
+ klass.add_handler 'post /v1/subscriptions/(.*)', :update_subscription
10
+ klass.add_handler 'delete /v1/subscriptions/(.*)', :cancel_subscription
11
+
12
+ klass.add_handler 'post /v1/customers/(.*)/subscription(?:s)?', :create_customer_subscription
13
+ klass.add_handler 'get /v1/customers/(.*)/subscription(?:s)?/(.*)', :retrieve_customer_subscription
14
+ klass.add_handler 'get /v1/customers/(.*)/subscription(?:s)?', :retrieve_customer_subscriptions
15
+ klass.add_handler 'post /v1/customers/(.*)subscription(?:s)?/(.*)', :update_subscription
16
+ klass.add_handler 'delete /v1/customers/(.*)/subscription(?:s)?/(.*)', :cancel_subscription
17
+ end
18
+
19
+ def retrieve_customer_subscription(route, method_url, params, headers)
20
+ route =~ method_url
21
+
22
+ customer = assert_existence :customer, $1, customers[$1]
23
+ subscription = get_customer_subscription(customer, $2)
24
+
25
+ assert_existence :subscription, $2, subscription
26
+ end
27
+
28
+ def retrieve_customer_subscriptions(route, method_url, params, headers)
29
+ route =~ method_url
30
+
31
+ customer = assert_existence :customer, $1, customers[$1]
32
+ customer[:subscriptions]
33
+ end
34
+
35
+ def create_customer_subscription(route, method_url, params, headers)
36
+ route =~ method_url
37
+
38
+ subscription_plans = get_subscription_plans_from_params(params)
39
+ customer = assert_existence :customer, $1, customers[$1]
40
+
41
+ if params[:source]
42
+ new_card = get_card_by_token(params.delete(:source))
43
+ add_card_to_object(:customer, new_card, customer)
44
+ customer[:default_source] = new_card[:id]
45
+ end
46
+
47
+ subscription = Data.mock_subscription({ id: (params[:id] || new_id('su')) })
48
+ subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
49
+
50
+ # Ensure customer has card to charge if plan has no trial and is not free
51
+ # Note: needs updating for subscriptions with multiple plans
52
+ verify_card_present(customer, subscription_plans.first, subscription, params)
53
+
54
+ if params[:coupon]
55
+ coupon_id = params[:coupon]
56
+
57
+ # assert_existence returns 404 error code but Stripe returns 400
58
+ # coupon = assert_existence :coupon, coupon_id, coupons[coupon_id]
59
+
60
+ coupon = coupons[coupon_id]
61
+
62
+ if coupon
63
+ add_coupon_to_object(subscription, coupon)
64
+ else
65
+ raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
66
+ end
67
+ end
68
+
69
+ subscriptions[subscription[:id]] = subscription
70
+ add_subscription_to_customer(customer, subscription)
71
+
72
+ subscriptions[subscription[:id]]
73
+ end
74
+
75
+ def create_subscription(route, method_url, params, headers)
76
+ if headers && headers[:idempotency_key]
77
+ if subscriptions.any?
78
+ original_subscription = subscriptions.values.find { |c| c[:idempotency_key] == headers[:idempotency_key]}
79
+ return subscriptions[original_subscription[:id]] if original_subscription
80
+ end
81
+ end
82
+ route =~ method_url
83
+
84
+ subscription_plans = get_subscription_plans_from_params(params)
85
+
86
+ customer = params[:customer]
87
+ customer_id = customer.is_a?(Stripe::Customer) ? customer[:id] : customer.to_s
88
+ customer = assert_existence :customer, customer_id, customers[customer_id]
89
+
90
+ if subscription_plans && customer
91
+ subscription_plans.each do |plan|
92
+ unless customer[:currency].to_s == plan[:currency].to_s
93
+ raise Stripe::InvalidRequestError.new("Customer's currency of #{customer[:currency]} does not match plan's currency of #{plan[:currency]}", 'currency', http_status: 400)
94
+ end
95
+ end
96
+ end
97
+
98
+ if params[:source]
99
+ new_card = get_card_by_token(params.delete(:source))
100
+ add_card_to_object(:customer, new_card, customer)
101
+ customer[:default_source] = new_card[:id]
102
+ end
103
+
104
+ allowed_params = %w(customer application_fee_percent coupon items metadata plan quantity source tax_percent trial_end trial_period_days current_period_start created prorate billing_cycle_anchor billing days_until_due idempotency_key)
105
+ unknown_params = params.keys - allowed_params.map(&:to_sym)
106
+ if unknown_params.length > 0
107
+ raise Stripe::InvalidRequestError.new("Received unknown parameter: #{unknown_params.join}", unknown_params.first.to_s, http_status: 400)
108
+ end
109
+
110
+ subscription = Data.mock_subscription({ id: (params[:id] || new_id('su')) })
111
+ subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
112
+ if headers[:idempotency_key]
113
+ subscription[:idempotency_key] = headers[:idempotency_key]
114
+ end
115
+
116
+ # Ensure customer has card to charge if plan has no trial and is not free
117
+ # Note: needs updating for subscriptions with multiple plans
118
+ verify_card_present(customer, subscription_plans.first, subscription, params)
119
+
120
+ if params[:coupon]
121
+ coupon_id = params[:coupon]
122
+
123
+ # assert_existence returns 404 error code but Stripe returns 400
124
+ # coupon = assert_existence :coupon, coupon_id, coupons[coupon_id]
125
+
126
+ coupon = coupons[coupon_id]
127
+
128
+ if coupon
129
+ add_coupon_to_object(subscription, coupon)
130
+ else
131
+ raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
132
+ end
133
+ end
134
+
135
+ subscriptions[subscription[:id]] = subscription
136
+ add_subscription_to_customer(customer, subscription)
137
+
138
+ subscriptions[subscription[:id]]
139
+ end
140
+
141
+ def retrieve_subscription(route, method_url, params, headers)
142
+ route =~ method_url
143
+
144
+ assert_existence :subscription, $1, subscriptions[$1]
145
+ end
146
+
147
+ def retrieve_subscriptions(route, method_url, params, headers)
148
+ route =~ method_url
149
+
150
+ Data.mock_list_object(subscriptions.values, params)
151
+ #customer = assert_existence :customer, $1, customers[$1]
152
+ #customer[:subscriptions]
153
+ end
154
+
155
+ def update_subscription(route, method_url, params, headers)
156
+ route =~ method_url
157
+
158
+ subscription_id = $2 ? $2 : $1
159
+ subscription = assert_existence :subscription, subscription_id, subscriptions[subscription_id]
160
+ verify_active_status(subscription)
161
+
162
+ customer_id = subscription[:customer]
163
+ customer = assert_existence :customer, customer_id, customers[customer_id]
164
+
165
+ if params[:source]
166
+ new_card = get_card_by_token(params.delete(:source))
167
+ add_card_to_object(:customer, new_card, customer)
168
+ customer[:default_source] = new_card[:id]
169
+ end
170
+
171
+ subscription_plans = get_subscription_plans_from_params(params)
172
+
173
+ # subscription plans are not being updated but load them for the response
174
+ if subscription_plans.empty?
175
+ subscription_plans = subscription[:items][:data].map { |item| item[:plan] }
176
+ end
177
+
178
+ if params[:coupon]
179
+ coupon_id = params[:coupon]
180
+
181
+ # assert_existence returns 404 error code but Stripe returns 400
182
+ # coupon = assert_existence :coupon, coupon_id, coupons[coupon_id]
183
+
184
+ coupon = coupons[coupon_id]
185
+ if coupon
186
+ add_coupon_to_object(subscription, coupon)
187
+ elsif coupon_id == ""
188
+ subscription[:discount] = nil
189
+ else
190
+ raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
191
+ end
192
+ end
193
+ verify_card_present(customer, subscription_plans.first, subscription)
194
+
195
+ if subscription[:cancel_at_period_end]
196
+ subscription[:cancel_at_period_end] = false
197
+ subscription[:canceled_at] = nil
198
+ end
199
+
200
+ params[:current_period_start] = subscription[:current_period_start]
201
+ params[:trial_end] = params[:trial_end] || subscription[:trial_end]
202
+ subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
203
+
204
+ # delete the old subscription, replace with the new subscription
205
+ customer[:subscriptions][:data].reject! { |sub| sub[:id] == subscription[:id] }
206
+ customer[:subscriptions][:data] << subscription
207
+
208
+ subscription
209
+ end
210
+
211
+ def cancel_subscription(route, method_url, params, headers)
212
+ route =~ method_url
213
+
214
+ subscription_id = $2 ? $2 : $1
215
+ subscription = assert_existence :subscription, subscription_id, subscriptions[subscription_id]
216
+
217
+ customer_id = subscription[:customer]
218
+ customer = assert_existence :customer, customer_id, customers[customer_id]
219
+
220
+ cancel_params = { canceled_at: Time.now.utc.to_i }
221
+ cancelled_at_period_end = (params[:at_period_end] == true)
222
+ if cancelled_at_period_end
223
+ cancel_params[:cancel_at_period_end] = true
224
+ else
225
+ cancel_params[:status] = 'canceled'
226
+ cancel_params[:cancel_at_period_end] = false
227
+ cancel_params[:ended_at] = Time.now.utc.to_i
228
+ end
229
+
230
+ subscription.merge!(cancel_params)
231
+
232
+ unless cancelled_at_period_end
233
+ delete_subscription_from_customer customer, subscription
234
+ end
235
+
236
+ subscription
237
+ end
238
+
239
+ private
240
+
241
+ def get_subscription_plans_from_params(params)
242
+ plan_ids = if params[:plan]
243
+ [params[:plan].to_s]
244
+ elsif params[:items]
245
+ items = params[:items]
246
+ items = items.values if items.respond_to?(:values)
247
+ items.map { |item| item[:plan].to_s if item[:plan] }
248
+ else
249
+ []
250
+ end
251
+ plan_ids.each do |plan_id|
252
+ assert_existence :plan, plan_id, plans[plan_id]
253
+ end
254
+ plan_ids.map { |plan_id| plans[plan_id] }
255
+ end
256
+
257
+ # Ensure customer has card to charge unless one of the following criterias is met:
258
+ # 1) is in trial
259
+ # 2) is free
260
+ # 3) has billing set to send invoice
261
+ def verify_card_present(customer, plan, subscription, params={})
262
+ return if customer[:default_source]
263
+ return if customer[:trial_end]
264
+ return if params[:trial_end]
265
+
266
+ plan_trial_period_days = plan[:trial_period_days] || 0
267
+ plan_has_trial = plan_trial_period_days != 0 || plan[:amount] == 0 || plan[:trial_end]
268
+ return if plan && plan_has_trial
269
+
270
+ return if subscription && subscription[:trial_end] && subscription[:trial_end] != 'now'
271
+
272
+ if subscription[:items]
273
+ trial = subscription[:items][:data].none? do |item|
274
+ plan = item[:plan]
275
+ (plan[:trial_period_days].nil? || plan[:trial_period_days] == 0) &&
276
+ (plan[:trial_end].nil? || plan[:trial_end] == 'now')
277
+ end
278
+ return if trial
279
+ end
280
+
281
+ return if params[:billing] == 'send_invoice'
282
+
283
+ raise Stripe::InvalidRequestError.new('You must supply a valid card xoxo', nil, http_status: 400)
284
+ end
285
+
286
+ def verify_active_status(subscription)
287
+ id, status = subscription.values_at(:id, :status)
288
+
289
+ if status == 'canceled'
290
+ message = "No such subscription: #{id}"
291
+ raise Stripe::InvalidRequestError.new(message, 'subscription', http_status: 404)
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
@@ -0,0 +1,36 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module TaxRates
4
+ def TaxRates.included(klass)
5
+ klass.add_handler 'post /v1/tax_rates', :new_tax_rate
6
+ klass.add_handler 'post /v1/tax_rates/([^/]*)', :update_tax_rate
7
+ klass.add_handler 'get /v1/tax_rates/([^/]*)', :get_tax_rate
8
+ klass.add_handler 'get /v1/tax_rates', :list_tax_rates
9
+ end
10
+
11
+ def update_tax_rate(route, method_url, params, headers)
12
+ route =~ method_url
13
+ rate = assert_existence :tax_rate, $1, tax_rates[$1]
14
+ rate.merge!(params)
15
+ rate
16
+ end
17
+
18
+ def new_tax_rate(route, method_url, params, headers)
19
+ params[:id] ||= new_id('txr')
20
+ tax_rates[ params[:id] ] = Data.mock_tax_rate(params)
21
+ tax_rates[ params[:id] ]
22
+ end
23
+
24
+ def list_tax_rates(route, method_url, params, headers)
25
+ Data.mock_list_object(tax_rates.values, params)
26
+ end
27
+
28
+ def get_tax_rate(route, method_url, params, headers)
29
+ route =~ method_url
30
+ tax_rate = assert_existence :tax_rate, $1, tax_rates[$1]
31
+ tax_rate.clone
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,75 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Tokens
4
+
5
+ def Tokens.included(klass)
6
+ klass.add_handler 'post /v1/tokens', :create_token
7
+ klass.add_handler 'get /v1/tokens/(.*)', :get_token
8
+ end
9
+
10
+ def create_token(route, method_url, params, headers)
11
+ if params[:customer].nil? && params[:card].nil? && params[:bank_account].nil?
12
+ raise Stripe::InvalidRequestError.new('You must supply either a card, customer, or bank account to create a token.', nil, http_status: 400)
13
+ end
14
+
15
+ cus_id = params[:customer]
16
+
17
+ if cus_id && params[:source]
18
+ customer = assert_existence :customer, cus_id, customers[cus_id]
19
+
20
+ # params[:card] is an id; grab it from the db
21
+ customer_card = get_card(customer, params[:source])
22
+ assert_existence :card, params[:source], customer_card
23
+ elsif params[:card].is_a?(String)
24
+ customer = assert_existence :customer, cus_id, customers[cus_id]
25
+
26
+ # params[:card] is an id; grab it from the db
27
+ customer_card = get_card(customer, params[:card])
28
+ assert_existence :card, params[:card], customer_card
29
+ elsif params[:card]
30
+ # params[:card] is a hash of cc info; "Sanitize" the card number
31
+ params[:card][:fingerprint] = StripeMock::Util.fingerprint(params[:card][:number])
32
+ params[:card][:last4] = params[:card][:number][-4,4]
33
+ customer_card = params[:card]
34
+ elsif params[:bank_account].is_a?(String)
35
+ customer = assert_existence :customer, cus_id, customers[cus_id]
36
+
37
+ # params[:bank_account] is an id; grab it from the db
38
+ bank_account = verify_bank_account(customer, params[:bank_account])
39
+ assert_existence :bank_account, params[:bank_account], bank_account
40
+ elsif params[:bank_account]
41
+ # params[:card] is a hash of cc info; "Sanitize" the card number
42
+ bank_account = params[:bank_account]
43
+ else
44
+ customer = assert_existence :customer, cus_id, customers[cus_id]
45
+ customer_card = get_card(customer, customer[:default_source])
46
+ end
47
+
48
+ if bank_account
49
+ token_id = generate_bank_token(bank_account.dup)
50
+ bank_account = @bank_tokens[token_id]
51
+
52
+ Data.mock_bank_account_token(params.merge :id => token_id, :bank_account => bank_account)
53
+ else
54
+ token_id = generate_card_token(customer_card.dup)
55
+ card = @card_tokens[token_id]
56
+
57
+ Data.mock_card_token(params.merge :id => token_id, :card => card)
58
+ end
59
+ end
60
+
61
+ def get_token(route, method_url, params, headers)
62
+ route =~ method_url
63
+ # A Stripe token can be either a bank token or a card token
64
+ bank_or_card = @bank_tokens[$1] || @card_tokens[$1]
65
+ assert_existence :token, $1, bank_or_card
66
+
67
+ if bank_or_card[:object] == 'card'
68
+ Data.mock_card_token(:id => $1, :card => bank_or_card)
69
+ elsif bank_or_card[:object] == 'bank_account'
70
+ Data.mock_bank_account_token(:id => $1, :bank_account => bank_or_card)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,65 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Transfers
4
+
5
+ def Transfers.included(klass)
6
+ klass.add_handler 'post /v1/transfers', :new_transfer
7
+ klass.add_handler 'get /v1/transfers', :get_all_transfers
8
+ klass.add_handler 'get /v1/transfers/(.*)', :get_transfer
9
+ klass.add_handler 'post /v1/transfers/(.*)/cancel', :cancel_transfer
10
+ end
11
+
12
+ def get_all_transfers(route, method_url, params, headers)
13
+ extra_params = params.keys - [:created, :destination, :ending_before,
14
+ :limit, :starting_after, :transfer_group]
15
+ unless extra_params.empty?
16
+ raise Stripe::InvalidRequestError.new("Received unknown parameter: #{extra_params[0]}", extra_params[0].to_s, http_status: 400)
17
+ end
18
+
19
+ if destination = params[:destination]
20
+ assert_existence :destination, destination, accounts[destination]
21
+ end
22
+
23
+ _transfers = transfers.each_with_object([]) do |(_, transfer), array|
24
+ if destination
25
+ array << transfer if transfer[:destination] == destination
26
+ else
27
+ array << transfer
28
+ end
29
+ end
30
+
31
+ if params[:limit]
32
+ _transfers = _transfers.first([params[:limit], _transfers.size].min)
33
+ end
34
+
35
+ Data.mock_list_object(_transfers, params)
36
+ end
37
+
38
+ def new_transfer(route, method_url, params, headers)
39
+ id = new_id('tr')
40
+ if params[:bank_account]
41
+ params[:account] = get_bank_by_token(params.delete(:bank_account))
42
+ end
43
+
44
+ unless params[:amount].is_a?(Integer) || (params[:amount].is_a?(String) && /^\d+$/.match(params[:amount]))
45
+ raise Stripe::InvalidRequestError.new("Invalid integer: #{params[:amount]}", 'amount', http_status: 400)
46
+ end
47
+
48
+ transfers[id] = Data.mock_transfer(params.merge :id => id)
49
+ end
50
+
51
+ def get_transfer(route, method_url, params, headers)
52
+ route =~ method_url
53
+ assert_existence :transfer, $1, transfers[$1]
54
+ transfers[$1] ||= Data.mock_transfer(:id => $1)
55
+ end
56
+
57
+ def cancel_transfer(route, method_url, params, headers)
58
+ route =~ method_url
59
+ assert_existence :transfer, $1, transfers[$1]
60
+ t = transfers[$1] ||= Data.mock_transfer(:id => $1)
61
+ t.merge!({:status => "canceled"})
62
+ end
63
+ end
64
+ end
65
+ end