nocheckout 0.1.4 → 0.2.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/CHANGELOG.md +13 -0
- data/Gemfile.lock +6 -1
- data/README.md +145 -22
- data/app/controllers/nocheckout/stripe/checkout_session.rb +57 -0
- data/app/controllers/nocheckout/stripe/checkout_sessions_controller.rb +1 -97
- data/lib/nocheckout/version.rb +1 -1
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36cc99edab4e1790d54150c8528af4a8909e9894c08716ee9d6893a4966772da
|
|
4
|
+
data.tar.gz: e909fba5b3d5dff31373ef0f268fabf3fa53297ea77d1fd09f7f13ad5147e541
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b03567f074c779298ed5d3ae1b2e3bf81146b169f7002ce81ab6b8a75e399dd26c8b54833cdc3469cbe636c368365d5225c30d191341a317b22beee1f411018a
|
|
7
|
+
data.tar.gz: 05e63b688befdcf2f12274e7b5daac3d9ff07cf8f90749d86e08cc952947d98773d5bc9e3019f3d44d902bcbe9eb0be441430952a8101dd0cbc6ac93a394b67c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
### Changed
|
|
4
|
+
- **BREAKING**: Refactored `CheckoutSessionsController` from a base class to a composable module
|
|
5
|
+
- `NoCheckout::Stripe::CheckoutSession` is now a concern/module that you include in your controllers
|
|
6
|
+
- Controllers no longer need to inherit from `NoCheckout::Stripe::CheckoutSessionsController`
|
|
7
|
+
- Provides more flexibility - controllers can inherit from any base class in your app
|
|
8
|
+
- All protected methods (`create_checkout_session`, `retrieve_checkout_session`, `callback_url`, etc.) remain the same
|
|
9
|
+
- `@checkout_session` is still automatically assigned via before_action callbacks
|
|
10
|
+
- See README for migration examples
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Comprehensive test suite for `CheckoutSession` module and `CheckoutSessionsController`
|
|
14
|
+
- Architecture documentation in README explaining the module-based design pattern
|
|
15
|
+
|
|
3
16
|
## [0.1.0] - 2023-09-08
|
|
4
17
|
|
|
5
18
|
- Initial release
|
data/Gemfile.lock
CHANGED
|
@@ -112,6 +112,7 @@ GEM
|
|
|
112
112
|
net-smtp
|
|
113
113
|
marcel (1.0.4)
|
|
114
114
|
mini_mime (1.1.5)
|
|
115
|
+
mini_portile2 (2.8.9)
|
|
115
116
|
minitest (5.25.1)
|
|
116
117
|
net-imap (0.4.16)
|
|
117
118
|
date
|
|
@@ -123,6 +124,9 @@ GEM
|
|
|
123
124
|
net-smtp (0.5.0)
|
|
124
125
|
net-protocol
|
|
125
126
|
nio4r (2.7.3)
|
|
127
|
+
nokogiri (1.16.7)
|
|
128
|
+
mini_portile2 (~> 2.8.2)
|
|
129
|
+
racc (~> 1.4)
|
|
126
130
|
nokogiri (1.16.7-arm64-darwin)
|
|
127
131
|
racc (~> 1.4)
|
|
128
132
|
nokogiri (1.16.7-x86_64-linux)
|
|
@@ -239,6 +243,7 @@ GEM
|
|
|
239
243
|
PLATFORMS
|
|
240
244
|
arm64-darwin-22
|
|
241
245
|
arm64-darwin-23
|
|
246
|
+
arm64-darwin-24
|
|
242
247
|
x86_64-linux
|
|
243
248
|
|
|
244
249
|
DEPENDENCIES
|
|
@@ -248,4 +253,4 @@ DEPENDENCIES
|
|
|
248
253
|
standard (~> 1.3)
|
|
249
254
|
|
|
250
255
|
BUNDLED WITH
|
|
251
|
-
2.
|
|
256
|
+
2.6.5
|
data/README.md
CHANGED
|
@@ -34,22 +34,32 @@ Stripe.api_key = Rails.configuration.stripe[:secret_key]
|
|
|
34
34
|
|
|
35
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.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
NoCheckout provides a `CheckoutSession` module that you can include in your controllers to handle the interface between Stripe and your Rails application. The module is designed to be minimal and flexible.
|
|
38
38
|
|
|
39
|
-
To get started, create a
|
|
39
|
+
To get started, create a controller and include the `NoCheckout::Stripe::CheckoutSession` module. The module provides:
|
|
40
|
+
|
|
41
|
+
- **`#new` action**: Creates a Checkout Session and redirects users to Stripe
|
|
42
|
+
- **`#show` action**: Handles the callback when users return from Stripe
|
|
43
|
+
- **Protected methods**: `create_checkout_session`, `retrieve_checkout_session`, `callback_url`, `success_url`, `cancel_url`
|
|
44
|
+
|
|
45
|
+
The module automatically sets up `before_action` callbacks that:
|
|
46
|
+
- Call `create_checkout_session` and assign it to `@checkout_session` before the `new` action
|
|
47
|
+
- Call `retrieve_checkout_session` and assign it to `@checkout_session` before the `show` action
|
|
40
48
|
|
|
41
49
|
### Create user record after checkout is complete
|
|
42
50
|
|
|
43
51
|
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
52
|
|
|
45
53
|
```ruby
|
|
46
|
-
class PaymentsController <
|
|
47
|
-
|
|
54
|
+
class PaymentsController < ApplicationController
|
|
55
|
+
include NoCheckout::Stripe::CheckoutSession
|
|
56
|
+
|
|
57
|
+
STRIPE_PRICE = "price_..."
|
|
48
58
|
|
|
49
59
|
def show
|
|
50
|
-
#
|
|
51
|
-
customer = Stripe::Customer.retrieve checkout_session.customer
|
|
52
|
-
subscription = Stripe::Subscription.retrieve checkout_session.subscription
|
|
60
|
+
# @checkout_session is automatically assigned by the module
|
|
61
|
+
customer = Stripe::Customer.retrieve @checkout_session.customer
|
|
62
|
+
subscription = Stripe::Subscription.retrieve @checkout_session.subscription
|
|
53
63
|
|
|
54
64
|
# Do stuff with Stripe info
|
|
55
65
|
user = User.find_or_create_by email: customer.email
|
|
@@ -76,7 +86,7 @@ class PaymentsController < NoCheckout::Stripe::CheckoutSessionsController
|
|
|
76
86
|
end
|
|
77
87
|
```
|
|
78
88
|
|
|
79
|
-
Then, for each product you want to offer, create a controller and
|
|
89
|
+
Then, for each product you want to offer, create a controller and include the `CheckoutSession` module. You can also inherit from a base controller:
|
|
80
90
|
|
|
81
91
|
```ruby
|
|
82
92
|
class PlusCheckoutSessionsController < PaymentsController
|
|
@@ -84,34 +94,70 @@ class PlusCheckoutSessionsController < PaymentsController
|
|
|
84
94
|
end
|
|
85
95
|
```
|
|
86
96
|
|
|
97
|
+
Or include the module directly:
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
class ProCheckoutSessionsController < ApplicationController
|
|
101
|
+
include NoCheckout::Stripe::CheckoutSession
|
|
102
|
+
|
|
103
|
+
STRIPE_PRICE = "price_..."
|
|
104
|
+
|
|
105
|
+
def show
|
|
106
|
+
# Handle callback after successful checkout
|
|
107
|
+
redirect_to dashboard_url, notice: "Welcome to Pro!"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
protected
|
|
111
|
+
def create_checkout_session
|
|
112
|
+
super \
|
|
113
|
+
mode: "subscription",
|
|
114
|
+
line_items: [{price: self.class::STRIPE_PRICE, quantity: 1}]
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
```
|
|
118
|
+
|
|
87
119
|
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
120
|
|
|
89
121
|
### Create a user record before checkout is complete
|
|
90
122
|
|
|
91
123
|
```ruby
|
|
92
|
-
class PaymentsController <
|
|
93
|
-
|
|
124
|
+
class PaymentsController < ApplicationController
|
|
125
|
+
include NoCheckout::Stripe::CheckoutSession
|
|
126
|
+
|
|
127
|
+
before_action :authenticate_user! # Loads a current_user
|
|
94
128
|
|
|
95
|
-
STRIPE_PRICE = "
|
|
129
|
+
STRIPE_PRICE = "price_..."
|
|
96
130
|
|
|
97
131
|
def show
|
|
98
|
-
|
|
99
|
-
|
|
132
|
+
# @checkout_session is automatically assigned by the module
|
|
133
|
+
customer = Stripe::Customer.retrieve @checkout_session.customer
|
|
134
|
+
subscription = Stripe::Subscription.retrieve @checkout_session.subscription
|
|
100
135
|
|
|
101
|
-
#
|
|
136
|
+
# Update user with subscription info
|
|
137
|
+
current_user.update!(
|
|
138
|
+
stripe_customer_id: customer.id,
|
|
139
|
+
stripe_subscription_id: subscription.id
|
|
140
|
+
)
|
|
102
141
|
|
|
103
|
-
redirect_to root_url
|
|
142
|
+
redirect_to root_url, notice: "Subscription activated!"
|
|
104
143
|
end
|
|
105
144
|
|
|
106
145
|
protected
|
|
107
146
|
def create_checkout_session
|
|
147
|
+
# Find or create a Stripe customer for the current user
|
|
148
|
+
customer = if current_user.stripe_customer_id.present?
|
|
149
|
+
Stripe::Customer.retrieve(current_user.stripe_customer_id)
|
|
150
|
+
else
|
|
151
|
+
Stripe::Customer.create(
|
|
152
|
+
email: current_user.email,
|
|
153
|
+
name: current_user.name,
|
|
154
|
+
metadata: {user_id: current_user.id}
|
|
155
|
+
)
|
|
156
|
+
end
|
|
157
|
+
|
|
108
158
|
super \
|
|
109
159
|
mode: "subscription",
|
|
110
|
-
customer:
|
|
111
|
-
id: current_user.id,
|
|
112
|
-
email: current_user.email,
|
|
113
|
-
name: current_user.name
|
|
114
|
-
),
|
|
160
|
+
customer: customer.id,
|
|
115
161
|
line_items: [{
|
|
116
162
|
price: self.class::STRIPE_PRICE,
|
|
117
163
|
quantity: 1
|
|
@@ -120,6 +166,85 @@ class PaymentsController < NoCheckout::Stripe::CheckoutSessionsController
|
|
|
120
166
|
end
|
|
121
167
|
```
|
|
122
168
|
|
|
169
|
+
### Customizing callback URLs
|
|
170
|
+
|
|
171
|
+
By default, the module uses the same URL for both `success_url` and `cancel_url`, pointing to the `show` action with the Checkout Session ID. You can override these methods to customize the behavior:
|
|
172
|
+
|
|
173
|
+
```ruby
|
|
174
|
+
class PaymentsController < ApplicationController
|
|
175
|
+
include NoCheckout::Stripe::CheckoutSession
|
|
176
|
+
|
|
177
|
+
protected
|
|
178
|
+
def success_url
|
|
179
|
+
# Custom success URL
|
|
180
|
+
callback_url(status: "success")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def cancel_url
|
|
184
|
+
# Custom cancel URL - could point to a different action or controller
|
|
185
|
+
pricing_url
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Routes
|
|
191
|
+
|
|
192
|
+
Don't forget to add routes for your checkout controllers:
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
# config/routes.rb
|
|
196
|
+
Rails.application.routes.draw do
|
|
197
|
+
resources :payments, controller: "payments", only: [:new, :show]
|
|
198
|
+
|
|
199
|
+
# Or for multiple products:
|
|
200
|
+
resource :plus_checkout, controller: "plus_checkout_sessions", only: [:new, :show]
|
|
201
|
+
resource :pro_checkout, controller: "pro_checkout_sessions", only: [:new, :show]
|
|
202
|
+
end
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Architecture
|
|
206
|
+
|
|
207
|
+
The `CheckoutSession` module is designed as a Rails concern that provides a minimal, composable interface for Stripe Checkout Sessions. Here's how it works:
|
|
208
|
+
|
|
209
|
+
### Module-Based Design
|
|
210
|
+
|
|
211
|
+
Instead of inheriting from a base controller class, you **include** the `CheckoutSession` module into your own controllers. This gives you maximum flexibility:
|
|
212
|
+
|
|
213
|
+
- **No forced inheritance**: Your controllers can inherit from any base controller in your app
|
|
214
|
+
- **Composable**: Mix and match with other concerns and modules
|
|
215
|
+
- **Customizable**: Override any method to change behavior
|
|
216
|
+
- **Testable**: Each piece can be tested independently
|
|
217
|
+
|
|
218
|
+
### What the Module Provides
|
|
219
|
+
|
|
220
|
+
1. **Before Actions**: Automatically sets up `@checkout_session` for `new` and `show` actions
|
|
221
|
+
2. **Action Methods**: Provides `#new` action that redirects to Stripe
|
|
222
|
+
3. **Protected Methods**: Gives you `create_checkout_session`, `retrieve_checkout_session`, `callback_url`, `success_url`, and `cancel_url` to override as needed
|
|
223
|
+
4. **Constants**: Includes helper constants for handling Stripe's callback parameter
|
|
224
|
+
|
|
225
|
+
### Customization Pattern
|
|
226
|
+
|
|
227
|
+
The module follows a simple pattern:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
class YourController < ApplicationController
|
|
231
|
+
include NoCheckout::Stripe::CheckoutSession
|
|
232
|
+
|
|
233
|
+
# 1. Override protected methods to customize Stripe session creation
|
|
234
|
+
protected
|
|
235
|
+
def create_checkout_session
|
|
236
|
+
super(mode: "payment", line_items: [...])
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# 2. Implement show action to handle the callback
|
|
240
|
+
def show
|
|
241
|
+
# Access @checkout_session that was automatically retrieved
|
|
242
|
+
# Do your business logic
|
|
243
|
+
# Redirect user
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
```
|
|
247
|
+
|
|
123
248
|
## Webhooks Controller
|
|
124
249
|
|
|
125
250
|
[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.
|
|
@@ -128,8 +253,6 @@ end
|
|
|
128
253
|
class StripesController < NoCheckout::Stripe::WebhooksController
|
|
129
254
|
STRIPE_SIGNING_SECRET = ENV["STRIPE_SIGNING_SECRET"]
|
|
130
255
|
|
|
131
|
-
protected
|
|
132
|
-
|
|
133
256
|
def customer_subscription_created
|
|
134
257
|
user.subscription_expires_at data.current_period_end
|
|
135
258
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module NoCheckout::Stripe
|
|
2
|
+
module CheckoutSession
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
# Unescaped placeholder for Stripe to insert the Checkout Session ID.
|
|
6
|
+
STRIPE_CALLBACK_PARAMETER = "{CHECKOUT_SESSION_ID}".freeze
|
|
7
|
+
|
|
8
|
+
# Escaped version that Rails will emit.
|
|
9
|
+
ESCAPED_STRIPE_CALLBACK_PARAMETER = CGI.escape(STRIPE_CALLBACK_PARAMETER).freeze
|
|
10
|
+
|
|
11
|
+
# Hoist the Stripe constant for easier access.
|
|
12
|
+
Stripe = ::Stripe
|
|
13
|
+
|
|
14
|
+
included do
|
|
15
|
+
before_action def assign_created_checkout_session
|
|
16
|
+
@checkout_session = create_checkout_session
|
|
17
|
+
end, only: :new
|
|
18
|
+
|
|
19
|
+
before_action def assign_retrieved_checkout_session
|
|
20
|
+
@checkout_session = retrieve_checkout_session
|
|
21
|
+
end, only: :show
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Creates a new Checkout Session and redirects to it.
|
|
25
|
+
def new
|
|
26
|
+
redirect_to @checkout_session.url, allow_other_host: true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
# Creates a Stripe Checkout Session with callback URLs appended.
|
|
32
|
+
def create_checkout_session(**)
|
|
33
|
+
Stripe::Checkout::Session.create(success_url:, cancel_url:, **)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Retrieves an existing Stripe Checkout Session by ID.
|
|
37
|
+
def retrieve_checkout_session(*, **)
|
|
38
|
+
Stripe::Checkout::Session.retrieve params.fetch(:id), *, **
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def unescape_stripe_callback_parameter(url)
|
|
42
|
+
url.gsub(ESCAPED_STRIPE_CALLBACK_PARAMETER, STRIPE_CALLBACK_PARAMETER)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Default success URL. Override for custom behavior.
|
|
46
|
+
def callback_url(**)
|
|
47
|
+
unescape_stripe_callback_parameter url_for(
|
|
48
|
+
action: :show,
|
|
49
|
+
id: STRIPE_CALLBACK_PARAMETER,
|
|
50
|
+
only_path: false,
|
|
51
|
+
**
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
alias :success_url :callback_url
|
|
55
|
+
alias :cancel_url :callback_url
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,101 +1,5 @@
|
|
|
1
1
|
module NoCheckout::Stripe
|
|
2
2
|
class CheckoutSessionsController < ApplicationController
|
|
3
|
-
|
|
4
|
-
CHECKOUT_SESSION_ID_KEY = :checkout_session_id
|
|
5
|
-
|
|
6
|
-
def new
|
|
7
|
-
redirect_to checkout_session.url, allow_other_host: true
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
protected
|
|
11
|
-
def checkout_session
|
|
12
|
-
@checkout_session ||= retrieve_or_create_checkout_session
|
|
13
|
-
end
|
|
14
|
-
|
|
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))
|
|
20
|
-
end
|
|
21
|
-
|
|
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)
|
|
26
|
-
end
|
|
27
|
-
|
|
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
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def callback_url_for(*args, only_path: false, **kwargs)
|
|
45
|
-
url_for(*args, only_path: only_path, **kwargs)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
STRIPE_CALLBACK_PARAMETER = "#{CHECKOUT_SESSION_ID_KEY}={CHECKOUT_SESSION_ID}"
|
|
49
|
-
|
|
50
|
-
# For some reason Stripe decided to not escape the `{CHECKOUT_SESSION_ID}`, if we try to
|
|
51
|
-
# pass it through Rails URL builders or the URI object, it will URL encode the value and
|
|
52
|
-
# not work with stripe. Consequently, we have to do some weirdness here to append the callback.
|
|
53
|
-
#
|
|
54
|
-
# More information at https://stripe.com/docs/payments/checkout/custom-success-page#modify-success-url
|
|
55
|
-
def concat_unescaped_stripe_checkout_session_id(url)
|
|
56
|
-
if URI(url).query
|
|
57
|
-
url.concat("&#{STRIPE_CALLBACK_PARAMETER}")
|
|
58
|
-
else
|
|
59
|
-
url.concat("?#{STRIPE_CALLBACK_PARAMETER}")
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# def success_url
|
|
64
|
-
# callback_url(state: :success)
|
|
65
|
-
# end
|
|
66
|
-
|
|
67
|
-
# def cancel_url
|
|
68
|
-
# callback_url(state: :cancel)
|
|
69
|
-
# end
|
|
70
|
-
|
|
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:)
|
|
74
|
-
return nil if customer_id.blank?
|
|
75
|
-
|
|
76
|
-
begin
|
|
77
|
-
Stripe::Customer.retrieve(String(customer_id))
|
|
78
|
-
# Blurg ... wish Stripe just returned a response object that's not an exception.
|
|
79
|
-
rescue Stripe::InvalidRequestError => e
|
|
80
|
-
case e.response.data
|
|
81
|
-
in error: { code: "resource_missing" }
|
|
82
|
-
nil
|
|
83
|
-
else
|
|
84
|
-
raise
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
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
|
|
3
|
+
include CheckoutSession
|
|
100
4
|
end
|
|
101
5
|
end
|
data/lib/nocheckout/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nocheckout
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brad Gessler
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-10-24 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: zeitwerk
|
|
@@ -69,6 +68,7 @@ files:
|
|
|
69
68
|
- README.md
|
|
70
69
|
- Rakefile
|
|
71
70
|
- app/controllers/nocheckout/stripe.rb
|
|
71
|
+
- app/controllers/nocheckout/stripe/checkout_session.rb
|
|
72
72
|
- app/controllers/nocheckout/stripe/checkout_sessions_controller.rb
|
|
73
73
|
- app/controllers/nocheckout/stripe/webhooks_controller.rb
|
|
74
74
|
- app/controllers/nocheckout/webhooks_controller.rb
|
|
@@ -87,7 +87,6 @@ metadata:
|
|
|
87
87
|
homepage_uri: https://github.com/rubymonolith/nocheckout
|
|
88
88
|
source_code_uri: https://github.com/rubymonolith/nocheckout
|
|
89
89
|
changelog_uri: https://github.com/rubymonolith/nocheckout
|
|
90
|
-
post_install_message:
|
|
91
90
|
rdoc_options: []
|
|
92
91
|
require_paths:
|
|
93
92
|
- lib
|
|
@@ -102,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
102
101
|
- !ruby/object:Gem::Version
|
|
103
102
|
version: '0'
|
|
104
103
|
requirements: []
|
|
105
|
-
rubygems_version: 3.
|
|
106
|
-
signing_key:
|
|
104
|
+
rubygems_version: 3.6.2
|
|
107
105
|
specification_version: 4
|
|
108
106
|
summary: Rails controllers for Stripe Checkout Sessions and Webhooks
|
|
109
107
|
test_files: []
|