nocheckout 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +160 -132
- data/README.md +68 -23
- data/app/controllers/nocheckout/stripe/checkout_sessions_controller.rb +51 -49
- data/lib/nocheckout/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1940078d7a818e06033361f4c961bb23fed76c724f7273d2c9cfc7e24cf509b8
|
4
|
+
data.tar.gz: 48a81f066625fd4d946358f5dd010e15703b59ad482e860493c48b28a56c95c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fb7484da98f62bef30539907231a8429f690419c9d0f0c7ac9cbf78ac9de62630391c82978dd6d1d0a9a89d3b7ffd326d3ff1858c6b7ea19afeda83d93504a9
|
7
|
+
data.tar.gz: 7beaf4fe8e90dda879b1107ee8173e0cd16ebf771f2fb1d53de35dcd90abf20f03333335b2443a87c2275f5f92c8704625c300ad40c19c5e651c7dbaf871ed14
|
data/Gemfile.lock
CHANGED
@@ -1,95 +1,108 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nocheckout (0.1.
|
5
|
-
rails (
|
4
|
+
nocheckout (0.1.4)
|
5
|
+
rails (>= 7.0)
|
6
6
|
stripe (>= 7.0)
|
7
7
|
zeitwerk (~> 2.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actioncable (7.
|
13
|
-
actionpack (= 7.
|
14
|
-
activesupport (= 7.
|
12
|
+
actioncable (7.2.1)
|
13
|
+
actionpack (= 7.2.1)
|
14
|
+
activesupport (= 7.2.1)
|
15
15
|
nio4r (~> 2.0)
|
16
16
|
websocket-driver (>= 0.6.1)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
activesupport (= 7.0.8)
|
40
|
-
rack (~> 2.0, >= 2.2.4)
|
17
|
+
zeitwerk (~> 2.6)
|
18
|
+
actionmailbox (7.2.1)
|
19
|
+
actionpack (= 7.2.1)
|
20
|
+
activejob (= 7.2.1)
|
21
|
+
activerecord (= 7.2.1)
|
22
|
+
activestorage (= 7.2.1)
|
23
|
+
activesupport (= 7.2.1)
|
24
|
+
mail (>= 2.8.0)
|
25
|
+
actionmailer (7.2.1)
|
26
|
+
actionpack (= 7.2.1)
|
27
|
+
actionview (= 7.2.1)
|
28
|
+
activejob (= 7.2.1)
|
29
|
+
activesupport (= 7.2.1)
|
30
|
+
mail (>= 2.8.0)
|
31
|
+
rails-dom-testing (~> 2.2)
|
32
|
+
actionpack (7.2.1)
|
33
|
+
actionview (= 7.2.1)
|
34
|
+
activesupport (= 7.2.1)
|
35
|
+
nokogiri (>= 1.8.5)
|
36
|
+
racc
|
37
|
+
rack (>= 2.2.4, < 3.2)
|
38
|
+
rack-session (>= 1.0.1)
|
41
39
|
rack-test (>= 0.6.3)
|
42
|
-
rails-dom-testing (~> 2.
|
43
|
-
rails-html-sanitizer (~> 1.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
rails-dom-testing (~> 2.2)
|
41
|
+
rails-html-sanitizer (~> 1.6)
|
42
|
+
useragent (~> 0.16)
|
43
|
+
actiontext (7.2.1)
|
44
|
+
actionpack (= 7.2.1)
|
45
|
+
activerecord (= 7.2.1)
|
46
|
+
activestorage (= 7.2.1)
|
47
|
+
activesupport (= 7.2.1)
|
49
48
|
globalid (>= 0.6.0)
|
50
49
|
nokogiri (>= 1.8.5)
|
51
|
-
actionview (7.
|
52
|
-
activesupport (= 7.
|
50
|
+
actionview (7.2.1)
|
51
|
+
activesupport (= 7.2.1)
|
53
52
|
builder (~> 3.1)
|
54
|
-
erubi (~> 1.
|
55
|
-
rails-dom-testing (~> 2.
|
56
|
-
rails-html-sanitizer (~> 1.
|
57
|
-
activejob (7.
|
58
|
-
activesupport (= 7.
|
53
|
+
erubi (~> 1.11)
|
54
|
+
rails-dom-testing (~> 2.2)
|
55
|
+
rails-html-sanitizer (~> 1.6)
|
56
|
+
activejob (7.2.1)
|
57
|
+
activesupport (= 7.2.1)
|
59
58
|
globalid (>= 0.3.6)
|
60
|
-
activemodel (7.
|
61
|
-
activesupport (= 7.
|
62
|
-
activerecord (7.
|
63
|
-
activemodel (= 7.
|
64
|
-
activesupport (= 7.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
activemodel (7.2.1)
|
60
|
+
activesupport (= 7.2.1)
|
61
|
+
activerecord (7.2.1)
|
62
|
+
activemodel (= 7.2.1)
|
63
|
+
activesupport (= 7.2.1)
|
64
|
+
timeout (>= 0.4.0)
|
65
|
+
activestorage (7.2.1)
|
66
|
+
actionpack (= 7.2.1)
|
67
|
+
activejob (= 7.2.1)
|
68
|
+
activerecord (= 7.2.1)
|
69
|
+
activesupport (= 7.2.1)
|
70
70
|
marcel (~> 1.0)
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
activesupport (7.2.1)
|
72
|
+
base64
|
73
|
+
bigdecimal
|
74
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
75
|
+
connection_pool (>= 2.2.5)
|
76
|
+
drb
|
74
77
|
i18n (>= 1.6, < 2)
|
78
|
+
logger (>= 1.4.2)
|
75
79
|
minitest (>= 5.1)
|
76
|
-
|
80
|
+
securerandom (>= 0.3)
|
81
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
77
82
|
ast (2.4.2)
|
78
|
-
base64 (0.
|
79
|
-
|
80
|
-
|
83
|
+
base64 (0.2.0)
|
84
|
+
bigdecimal (3.1.8)
|
85
|
+
builder (3.3.0)
|
86
|
+
concurrent-ruby (1.3.4)
|
87
|
+
connection_pool (2.4.1)
|
81
88
|
crass (1.0.6)
|
82
|
-
date (3.3.
|
83
|
-
diff-lcs (1.5.
|
84
|
-
|
89
|
+
date (3.3.4)
|
90
|
+
diff-lcs (1.5.1)
|
91
|
+
drb (2.2.1)
|
92
|
+
erubi (1.13.0)
|
85
93
|
globalid (1.2.1)
|
86
94
|
activesupport (>= 6.1)
|
87
|
-
i18n (1.14.
|
95
|
+
i18n (1.14.6)
|
88
96
|
concurrent-ruby (~> 1.0)
|
89
|
-
|
97
|
+
io-console (0.7.2)
|
98
|
+
irb (1.14.1)
|
99
|
+
rdoc (>= 4.0.0)
|
100
|
+
reline (>= 0.4.2)
|
101
|
+
json (2.7.2)
|
90
102
|
language_server-protocol (3.17.0.3)
|
91
103
|
lint_roller (1.1.0)
|
92
|
-
|
104
|
+
logger (1.6.1)
|
105
|
+
loofah (2.22.0)
|
93
106
|
crass (~> 1.0.2)
|
94
107
|
nokogiri (>= 1.12.0)
|
95
108
|
mail (2.8.1)
|
@@ -97,46 +110,52 @@ GEM
|
|
97
110
|
net-imap
|
98
111
|
net-pop
|
99
112
|
net-smtp
|
100
|
-
marcel (1.0.
|
101
|
-
method_source (1.0.0)
|
113
|
+
marcel (1.0.4)
|
102
114
|
mini_mime (1.1.5)
|
103
|
-
minitest (5.
|
104
|
-
net-imap (0.
|
115
|
+
minitest (5.25.1)
|
116
|
+
net-imap (0.4.16)
|
105
117
|
date
|
106
118
|
net-protocol
|
107
119
|
net-pop (0.1.2)
|
108
120
|
net-protocol
|
109
|
-
net-protocol (0.2.
|
121
|
+
net-protocol (0.2.2)
|
110
122
|
timeout
|
111
|
-
net-smtp (0.
|
123
|
+
net-smtp (0.5.0)
|
112
124
|
net-protocol
|
113
|
-
nio4r (2.
|
114
|
-
nokogiri (1.
|
125
|
+
nio4r (2.7.3)
|
126
|
+
nokogiri (1.16.7-arm64-darwin)
|
115
127
|
racc (~> 1.4)
|
116
|
-
nokogiri (1.
|
128
|
+
nokogiri (1.16.7-x86_64-linux)
|
117
129
|
racc (~> 1.4)
|
118
|
-
parallel (1.
|
119
|
-
parser (3.
|
130
|
+
parallel (1.26.3)
|
131
|
+
parser (3.3.5.0)
|
120
132
|
ast (~> 2.4.1)
|
121
133
|
racc
|
122
|
-
|
123
|
-
|
134
|
+
psych (5.1.2)
|
135
|
+
stringio
|
136
|
+
racc (1.8.1)
|
137
|
+
rack (3.1.7)
|
138
|
+
rack-session (2.0.0)
|
139
|
+
rack (>= 3.0.0)
|
124
140
|
rack-test (2.1.0)
|
125
141
|
rack (>= 1.3)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
142
|
+
rackup (2.1.0)
|
143
|
+
rack (>= 3)
|
144
|
+
webrick (~> 1.8)
|
145
|
+
rails (7.2.1)
|
146
|
+
actioncable (= 7.2.1)
|
147
|
+
actionmailbox (= 7.2.1)
|
148
|
+
actionmailer (= 7.2.1)
|
149
|
+
actionpack (= 7.2.1)
|
150
|
+
actiontext (= 7.2.1)
|
151
|
+
actionview (= 7.2.1)
|
152
|
+
activejob (= 7.2.1)
|
153
|
+
activemodel (= 7.2.1)
|
154
|
+
activerecord (= 7.2.1)
|
155
|
+
activestorage (= 7.2.1)
|
156
|
+
activesupport (= 7.2.1)
|
138
157
|
bundler (>= 1.15.0)
|
139
|
-
railties (= 7.
|
158
|
+
railties (= 7.2.1)
|
140
159
|
rails-dom-testing (2.2.0)
|
141
160
|
activesupport (>= 5.0.0)
|
142
161
|
minitest
|
@@ -144,73 +163,82 @@ GEM
|
|
144
163
|
rails-html-sanitizer (1.6.0)
|
145
164
|
loofah (~> 2.21)
|
146
165
|
nokogiri (~> 1.14)
|
147
|
-
railties (7.
|
148
|
-
actionpack (= 7.
|
149
|
-
activesupport (= 7.
|
150
|
-
|
166
|
+
railties (7.2.1)
|
167
|
+
actionpack (= 7.2.1)
|
168
|
+
activesupport (= 7.2.1)
|
169
|
+
irb (~> 1.13)
|
170
|
+
rackup (>= 1.0.0)
|
151
171
|
rake (>= 12.2)
|
152
|
-
thor (~> 1.0)
|
153
|
-
zeitwerk (~> 2.
|
172
|
+
thor (~> 1.0, >= 1.2.2)
|
173
|
+
zeitwerk (~> 2.6)
|
154
174
|
rainbow (3.1.1)
|
155
|
-
rake (13.
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
rspec
|
163
|
-
rspec-
|
164
|
-
|
175
|
+
rake (13.2.1)
|
176
|
+
rdoc (6.7.0)
|
177
|
+
psych (>= 4.0.0)
|
178
|
+
regexp_parser (2.9.2)
|
179
|
+
reline (0.5.10)
|
180
|
+
io-console (~> 0.5)
|
181
|
+
rexml (3.3.8)
|
182
|
+
rspec (3.13.0)
|
183
|
+
rspec-core (~> 3.13.0)
|
184
|
+
rspec-expectations (~> 3.13.0)
|
185
|
+
rspec-mocks (~> 3.13.0)
|
186
|
+
rspec-core (3.13.1)
|
187
|
+
rspec-support (~> 3.13.0)
|
188
|
+
rspec-expectations (3.13.3)
|
165
189
|
diff-lcs (>= 1.2.0, < 2.0)
|
166
|
-
rspec-support (~> 3.
|
167
|
-
rspec-mocks (3.
|
190
|
+
rspec-support (~> 3.13.0)
|
191
|
+
rspec-mocks (3.13.2)
|
168
192
|
diff-lcs (>= 1.2.0, < 2.0)
|
169
|
-
rspec-support (~> 3.
|
170
|
-
rspec-support (3.
|
171
|
-
rubocop (1.
|
172
|
-
base64 (~> 0.1.1)
|
193
|
+
rspec-support (~> 3.13.0)
|
194
|
+
rspec-support (3.13.1)
|
195
|
+
rubocop (1.65.1)
|
173
196
|
json (~> 2.3)
|
174
197
|
language_server-protocol (>= 3.17.0)
|
175
198
|
parallel (~> 1.10)
|
176
|
-
parser (>= 3.
|
199
|
+
parser (>= 3.3.0.2)
|
177
200
|
rainbow (>= 2.2.2, < 4.0)
|
178
|
-
regexp_parser (>=
|
201
|
+
regexp_parser (>= 2.4, < 3.0)
|
179
202
|
rexml (>= 3.2.5, < 4.0)
|
180
|
-
rubocop-ast (>= 1.
|
203
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
181
204
|
ruby-progressbar (~> 1.7)
|
182
205
|
unicode-display_width (>= 2.4.0, < 3.0)
|
183
|
-
rubocop-ast (1.
|
184
|
-
parser (>= 3.
|
185
|
-
rubocop-performance (1.
|
186
|
-
rubocop (>= 1.
|
187
|
-
rubocop-ast (>=
|
206
|
+
rubocop-ast (1.32.3)
|
207
|
+
parser (>= 3.3.1.0)
|
208
|
+
rubocop-performance (1.21.1)
|
209
|
+
rubocop (>= 1.48.1, < 2.0)
|
210
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
188
211
|
ruby-progressbar (1.13.0)
|
189
|
-
|
212
|
+
securerandom (0.3.1)
|
213
|
+
standard (1.40.1)
|
190
214
|
language_server-protocol (~> 3.17.0.2)
|
191
215
|
lint_roller (~> 1.0)
|
192
|
-
rubocop (~> 1.
|
216
|
+
rubocop (~> 1.65.0)
|
193
217
|
standard-custom (~> 1.0.0)
|
194
|
-
standard-performance (~> 1.
|
218
|
+
standard-performance (~> 1.4)
|
195
219
|
standard-custom (1.0.2)
|
196
220
|
lint_roller (~> 1.0)
|
197
221
|
rubocop (~> 1.50)
|
198
|
-
standard-performance (1.
|
222
|
+
standard-performance (1.4.0)
|
199
223
|
lint_roller (~> 1.1)
|
200
|
-
rubocop-performance (~> 1.
|
201
|
-
|
202
|
-
|
203
|
-
|
224
|
+
rubocop-performance (~> 1.21.0)
|
225
|
+
stringio (3.1.1)
|
226
|
+
stripe (13.0.0)
|
227
|
+
thor (1.3.2)
|
228
|
+
timeout (0.4.1)
|
204
229
|
tzinfo (2.0.6)
|
205
230
|
concurrent-ruby (~> 1.0)
|
206
|
-
unicode-display_width (2.
|
231
|
+
unicode-display_width (2.6.0)
|
232
|
+
useragent (0.16.10)
|
233
|
+
webrick (1.8.2)
|
207
234
|
websocket-driver (0.7.6)
|
208
235
|
websocket-extensions (>= 0.1.0)
|
209
236
|
websocket-extensions (0.1.5)
|
210
|
-
zeitwerk (2.6.
|
237
|
+
zeitwerk (2.6.18)
|
211
238
|
|
212
239
|
PLATFORMS
|
213
240
|
arm64-darwin-22
|
241
|
+
arm64-darwin-23
|
214
242
|
x86_64-linux
|
215
243
|
|
216
244
|
DEPENDENCIES
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# NoCheckout
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/nocheckout.svg)](https://badge.fury.io/rb/nocheckout) [![Tests](https://github.com/rubymonolith/nocheckout/actions/workflows/main.yml/badge.svg)](https://github.com/rubymonolith/nocheckout/actions/workflows/main.yml)
|
4
|
+
|
3
5
|
> [!IMPORTANT]
|
4
6
|
> This project is a work in progress. This README was written to better understand the implementation for developers. **Some of the APIs may not have yet been implemented, renamed, or removed**. When the API settles down and is running in production for a while, a 1.0 release will be cut and this notice removed.
|
5
7
|
|
@@ -28,11 +30,7 @@ Before you do anything you'll need to go to https://dashboard.stripe.com/test/ap
|
|
28
30
|
Stripe.api_key = Rails.configuration.stripe[:secret_key]
|
29
31
|
```
|
30
32
|
|
31
|
-
##
|
32
|
-
|
33
|
-
This library comes with two controllers, both map closely to their respective Stripe docs.
|
34
|
-
|
35
|
-
### Checkout Sessions Controller
|
33
|
+
## Checkout Sessions Controller
|
36
34
|
|
37
35
|
[Stripe Checkout Sessions](https://stripe.com/docs/api/checkout/sessions) send users from your website to a branded stripe.com page where they can enter their credit card details and complete the purchase. Once the purchase is complete, the user is redirected back to your website.
|
38
36
|
|
@@ -40,19 +38,40 @@ The NoCheckout::CheckoutSessionsController handles the interface between Stripe
|
|
40
38
|
|
41
39
|
To get started, create a base CheckoutSessionsController that maps the Users from your application with [Stripe Customers](https://stripe.com/docs/api/customers).
|
42
40
|
|
41
|
+
### Create user record after checkout is complete
|
42
|
+
|
43
|
+
This approach creates a new user record after the checkout is complete with the name and email they give during the Stripe checkout process.
|
44
|
+
|
43
45
|
```ruby
|
44
|
-
class
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
class PaymentsController < NoCheckout::Stripe::CheckoutSessionsController
|
47
|
+
STRIPE_PRICE = "test_price_..."
|
48
|
+
|
49
|
+
def show
|
50
|
+
# Retrieve info from Stripe
|
51
|
+
customer = Stripe::Customer.retrieve checkout_session.customer
|
52
|
+
subscription = Stripe::Subscription.retrieve checkout_session.subscription
|
53
|
+
|
54
|
+
# Do stuff with Stripe info
|
55
|
+
user = User.find_or_create_by email: customer.email
|
56
|
+
customer.metadata.user_id = user.id
|
57
|
+
customer.save
|
58
|
+
user.name = customer.name
|
59
|
+
user.save!
|
60
|
+
|
61
|
+
# In this example we set the current user to stripe info. This likely
|
62
|
+
# doesn't make sense for your security context, so be careful...
|
63
|
+
self.current_user = user
|
64
|
+
redirect_to root_url
|
65
|
+
end
|
49
66
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
67
|
+
protected
|
68
|
+
def create_checkout_session
|
69
|
+
super \
|
70
|
+
mode: "subscription",
|
71
|
+
line_items: [{
|
72
|
+
price: self.class::STRIPE_PRICE,
|
73
|
+
quantity: 1
|
74
|
+
}]
|
56
75
|
end
|
57
76
|
end
|
58
77
|
```
|
@@ -62,20 +81,46 @@ Then, for each product you want to offer, create a controller and inherit the `C
|
|
62
81
|
```ruby
|
63
82
|
class PlusCheckoutSessionsController < PaymentsController
|
64
83
|
STRIPE_PRICE = "price_..."
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
There's a lot of different ways you can wire up the controllers depending on how many Stripe prices are in your application. This README assumes you're selling just a few products, so the prices are hard coded as constants in the controller. This could easily be populated from a database.
|
88
|
+
|
89
|
+
### Create a user record before checkout is complete
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
class PaymentsController < NoCheckout::Stripe::CheckoutSessionsController
|
93
|
+
before_action :authorize_user # Loads a current_user
|
94
|
+
|
95
|
+
STRIPE_PRICE = "test_price_..."
|
96
|
+
|
97
|
+
def show
|
98
|
+
customer = Stripe::Customer.retrieve checkout_session.customer
|
99
|
+
subscription = Stripe::Subscription.retrieve checkout_session.subscription
|
100
|
+
|
101
|
+
# Do stuff with Stripe info
|
102
|
+
|
103
|
+
redirect_to root_url
|
104
|
+
end
|
65
105
|
|
66
106
|
protected
|
67
107
|
def create_checkout_session
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
108
|
+
super \
|
109
|
+
mode: "subscription",
|
110
|
+
customer: retrieve_or_create_customer(
|
111
|
+
id: current_user.id,
|
112
|
+
email: current_user.email,
|
113
|
+
name: current_user.name
|
114
|
+
),
|
115
|
+
line_items: [{
|
116
|
+
price: self.class::STRIPE_PRICE,
|
117
|
+
quantity: 1
|
118
|
+
}]
|
72
119
|
end
|
73
120
|
end
|
74
121
|
```
|
75
122
|
|
76
|
-
|
77
|
-
|
78
|
-
### Webhooks Controller
|
123
|
+
## Webhooks Controller
|
79
124
|
|
80
125
|
[Stripe Webhooks](https://stripe.com/docs/webhooks) are extensive and keep your application up-to-date with what Stripe. In this example, we'll look at how to handle a subscription that's expiring and update a User record in our database.
|
81
126
|
|
@@ -1,42 +1,51 @@
|
|
1
1
|
module NoCheckout::Stripe
|
2
2
|
class CheckoutSessionsController < ApplicationController
|
3
|
+
# Name of the URL parameter stripe uses for the Checkout Session ID.
|
4
|
+
CHECKOUT_SESSION_ID_KEY = :checkout_session_id
|
5
|
+
|
3
6
|
def new
|
4
7
|
redirect_to checkout_session.url, allow_other_host: true
|
5
8
|
end
|
6
9
|
|
7
10
|
protected
|
8
11
|
def checkout_session
|
9
|
-
@checkout_session ||=
|
12
|
+
@checkout_session ||= retrieve_or_create_checkout_session
|
10
13
|
end
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
# Actually creates a Stripe checkout session. The reason I had to create
|
16
|
+
# this method is so I could "curry" the values within so the `create_checkout_session`
|
17
|
+
# could be a bit more readable and work better with inheritance.
|
18
|
+
def create_checkout_session(**attributes)
|
19
|
+
Stripe::Checkout::Session.create(**append_callback_urls(**attributes))
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
17
|
-
|
22
|
+
def append_callback_urls(success_url:, cancel_url:, **attributes)
|
23
|
+
attributes.merge \
|
24
|
+
success_url: concat_unescaped_stripe_checkout_session_id(success_url),
|
25
|
+
cancel_url: concat_unescaped_stripe_checkout_session_id(cancel_url)
|
18
26
|
end
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def retrieve_checkout_session(id: checkout_session_id)
|
29
|
+
Stripe::Checkout::Session.retrieve id
|
30
|
+
end
|
31
|
+
|
32
|
+
def checkout_session_id
|
33
|
+
params.fetch CHECKOUT_SESSION_ID_KEY, nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def retrieve_or_create_checkout_session
|
37
|
+
if checkout_session_id.present?
|
38
|
+
retrieve_checkout_session
|
39
|
+
else
|
40
|
+
create_checkout_session
|
41
|
+
end
|
30
42
|
end
|
31
43
|
|
32
|
-
def
|
33
|
-
|
34
|
-
# to `session_id=%7BCHECKOUT_SESSION_ID%7D`. This will work though, but its def not pretty and feels a tad
|
35
|
-
# dangerous.
|
36
|
-
concat_unescaped_stripe_checkout_session_id url_for(action: :show, only_path: false, **kwargs)
|
44
|
+
def callback_url_for(*args, only_path: false, **kwargs)
|
45
|
+
url_for(*args, only_path: only_path, **kwargs)
|
37
46
|
end
|
38
47
|
|
39
|
-
STRIPE_CALLBACK_PARAMETER = "
|
48
|
+
STRIPE_CALLBACK_PARAMETER = "#{CHECKOUT_SESSION_ID_KEY}={CHECKOUT_SESSION_ID}"
|
40
49
|
|
41
50
|
# For some reason Stripe decided to not escape the `{CHECKOUT_SESSION_ID}`, if we try to
|
42
51
|
# pass it through Rails URL builders or the URI object, it will URL encode the value and
|
@@ -51,35 +60,17 @@ module NoCheckout::Stripe
|
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
54
|
-
def success_url
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
def cancel_url
|
59
|
-
callback_url(state: :cancel)
|
60
|
-
end
|
61
|
-
|
62
|
-
def stripe_customer
|
63
|
-
@stripe_customer ||= find_or_create_customer
|
64
|
-
end
|
65
|
-
|
66
|
-
def create_customer
|
67
|
-
Stripe::Customer.create(
|
68
|
-
id: String(customer_id),
|
69
|
-
name: current_user.name,
|
70
|
-
email: current_user.email
|
71
|
-
)
|
72
|
-
end
|
63
|
+
# def success_url
|
64
|
+
# callback_url(state: :success)
|
65
|
+
# end
|
73
66
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
else
|
78
|
-
create_checkout_session
|
79
|
-
end
|
80
|
-
end
|
67
|
+
# def cancel_url
|
68
|
+
# callback_url(state: :cancel)
|
69
|
+
# end
|
81
70
|
|
82
|
-
|
71
|
+
# Retrives a customer from Stripe and returns a nil if the customer does not exist (instead)
|
72
|
+
# of raising an exception, because this is not exceptional).
|
73
|
+
def retrieve_customer(id:)
|
83
74
|
return nil if customer_id.blank?
|
84
75
|
|
85
76
|
begin
|
@@ -88,12 +79,23 @@ module NoCheckout::Stripe
|
|
88
79
|
rescue Stripe::InvalidRequestError => e
|
89
80
|
case e.response.data
|
90
81
|
in error: { code: "resource_missing" }
|
91
|
-
|
82
|
+
nil
|
92
83
|
else
|
93
84
|
raise
|
94
85
|
end
|
95
86
|
end
|
96
87
|
end
|
97
88
|
|
89
|
+
# Creates a customer and automatically converts the ID to a string so this
|
90
|
+
# thing doesn't explode into oblivion.
|
91
|
+
def create_customer(id: nil, **attributes)
|
92
|
+
# If an ID is given, stripe insists that its a string.
|
93
|
+
id = String(id) unless id.nil?
|
94
|
+
Stripe::Customer.create(id: id, **attributes)
|
95
|
+
end
|
96
|
+
|
97
|
+
def retrieve_or_create_customer(id:, **attributes)
|
98
|
+
retrieve_customer(id: id) || create_customer(id: id, **attributes)
|
99
|
+
end
|
98
100
|
end
|
99
101
|
end
|
data/lib/nocheckout/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nocheckout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brad Gessler
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -42,14 +42,14 @@ dependencies:
|
|
42
42
|
name: rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '7.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '7.0'
|
55
55
|
description: Rails controllers for Stripe Checkout Sessions and Webhooks
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
105
|
+
rubygems_version: 3.5.9
|
106
106
|
signing_key:
|
107
107
|
specification_version: 4
|
108
108
|
summary: Rails controllers for Stripe Checkout Sessions and Webhooks
|