stripe-ruby-mock 3.1.0.rc3 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec_tests.yml +38 -0
  3. data/.rspec +2 -1
  4. data/CHANGELOG.md +28 -0
  5. data/README.md +5 -3
  6. data/lib/stripe_mock/api/webhooks.rb +65 -26
  7. data/lib/stripe_mock/data.rb +80 -11
  8. data/lib/stripe_mock/instance.rb +6 -2
  9. data/lib/stripe_mock/request_handlers/accounts.rb +17 -6
  10. data/lib/stripe_mock/request_handlers/charges.rb +5 -0
  11. data/lib/stripe_mock/request_handlers/checkout_session.rb +158 -1
  12. data/lib/stripe_mock/request_handlers/events.rb +30 -3
  13. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +1 -0
  14. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +28 -9
  15. data/lib/stripe_mock/request_handlers/invoices.rb +6 -1
  16. data/lib/stripe_mock/request_handlers/payment_intents.rb +13 -2
  17. data/lib/stripe_mock/request_handlers/payment_methods.rb +5 -1
  18. data/lib/stripe_mock/request_handlers/prices.rb +18 -0
  19. data/lib/stripe_mock/request_handlers/promotion_codes.rb +43 -0
  20. data/lib/stripe_mock/request_handlers/refunds.rb +13 -2
  21. data/lib/stripe_mock/request_handlers/setup_intents.rb +16 -9
  22. data/lib/stripe_mock/request_handlers/subscriptions.rb +93 -4
  23. data/lib/stripe_mock/request_handlers/transfers.rb +12 -1
  24. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +5 -4
  25. data/lib/stripe_mock/test_strategies/base.rb +51 -24
  26. data/lib/stripe_mock/version.rb +1 -1
  27. data/lib/stripe_mock/webhook_fixtures/account.updated.json +1 -1
  28. data/lib/stripe_mock/webhook_fixtures/balance.available.json +26 -20
  29. data/lib/stripe_mock/webhook_fixtures/charge.captured.json +143 -0
  30. data/lib/stripe_mock/webhook_fixtures/charge.dispute.created.json +63 -16
  31. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +49 -120
  32. data/lib/stripe_mock/webhook_fixtures/charge.refund.updated.json +35 -0
  33. data/lib/stripe_mock/webhook_fixtures/charge.refunded.json +145 -50
  34. data/lib/stripe_mock/webhook_fixtures/charge.succeeded.json +114 -43
  35. data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.json +79 -0
  36. data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.payment_mode.json +53 -0
  37. data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.setup_mode.json +45 -0
  38. data/lib/stripe_mock/webhook_fixtures/customer.created.json +37 -46
  39. data/lib/stripe_mock/webhook_fixtures/customer.deleted.json +36 -32
  40. data/lib/stripe_mock/webhook_fixtures/customer.source.created.json +31 -22
  41. data/lib/stripe_mock/webhook_fixtures/customer.source.updated.json +36 -25
  42. data/lib/stripe_mock/webhook_fixtures/customer.subscription.created.json +135 -47
  43. data/lib/stripe_mock/webhook_fixtures/customer.subscription.deleted.json +134 -45
  44. data/lib/stripe_mock/webhook_fixtures/customer.subscription.updated.json +135 -56
  45. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +38 -47
  46. data/lib/stripe_mock/webhook_fixtures/invoice.created.json +176 -49
  47. data/lib/stripe_mock/webhook_fixtures/invoice.finalized.json +171 -0
  48. data/lib/stripe_mock/webhook_fixtures/invoice.paid.json +171 -0
  49. data/lib/stripe_mock/webhook_fixtures/invoice.payment_action_required.json +171 -0
  50. data/lib/stripe_mock/webhook_fixtures/invoice.payment_failed.json +149 -83
  51. data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +149 -90
  52. data/lib/stripe_mock/webhook_fixtures/invoice.upcoming.json +70 -0
  53. data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +178 -50
  54. data/lib/stripe_mock/webhook_fixtures/invoiceitem.created.json +87 -13
  55. data/lib/stripe_mock/webhook_fixtures/invoiceitem.updated.json +88 -14
  56. data/lib/stripe_mock/webhook_fixtures/mandate.updated.json +34 -0
  57. data/lib/stripe_mock/webhook_fixtures/payment_intent.amount_capturable_updated.json +170 -0
  58. data/lib/stripe_mock/webhook_fixtures/payment_intent.canceled.json +73 -0
  59. data/lib/stripe_mock/webhook_fixtures/payment_intent.created.json +86 -0
  60. data/lib/stripe_mock/webhook_fixtures/payment_intent.payment_failed.json +118 -79
  61. data/lib/stripe_mock/webhook_fixtures/payment_intent.processing.json +162 -0
  62. data/lib/stripe_mock/webhook_fixtures/payment_intent.requires_action.json +191 -0
  63. data/lib/stripe_mock/webhook_fixtures/payment_intent.succeeded.json +85 -53
  64. data/lib/stripe_mock/webhook_fixtures/payment_link.created.json +47 -0
  65. data/lib/stripe_mock/webhook_fixtures/payment_link.updated.json +50 -0
  66. data/lib/stripe_mock/webhook_fixtures/payment_method.attached.json +63 -0
  67. data/lib/stripe_mock/webhook_fixtures/payment_method.detached.json +62 -0
  68. data/lib/stripe_mock/webhook_fixtures/payout.created.json +40 -0
  69. data/lib/stripe_mock/webhook_fixtures/payout.paid.json +40 -0
  70. data/lib/stripe_mock/webhook_fixtures/payout.updated.json +46 -0
  71. data/lib/stripe_mock/webhook_fixtures/plan.created.json +30 -13
  72. data/lib/stripe_mock/webhook_fixtures/plan.deleted.json +30 -13
  73. data/lib/stripe_mock/webhook_fixtures/plan.updated.json +34 -14
  74. data/lib/stripe_mock/webhook_fixtures/price.created.json +42 -0
  75. data/lib/stripe_mock/webhook_fixtures/price.deleted.json +42 -0
  76. data/lib/stripe_mock/webhook_fixtures/price.updated.json +48 -0
  77. data/lib/stripe_mock/webhook_fixtures/product.created.json +19 -13
  78. data/lib/stripe_mock/webhook_fixtures/product.deleted.json +20 -14
  79. data/lib/stripe_mock/webhook_fixtures/product.updated.json +24 -15
  80. data/lib/stripe_mock/webhook_fixtures/quote.accepted.json +92 -0
  81. data/lib/stripe_mock/webhook_fixtures/quote.canceled.json +92 -0
  82. data/lib/stripe_mock/webhook_fixtures/quote.created.json +92 -0
  83. data/lib/stripe_mock/webhook_fixtures/quote.finalized.json +92 -0
  84. data/lib/stripe_mock/webhook_fixtures/setup_intent.canceled.json +46 -0
  85. data/lib/stripe_mock/webhook_fixtures/setup_intent.created.json +51 -0
  86. data/lib/stripe_mock/webhook_fixtures/setup_intent.setup_failed.json +100 -0
  87. data/lib/stripe_mock/webhook_fixtures/setup_intent.succeeded.json +46 -0
  88. data/lib/stripe_mock/webhook_fixtures/subscription_schedule.canceled.json +119 -0
  89. data/lib/stripe_mock/webhook_fixtures/subscription_schedule.created.json +114 -0
  90. data/lib/stripe_mock/webhook_fixtures/subscription_schedule.released.json +111 -0
  91. data/lib/stripe_mock/webhook_fixtures/subscription_schedule.updated.json +125 -0
  92. data/lib/stripe_mock/webhook_fixtures/tax_rate.created.json +32 -0
  93. data/lib/stripe_mock/webhook_fixtures/tax_rate.updated.json +37 -0
  94. data/lib/stripe_mock.rb +3 -1
  95. data/spec/instance_spec.rb +3 -1
  96. data/spec/integration_examples/completing_checkout_sessions_example.rb +37 -0
  97. data/spec/readme_spec.rb +1 -1
  98. data/spec/shared_stripe_examples/account_examples.rb +9 -1
  99. data/spec/shared_stripe_examples/checkout_session_examples.rb +99 -0
  100. data/spec/shared_stripe_examples/invoice_examples.rb +21 -0
  101. data/spec/shared_stripe_examples/payment_intent_examples.rb +74 -0
  102. data/spec/shared_stripe_examples/payment_method_examples.rb +32 -27
  103. data/spec/shared_stripe_examples/price_examples.rb +42 -2
  104. data/spec/shared_stripe_examples/promotion_code_examples.rb +68 -0
  105. data/spec/shared_stripe_examples/refund_examples.rb +13 -0
  106. data/spec/shared_stripe_examples/setup_intent_examples.rb +17 -0
  107. data/spec/shared_stripe_examples/subscription_examples.rb +213 -2
  108. data/spec/shared_stripe_examples/transfer_examples.rb +10 -1
  109. data/spec/shared_stripe_examples/webhook_event_examples.rb +51 -5
  110. data/spec/support/stripe_examples.rb +3 -1
  111. data/stripe-ruby-mock.gemspec +1 -1
  112. metadata +54 -11
  113. data/.travis.yml +0 -25
  114. data/lib/stripe_mock/request_handlers/checkout.rb +0 -15
  115. data/spec/shared_stripe_examples/checkout_examples.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 334d13aee8d09763d8bddf689cfa992de81006364b510887073df7d05a0bf531
