stripe-ruby-mock 2.5.8 → 3.0.0
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 +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +6 -6
- data/README.md +8 -8
- data/lib/stripe_mock.rb +3 -0
- data/lib/stripe_mock/api/errors.rb +31 -28
- data/lib/stripe_mock/api/webhooks.rb +3 -0
- data/lib/stripe_mock/data.rb +140 -13
- data/lib/stripe_mock/instance.rb +10 -3
- data/lib/stripe_mock/request_handlers/balance_transactions.rb +2 -2
- data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +1 -1
- data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +1 -1
- data/lib/stripe_mock/request_handlers/invoices.rb +6 -1
- data/lib/stripe_mock/request_handlers/payment_intents.rb +175 -0
- data/lib/stripe_mock/request_handlers/payment_methods.rb +138 -0
- data/lib/stripe_mock/request_handlers/products.rb +1 -0
- data/lib/stripe_mock/request_handlers/setup_intents.rb +93 -0
- data/lib/stripe_mock/request_handlers/subscriptions.rb +17 -4
- data/lib/stripe_mock/request_handlers/validators/param_validators.rb +95 -9
- data/lib/stripe_mock/test_strategies/base.rb +42 -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/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/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 +6 -6
- data/spec/server_spec.rb +2 -1
- data/spec/shared_stripe_examples/account_examples.rb +1 -1
- 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/charge_examples.rb +9 -22
- data/spec/shared_stripe_examples/coupon_examples.rb +1 -1
- data/spec/shared_stripe_examples/customer_examples.rb +44 -30
- 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/external_account_examples.rb +3 -3
- data/spec/shared_stripe_examples/invoice_examples.rb +41 -39
- data/spec/shared_stripe_examples/invoice_item_examples.rb +1 -1
- data/spec/shared_stripe_examples/payment_intent_examples.rb +137 -0
- data/spec/shared_stripe_examples/payment_method_examples.rb +185 -0
- data/spec/shared_stripe_examples/payout_examples.rb +2 -2
- data/spec/shared_stripe_examples/plan_examples.rb +135 -92
- data/spec/shared_stripe_examples/product_examples.rb +155 -0
- data/spec/shared_stripe_examples/refund_examples.rb +25 -21
- data/spec/shared_stripe_examples/setup_intent_examples.rb +68 -0
- data/spec/shared_stripe_examples/subscription_examples.rb +281 -310
- data/spec/shared_stripe_examples/subscription_items_examples.rb +3 -2
- data/spec/shared_stripe_examples/transfer_examples.rb +6 -6
- data/spec/shared_stripe_examples/webhook_event_examples.rb +11 -11
- data/spec/spec_helper.rb +3 -4
- data/spec/stripe_mock_spec.rb +2 -2
- data/spec/support/shared_contexts/stripe_validator_spec.rb +8 -0
- data/spec/support/stripe_examples.rb +3 -0
- data/stripe-ruby-mock.gemspec +2 -2
- metadata +47 -27
- data/spec/shared_stripe_examples/product_example.rb +0 -65
@@ -102,7 +102,7 @@ module StripeMock
|
|
102
102
|
customer[:default_source] = new_card[:id]
|
103
103
|
end
|
104
104
|
|
105
|
-
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
|
+
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 enable_incomplete_payments cancel_at_period_end default_tax_rates)
|
106
106
|
unknown_params = params.keys - allowed_params.map(&:to_sym)
|
107
107
|
if unknown_params.length > 0
|
108
108
|
raise Stripe::InvalidRequestError.new("Received unknown parameter: #{unknown_params.join}", unknown_params.first.to_s, http_status: 400)
|
@@ -133,6 +133,11 @@ module StripeMock
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
+
if params[:cancel_at_period_end]
|
137
|
+
subscription[:cancel_at_period_end] = true
|
138
|
+
subscription[:canceled_at] = Time.now.utc.to_i
|
139
|
+
end
|
140
|
+
|
136
141
|
subscriptions[subscription[:id]] = subscription
|
137
142
|
add_subscription_to_customer(customer, subscription)
|
138
143
|
|
@@ -191,17 +196,24 @@ module StripeMock
|
|
191
196
|
raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
|
192
197
|
end
|
193
198
|
end
|
194
|
-
verify_card_present(customer, subscription_plans.first, subscription)
|
195
199
|
|
196
|
-
if
|
200
|
+
if params[:cancel_at_period_end]
|
201
|
+
subscription[:cancel_at_period_end] = true
|
202
|
+
subscription[:canceled_at] = Time.now.utc.to_i
|
203
|
+
elsif params.has_key?(:cancel_at_period_end)
|
197
204
|
subscription[:cancel_at_period_end] = false
|
198
205
|
subscription[:canceled_at] = nil
|
199
206
|
end
|
200
207
|
|
201
208
|
params[:current_period_start] = subscription[:current_period_start]
|
202
209
|
params[:trial_end] = params[:trial_end] || subscription[:trial_end]
|
210
|
+
|
211
|
+
plan_amount_was = subscription.dig(:plan, :amount)
|
212
|
+
|
203
213
|
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
204
214
|
|
215
|
+
verify_card_present(customer, subscription_plans.first, subscription, params) if plan_amount_was == 0 && subscription.dig(:plan, :amount) && subscription.dig(:plan, :amount) > 0
|
216
|
+
|
205
217
|
# delete the old subscription, replace with the new subscription
|
206
218
|
customer[:subscriptions][:data].reject! { |sub| sub[:id] == subscription[:id] }
|
207
219
|
customer[:subscriptions][:data] << subscription
|
@@ -261,6 +273,7 @@ module StripeMock
|
|
261
273
|
# 3) has billing set to send invoice
|
262
274
|
def verify_card_present(customer, plan, subscription, params={})
|
263
275
|
return if customer[:default_source]
|
276
|
+
return if customer[:invoice_settings][:default_payment_method]
|
264
277
|
return if customer[:trial_end]
|
265
278
|
return if params[:trial_end]
|
266
279
|
|
@@ -281,7 +294,7 @@ module StripeMock
|
|
281
294
|
|
282
295
|
return if params[:billing] == 'send_invoice'
|
283
296
|
|
284
|
-
raise Stripe::InvalidRequestError.new('
|
297
|
+
raise Stripe::InvalidRequestError.new('This customer has no attached payment source', nil, http_status: 400)
|
285
298
|
end
|
286
299
|
|
287
300
|
def verify_active_status(subscription)
|
@@ -2,26 +2,112 @@ module StripeMock
|
|
2
2
|
module RequestHandlers
|
3
3
|
module ParamValidators
|
4
4
|
|
5
|
-
def
|
5
|
+
def already_exists_message(obj_class)
|
6
|
+
"#{obj_class.to_s.split("::").last} already exists."
|
7
|
+
end
|
8
|
+
|
9
|
+
def not_found_message(obj_class, obj_id)
|
10
|
+
"No such #{obj_class.to_s.split("::").last.downcase}: #{obj_id}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def missing_param_message(attr_name)
|
14
|
+
"Missing required param: #{attr_name}."
|
15
|
+
end
|
16
|
+
|
17
|
+
def invalid_integer_message(my_val)
|
18
|
+
"Invalid integer: #{my_val}"
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# ProductValidator
|
23
|
+
#
|
24
|
+
|
25
|
+
|
26
|
+
def validate_create_product_params(params)
|
6
27
|
params[:id] = params[:id].to_s
|
28
|
+
@base_strategy.create_product_params.keys.reject{ |k,_| k == :id }.each do |k|
|
29
|
+
raise Stripe::InvalidRequestError.new(missing_param_message(k), k) if params[k].nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
if !%w[good service].include?(params[:type])
|
33
|
+
raise Stripe::InvalidRequestError.new("Invalid type: must be one of good or service", :type)
|
34
|
+
end
|
35
|
+
|
36
|
+
if products[ params[:id] ]
|
37
|
+
raise Stripe::InvalidRequestError.new(already_exists_message(Stripe::Product), :id)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# PlanValidator
|
43
|
+
#
|
7
44
|
|
8
|
-
|
45
|
+
def missing_plan_amount_message
|
46
|
+
"Plans require an `amount` parameter to be set."
|
47
|
+
end
|
48
|
+
|
49
|
+
SUPPORTED_PLAN_INTERVALS = ["month", "year", "week", "day"]
|
50
|
+
|
51
|
+
def invalid_plan_interval_message
|
52
|
+
"Invalid interval: must be one of day, month, week, or year"
|
53
|
+
end
|
54
|
+
|
55
|
+
SUPPORTED_CURRENCIES = [
|
56
|
+
"usd", "aed", "afn", "all", "amd", "ang", "aoa", "ars", "aud", "awg", "azn", "bam", "bbd", "bdt", "bgn",
|
57
|
+
"bif", "bmd", "bnd", "bob", "brl", "bsd", "bwp", "bzd", "cad", "cdf", "chf", "clp", "cny", "cop", "crc",
|
58
|
+
"cve", "czk", "djf", "dkk", "dop", "dzd", "egp", "etb", "eur", "fjd", "fkp", "gbp", "gel", "gip", "gmd",
|
59
|
+
"gnf", "gtq", "gyd", "hkd", "hnl", "hrk", "htg", "huf", "idr", "ils", "inr", "isk", "jmd", "jpy", "kes",
|
60
|
+
"kgs", "khr", "kmf", "krw", "kyd", "kzt", "lak", "lbp", "lkr", "lrd", "lsl", "mad", "mdl", "mga", "mkd",
|
61
|
+
"mmk", "mnt", "mop", "mro", "mur", "mvr", "mwk", "mxn", "myr", "mzn", "nad", "ngn", "nio", "nok", "npr",
|
62
|
+
"nzd", "pab", "pen", "pgk", "php", "pkr", "pln", "pyg", "qar", "ron", "rsd", "rub", "rwf", "sar", "sbd",
|
63
|
+
"scr", "sek", "sgd", "shp", "sll", "sos", "srd", "std", "szl", "thb", "tjs", "top", "try", "ttd", "twd",
|
64
|
+
"tzs", "uah", "ugx", "uyu", "uzs", "vnd", "vuv", "wst", "xaf", "xcd", "xof", "xpf", "yer", "zar", "zmw",
|
65
|
+
"eek", "lvl", "svc", "vef", "ltl"
|
66
|
+
]
|
67
|
+
|
68
|
+
def invalid_currency_message(my_val)
|
69
|
+
"Invalid currency: #{my_val.downcase}. Stripe currently supports these currencies: #{SUPPORTED_CURRENCIES.join(", ")}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_create_plan_params(params)
|
73
|
+
plan_id = params[:id].to_s
|
74
|
+
product_id = params[:product]
|
75
|
+
|
76
|
+
@base_strategy.create_plan_params.keys.each do |attr_name|
|
9
77
|
message =
|
10
|
-
if
|
11
|
-
"Plans require an `#{
|
78
|
+
if attr_name == :amount
|
79
|
+
"Plans require an `#{attr_name}` parameter to be set."
|
12
80
|
else
|
13
|
-
"Missing required param: #{
|
81
|
+
"Missing required param: #{attr_name}."
|
14
82
|
end
|
15
|
-
raise Stripe::InvalidRequestError.new(message,
|
83
|
+
raise Stripe::InvalidRequestError.new(message, attr_name) if params[attr_name].nil?
|
84
|
+
end
|
85
|
+
|
86
|
+
if plans[plan_id]
|
87
|
+
message = already_exists_message(Stripe::Plan)
|
88
|
+
raise Stripe::InvalidRequestError.new(message, :id)
|
89
|
+
end
|
90
|
+
|
91
|
+
unless products[product_id]
|
92
|
+
message = not_found_message(Stripe::Product, product_id)
|
93
|
+
raise Stripe::InvalidRequestError.new(message, :product)
|
94
|
+
end
|
95
|
+
|
96
|
+
unless SUPPORTED_PLAN_INTERVALS.include?(params[:interval])
|
97
|
+
message = invalid_plan_interval_message
|
98
|
+
raise Stripe::InvalidRequestError.new(message, :interval)
|
16
99
|
end
|
17
100
|
|
18
|
-
|
19
|
-
|
101
|
+
unless SUPPORTED_CURRENCIES.include?(params[:currency])
|
102
|
+
message = invalid_currency_message(params[:currency])
|
103
|
+
raise Stripe::InvalidRequestError.new(message, :currency)
|
20
104
|
end
|
21
105
|
|
22
106
|
unless params[:amount].integer?
|
23
|
-
|
107
|
+
message = invalid_integer_message(params[:amount])
|
108
|
+
raise Stripe::InvalidRequestError.new(message, :amount)
|
24
109
|
end
|
110
|
+
|
25
111
|
end
|
26
112
|
|
27
113
|
def require_param(param_name)
|
@@ -2,19 +2,51 @@ module StripeMock
|
|
2
2
|
module TestStrategies
|
3
3
|
class Base
|
4
4
|
|
5
|
+
def list_products(limit)
|
6
|
+
Stripe::Product.list(limit: limit)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_product(params = {})
|
10
|
+
Stripe::Product.create create_product_params(params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_product_params(params={})
|
14
|
+
{
|
15
|
+
:id => 'stripe_mock_default_product_id',
|
16
|
+
:name => 'Default Product',
|
17
|
+
:type => 'service'
|
18
|
+
}.merge(params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def retrieve_product(product_id)
|
22
|
+
Stripe::Product.retrieve(product_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def list_plans(limit)
|
27
|
+
Stripe::Plan.list(limit: limit)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_plan(params={})
|
31
|
+
Stripe::Plan.create create_plan_params(params)
|
32
|
+
end
|
33
|
+
|
5
34
|
def create_plan_params(params={})
|
6
|
-
currency = params[:currency] || StripeMock.default_currency
|
7
35
|
{
|
8
36
|
:id => 'stripe_mock_default_plan_id',
|
9
|
-
:
|
10
|
-
|
11
|
-
|
12
|
-
:amount => 1337
|
13
|
-
:currency => currency,
|
14
|
-
:interval => 'month'
|
37
|
+
:interval => 'month',
|
38
|
+
:currency => StripeMock.default_currency,
|
39
|
+
:product => nil, # need to override yourself to pass validations
|
40
|
+
:amount => 1337
|
15
41
|
}.merge(params)
|
16
42
|
end
|
17
43
|
|
44
|
+
|
45
|
+
def list_subscriptions(limit)
|
46
|
+
Stripe::Subscription.list(limit: limit)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
18
50
|
def generate_card_token(card_params={})
|
19
51
|
card_data = { :number => "4242424242424242", :exp_month => 9, :exp_year => (Time.now.year + 5), :cvc => "999", :tokenization_method => nil }
|
20
52
|
card = StripeMock::Util.card_merge(card_data, card_params)
|
@@ -40,6 +72,7 @@ module StripeMock
|
|
40
72
|
stripe_token.id
|
41
73
|
end
|
42
74
|
|
75
|
+
|
43
76
|
def create_coupon_params(params = {})
|
44
77
|
currency = params[:currency] || StripeMock.default_currency
|
45
78
|
{
|
@@ -69,13 +102,14 @@ module StripeMock
|
|
69
102
|
end
|
70
103
|
|
71
104
|
def delete_all_coupons
|
72
|
-
coupons = Stripe::Coupon.
|
105
|
+
coupons = Stripe::Coupon.list
|
73
106
|
coupons.data.map(&:delete) if coupons.data.count > 0
|
74
107
|
end
|
75
108
|
|
76
109
|
def prepare_card_error
|
77
110
|
StripeMock.prepare_card_error(:card_error, :new_customer) if StripeMock.state == 'local'
|
78
111
|
end
|
112
|
+
|
79
113
|
end
|
80
114
|
end
|
81
115
|
end
|
@@ -2,6 +2,21 @@ module StripeMock
|
|
2
2
|
module TestStrategies
|
3
3
|
class Live < Base
|
4
4
|
|
5
|
+
def create_product(params={})
|
6
|
+
params = create_product_params(params)
|
7
|
+
raise "create_product requires an :id" if params[:id].nil?
|
8
|
+
delete_product(params[:id])
|
9
|
+
Stripe::Product.create params
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_product(product_id)
|
13
|
+
product = Stripe::Product.retrieve(product_id)
|
14
|
+
Stripe::Plan.list(product: product_id).each(&:delete) if product.type == 'service'
|
15
|
+
product.delete
|
16
|
+
rescue Stripe::StripeError => e
|
17
|
+
# do nothing
|
18
|
+
end
|
19
|
+
|
5
20
|
def create_plan(params={})
|
6
21
|
raise "create_plan requires an :id" if params[:id].nil?
|
7
22
|
delete_plan(params[:id])
|
@@ -9,12 +24,10 @@ module StripeMock
|
|
9
24
|
end
|
10
25
|
|
11
26
|
def delete_plan(plan_id)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# Do nothing; we just want to make sure this plan ceases to exists
|
17
|
-
end
|
27
|
+
plan = Stripe::Plan.retrieve(plan_id)
|
28
|
+
plan.delete
|
29
|
+
rescue Stripe::StripeError => e
|
30
|
+
# do nothing
|
18
31
|
end
|
19
32
|
|
20
33
|
def create_coupon(params={})
|
@@ -23,12 +36,10 @@ module StripeMock
|
|
23
36
|
end
|
24
37
|
|
25
38
|
def delete_coupon(id)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
# do nothing
|
31
|
-
end
|
39
|
+
coupon = Stripe::Coupon.retrieve(id)
|
40
|
+
coupon.delete
|
41
|
+
rescue Stripe::StripeError
|
42
|
+
# do nothing
|
32
43
|
end
|
33
44
|
|
34
45
|
def upsert_stripe_object(object, attributes)
|
@@ -2,8 +2,12 @@ module StripeMock
|
|
2
2
|
module TestStrategies
|
3
3
|
class Mock < Base
|
4
4
|
|
5
|
-
def
|
6
|
-
|
5
|
+
def delete_product(product_id)
|
6
|
+
if StripeMock.state == 'remote'
|
7
|
+
StripeMock.client.destroy_resource('products', product_id)
|
8
|
+
elsif StripeMock.state == 'local'
|
9
|
+
StripeMock.instance.products.delete(product_id)
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
def delete_plan(plan_id)
|
data/lib/stripe_mock/version.rb
CHANGED
@@ -4,53 +4,181 @@
|
|
4
4
|
"id": "evt_00000000000000",
|
5
5
|
"type": "charge.failed",
|
6
6
|
"object": "event",
|
7
|
+
"request": null,
|
8
|
+
"pending_webhooks": 1,
|
9
|
+
"api_version": "2018-02-28",
|
7
10
|
"data": {
|
8
11
|
"object": {
|
9
12
|
"id": "ch_00000000000000",
|
10
13
|
"object": "charge",
|
11
|
-
"
|
14
|
+
"amount": 100,
|
15
|
+
"amount_refunded": 0,
|
16
|
+
"application": null,
|
17
|
+
"application_fee": null,
|
18
|
+
"application_fee_amount": null,
|
19
|
+
"balance_transaction": "txn_00000000000000",
|
20
|
+
"billing_details": {
|
21
|
+
"address": {
|
22
|
+
"city": null,
|
23
|
+
"country": null,
|
24
|
+
"line1": null,
|
25
|
+
"line2": null,
|
26
|
+
"postal_code": null,
|
27
|
+
"state": null
|
28
|
+
},
|
29
|
+
"email": null,
|
30
|
+
"name": "Jenny Rosen",
|
31
|
+
"phone": null
|
32
|
+
},
|
33
|
+
"captured": false,
|
34
|
+
"created": 1572389205,
|
35
|
+
"currency": "cad",
|
36
|
+
"customer": null,
|
37
|
+
"description": "My First Test Charge (created for API docs)",
|
38
|
+
"dispute": null,
|
39
|
+
"failure_code": null,
|
40
|
+
"failure_message": null,
|
41
|
+
"fraud_details": {},
|
42
|
+
"invoice": null,
|
12
43
|
"livemode": false,
|
44
|
+
"metadata": {},
|
45
|
+
"on_behalf_of": null,
|
46
|
+
"order": null,
|
47
|
+
"outcome": null,
|
13
48
|
"paid": false,
|
14
|
-
"
|
15
|
-
"
|
16
|
-
"
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
"
|
36
|
-
"cvc_check": null,
|
37
|
-
"address_line1_check": null,
|
38
|
-
"address_zip_check": null
|
49
|
+
"payment_intent": null,
|
50
|
+
"payment_method": "card_00000000000000",
|
51
|
+
"payment_method_details": {
|
52
|
+
"card": {
|
53
|
+
"brand": "visa",
|
54
|
+
"checks": {
|
55
|
+
"address_line1_check": null,
|
56
|
+
"address_postal_code_check": null,
|
57
|
+
"cvc_check": null
|
58
|
+
},
|
59
|
+
"country": "US",
|
60
|
+
"exp_month": 8,
|
61
|
+
"exp_year": 2019,
|
62
|
+
"fingerprint": "C8aRpBae2T8GeJcn",
|
63
|
+
"funding": "credit",
|
64
|
+
"installments": null,
|
65
|
+
"last4": "4242",
|
66
|
+
"network": "visa",
|
67
|
+
"three_d_secure": null,
|
68
|
+
"wallet": null
|
69
|
+
},
|
70
|
+
"type": "card"
|
39
71
|
},
|
40
|
-
"
|
72
|
+
"receipt_email": null,
|
73
|
+
"receipt_number": null,
|
74
|
+
"receipt_url": "https://pay.stripe.com/receipts/acct_1C0lZEHvOcc4e36o/ch_1FZ3SbHsssvOcc4e36o87NHFK7i/rcpt_G5DuglJFhskXjsEDnLzxF6ESuGQe0Qj",
|
75
|
+
"refunded": false,
|
41
76
|
"refunds": {
|
42
|
-
|
77
|
+
"object": "list",
|
78
|
+
"data": [],
|
79
|
+
"has_more": false,
|
80
|
+
"url": "/v1/charges/ch_1FZ3SbHvOcc4e36o87NHFK7i/refunds"
|
43
81
|
},
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"
|
52
|
-
|
82
|
+
"review": null,
|
83
|
+
"shipping": null,
|
84
|
+
"source_transfer": null,
|
85
|
+
"statement_descriptor": null,
|
86
|
+
"statement_descriptor_suffix": null,
|
87
|
+
"status": "failed",
|
88
|
+
"transfer_data": null,
|
89
|
+
"transfer_group": null
|
90
|
+
}
|
91
|
+
},
|
92
|
+
"webhook": {
|
93
|
+
"created": 1326853478,
|
94
|
+
"livemode": false,
|
95
|
+
"id": "evt_00000000000000",
|
96
|
+
"type": "charge.failed",
|
97
|
+
"object": "event",
|
98
|
+
"request": null,
|
99
|
+
"pending_webhooks": 1,
|
100
|
+
"api_version": "2018-02-28",
|
101
|
+
"data": {
|
102
|
+
"object": {
|
103
|
+
"id": "ch_00000000000000",
|
104
|
+
"object": "charge",
|
105
|
+
"amount": 100,
|
106
|
+
"amount_refunded": 0,
|
107
|
+
"application": null,
|
108
|
+
"application_fee": null,
|
109
|
+
"application_fee_amount": null,
|
110
|
+
"balance_transaction": "txn_00000000000000",
|
111
|
+
"billing_details": {
|
112
|
+
"address": {
|
113
|
+
"city": null,
|
114
|
+
"country": null,
|
115
|
+
"line1": null,
|
116
|
+
"line2": null,
|
117
|
+
"postal_code": null,
|
118
|
+
"state": null
|
119
|
+
},
|
120
|
+
"email": null,
|
121
|
+
"name": "Jenny Rosen",
|
122
|
+
"phone": null
|
123
|
+
},
|
124
|
+
"captured": false,
|
125
|
+
"created": 1572389205,
|
126
|
+
"currency": "cad",
|
127
|
+
"customer": null,
|
128
|
+
"description": "My First Test Charge (created for API docs)",
|
129
|
+
"dispute": null,
|
130
|
+
"failure_code": null,
|
131
|
+
"failure_message": null,
|
132
|
+
"fraud_details": {},
|
133
|
+
"invoice": null,
|
134
|
+
"livemode": false,
|
135
|
+
"metadata": {},
|
136
|
+
"on_behalf_of": null,
|
137
|
+
"order": null,
|
138
|
+
"outcome": null,
|
139
|
+
"paid": false,
|
140
|
+
"payment_intent": null,
|
141
|
+
"payment_method": "card_00000000000000",
|
142
|
+
"payment_method_details": {
|
143
|
+
"card": {
|
144
|
+
"brand": "visa",
|
145
|
+
"checks": {
|
146
|
+
"address_line1_check": null,
|
147
|
+
"address_postal_code_check": null,
|
148
|
+
"cvc_check": null
|
149
|
+
},
|
150
|
+
"country": "US",
|
151
|
+
"exp_month": 8,
|
152
|
+
"exp_year": 2019,
|
153
|
+
"fingerprint": "C8aRpBae2T8GeJcn",
|
154
|
+
"funding": "credit",
|
155
|
+
"installments": null,
|
156
|
+
"last4": "4242",
|
157
|
+
"network": "visa",
|
158
|
+
"three_d_secure": null,
|
159
|
+
"wallet": null
|
160
|
+
},
|
161
|
+
"type": "card"
|
162
|
+
},
|
163
|
+
"receipt_email": null,
|
164
|
+
"receipt_number": null,
|
165
|
+
"receipt_url": "https://pay.stripe.com/receipts/acct_1C0lZEHvOcc4e36o/ch_1FZ3SbHvOcc4sssse36o87NHFK7i/rcpt_G5DuglJFhskXjsEDnLzxF6ESuGQe0Qj",
|
166
|
+
"refunded": false,
|
167
|
+
"refunds": {
|
168
|
+
"object": "list",
|
169
|
+
"data": [],
|
170
|
+
"has_more": false,
|
171
|
+
"url": "/v1/charges/ch_1FZ3SbHvOccssssss4e36o87NHFK7i/refunds"
|
172
|
+
},
|
173
|
+
"review": null,
|
174
|
+
"shipping": null,
|
175
|
+
"source_transfer": null,
|
176
|
+
"statement_descriptor": null,
|
177
|
+
"statement_descriptor_suffix": null,
|
178
|
+
"status": "failed",
|
179
|
+
"transfer_data": null,
|
180
|
+
"transfer_group": null
|
53
181
|
}
|
54
182
|
}
|
55
183
|
}
|
56
|
-
}
|
184
|
+
}
|