stripe-ruby-mock 2.5.6 → 3.1.0.rc2
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.travis.yml +6 -9
- data/CHANGELOG.md +35 -0
- data/Gemfile +1 -0
- data/README.md +17 -11
- data/lib/stripe_mock.rb +11 -0
- data/lib/stripe_mock/api/client.rb +1 -1
- data/lib/stripe_mock/api/errors.rb +34 -28
- data/lib/stripe_mock/api/instance.rb +1 -1
- data/lib/stripe_mock/api/webhooks.rb +7 -0
- data/lib/stripe_mock/client.rb +2 -1
- data/lib/stripe_mock/data.rb +323 -13
- data/lib/stripe_mock/data/list.rb +42 -9
- data/lib/stripe_mock/instance.rb +52 -5
- data/lib/stripe_mock/request_handlers/account_links.rb +15 -0
- data/lib/stripe_mock/request_handlers/balance_transactions.rb +2 -2
- data/lib/stripe_mock/request_handlers/charges.rb +13 -12
- data/lib/stripe_mock/request_handlers/checkout.rb +15 -0
- data/lib/stripe_mock/request_handlers/checkout_session.rb +16 -0
- data/lib/stripe_mock/request_handlers/customers.rb +35 -18
- data/lib/stripe_mock/request_handlers/ephemeral_key.rb +1 -1
- data/lib/stripe_mock/request_handlers/express_login_links.rb +15 -0
- data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +14 -10
- data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +22 -7
- data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +1 -1
- data/lib/stripe_mock/request_handlers/invoices.rb +11 -5
- data/lib/stripe_mock/request_handlers/payment_intents.rb +182 -0
- data/lib/stripe_mock/request_handlers/payment_methods.rb +120 -0
- data/lib/stripe_mock/request_handlers/plans.rb +1 -1
- data/lib/stripe_mock/request_handlers/prices.rb +44 -0
- data/lib/stripe_mock/request_handlers/products.rb +44 -0
- data/lib/stripe_mock/request_handlers/refunds.rb +6 -3
- data/lib/stripe_mock/request_handlers/setup_intents.rb +93 -0
- data/lib/stripe_mock/request_handlers/sources.rb +12 -6
- data/lib/stripe_mock/request_handlers/subscription_items.rb +36 -0
- data/lib/stripe_mock/request_handlers/subscriptions.rb +82 -41
- data/lib/stripe_mock/request_handlers/tax_rates.rb +36 -0
- data/lib/stripe_mock/request_handlers/tokens.rb +8 -6
- data/lib/stripe_mock/request_handlers/validators/param_validators.rb +130 -9
- data/lib/stripe_mock/test_strategies/base.rb +68 -8
- data/lib/stripe_mock/test_strategies/live.rb +23 -12
- data/lib/stripe_mock/test_strategies/mock.rb +6 -2
- data/lib/stripe_mock/version.rb +1 -1
- data/lib/stripe_mock/webhook_fixtures/balance.available.json +6 -0
- data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_reinstated.json +88 -0
- data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_withdrawn.json +88 -0
- data/lib/stripe_mock/webhook_fixtures/charge.failed.json +166 -38
- data/lib/stripe_mock/webhook_fixtures/customer.created.json +1 -0
- data/lib/stripe_mock/webhook_fixtures/customer.updated.json +1 -0
- data/lib/stripe_mock/webhook_fixtures/invoice.created.json +2 -1
- data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +1 -1
- data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +2 -1
- data/lib/stripe_mock/webhook_fixtures/payment_intent.payment_failed.json +186 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.succeeded.json +164 -0
- data/lib/stripe_mock/webhook_fixtures/product.created.json +34 -0
- data/lib/stripe_mock/webhook_fixtures/product.deleted.json +34 -0
- data/lib/stripe_mock/webhook_fixtures/product.updated.json +38 -0
- data/spec/instance_spec.rb +10 -12
- data/spec/list_spec.rb +38 -0
- data/spec/server_spec.rb +6 -3
- data/spec/shared_stripe_examples/account_examples.rb +1 -1
- data/spec/shared_stripe_examples/account_link_examples.rb +16 -0
- data/spec/shared_stripe_examples/balance_examples.rb +6 -0
- data/spec/shared_stripe_examples/balance_transaction_examples.rb +3 -3
- data/spec/shared_stripe_examples/bank_examples.rb +3 -3
- data/spec/shared_stripe_examples/card_examples.rb +4 -4
- data/spec/shared_stripe_examples/card_token_examples.rb +17 -21
- data/spec/shared_stripe_examples/charge_examples.rb +32 -36
- data/spec/shared_stripe_examples/checkout_examples.rb +38 -0
- data/spec/shared_stripe_examples/coupon_examples.rb +1 -1
- data/spec/shared_stripe_examples/customer_examples.rb +103 -53
- data/spec/shared_stripe_examples/dispute_examples.rb +2 -2
- data/spec/shared_stripe_examples/error_mock_examples.rb +8 -7
- data/spec/shared_stripe_examples/express_login_link_examples.rb +12 -0
- data/spec/shared_stripe_examples/external_account_examples.rb +3 -3
- data/spec/shared_stripe_examples/invoice_examples.rb +43 -41
- data/spec/shared_stripe_examples/invoice_item_examples.rb +1 -1
- data/spec/shared_stripe_examples/payment_intent_examples.rb +147 -0
- data/spec/shared_stripe_examples/payment_method_examples.rb +449 -0
- data/spec/shared_stripe_examples/payout_examples.rb +2 -2
- data/spec/shared_stripe_examples/plan_examples.rb +135 -77
- data/spec/shared_stripe_examples/price_examples.rb +183 -0
- data/spec/shared_stripe_examples/product_examples.rb +155 -0
- data/spec/shared_stripe_examples/refund_examples.rb +41 -31
- data/spec/shared_stripe_examples/setup_intent_examples.rb +68 -0
- data/spec/shared_stripe_examples/subscription_examples.rb +546 -295
- data/spec/shared_stripe_examples/subscription_items_examples.rb +76 -0
- data/spec/shared_stripe_examples/tax_rate_examples.rb +42 -0
- data/spec/shared_stripe_examples/transfer_examples.rb +9 -9
- data/spec/shared_stripe_examples/webhook_event_examples.rb +11 -11
- data/spec/spec_helper.rb +7 -4
- data/spec/stripe_mock_spec.rb +4 -4
- data/spec/support/shared_contexts/stripe_validator_spec.rb +8 -0
- data/spec/support/stripe_examples.rb +12 -2
- data/stripe-ruby-mock.gemspec +8 -3
- metadata +81 -32
@@ -0,0 +1,15 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module ExpressLoginLinks
|
4
|
+
|
5
|
+
def ExpressLoginLinks.included(klass)
|
6
|
+
klass.add_handler 'post /v1/accounts/(.*)/login_links', :new_account_login_link
|
7
|
+
end
|
8
|
+
|
9
|
+
def new_account_login_link(route, method_url, params, headers)
|
10
|
+
route =~ method_url
|
11
|
+
Data.mock_express_login_link(params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,18 +1,22 @@
|
|
1
1
|
module StripeMock
|
2
2
|
module RequestHandlers
|
3
3
|
module Helpers
|
4
|
+
def add_coupon_to_object(object, coupon)
|
5
|
+
discount_attrs = {}.tap do |attrs|
|
6
|
+
attrs[object[:object]] = object[:id]
|
7
|
+
attrs[:coupon] = coupon
|
8
|
+
attrs[:start] = Time.now.to_i
|
9
|
+
attrs[:end] = (DateTime.now >> coupon[:duration_in_months].to_i).to_time.to_i if coupon[:duration] == 'repeating'
|
10
|
+
end
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
coupon: coupon,
|
8
|
-
customer: customer[:id],
|
9
|
-
start: Time.now.to_i,
|
10
|
-
}
|
11
|
-
customer[:discount][:end] = (DateTime.now >> coupon[:duration_in_months]).to_time.to_i if coupon[:duration].to_sym == :repeating && coupon[:duration_in_months]
|
12
|
-
|
13
|
-
customer
|
12
|
+
object[:discount] = Stripe::Discount.construct_from(discount_attrs)
|
13
|
+
object
|
14
14
|
end
|
15
15
|
|
16
|
+
def delete_coupon_from_object(object)
|
17
|
+
object[:discount] = nil
|
18
|
+
object
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
|
-
end
|
22
|
+
end
|
@@ -8,13 +8,16 @@ module StripeMock
|
|
8
8
|
|
9
9
|
def resolve_subscription_changes(subscription, plans, customer, options = {})
|
10
10
|
subscription.merge!(custom_subscription_params(plans, customer, options))
|
11
|
+
items = options[:items]
|
12
|
+
items = items.values if items.respond_to?(:values)
|
11
13
|
subscription[:items][:data] = plans.map do |plan|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
matching_item = items && items.detect { |item| [item[:price], item[:plan]].include? plan[:id] }
|
15
|
+
if matching_item
|
16
|
+
quantity = matching_item[:quantity] || 1
|
17
|
+
id = matching_item[:id] || new_id('si')
|
18
|
+
Data.mock_subscription_item({ plan: plan, quantity: quantity, id: id })
|
16
19
|
else
|
17
|
-
Data.mock_subscription_item({ plan: plan })
|
20
|
+
Data.mock_subscription_item({ plan: plan, id: new_id('si') })
|
18
21
|
end
|
19
22
|
end
|
20
23
|
subscription
|
@@ -30,7 +33,15 @@ module StripeMock
|
|
30
33
|
start_time = options[:current_period_start] || now
|
31
34
|
params = { customer: cus[:id], current_period_start: start_time, created: created_time }
|
32
35
|
params.merge!({ :plan => (plans.size == 1 ? plans.first : nil) })
|
33
|
-
|
36
|
+
keys_to_merge = /application_fee_percent|quantity|metadata|tax_percent|billing|days_until_due|default_tax_rates|pending_invoice_item_interval|default_payment_method|collection_method/
|
37
|
+
params.merge! options.select {|k,v| k =~ keys_to_merge}
|
38
|
+
|
39
|
+
if options[:cancel_at_period_end] == true
|
40
|
+
params.merge!(cancel_at_period_end: true, canceled_at: now)
|
41
|
+
elsif options[:cancel_at_period_end] == false
|
42
|
+
params.merge!(cancel_at_period_end: false, canceled_at: nil)
|
43
|
+
end
|
44
|
+
|
34
45
|
# TODO: Implement coupon logic
|
35
46
|
|
36
47
|
if (((plan && plan[:trial_period_days]) || 0) == 0 && options[:trial_end].nil?) || options[:trial_end] == "now"
|
@@ -101,7 +112,11 @@ module StripeMock
|
|
101
112
|
|
102
113
|
def total_items_amount(items)
|
103
114
|
total = 0
|
104
|
-
items.each
|
115
|
+
items.each do |item|
|
116
|
+
quantity = item[:quantity] || 1
|
117
|
+
amount = item[:plan][:unit_amount] || item[:plan][:amount]
|
118
|
+
total += quantity * amount
|
119
|
+
end
|
105
120
|
total
|
106
121
|
end
|
107
122
|
end
|
@@ -36,7 +36,7 @@ module StripeMock
|
|
36
36
|
|
37
37
|
def get_card_or_bank_by_token(token)
|
38
38
|
token_id = token['id'] || token
|
39
|
-
|
39
|
+
@card_tokens[token_id] || @bank_tokens[token_id] || raise(Stripe::InvalidRequestError.new("Invalid token id: #{token_id}", 'tok', http_status: 404))
|
40
40
|
end
|
41
41
|
|
42
42
|
end
|
@@ -56,13 +56,14 @@ module StripeMock
|
|
56
56
|
invoices[$1].merge!(:paid => true, :attempted => true, :charge => charge[:id])
|
57
57
|
end
|
58
58
|
|
59
|
-
def upcoming_invoice(route, method_url, params, headers)
|
59
|
+
def upcoming_invoice(route, method_url, params, headers = {})
|
60
|
+
stripe_account = headers && headers[:stripe_account] || Stripe.api_key
|
60
61
|
route =~ method_url
|
61
|
-
raise Stripe::InvalidRequestError.new('Missing required param: customer', nil, http_status: 400) if params[:customer].nil?
|
62
|
+
raise Stripe::InvalidRequestError.new('Missing required param: customer if subscription is not provided', nil, http_status: 400) if params[:customer].nil? && params[:subscription].nil?
|
62
63
|
raise Stripe::InvalidRequestError.new('When previewing changes to a subscription, you must specify either `subscription` or `subscription_items`', nil, http_status: 400) if !params[:subscription_proration_date].nil? && params[:subscription].nil? && params[:subscription_plan].nil?
|
63
64
|
raise Stripe::InvalidRequestError.new('Cannot specify proration date without specifying a subscription', nil, http_status: 400) if !params[:subscription_proration_date].nil? && params[:subscription].nil?
|
64
65
|
|
65
|
-
customer = customers[params[:customer]]
|
66
|
+
customer = customers[stripe_account][params[:customer]]
|
66
67
|
assert_existence :customer, params[:customer], customer
|
67
68
|
|
68
69
|
raise Stripe::InvalidRequestError.new("No upcoming invoices for customer: #{customer[:id]}", nil, http_status: 404) if customer[:subscriptions][:data].length == 0
|
@@ -99,7 +100,12 @@ module StripeMock
|
|
99
100
|
invoice_lines = []
|
100
101
|
|
101
102
|
if prorating
|
102
|
-
unused_amount =
|
103
|
+
unused_amount = (
|
104
|
+
subscription[:plan][:amount].to_f *
|
105
|
+
subscription[:quantity] *
|
106
|
+
(subscription[:current_period_end] - subscription_proration_date.to_i) / (subscription[:current_period_end] - subscription[:current_period_start])
|
107
|
+
).ceil
|
108
|
+
|
103
109
|
invoice_lines << Data.mock_line_item(
|
104
110
|
id: new_id('ii'),
|
105
111
|
amount: -unused_amount,
|
@@ -138,7 +144,7 @@ module StripeMock
|
|
138
144
|
id: new_id('in'),
|
139
145
|
customer: customer[:id],
|
140
146
|
discount: customer[:discount],
|
141
|
-
|
147
|
+
created: invoice_date,
|
142
148
|
starting_balance: customer[:account_balance],
|
143
149
|
subscription: preview_subscription[:id],
|
144
150
|
period_start: prorating ? invoice_date : preview_subscription[:current_period_start],
|
@@ -0,0 +1,182 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module PaymentIntents
|
4
|
+
ALLOWED_PARAMS = [:description, :metadata, :receipt_email, :shipping, :destination, :payment_method, :payment_method_types, :setup_future_usage, :transfer_data, :amount, :currency]
|
5
|
+
|
6
|
+
def PaymentIntents.included(klass)
|
7
|
+
klass.add_handler 'post /v1/payment_intents', :new_payment_intent
|
8
|
+
klass.add_handler 'get /v1/payment_intents', :get_payment_intents
|
9
|
+
klass.add_handler 'get /v1/payment_intents/(.*)', :get_payment_intent
|
10
|
+
klass.add_handler 'post /v1/payment_intents/(.*)/confirm', :confirm_payment_intent
|
11
|
+
klass.add_handler 'post /v1/payment_intents/(.*)/capture', :capture_payment_intent
|
12
|
+
klass.add_handler 'post /v1/payment_intents/(.*)/cancel', :cancel_payment_intent
|
13
|
+
klass.add_handler 'post /v1/payment_intents/(.*)', :update_payment_intent
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_payment_intent(route, method_url, params, headers)
|
17
|
+
id = new_id('pi')
|
18
|
+
|
19
|
+
ensure_payment_intent_required_params(params)
|
20
|
+
status = case params[:amount]
|
21
|
+
when 3184 then 'requires_action'
|
22
|
+
when 3178 then 'requires_payment_method'
|
23
|
+
when 3055 then 'requires_capture'
|
24
|
+
else
|
25
|
+
'succeeded'
|
26
|
+
end
|
27
|
+
last_payment_error = params[:amount] == 3178 ? last_payment_error_generator(code: 'card_declined', decline_code: 'insufficient_funds', message: 'Not enough funds.') : nil
|
28
|
+
payment_intents[id] = Data.mock_payment_intent(
|
29
|
+
params.merge(
|
30
|
+
id: id,
|
31
|
+
status: status,
|
32
|
+
last_payment_error: last_payment_error
|
33
|
+
)
|
34
|
+
)
|
35
|
+
|
36
|
+
if params[:confirm] && status == 'succeeded'
|
37
|
+
payment_intents[id] = succeeded_payment_intent(payment_intents[id])
|
38
|
+
end
|
39
|
+
|
40
|
+
payment_intents[id].clone
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_payment_intent(route, method_url, params, headers)
|
44
|
+
route =~ method_url
|
45
|
+
id = $1
|
46
|
+
|
47
|
+
payment_intent = assert_existence :payment_intent, id, payment_intents[id]
|
48
|
+
payment_intents[id] = Util.rmerge(payment_intent, params.select{ |k,v| ALLOWED_PARAMS.include?(k)})
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_payment_intents(route, method_url, params, headers)
|
52
|
+
params[:offset] ||= 0
|
53
|
+
params[:limit] ||= 10
|
54
|
+
|
55
|
+
clone = payment_intents.clone
|
56
|
+
|
57
|
+
if params[:customer]
|
58
|
+
clone.delete_if { |k,v| v[:customer] != params[:customer] }
|
59
|
+
end
|
60
|
+
|
61
|
+
Data.mock_list_object(clone.values, params)
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_payment_intent(route, method_url, params, headers)
|
65
|
+
route =~ method_url
|
66
|
+
payment_intent_id = $1 || params[:payment_intent]
|
67
|
+
payment_intent = assert_existence :payment_intent, payment_intent_id, payment_intents[payment_intent_id]
|
68
|
+
|
69
|
+
payment_intent = payment_intent.clone
|
70
|
+
payment_intent
|
71
|
+
end
|
72
|
+
|
73
|
+
def capture_payment_intent(route, method_url, params, headers)
|
74
|
+
route =~ method_url
|
75
|
+
payment_intent = assert_existence :payment_intent, $1, payment_intents[$1]
|
76
|
+
|
77
|
+
succeeded_payment_intent(payment_intent)
|
78
|
+
end
|
79
|
+
|
80
|
+
def confirm_payment_intent(route, method_url, params, headers)
|
81
|
+
route =~ method_url
|
82
|
+
payment_intent = assert_existence :payment_intent, $1, payment_intents[$1]
|
83
|
+
|
84
|
+
succeeded_payment_intent(payment_intent)
|
85
|
+
end
|
86
|
+
|
87
|
+
def cancel_payment_intent(route, method_url, params, headers)
|
88
|
+
route =~ method_url
|
89
|
+
payment_intent = assert_existence :payment_intent, $1, payment_intents[$1]
|
90
|
+
|
91
|
+
payment_intent[:status] = 'canceled'
|
92
|
+
payment_intent
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def ensure_payment_intent_required_params(params)
|
98
|
+
if params[:amount].nil?
|
99
|
+
require_param(:amount)
|
100
|
+
elsif params[:currency].nil?
|
101
|
+
require_param(:currency)
|
102
|
+
elsif non_integer_charge_amount?(params)
|
103
|
+
raise Stripe::InvalidRequestError.new("Invalid integer: #{params[:amount]}", 'amount', http_status: 400)
|
104
|
+
elsif non_positive_charge_amount?(params)
|
105
|
+
raise Stripe::InvalidRequestError.new('Invalid positive integer', 'amount', http_status: 400)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def non_integer_charge_amount?(params)
|
110
|
+
params[:amount] && !params[:amount].is_a?(Integer)
|
111
|
+
end
|
112
|
+
|
113
|
+
def non_positive_charge_amount?(params)
|
114
|
+
params[:amount] && params[:amount] < 1
|
115
|
+
end
|
116
|
+
|
117
|
+
def last_payment_error_generator(code: nil, message: nil, decline_code: nil)
|
118
|
+
{
|
119
|
+
code: code,
|
120
|
+
doc_url: "https://stripe.com/docs/error-codes/payment-intent-authentication-failure",
|
121
|
+
message: message,
|
122
|
+
decline_code: decline_code,
|
123
|
+
payment_method: {
|
124
|
+
id: "pm_1EwXFA2eZvKYlo2C0tlY091l",
|
125
|
+
object: "payment_method",
|
126
|
+
billing_details: {
|
127
|
+
address: {
|
128
|
+
city: nil,
|
129
|
+
country: nil,
|
130
|
+
line1: nil,
|
131
|
+
line2: nil,
|
132
|
+
postal_code: nil,
|
133
|
+
state: nil
|
134
|
+
},
|
135
|
+
email: nil,
|
136
|
+
name: "seller_08072019090000",
|
137
|
+
phone: nil
|
138
|
+
},
|
139
|
+
card: {
|
140
|
+
brand: "visa",
|
141
|
+
checks: {
|
142
|
+
address_line1_check: nil,
|
143
|
+
address_postal_code_check: nil,
|
144
|
+
cvc_check: "unchecked"
|
145
|
+
},
|
146
|
+
country: "US",
|
147
|
+
exp_month: 12,
|
148
|
+
exp_year: 2021,
|
149
|
+
fingerprint: "LQBhEmJnItuj3mxf",
|
150
|
+
funding: "credit",
|
151
|
+
generated_from: nil,
|
152
|
+
last4: "1629",
|
153
|
+
three_d_secure_usage: {
|
154
|
+
supported: true
|
155
|
+
},
|
156
|
+
wallet: nil
|
157
|
+
},
|
158
|
+
created: 1563208900,
|
159
|
+
customer: nil,
|
160
|
+
livemode: false,
|
161
|
+
metadata: {},
|
162
|
+
type: "card"
|
163
|
+
},
|
164
|
+
type: "invalid_request_error"
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def succeeded_payment_intent(payment_intent)
|
169
|
+
payment_intent[:status] = 'succeeded'
|
170
|
+
btxn = new_balance_transaction('txn', { source: payment_intent[:id] })
|
171
|
+
|
172
|
+
payment_intent[:charges][:data] << Data.mock_charge(
|
173
|
+
balance_transaction: btxn,
|
174
|
+
amount: payment_intent[:amount],
|
175
|
+
currency: payment_intent[:currency]
|
176
|
+
)
|
177
|
+
|
178
|
+
payment_intent
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module PaymentMethods
|
4
|
+
ALLOWED_PARAMS = [:customer, :type]
|
5
|
+
|
6
|
+
def PaymentMethods.included(klass)
|
7
|
+
klass.add_handler 'post /v1/payment_methods', :new_payment_method
|
8
|
+
klass.add_handler 'get /v1/payment_methods/(.*)', :get_payment_method
|
9
|
+
klass.add_handler 'get /v1/payment_methods', :get_payment_methods
|
10
|
+
klass.add_handler 'post /v1/payment_methods/(.*)/attach', :attach_payment_method
|
11
|
+
klass.add_handler 'post /v1/payment_methods/(.*)/detach', :detach_payment_method
|
12
|
+
klass.add_handler 'post /v1/payment_methods/(.*)', :update_payment_method
|
13
|
+
end
|
14
|
+
|
15
|
+
# post /v1/payment_methods
|
16
|
+
def new_payment_method(route, method_url, params, headers)
|
17
|
+
id = new_id('pm')
|
18
|
+
|
19
|
+
ensure_payment_method_required_params(params)
|
20
|
+
|
21
|
+
payment_methods[id] = Data.mock_payment_method(
|
22
|
+
params.merge(
|
23
|
+
id: id
|
24
|
+
)
|
25
|
+
)
|
26
|
+
|
27
|
+
payment_methods[id].clone
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# params: {:type=>"card", :customer=>"test_cus_3"}
|
32
|
+
#
|
33
|
+
# get /v1/payment_methods/:id
|
34
|
+
def get_payment_method(route, method_url, params, headers)
|
35
|
+
id = method_url.match(route)[1] || params[:payment_method]
|
36
|
+
payment_method = assert_existence :payment_method, id, payment_methods[id]
|
37
|
+
|
38
|
+
payment_method.clone
|
39
|
+
end
|
40
|
+
|
41
|
+
# get /v1/payment_methods
|
42
|
+
def get_payment_methods(route, method_url, params, headers)
|
43
|
+
params[:offset] ||= 0
|
44
|
+
params[:limit] ||= 10
|
45
|
+
|
46
|
+
clone = payment_methods.clone
|
47
|
+
|
48
|
+
if params[:customer]
|
49
|
+
clone.delete_if { |_k, v| v[:customer] != params[:customer] }
|
50
|
+
end
|
51
|
+
|
52
|
+
Data.mock_list_object(clone.values, params)
|
53
|
+
end
|
54
|
+
|
55
|
+
# post /v1/payment_methods/:id/attach
|
56
|
+
def attach_payment_method(route, method_url, params, headers)
|
57
|
+
stripe_account = headers && headers[:stripe_account] || Stripe.api_key
|
58
|
+
allowed_params = [:customer]
|
59
|
+
|
60
|
+
id = method_url.match(route)[1]
|
61
|
+
|
62
|
+
assert_existence :customer, params[:customer], customers[stripe_account][params[:customer]]
|
63
|
+
|
64
|
+
payment_method = assert_existence :payment_method, id, payment_methods[id]
|
65
|
+
payment_methods[id] = Util.rmerge(payment_method, params.select { |k, _v| allowed_params.include?(k) })
|
66
|
+
payment_methods[id].clone
|
67
|
+
end
|
68
|
+
|
69
|
+
# post /v1/payment_methods/:id/detach
|
70
|
+
def detach_payment_method(route, method_url, params, headers)
|
71
|
+
id = method_url.match(route)[1]
|
72
|
+
|
73
|
+
payment_method = assert_existence :payment_method, id, payment_methods[id]
|
74
|
+
payment_method[:customer] = nil
|
75
|
+
|
76
|
+
payment_method.clone
|
77
|
+
end
|
78
|
+
|
79
|
+
# post /v1/payment_methods/:id
|
80
|
+
def update_payment_method(route, method_url, params, headers)
|
81
|
+
allowed_params = [:billing_details, :card, :ideal, :sepa_debit, :metadata]
|
82
|
+
|
83
|
+
id = method_url.match(route)[1]
|
84
|
+
|
85
|
+
payment_method = assert_existence :payment_method, id, payment_methods[id]
|
86
|
+
|
87
|
+
if payment_method[:customer].nil?
|
88
|
+
raise Stripe::InvalidRequestError.new(
|
89
|
+
'You must save this PaymentMethod to a customer before you can update it.',
|
90
|
+
nil,
|
91
|
+
http_status: 400
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
payment_methods[id] =
|
96
|
+
Util.rmerge(payment_method, params.select { |k, _v| allowed_params.include?(k)} )
|
97
|
+
|
98
|
+
payment_methods[id].clone
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def ensure_payment_method_required_params(params)
|
104
|
+
require_param(:type) if params[:type].nil?
|
105
|
+
|
106
|
+
if invalid_type?(params[:type])
|
107
|
+
raise Stripe::InvalidRequestError.new(
|
108
|
+
'Invalid type: must be one of card, ideal or sepa_debit',
|
109
|
+
nil,
|
110
|
+
http_status: 400
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def invalid_type?(type)
|
116
|
+
!%w(card ideal sepa_debit).include?(type)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|