tang 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/app/controllers/tang/admin/subscriptions_controller.rb +1 -1
  4. data/app/jobs/tang/import_customers_job.rb +7 -1
  5. data/app/models/tang/invoice.rb +2 -2
  6. data/app/models/tang/subscription.rb +3 -3
  7. data/app/services/tang/create_subscription.rb +4 -1
  8. data/app/services/tang/delete_card.rb +4 -2
  9. data/app/services/tang/fail_invoice.rb +6 -3
  10. data/app/services/tang/save_card.rb +4 -1
  11. data/app/services/tang/update_subscription.rb +1 -1
  12. data/app/views/tang/account/cards/_payment.html.erb +0 -32
  13. data/app/views/tang/admin/subscriptions/_form.html.erb +0 -5
  14. data/app/views/tang/admin/subscriptions/show.html.erb +0 -7
  15. data/lib/css/main.css +31 -0
  16. data/lib/js/index.js +3 -2
  17. data/lib/tang/version.rb +1 -1
  18. data/spec/fixtures/stripe_webhooks/invoice.created.json +1 -2
  19. data/spec/fixtures/stripe_webhooks/invoice.payment_failed.json +172 -0
  20. data/spec/models/tang/card_spec.rb +4 -1
  21. data/spec/models/tang/charge_spec.rb +47 -1
  22. data/spec/tang_app/Gemfile.lock +70 -0
  23. data/spec/tang_app/app/javascript/packs/application.js +2 -1
  24. data/spec/tang_app/app/views/layouts/application.html.erb +1 -0
  25. data/spec/tang_app/log/development.log +342 -0
  26. data/spec/tang_app/log/test.log +52349 -0
  27. data/spec/tang_app/node_modules/fsevents/build/Release/fse.node +0 -0
  28. data/spec/tang_app/package.json +3 -0
  29. data/spec/tang_app/public/packs-test/js/application-0dded7840d00b04c8937.js +653 -0
  30. data/spec/tang_app/public/packs-test/js/application-0dded7840d00b04c8937.js.map +1 -0
  31. data/spec/tang_app/public/packs-test/manifest.json +4 -4
  32. data/spec/tang_app/public/packs/js/application-080539f58098495f5fea.js +873 -0
  33. data/spec/tang_app/public/packs/js/application-080539f58098495f5fea.js.map +1 -0
  34. data/spec/tang_app/public/packs/js/application-63744ba8e1d5132a70a7.js +653 -0
  35. data/spec/tang_app/public/packs/js/application-63744ba8e1d5132a70a7.js.map +1 -0
  36. data/spec/tang_app/public/packs/js/application-6ed6c7d5740861886e33.js +908 -0
  37. data/spec/tang_app/public/packs/js/application-6ed6c7d5740861886e33.js.map +1 -0
  38. data/spec/tang_app/public/packs/js/application-95a81db325472bcd27be.js +873 -0
  39. data/spec/tang_app/public/packs/js/application-95a81db325472bcd27be.js.map +1 -0
  40. data/spec/tang_app/public/packs/js/application-a4d14e60f459eb6278f8.js +873 -0
  41. data/spec/tang_app/public/packs/js/application-a4d14e60f459eb6278f8.js.map +1 -0
  42. data/spec/tang_app/public/packs/js/application-e5d6d1269e6e876bad16.js +654 -0
  43. data/spec/tang_app/public/packs/js/application-e5d6d1269e6e876bad16.js.map +1 -0
  44. data/spec/tang_app/public/packs/manifest.json +4 -4
  45. data/spec/tang_app/tmp/cache/webpacker/last-compilation-digest-development +1 -1
  46. data/spec/tang_app/tmp/cache/webpacker/last-compilation-digest-test +1 -1
  47. metadata +35 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df85707ff7cd740755608c6f6f5a4a396fe36de36ac30561fd0ff8139eb872ee
4
- data.tar.gz: a3a632a34b2f807f290a3434853d73a9d3288ca91fd4ea4377f8ed68e238493d
3
+ metadata.gz: afcc7d64662d251041c9106406151ef1c0eb633c4f52648aad4bf065e73d5715
4
+ data.tar.gz: 70a3bb4255182c594a89773546518ae1972af6dbd9efe4a48a0e04cd0048568a
5
5
  SHA512:
6
- metadata.gz: badaae0c19b133cd7d7ec66248f16b1d84e94851f26f5e9002ceaf92b608bf42b22438442d2a60553fee2e30928e84c78859787ac93e7adfb76fa9a230a5a246
7
- data.tar.gz: 6a6e10e51fcdf7fb172b7cfdeb03b46f29726c4e0869a2dd3220bc6d3ba7874d43409e3ab80bc627cc4a3abc7e3263ceb330b198c8528c6bea8ad810377a773b
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, :tax_percent)
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
- Card.from_stripe(stripe_customer.sources.retrieve(stripe_customer.default_source), customer) if stripe_customer.default_source.present?
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
 
@@ -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
- format: { with: /\A\d+(?:\.\d{0,4})?\z/ }
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 = stripe_customer.sources.retrieve(stripe_customer.default_source)
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
- customer = Stripe::Customer.retrieve(card.customer.stripe_id)
6
- customer.sources.retrieve(card.stripe_id).delete
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
- subscription.fail! if !subscription.past_due?
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 = cu.sources.retrieve(cu.default_source)
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
 
@@ -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
+ }
@@ -1,5 +1,6 @@
1
1
  // Create a Stripe client.
2
- var stripe = Stripe('pk_test_ufmXOx2149BsFX2Hf6i8zTTL');
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
- module.exports = { registerElements }
87
+ export default registerElements
@@ -1,3 +1,3 @@
1
1
  module Tang
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -6,7 +6,7 @@
6
6
  "object": "event",
7
7
  "data": {
8
8
  "object": {
9
- "date": 1380674206,
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
+ }