4
- data.tar.gz: 684baff9323adb815a14b6cf94f4c94d5abbbecb5cdf77c5ba3ccce296149741
3
+ metadata.gz: 7b5b1b83df91e8e6fd700456710804749b9b1008e572fd8c74eec4f1519e8a49
4
+ data.tar.gz: bf362cf2fe9aa556e155df2b61076248335e3b2a43f69e0e6fc046406d65da57
5
5
  SHA512:
6
- metadata.gz: 1d3a8fd548a29e7dbc7a6190862e70e79594ee43432b68998882628419d715d44a48df2068b8748e0c68c8a6cbb872659fb5952309737a464a585d53389158bc
7
- data.tar.gz: 1751365b6dbc521d23bff923b7ae91852509b8b8fde41d75824d04fa51213819682749fee56d111a986bf2a4c37f37e0969b3e50f5f8687edfa30d3ee0d1cd18
6
+ metadata.gz: a397bf1b196f62bb7c8d76f79e2582f6d6594d20ddb9473b8dd5e7680c1844620a29456cddd8be8c5d9b785f4317ea1b092b340f841ccdbef92d849c6bb116e7
7
+ data.tar.gz: 90f97fe65c4dcd10eaa853aec740bce21c56b8df57bc1a589acc6f13ebf1b65943731b50f820d9f8eaa77954673f78b34bb62b326cbb7c71f5692a0b74a347c0
@@ -0,0 +1,38 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Tests
9
+
10
+ on:
11
+ push:
12
+ branches: [ "master" ]
13
+ pull_request:
14
+ branches: [ "master" ]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ test:
21
+
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ matrix:
25
+ ruby-version: ['2.6', '2.7', '3.0']
26
+
27
+ steps:
28
+ - uses: actions/checkout@v3
29
+ - name: Set up Ruby
30
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
31
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
32
+ # uses: ruby/setup-ruby@v1
33
+ uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
34
+ with:
35
+ ruby-version: ${{ matrix.ruby-version }}
36
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
37
+ - name: Run tests
38
+ run: bundle exec rspec
data/.rspec CHANGED
@@ -1 +1,2 @@
1
- --colour --format documentation
1
+ --colour
2
+ --format progress
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ### Unreleased
2
+
3
+ - [#693](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/693) gemspec: add change,issue,source_code URL by [@mtmail](https://github.com/mtmail)
4
+ - [#700](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/700) update the balance API to respond with instant_available by [@iamnader](https://github.com/iamnader)
5
+ - [#687](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/687) Add PaymentIntent Webhooks by [@klaustopher](https://github.com/klaustopher)
6
+ - [#708](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/708) Implement Stripe::Checkout::Session.retrieve by [@coorasse](https://github.com/coorasse)
7
+ - [#711](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/711) Adding account link mock by [@amenon](https://github.com/amenon)
8
+ - [#715](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/715) Added application_fee_amount to mock charge object by [@espen](https://github.com/espen)
9
+ - [#694](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/694) Introduce ideal and sepa_debit types for PaymentMethod by [@mnin](https://github.com/mnin)
10
+ - [#720](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/720) Add additional parameters by [@rpietraszko](https://github.com/rpietraszko)
11
+ - [#695](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/695) Add `has_more` attribute to all ListObject instances by [@gbp](https://github.com/gbp)
12
+ - [#727](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/727) Fix List initialize error with deleted records by [@jmulieri](https://github.com/jmulieri)
13
+ - [#739](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/739) Add data to account links by [@dudyn5ky1](https://github.com/dudyn5ky1)
14
+ - [#756](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/756) Added #715 PR to changelog by [@espen](https://github.com/espen)
15
+ - [#759](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/759) Adding express dashboard login link mock by [@rohitbegani](https://github.com/rohitbegani)
16
+ - [#747](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/747) Fix ruby 2.7 deprecation warnings by [@coding-chimp](https://github.com/coding-chimp)
17
+ - [#762](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/762) Support Stripe Connect by adding stripe_account header namespace for customers by [@csalvato](https://github.com/csalvato)
18
+ - [#758](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/758) Create price by [@jamesprior](https://github.com/jamesprior)
19
+ - [#730](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/730) support on price api by [@hidenba](https://github.com/hidenba)
20
+ - [#764](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/764) Fixes erroneous error message when fetching upcoming invoices. by [@csalvato](https://github.com/csalvato)
21
+ - [#765](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/765) Properly set the status of a trialing subscription by [@csalvato](https://github.com/csalvato)
22
+ - [#755](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/755) Add allowed params to subscriptions by [@dominikdarnel](https://github.com/dominikdarnel)
23
+ - [#709](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/709) Remove unnecessary check on customer's currency by [@coorasse](https://github.com/coorasse)
24
+
25
+ - [#806](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/806) - Remove `payment_method_types` from required arguments for `Stripe::Checkout::Session`
26
+ - [#806](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/806) - Raise more helpful exception when Stripe::Price cannot be found within a `Stripe::Checkout::Session` `line_items` argument.
27
+
28
+
1
29
  ### 3.1.0.rc3 (pre-release 2021-07-14)
2
30
 
3
31
  - [#785](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/785): `Stripe::Product` no longer requires `type`. [@TastyPi](https://github.com/TastyPi)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # stripe-ruby-mock [![Build Status](https://travis-ci.org/stripe-ruby-mock/stripe-ruby-mock.png?branch=master)](https://travis-ci.org/stripe-ruby-mock/stripe-ruby-mock) [![Gitter chat](https://badges.gitter.im/rebelidealist/stripe-ruby-mock.png)](https://gitter.im/rebelidealist/stripe-ruby-mock)
1
+ # stripe-ruby-mock [![Tests](https://github.com/stripe-ruby-mock/stripe-ruby-mock/actions/workflows/rspec_tests.yml/badge.svg)](https://github.com/stripe-ruby-mock/stripe-ruby-mock/actions/workflows/rspec_tests.yml)
2
2
 
3
3
  * Homepage: https://github.com/stripe-ruby-mock/stripe-ruby-mock
4
4
  * Issues: https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues
@@ -12,7 +12,7 @@ This gem has unexpectedly grown in popularity and I've gotten pretty busy, so I'
12
12
 
13
13
  In your gemfile:
14
14
 
15
- gem 'stripe-ruby-mock', '~> 3.0.1', :require => 'stripe_mock'
15
+ gem 'stripe-ruby-mock', '~> 3.1.0', :require => 'stripe_mock'
16
16
 
17
17
  ## !!! Important
18
18
 
@@ -29,7 +29,7 @@ version `3.0.0` has [breaking changes](https://github.com/stripe-ruby-mock/strip
29
29
 
30
30
  ### Requirements
31
31
 
32
- * ruby >= 2.4.0
32
+ * ruby >= 2.6.0
33
33
  * stripe >= 5.0.0
34
34
 
35
35
  ### Specifications
@@ -406,6 +406,8 @@ Patches are welcome and greatly appreciated! If you're contributing to fix a pro
406
406
  be sure to write tests that illustrate the problem being fixed.
407
407
  This will help ensure that the problem remains fixed in future updates.
408
408
 
409
+ Note: You may need to `ulimit -n 4048` before running the test suite to get all tests to pass.
410
+
409
411
  ## Copyright
410
412
 
411
413
  Copyright (c) 2013 Gilbert
@@ -4,7 +4,7 @@ module StripeMock
4
4
 
5
5
  fixture_file = File.join(@webhook_fixture_path, "#{type}.json")
6
6
 
7
- unless File.exists?(fixture_file)
7
+ unless File.exist?(fixture_file)
8
8
  unless Webhooks.event_list.include?(type)
9
9
  raise UnsupportedRequestError.new "Unsupported webhook event `#{type}` (Searched in #{@webhook_fixture_path})"
10
10
  end
@@ -37,55 +37,94 @@ module StripeMock
37
37
  module Webhooks
38
38
  def self.event_list
39
39
  @__list = [
40
- 'account.updated',
41
40
  'account.application.deauthorized',
42
41
  'account.external_account.created',
43
- 'account.external_account.updated',
44
42
  'account.external_account.deleted',
43
+ 'account.external_account.updated',
44
+ 'account.updated',
45
45
  'balance.available',
46
- 'charge.succeeded',
47
- 'charge.updated',
48
- 'charge.failed',
49
- 'charge.refunded',
50
- 'charge.dispute.created',
51
- 'charge.dispute.updated',
46
+ 'charge.captured',
52
47
  'charge.dispute.closed',
48
+ 'charge.dispute.created',
53
49
  'charge.dispute.funds_reinstated',
54
50
  'charge.dispute.funds_withdrawn',
51
+ 'charge.dispute.updated',
52
+ 'charge.failed',
53
+ 'charge.refund.updated',
54
+ 'charge.refunded',
55
+ 'charge.succeeded',
56
+ 'charge.updated',
57
+ 'checkout.session.completed',
58
+ 'checkout.session.completed.payment_mode',
59
+ 'checkout.session.completed.setup_mode',
60
+ 'coupon.created',
61
+ 'coupon.deleted',
62
+ 'customer.created',
63
+ 'customer.deleted',
64
+ 'customer.discount.created',
65
+ 'customer.discount.deleted',
66
+ 'customer.discount.updated',
55
67
  'customer.source.created',
56
68
  'customer.source.deleted',
57
69
  'customer.source.updated',
58
- 'customer.created',
59
- 'customer.updated',
60
- 'customer.deleted',
61
70
  'customer.subscription.created',
62
- 'customer.subscription.updated',
63
71
  'customer.subscription.deleted',
64
72
  'customer.subscription.trial_will_end',
65
- 'customer.discount.created',
66
- 'customer.discount.updated',
67
- 'customer.discount.deleted',
73
+ 'customer.subscription.updated',
74
+ 'customer.updated',
68
75
  'invoice.created',
69
- 'invoice.updated',
70
- 'invoice.payment_succeeded',
76
+ 'invoice.finalized',
77
+ 'invoice.paid',
78
+ 'invoice.payment_action_required',
71
79
  'invoice.payment_failed',
80
+ 'invoice.payment_succeeded',
81
+ 'invoice.upcoming',
82
+ 'invoice.updated',
72
83
  'invoiceitem.created',
73
- 'invoiceitem.updated',
74
84
  'invoiceitem.deleted',
75
- 'payment_intent.succeeded',
85
+ 'invoiceitem.updated',
86
+ 'mandate.updated',
87
+ 'payment_intent.amount_capturable_updated',
88
+ 'payment_intent.canceled',
89
+ 'payment_intent.created',
76
90
  'payment_intent.payment_failed',
91
+ 'payment_intent.processing',
92
+ 'payment_intent.requires_action',
93
+ 'payment_intent.succeeded',
94
+ 'payment_link.created',
95
+ 'payment_link.updated',
96
+ 'payment_method.attached',
97
+ 'payment_method.detached',
98
+ 'payout.created',
99
+ 'payout.paid',
100
+ 'payout.updated',
77
101
  'plan.created',
78
- 'plan.updated',
79
102
  'plan.deleted',
103
+ 'plan.updated',
104
+ 'price.created',
105
+ 'price.deleted',
106
+ 'price.updated',
80
107
  'product.created',
81
- 'product.updated',
82
108
  'product.deleted',
83
- 'coupon.created',
84
- 'coupon.deleted',
109
+ 'product.updated',
110
+ 'quote.accepted',
111
+ 'quote.canceled',
112
+ 'quote.created',
113
+ 'quote.finalized',
114
+ 'setup_intent.canceled',
115
+ 'setup_intent.created',
116
+ 'setup_intent.setup_failed',
117
+ 'setup_intent.succeeded',
118
+ 'subscription_schedule.canceled',
119
+ 'subscription_schedule.created',
120
+ 'subscription_schedule.released',
121
+ 'subscription_schedule.updated',
122
+ 'tax_rate.created',
123
+ 'tax_rate.updated',
85
124
  'transfer.created',
125
+ 'transfer.failed',
86
126
  'transfer.paid',
87
- 'transfer.updated',
88
- 'transfer.failed'
127
+ 'transfer.updated'
89
128
  ]
90
129
  end
91
130
  end
@@ -193,8 +193,30 @@ module StripeMock
193
193
  currency: currency,
194
194
  destination: nil,
195
195
  fraud_details: {},
196
+ payment_method_details: {
197
+ card: {
198
+ brand: "visa",
199
+ checks: {
200
+ address_line1_check: nil,
201
+ address_postal_code_check: nil,
202
+ cvc_check: "pass"
203
+ },
204
+ country: "US",
205
+ exp_month: 12,
206
+ exp_year: 2013,
207
+ fingerprint: "3TQGpK9JoY1GgXPw",
208
+ funding: "credit",
209
+ installments: nil,
210
+ last4: "4242",
211
+ network: "visa",
212
+ three_d_secure: nil,
213
+ wallet: nil
214
+ },
215
+ type: "card"
216
+ },
196
217
  receipt_email: nil,
197
218
  receipt_number: nil,
219
+ receipt_url: nil,
198
220
  refunded: false,
199
221
  shipping: {},
200
222
  statement_descriptor: "Charge #{charge_id}",
@@ -255,7 +277,8 @@ module StripeMock
255
277
  charge: "ch_4fWhYjzQ23UFWT",
256
278
  receipt_number: nil,
257
279
  status: "succeeded",
258
- reason: "requested_by_customer"
280
+ reason: "requested_by_customer",
281
+ receipt_url: nil
259
282
  }.merge(params)
260
283
  end
261
284
 
@@ -365,7 +388,7 @@ module StripeMock
365
388
  canceled_at: nil,
366
389
  collection_method: 'charge_automatically',
367
390
  ended_at: nil,
368
- start: 1308595038,
391
+ start_date: 1308595038,
369
392
  object: 'subscription',
370
393
  trial_start: 1308595038,
371
394
  trial_end: 1308681468,
@@ -427,7 +450,8 @@ module StripeMock
427
450
  next_payment_attempt: 1349825350,
428
451
  charge: nil,
429
452
  discount: nil,
430
- subscription: nil
453
+ subscription: nil,
454
+ number: "6C41730-0001"
431
455
  }.merge(params)
432
456
  if invoice[:discount]
433
457
  invoice[:total] = [0, invoice[:subtotal] - invoice[:discount][:coupon][:amount_off]].max if invoice[:discount][:coupon][:amount_off]
@@ -634,6 +658,44 @@ module StripeMock
634
658
  }.merge(params)
635
659
  end
636
660
 
661
+ def self.mock_promotion_code(params={})
662
+ {
663
+ id: "mock_promo_abc123",
664
+ object: "promotion_code",
665
+ active: true,
666
+ code: "TESTCODE",
667
+ coupon: {
668
+ id: "mock_coupon_abc123",
669
+ object: "coupon",
670
+ amount_off: nil,
671
+ created: 1665773498,
672
+ currency: "usd",
673
+ duration: "repeating",
674
+ duration_in_months: 1,
675
+ livemode: false,
676
+ max_redemptions: nil,
677
+ metadata: {},
678
+ name: "Mock Coupon",
679
+ percent_off: 10.0,
680
+ redeem_by: nil,
681
+ times_redeemed: 0,
682
+ valid: true
683
+ },
684
+ created: 1665773499,
685
+ customer: nil,
686
+ expires_at: nil,
687
+ livemode: false,
688
+ max_redemptions: nil,
689
+ metadata: {},
690
+ restrictions: {
691
+ first_time_transaction: false,
692
+ minimum_amount: nil,
693
+ minimum_amount_currency: nil
694
+ },
695
+ times_redeemed: 0
696
+ }.merge(params)
697
+ end
698
+
637
699
  def self.mock_recipient(cards, params={})
638
700
  rp_id = params[:id] || "test_rp_default"
639
701
  cards.each {|card| card[:recipient] = rp_id}
@@ -1144,8 +1206,7 @@ module StripeMock
1144
1206
  id: id,
1145
1207
  object: 'subscription_item',
1146
1208
  created: 1504716183,
1147
- metadata: {
1148
- },
1209
+ metadata: {},
1149
1210
  plan: {
1150
1211
  id: 'PER_USER_PLAN1',
1151
1212
  object: 'plan',
@@ -1237,21 +1298,29 @@ module StripeMock
1237
1298
  payment_method_id = params[:id] || 'pm_1ExEuFL2DI6wht39WNJgbybl'
1238
1299
 
1239
1300
  type = params[:type].to_sym
1301
+ last4 = params.dig(:card, :number)
1240
1302
  data = {
1241
1303
  card: {
1242
- brand: 'visa',
1304
+ brand: case last4&.to_s
1305
+ when /^4/, nil
1306
+ 'visa'
1307
+ when /^5[1-5]/
1308
+ 'mastercard'
1309
+ else
1310
+ 'unknown'
1311
+ end,
1243
1312
  checks: {
1244
1313
  address_line1_check: nil,
1245
1314
  address_postal_code_check: nil,
1246
1315
  cvc_check: 'pass'
1247
1316
  },
1248
1317
  country: 'FR',
1249
- exp_month: 2,
1250
- exp_year: 2022,
1318
+ exp_month: params.dig(:card, :exp_month) || 2,
1319
+ exp_year: params.dig(:card, :exp_year) || 2022,
1251
1320
  fingerprint: 'Hr3Ly5z5IYxsokWA',
1252
1321
  funding: 'credit',
1253
1322
  generated_from: nil,
1254
- last4: '3155',
1323
+ last4: last4.nil? ? '3155' : last4.to_s[-4..],
1255
1324
  three_d_secure_usage: { supported: true },
1256
1325
  wallet: nil
1257
1326
  },
@@ -1266,7 +1335,7 @@ module StripeMock
1266
1335
  branch_code: '',
1267
1336
  country: 'DE',
1268
1337
  fingerprint: 'FD81kbVPe7M05BMj',
1269
- last4: '3000'
1338
+ last4: params.dig(:sepa_debit, :iban)&.[](-4..) || '3000'
1270
1339
  }
1271
1340
  }
1272
1341
 
@@ -1291,7 +1360,7 @@ module StripeMock
1291
1360
  metadata: {
1292
1361
  order_id: '123456789'
1293
1362
  }
1294
- }.merge(type => data[type]).merge(params)
1363
+ }.merge(params).merge(type => data[type])
1295
1364
  end
1296
1365
 
1297
1366
  def self.mock_setup_intent(params = {})
@@ -44,6 +44,7 @@ module StripeMock
44
44
  include StripeMock::RequestHandlers::Plans
45
45
  include StripeMock::RequestHandlers::Prices
46
46
  include StripeMock::RequestHandlers::Products
47
+ include StripeMock::RequestHandlers::PromotionCodes
47
48
  include StripeMock::RequestHandlers::Refunds
48
49
  include StripeMock::RequestHandlers::Recipients
49
50
  include StripeMock::RequestHandlers::Transfers
@@ -57,8 +58,9 @@ module StripeMock
57
58
 
58
59
  attr_reader :accounts, :balance, :balance_transactions, :bank_tokens, :charges, :coupons, :customers,
59
60
  :disputes, :events, :invoices, :invoice_items, :orders, :payment_intents, :payment_methods,
60
- :setup_intents, :plans, :prices, :recipients, :refunds, :transfers, :payouts, :subscriptions, :country_spec,
61
- :subscriptions_items, :products, :tax_rates, :checkout_sessions
61
+ :setup_intents, :plans, :prices, :promotion_codes, :recipients, :refunds, :transfers, :payouts,
62
+ :subscriptions, :country_spec, :subscriptions_items, :products, :tax_rates, :checkout_sessions,
63
+ :checkout_session_line_items
62
64
 
63
65
  attr_accessor :error_queue, :debug, :conversion_rate, :account_balance
64
66
 
@@ -83,6 +85,7 @@ module StripeMock
83
85
  @plans = {}
84
86
  @prices = {}
85
87
  @products = {}
88
+ @promotion_codes = {}
86
89
  @recipients = {}
87
90
  @refunds = {}
88
91
  @transfers = {}
@@ -92,6 +95,7 @@ module StripeMock
92
95
  @country_spec = {}
93
96
  @tax_rates = {}
94
97
  @checkout_sessions = {}
98
+ @checkout_session_line_items = {}
95
99
 
96
100
  @debug = false
97
101
  @error_queue = ErrorQueue.new
@@ -4,12 +4,13 @@ module StripeMock
4
4
  VALID_START_YEAR = 2009
5
5
 
6
6
  def Accounts.included(klass)
7
- klass.add_handler 'post /v1/accounts', :new_account
8
- klass.add_handler 'get /v1/account', :get_account
9
- klass.add_handler 'get /v1/accounts/(.*)', :get_account
10
- klass.add_handler 'post /v1/accounts/(.*)', :update_account
11
- klass.add_handler 'get /v1/accounts', :list_accounts
12
- klass.add_handler 'post /oauth/deauthorize',:deauthorize
7
+ klass.add_handler 'post /v1/accounts', :new_account
8
+ klass.add_handler 'get /v1/account', :get_account
9
+ klass.add_handler 'get /v1/accounts/(.*)', :get_account
10
+ klass.add_handler 'post /v1/accounts/(.*)', :update_account
11
+ klass.add_handler 'get /v1/accounts', :list_accounts
12
+ klass.add_handler 'post /oauth/deauthorize', :deauthorize
13
+ klass.add_handler 'delete /v1/accounts/(.*)', :delete_account
13
14
  end
14
15
 
15
16
  def new_account(route, method_url, params, headers)
@@ -48,6 +49,16 @@ module StripeMock
48
49
  Stripe::StripeObject.construct_from(:stripe_user_id => params[:stripe_user_id])
49
50
  end
50
51
 
52
+ def delete_account(route, method_url, params, headers)
53
+ init_account
54
+ route =~ method_url
55
+ assert_existence :account, $1, accounts[$1]
56
+ accounts[$1] = {
57
+ id: accounts[$1][:id],
58
+ deleted: true
59
+ }
60
+ end
61
+
51
62
  private
52
63
 
53
64
  def init_account
@@ -171,6 +171,11 @@ module StripeMock
171
171
  params[:refunds].has_key?(:data) && params[:refunds][:data].nil?)
172
172
  allowed << :refunds
173
173
  end
174
+ if params.has_key?(:payment_method_details) && (params[:payment_method_details].empty? ||
175
+ params[:payment_method_details].has_key?(:card) && (params[:payment_method_details][:card].empty? ||
176
+ params[:payment_method_details][:card].has_key?(:checks) && params[:payment_method_details][:card][:checks].empty?))
177
+ allowed << :payment_method_details
178
+ end
174
179
 
175
180
  allowed
176
181
  end
@@ -3,7 +3,135 @@ module StripeMock
3
3
  module Checkout
4
4
  module Session
5
5
  def Session.included(klass)
6
- klass.add_handler 'get /v1/checkout/sessions/(.*)', :get_checkout_session
6
+ klass.add_handler 'post /v1/checkout/sessions', :new_session
7
+ klass.add_handler 'get /v1/checkout/sessions', :list_checkout_sessions
8
+ klass.add_handler 'get /v1/checkout/sessions/([^/]*)', :get_checkout_session
9
+ klass.add_handler 'get /v1/checkout/sessions/([^/]*)/line_items', :list_line_items
10
+ end
11
+
12
+ def new_session(route, method_url, params, headers)
13
+ id = params[:id] || new_id('cs')
14
+
15
+ [:cancel_url, :success_url].each do |p|
16
+ require_param(p) if params[p].nil? || params[p].empty?
17
+ end
18
+
19
+ line_items = nil
20
+ if params[:line_items]
21
+ line_items = params[:line_items].each_with_index.map do |line_item, i|
22
+ throw Stripe::InvalidRequestError("Quantity is required. Add `quantity` to `line_items[#{i}]`") unless line_item[:quantity]
23
+ unless line_item[:price] || line_item[:price_data] || (line_item[:amount] && line_item[:currency] && line_item[:name])
24
+ throw Stripe::InvalidRequestError("Price or amount and currency is required. Add `price`, `price_data`, or `amount`, `currency` and `name` to `line_items[#{i}]`")
25
+ end
26
+ {
27
+ id: new_id("li"),
28
+ price: if line_item[:price]
29
+ line_item[:price]
30
+ elsif line_item[:price_data]
31
+ new_price(nil, nil, line_item[:price_data], nil)[:id]
32
+ else
33
+ new_price(nil, nil, {
34
+ unit_amount: line_item[:amount],
35
+ currency: line_item[:currency],
36
+ product_data: {
37
+ name: line_item[:name]
38
+ }
39
+ }, nil)[:id]
40
+ end,
41
+ quantity: line_item[:quantity]
42
+ }
43
+ end
44
+ end
45
+
46
+ amount = nil
47
+ currency = nil
48
+ if line_items
49
+ amount = 0
50
+
51
+ line_items.each do |line_item|
52
+ price = prices[line_item[:price]]
53
+
54
+ if price.nil?
55
+ raise StripeMock::StripeMockError.new("Price not found for ID: #{line_item[:price]}")
56
+ end
57
+
58
+ amount += (price[:unit_amount] * line_item[:quantity])
59
+ end
60
+
61
+ currency = prices[line_items.first[:price]][:currency]
62
+ end
63
+
64
+ payment_status = "unpaid"
65
+ payment_intent = nil
66
+ setup_intent = nil
67
+ case params[:mode]
68
+ when nil, "payment"
69
+ params[:customer] ||= new_customer(nil, nil, {email: params[:customer_email]}, nil)[:id]
70
+ require_param(:line_items) if params[:line_items].nil? || params[:line_items].empty?
71
+ payment_intent = new_payment_intent(nil, nil, {
72
+ amount: amount,
73
+ currency: currency,
74
+ customer: params[:customer],
75
+ payment_method_options: params[:payment_method_options],
76
+ payment_method_types: params[:payment_method_types]
77
+ }.merge(params[:payment_intent_data] || {}), nil)[:id]
78
+ checkout_session_line_items[id] = line_items
79
+ when "setup"
80
+ if !params[:line_items].nil? && !params[:line_items].empty?
81
+ throw Stripe::InvalidRequestError.new("You cannot pass `line_items` in `setup` mode", :line_items, http_status: 400)
82
+ end
83
+ setup_intent = new_setup_intent(nil, nil, {
84
+ customer: params[:customer],
85
+ payment_method_options: params[:payment_method_options],
86
+ payment_method_types: params[:payment_method_types]
87
+ }.merge(params[:setup_intent_data] || {}), nil)[:id]
88
+ payment_status = "no_payment_required"
89
+ when "subscription"
90
+ params[:customer] ||= new_customer(nil, nil, {email: params[:customer_email]}, nil)[:id]
91
+ require_param(:line_items) if params[:line_items].nil? || params[:line_items].empty?
92
+ checkout_session_line_items[id] = line_items
93
+ else
94
+ throw Stripe::InvalidRequestError.new("Invalid mode: must be one of payment, setup, or subscription", :mode, http_status: 400)
95
+ end
96
+
97
+ checkout_sessions[id] = {
98
+ id: id,
99
+ object: "checkout.session",
100
+ allow_promotion_codes: nil,
101
+ amount_subtotal: amount,
102
+ amount_total: amount,
103
+ automatic_tax: {
104
+ enabled: false,
105
+ status: nil
106
+ },
107
+ billing_address_collection: nil,
108
+ cancel_url: params[:cancel_url],
109
+ client_reference_id: nil,
110
+ currency: currency,
111
+ customer: params[:customer],
112
+ customer_details: nil,
113
+ customer_email: params[:customer_email],
114
+ livemode: false,
115
+ locale: nil,
116
+ metadata: params[:metadata],
117
+ mode: params[:mode],
118
+ payment_intent: payment_intent,
119
+ payment_method_options: params[:payment_method_options],
120
+ payment_method_types: params[:payment_method_types],
121
+ payment_status: payment_status,
122
+ setup_intent: setup_intent,
123
+ shipping: nil,
124
+ shipping_address_collection: nil,
125
+ submit_type: nil,
126
+ subscription: nil,
127
+ success_url: params[:success_url],
128
+ total_details: nil,
129
+ url: URI.join(StripeMock.checkout_base, id).to_s
130
+ }
131
+ end
132
+
133
+ def list_checkout_sessions(route, method_url, params, headers)
134
+ Data.mock_list_object(checkout_sessions.values)
7
135
  end
8
136
 
9
137
  def get_checkout_session(route, method_url, params, headers)
@@ -16,6 +144,35 @@ module StripeMock
16
144
  end
17
145
  checkout_session
18
146
  end
147
+
148
+ def list_line_items(route, method_url, params, headers)
149
+ route =~ method_url
150
+ checkout_session = assert_existence :checkout_session, $1, checkout_sessions[$1]
151
+
152
+ case checkout_session[:mode]
153
+ when "payment", "subscription"
154
+ line_items = assert_existence :checkout_session_line_items, $1, checkout_session_line_items[$1]
155
+ line_items.map do |line_item|
156
+ price = prices[line_item[:price]].clone
157
+
158
+ if price.nil?
159
+ raise StripeMock::StripeMockError.new("Price not found for ID: #{line_item[:price]}")
160
+ end
161
+
162
+ {
163
+ id: line_item[:id],
164
+ object: "item",
165
+ amount_subtotal: price[:unit_amount] * line_item[:quantity],
166
+ amount_total: price[:unit_amount] * line_item[:quantity],
167
+ currency: price[:currency],
168
+ price: price.clone,
169
+ quantity: line_item[:quantity]
170
+ }
171
+ end
172
+ else
173
+ throw Stripe::InvalidRequestError("Only payment and subscription sessions have line items")
174
+ end
175
+ end
19
176
  end
20
177
  end
21
178
  end