tang 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/app/controllers/tang/admin/subscriptions_controller.rb +1 -1
- data/app/jobs/tang/import_customers_job.rb +7 -1
- data/app/models/tang/invoice.rb +2 -2
- data/app/models/tang/subscription.rb +3 -3
- data/app/services/tang/create_subscription.rb +4 -1
- data/app/services/tang/delete_card.rb +4 -2
- data/app/services/tang/fail_invoice.rb +6 -3
- data/app/services/tang/save_card.rb +4 -1
- data/app/services/tang/update_subscription.rb +1 -1
- data/app/views/tang/account/cards/_payment.html.erb +0 -32
- data/app/views/tang/admin/subscriptions/_form.html.erb +0 -5
- data/app/views/tang/admin/subscriptions/show.html.erb +0 -7
- data/lib/css/main.css +31 -0
- data/lib/js/index.js +3 -2
- data/lib/tang/version.rb +1 -1
- data/spec/fixtures/stripe_webhooks/invoice.created.json +1 -2
- data/spec/fixtures/stripe_webhooks/invoice.payment_failed.json +172 -0
- data/spec/models/tang/card_spec.rb +4 -1
- data/spec/models/tang/charge_spec.rb +47 -1
- data/spec/tang_app/Gemfile.lock +70 -0
- data/spec/tang_app/app/javascript/packs/application.js +2 -1
- data/spec/tang_app/app/views/layouts/application.html.erb +1 -0
- data/spec/tang_app/log/development.log +342 -0
- data/spec/tang_app/log/test.log +52349 -0
- data/spec/tang_app/node_modules/fsevents/build/Release/fse.node +0 -0
- data/spec/tang_app/package.json +3 -0
- data/spec/tang_app/public/packs-test/js/application-0dded7840d00b04c8937.js +653 -0
- data/spec/tang_app/public/packs-test/js/application-0dded7840d00b04c8937.js.map +1 -0
- data/spec/tang_app/public/packs-test/manifest.json +4 -4
- data/spec/tang_app/public/packs/js/application-080539f58098495f5fea.js +873 -0
- data/spec/tang_app/public/packs/js/application-080539f58098495f5fea.js.map +1 -0
- data/spec/tang_app/public/packs/js/application-63744ba8e1d5132a70a7.js +653 -0
- data/spec/tang_app/public/packs/js/application-63744ba8e1d5132a70a7.js.map +1 -0
- data/spec/tang_app/public/packs/js/application-6ed6c7d5740861886e33.js +908 -0
- data/spec/tang_app/public/packs/js/application-6ed6c7d5740861886e33.js.map +1 -0
- data/spec/tang_app/public/packs/js/application-95a81db325472bcd27be.js +873 -0
- data/spec/tang_app/public/packs/js/application-95a81db325472bcd27be.js.map +1 -0
- data/spec/tang_app/public/packs/js/application-a4d14e60f459eb6278f8.js +873 -0
- data/spec/tang_app/public/packs/js/application-a4d14e60f459eb6278f8.js.map +1 -0
- data/spec/tang_app/public/packs/js/application-e5d6d1269e6e876bad16.js +654 -0
- data/spec/tang_app/public/packs/js/application-e5d6d1269e6e876bad16.js.map +1 -0
- data/spec/tang_app/public/packs/manifest.json +4 -4
- data/spec/tang_app/tmp/cache/webpacker/last-compilation-digest-development +1 -1
- data/spec/tang_app/tmp/cache/webpacker/last-compilation-digest-test +1 -1
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afcc7d64662d251041c9106406151ef1c0eb633c4f52648aad4bf065e73d5715
|
4
|
+
data.tar.gz: 70a3bb4255182c594a89773546518ae1972af6dbd9efe4a48a0e04cd0048568a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 729756368750f8bd9bddc7db310caa1bb0b64d93ad604b9d8718361bf68be13c58cfacc269d225308a35130c50d5ece613e3fb286f855bf10b54afeb8122579a
|
7
|
+
data.tar.gz: 6efa4353dfa69a47657ed8573b026907922d8dadb37f04efd8af5fd892dc4ec8cd65c789ccba00a67f2a1cdac8b87459f52909e1077ce77eb712e8bb7f16942c
|
data/README.md
CHANGED
@@ -7,4 +7,12 @@ Stripe subscriptions
|
|
7
7
|
[![Test Coverage](https://codeclimate.com/github/sixoverground/tang/badges/coverage.svg)](https://codeclimate.com/github/sixoverground/tang/coverage)
|
8
8
|
[![Issue Count](https://codeclimate.com/github/sixoverground/tang/badges/issue_count.svg)](https://codeclimate.com/github/sixoverground/tang)
|
9
9
|
|
10
|
+
## Publishing
|
11
|
+
|
12
|
+
```
|
13
|
+
gem build tang.gemspec
|
14
|
+
gem push tang-x.x.x.gem
|
15
|
+
npm publish
|
16
|
+
```
|
17
|
+
|
10
18
|
|
@@ -67,7 +67,7 @@ module Tang
|
|
67
67
|
|
68
68
|
# Only allow a trusted parameter "white list" through.
|
69
69
|
def subscription_params
|
70
|
-
params.require(:subscription).permit(:plan_id, :quantity, :trial_end
|
70
|
+
params.require(:subscription).permit(:plan_id, :quantity, :trial_end)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
@@ -16,7 +16,13 @@ module Tang
|
|
16
16
|
customer = update_customer(customer, stripe_customer)
|
17
17
|
|
18
18
|
# import card
|
19
|
-
|
19
|
+
if stripe_customer.default_source.present?
|
20
|
+
stripe_card = Stripe::Customer.retrieve_source(
|
21
|
+
stripe_customer.id,
|
22
|
+
stripe_customer.default_source,
|
23
|
+
)
|
24
|
+
Card.from_stripe(stripe_card, customer)
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
data/app/models/tang/invoice.rb
CHANGED
@@ -43,10 +43,10 @@ module Tang
|
|
43
43
|
i.customer = customer
|
44
44
|
i.period_start = stripe_invoice.period_start
|
45
45
|
i.period_end = stripe_invoice.period_end
|
46
|
-
i.date = stripe_invoice.date
|
46
|
+
i.date = stripe_invoice.created # changed from date
|
47
47
|
i.currency = stripe_invoice.currency
|
48
48
|
i.subtotal = stripe_invoice.subtotal
|
49
|
-
i.tax_percent = stripe_invoice.tax_percent
|
49
|
+
# i.tax_percent = stripe_invoice.tax_percent # removed from api, replaced with tax rates
|
50
50
|
i.tax = stripe_invoice.tax
|
51
51
|
i.total = stripe_invoice.total
|
52
52
|
i.amount_due = stripe_invoice.amount_due
|
@@ -37,8 +37,8 @@ module Tang
|
|
37
37
|
validates :stripe_id, presence: true, uniqueness: true
|
38
38
|
validates :application_fee_percent, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
|
39
39
|
validates :quantity, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
|
40
|
-
validates :tax_percent, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true,
|
41
|
-
|
40
|
+
# validates :tax_percent, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true,
|
41
|
+
# format: { with: /\A\d+(?:\.\d{0,4})?\z/ }
|
42
42
|
|
43
43
|
# before_save :nil_if_blank
|
44
44
|
before_update :update_stripe_subscription
|
@@ -54,7 +54,7 @@ module Tang
|
|
54
54
|
s.plan = plan
|
55
55
|
s.application_fee_percent = stripe_subscription.application_fee_percent
|
56
56
|
s.quantity = stripe_subscription.quantity
|
57
|
-
s.tax_percent = stripe_subscription.tax_percent
|
57
|
+
# s.tax_percent = stripe_subscription.tax_percent # removed from api in favor of tax rates
|
58
58
|
s.trial_end = stripe_subscription.trial_end
|
59
59
|
s.coupon = Coupon.find_by(stripe_id: stripe_subscription.discount.coupon.id) if stripe_subscription.discount.present?
|
60
60
|
s.status = stripe_subscription.status
|
@@ -31,7 +31,10 @@ module Tang
|
|
31
31
|
subscription.activate!
|
32
32
|
|
33
33
|
# Save the payment method
|
34
|
-
stripe_card =
|
34
|
+
stripe_card = Stripe::Customer.retrieve_source(
|
35
|
+
stripe_customer.id,
|
36
|
+
stripe_customer.default_source,
|
37
|
+
)
|
35
38
|
|
36
39
|
# Finalize customer with subscription and payment method
|
37
40
|
finalize_customer(customer, stripe_sub, stripe_card)
|
@@ -2,8 +2,10 @@ module Tang
|
|
2
2
|
class DeleteCard
|
3
3
|
def self.call(card)
|
4
4
|
begin
|
5
|
-
|
6
|
-
|
5
|
+
Stripe::Customer.delete_source(
|
6
|
+
card.customer.stripe_id,
|
7
|
+
card.stripe_id,
|
8
|
+
)
|
7
9
|
rescue Stripe::StripeError => e
|
8
10
|
card.errors[:base] << e.message
|
9
11
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Tang
|
2
2
|
class FailInvoice
|
3
3
|
def self.call(stripe_invoice)
|
4
|
-
invoice = Invoice.find_by(stripe_id: stripe_invoice.id)
|
4
|
+
# invoice = Invoice.find_by(stripe_id: stripe_invoice.id)
|
5
|
+
invoice = Invoice.from_stripe(stripe_invoice)
|
5
6
|
|
6
7
|
# create charge
|
7
8
|
charge = nil
|
@@ -12,8 +13,10 @@ module Tang
|
|
12
13
|
|
13
14
|
# update subscription
|
14
15
|
subscription = Subscription.find_by(stripe_id: stripe_invoice.subscription)
|
15
|
-
|
16
|
-
|
16
|
+
if subscription.present?
|
17
|
+
subscription.fail! if !subscription.past_due?
|
18
|
+
end
|
19
|
+
|
17
20
|
return charge
|
18
21
|
end
|
19
22
|
end
|
@@ -22,7 +22,10 @@ module Tang
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Save the payment method
|
25
|
-
stripe_card =
|
25
|
+
stripe_card = Stripe::Customer.retrieve_source(
|
26
|
+
cu.id,
|
27
|
+
cu.default_source,
|
28
|
+
)
|
26
29
|
card.update_from_stripe(stripe_card)
|
27
30
|
|
28
31
|
rescue Stripe::StripeError => e
|
@@ -10,7 +10,7 @@ module Tang
|
|
10
10
|
s.plan = subscription.plan.stripe_id
|
11
11
|
s.quantity = subscription.quantity
|
12
12
|
s.trial_end = subscription.stripe_trial_end if subscription.stripe_trial_end.present?
|
13
|
-
s.tax_percent = subscription.tax_percent if subscription.tax_percent.present?
|
13
|
+
# s.tax_percent = subscription.tax_percent if subscription.tax_percent.present?
|
14
14
|
s.coupon = subscription.coupon.stripe_id if subscription.coupon.present?
|
15
15
|
s.save
|
16
16
|
rescue Stripe::StripeError => e
|
@@ -1,35 +1,3 @@
|
|
1
|
-
<% if false %>
|
2
|
-
<span class="payment-errors"></span>
|
3
|
-
|
4
|
-
<div class="payment-row">
|
5
|
-
<label for="name">
|
6
|
-
<span>Cardholder name</span>
|
7
|
-
</label>
|
8
|
-
<input id="name" type="text" data-stripe="name" autocomplete="cc-name" placeholder="Full Name" required class="form-control">
|
9
|
-
<label for="number">
|
10
|
-
<span>Card number</span>
|
11
|
-
</label>
|
12
|
-
<input id="number" type="tel" size="20" data-stripe="number" autocomplete="cc-number" placeholder="•••• •••• •••• ••••" required class="form-control">
|
13
|
-
</div>
|
14
|
-
|
15
|
-
<div class="payment-row">
|
16
|
-
<label>
|
17
|
-
<span>Expiration (MM/YY)</span>
|
18
|
-
<input type="tel" size="5" data-stripe="exp" autocomplete="cc-exp" placeholder="•• / ••" required class="form-control">
|
19
|
-
</label>
|
20
|
-
|
21
|
-
<label>
|
22
|
-
<span>CVC</span>
|
23
|
-
<input type="tel" size="4" data-stripe="cvc" autocomplete="off" placeholder="•••" required class="form-control">
|
24
|
-
</label>
|
25
|
-
|
26
|
-
<label>
|
27
|
-
<span>Postal code</span>
|
28
|
-
<input type="text" data-stripe="address_zip" autocomplete="postal-code" placeholder="•••••" required class="form-control">
|
29
|
-
</label>
|
30
|
-
</div>
|
31
|
-
<% end %>
|
32
|
-
|
33
1
|
<div class="payment-row">
|
34
2
|
<label for="name">Cardholder name</label>
|
35
3
|
<input id="name" type="text" autocomplete="cc-name" placeholder="Full Name" required class="form-control">
|
@@ -31,11 +31,6 @@
|
|
31
31
|
<% end %>
|
32
32
|
</div>
|
33
33
|
|
34
|
-
<div class="form-group">
|
35
|
-
<%= f.label :tax_percent %>
|
36
|
-
<%= f.number_field :tax_percent, min: 0, step: 0.0001, class: 'form-control' %>
|
37
|
-
</div>
|
38
|
-
|
39
34
|
<%= link_to 'Cancel', tang.admin_subscription_path(subscription), class: 'btn btn-secondary' %>
|
40
35
|
<%= f.submit class: 'btn btn-primary' %>
|
41
36
|
<% end %>
|
@@ -37,13 +37,6 @@
|
|
37
37
|
<dt>Trialing until:</dt>
|
38
38
|
<dd><%= @subscription.trial_end.strftime('%Y/%m/%d') %></dd>
|
39
39
|
<% end %>
|
40
|
-
|
41
|
-
<dt>Tax percent:</dt>
|
42
|
-
<% if @subscription.tax_percent.present? %>
|
43
|
-
<dd><%= @subscription.tax_percent %>%</dd>
|
44
|
-
<% else %>
|
45
|
-
<dd>No tax applied</dd>
|
46
|
-
<% end %>
|
47
40
|
</dl>
|
48
41
|
</div>
|
49
42
|
|
data/lib/css/main.css
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
/**
|
2
|
+
* The CSS shown here will not be introduced in the Quickstart guide, but shows
|
3
|
+
* how you can use CSS to style your Element's container.
|
4
|
+
*/
|
5
|
+
.StripeElement {
|
6
|
+
box-sizing: border-box;
|
7
|
+
|
8
|
+
height: 40px;
|
9
|
+
|
10
|
+
padding: 10px 12px;
|
11
|
+
|
12
|
+
border: 1px solid transparent;
|
13
|
+
border-radius: 4px;
|
14
|
+
background-color: white;
|
15
|
+
|
16
|
+
box-shadow: 0 1px 3px 0 #e6ebf1;
|
17
|
+
-webkit-transition: box-shadow 150ms ease;
|
18
|
+
transition: box-shadow 150ms ease;
|
19
|
+
}
|
20
|
+
|
21
|
+
.StripeElement--focus {
|
22
|
+
box-shadow: 0 1px 3px 0 #cfd7df;
|
23
|
+
}
|
24
|
+
|
25
|
+
.StripeElement--invalid {
|
26
|
+
border-color: #fa755a;
|
27
|
+
}
|
28
|
+
|
29
|
+
.StripeElement--webkit-autofill {
|
30
|
+
background-color: #fefde5 !important;
|
31
|
+
}
|
data/lib/js/index.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// Create a Stripe client.
|
2
|
-
var stripe = Stripe(
|
2
|
+
// var stripe = Stripe(process.env.STRIPE_PUBLISHABLE_KEY);
|
3
|
+
var stripe = Stripe(window.Tang.STRIPE_PUBLISHABLE_KEY)
|
3
4
|
|
4
5
|
const registerElements = () => {
|
5
6
|
|
@@ -83,4 +84,4 @@ const registerElements = () => {
|
|
83
84
|
|
84
85
|
}
|
85
86
|
|
86
|
-
|
87
|
+
export default registerElements
|
data/lib/tang/version.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
"object": "event",
|
7
7
|
"data": {
|
8
8
|
"object": {
|
9
|
-
"
|
9
|
+
"created": 1380674206,
|
10
10
|
"id": "in_00000000000000",
|
11
11
|
"period_start": 1378082075,
|
12
12
|
"period_end": 1380674075,
|
@@ -66,7 +66,6 @@
|
|
66
66
|
"subscription": "sub_00000000000000",
|
67
67
|
"metadata": {},
|
68
68
|
"description": null,
|
69
|
-
"tax_percent": 0,
|
70
69
|
"tax": 0,
|
71
70
|
"invoice_pdf": "pdf_url"
|
72
71
|
}
|
@@ -0,0 +1,172 @@
|
|
1
|
+
{
|
2
|
+
"id": "evt_00000000000000",
|
3
|
+
"object": "event",
|
4
|
+
"api_version": "2020-08-27",
|
5
|
+
"created": 1601579547,
|
6
|
+
"data": {
|
7
|
+
"object": {
|
8
|
+
"id": "in_00000000000000",
|
9
|
+
"object": "invoice",
|
10
|
+
"account_country": "US",
|
11
|
+
"account_name": "Link My Photos",
|
12
|
+
"account_tax_ids": null,
|
13
|
+
"amount_due": 499,
|
14
|
+
"amount_paid": 0,
|
15
|
+
"amount_remaining": 499,
|
16
|
+
"application_fee_amount": null,
|
17
|
+
"attempt_count": 4,
|
18
|
+
"attempted": true,
|
19
|
+
"auto_advance": true,
|
20
|
+
"billing_reason": "subscription_cycle",
|
21
|
+
"charge": "ch_00000000000000",
|
22
|
+
"collection_method": "charge_automatically",
|
23
|
+
"created": 1600279843,
|
24
|
+
"currency": "usd",
|
25
|
+
"custom_fields": null,
|
26
|
+
"customer": "cus_00000000000000",
|
27
|
+
"customer_address": null,
|
28
|
+
"customer_email": "test@example.com",
|
29
|
+
"customer_name": null,
|
30
|
+
"customer_phone": null,
|
31
|
+
"customer_shipping": null,
|
32
|
+
"customer_tax_exempt": "none",
|
33
|
+
"customer_tax_ids": [
|
34
|
+
],
|
35
|
+
"default_payment_method": null,
|
36
|
+
"default_source": null,
|
37
|
+
"default_tax_rates": [
|
38
|
+
],
|
39
|
+
"description": null,
|
40
|
+
"discount": null,
|
41
|
+
"discounts": [
|
42
|
+
],
|
43
|
+
"due_date": null,
|
44
|
+
"ending_balance": 0,
|
45
|
+
"footer": null,
|
46
|
+
"hosted_invoice_url": "https://pay.stripe.com/invoice/acct_00000000000000/invst_00000000000000",
|
47
|
+
"invoice_pdf": "https://pay.stripe.com/invoice/acct_00000000000000/invst_00000000000000/pdf",
|
48
|
+
"lines": {
|
49
|
+
"object": "list",
|
50
|
+
"data": [
|
51
|
+
{
|
52
|
+
"id": "il_00000000000000",
|
53
|
+
"object": "line_item",
|
54
|
+
"amount": 499,
|
55
|
+
"currency": "usd",
|
56
|
+
"description": "1 × Shutterbug (at $4.99 / month)",
|
57
|
+
"discount_amounts": [
|
58
|
+
],
|
59
|
+
"discountable": true,
|
60
|
+
"discounts": [
|
61
|
+
],
|
62
|
+
"livemode": true,
|
63
|
+
"metadata": {
|
64
|
+
},
|
65
|
+
"period": {
|
66
|
+
"end": 1602871812,
|
67
|
+
"start": 1600279812
|
68
|
+
},
|
69
|
+
"plan": {
|
70
|
+
"id": "shutterbug",
|
71
|
+
"object": "plan",
|
72
|
+
"active": true,
|
73
|
+
"aggregate_usage": null,
|
74
|
+
"amount": 499,
|
75
|
+
"amount_decimal": "499",
|
76
|
+
"billing_scheme": "per_unit",
|
77
|
+
"created": 1467324765,
|
78
|
+
"currency": "usd",
|
79
|
+
"interval": "month",
|
80
|
+
"interval_count": 1,
|
81
|
+
"livemode": true,
|
82
|
+
"metadata": {
|
83
|
+
},
|
84
|
+
"nickname": null,
|
85
|
+
"product": "prod_00000000000000",
|
86
|
+
"tiers_mode": null,
|
87
|
+
"transform_usage": null,
|
88
|
+
"trial_period_days": null,
|
89
|
+
"usage_type": "licensed"
|
90
|
+
},
|
91
|
+
"price": {
|
92
|
+
"id": "shutterbug",
|
93
|
+
"object": "price",
|
94
|
+
"active": true,
|
95
|
+
"billing_scheme": "per_unit",
|
96
|
+
"created": 1467324765,
|
97
|
+
"currency": "usd",
|
98
|
+
"livemode": true,
|
99
|
+
"lookup_key": null,
|
100
|
+
"metadata": {
|
101
|
+
},
|
102
|
+
"nickname": null,
|
103
|
+
"product": "prod_00000000000000",
|
104
|
+
"recurring": {
|
105
|
+
"aggregate_usage": null,
|
106
|
+
"interval": "month",
|
107
|
+
"interval_count": 1,
|
108
|
+
"trial_period_days": null,
|
109
|
+
"usage_type": "licensed"
|
110
|
+
},
|
111
|
+
"tiers_mode": null,
|
112
|
+
"transform_quantity": null,
|
113
|
+
"type": "recurring",
|
114
|
+
"unit_amount": 499,
|
115
|
+
"unit_amount_decimal": "499"
|
116
|
+
},
|
117
|
+
"proration": false,
|
118
|
+
"quantity": 1,
|
119
|
+
"subscription": "sub_00000000000000",
|
120
|
+
"subscription_item": "si_00000000000000",
|
121
|
+
"tax_amounts": [
|
122
|
+
],
|
123
|
+
"tax_rates": [
|
124
|
+
],
|
125
|
+
"type": "subscription"
|
126
|
+
}
|
127
|
+
],
|
128
|
+
"has_more": false,
|
129
|
+
"total_count": 1,
|
130
|
+
"url": "/v1/invoices/in_00000000000000/lines"
|
131
|
+
},
|
132
|
+
"livemode": true,
|
133
|
+
"metadata": {
|
134
|
+
},
|
135
|
+
"next_payment_attempt": null,
|
136
|
+
"number": "6E05A6C5-0010",
|
137
|
+
"paid": false,
|
138
|
+
"payment_intent": "pi_00000000000000",
|
139
|
+
"period_end": 1600279812,
|
140
|
+
"period_start": 1597601412,
|
141
|
+
"post_payment_credit_notes_amount": 0,
|
142
|
+
"pre_payment_credit_notes_amount": 0,
|
143
|
+
"receipt_number": null,
|
144
|
+
"starting_balance": 0,
|
145
|
+
"statement_descriptor": null,
|
146
|
+
"status": "open",
|
147
|
+
"status_transitions": {
|
148
|
+
"finalized_at": 1600283533,
|
149
|
+
"marked_uncollectible_at": null,
|
150
|
+
"paid_at": null,
|
151
|
+
"voided_at": null
|
152
|
+
},
|
153
|
+
"subscription": "sub_00000000000000",
|
154
|
+
"subtotal": 499,
|
155
|
+
"tax": null,
|
156
|
+
"total": 499,
|
157
|
+
"total_discount_amounts": [
|
158
|
+
],
|
159
|
+
"total_tax_amounts": [
|
160
|
+
],
|
161
|
+
"transfer_data": null,
|
162
|
+
"webhooks_delivered_at": 1600279844
|
163
|
+
}
|
164
|
+
},
|
165
|
+
"livemode": true,
|
166
|
+
"pending_webhooks": 3,
|
167
|
+
"request": {
|
168
|
+
"id": null,
|
169
|
+
"idempotency_key": null
|
170
|
+
},
|
171
|
+
"type": "invoice.payment_failed"
|
172
|
+
}
|