purchasekit 0.6.1 → 0.7.1
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/README.md +30 -1
- data/app/controllers/purchase_kit/purchase/completions_controller.rb +1 -1
- data/app/controllers/purchase_kit/purchases_controller.rb +2 -0
- data/app/helpers/purchase_kit/paywall_helper.rb +7 -3
- data/lib/purchasekit/events.rb +5 -0
- data/lib/purchasekit/pay/webhooks/subscription_created.rb +1 -0
- data/lib/purchasekit/pay/webhooks/subscription_updated.rb +16 -5
- data/lib/purchasekit/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 82311c2fb6a6a3aea1ffe6997cfece956e4aef5544fa2ef3cb5e4fcb5a8266d8
|
|
4
|
+
data.tar.gz: aa2785f59d913cade15b3bd0c1335326279673c0a9e519af90fdc22d9de37e90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 752531ead05262da654b7069194df36af97cc4c9dd7fa2c496d230bf637e356ba4aebc97b1d02e44bccd37b34836fcaf432929c7fe46041bb518002979738d0c
|
|
7
|
+
data.tar.gz: 131b2ecb97d17134ff6ecea92162422bf82c9d14e7c938f526ba31c245e47bafdc5d14a394818260598b137e1588aea45981a5dcbe42ee86c6bed25a9d5f5340
|
data/README.md
CHANGED
|
@@ -125,7 +125,36 @@ Webhooks may be delivered more than once. Write idempotent callbacks using `find
|
|
|
125
125
|
|
|
126
126
|
## Paywall helper
|
|
127
127
|
|
|
128
|
-
Build a paywall using the included helper. Subscribe to
|
|
128
|
+
Build a paywall using the included helper. Subscribe to a Turbo Stream channel for real-time redirects after purchase. The `customer_id` you pass flows through the store and back to your webhook handler, so it must match what the handler expects.
|
|
129
|
+
|
|
130
|
+
### With Pay
|
|
131
|
+
|
|
132
|
+
Pass the `Pay::Customer.id` (not your user ID), and subscribe to the Pay customer's `dom_id` channel:
|
|
133
|
+
|
|
134
|
+
```erb
|
|
135
|
+
<% pay_customer = current_user.set_payment_processor(:purchasekit) %>
|
|
136
|
+
|
|
137
|
+
<%= turbo_stream_from dom_id(pay_customer) %>
|
|
138
|
+
|
|
139
|
+
<%= purchasekit_paywall customer_id: pay_customer.id, success_path: dashboard_path do |paywall| %>
|
|
140
|
+
<%= paywall.plan_option product: @annual, selected: true do %>
|
|
141
|
+
Annual - <%= paywall.price %>/year
|
|
142
|
+
<% end %>
|
|
143
|
+
|
|
144
|
+
<%= paywall.plan_option product: @monthly do %>
|
|
145
|
+
Monthly - <%= paywall.price %>/month
|
|
146
|
+
<% end %>
|
|
147
|
+
|
|
148
|
+
<%= paywall.submit "Subscribe" %>
|
|
149
|
+
<%= paywall.restore url: restore_purchases_path, class: "btn btn-link" %>
|
|
150
|
+
<% end %>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`set_payment_processor(:purchasekit)` finds or creates the `Pay::Customer` row. Calling it on every paywall render guarantees the row exists before the webhook tries to look it up.
|
|
154
|
+
|
|
155
|
+
### Without Pay
|
|
156
|
+
|
|
157
|
+
Use your own user ID for both the `customer_id` and the Turbo Stream channel:
|
|
129
158
|
|
|
130
159
|
```erb
|
|
131
160
|
<%= turbo_stream_from "purchasekit_customer_#{current_user.id}" %>
|
|
@@ -19,7 +19,7 @@ module PurchaseKit
|
|
|
19
19
|
subscription_name: "Demo Subscription",
|
|
20
20
|
status: "active",
|
|
21
21
|
current_period_start: Time.current.iso8601,
|
|
22
|
-
current_period_end: 1.
|
|
22
|
+
current_period_end: 1.month.from_now.iso8601,
|
|
23
23
|
ends_at: nil,
|
|
24
24
|
success_path: intent.success_path
|
|
25
25
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module PurchaseKit
|
|
2
2
|
class PurchasesController < ApplicationController
|
|
3
3
|
def create
|
|
4
|
+
raise PurchaseKit::NotFoundError, "No product selected" if params[:product_id].blank?
|
|
5
|
+
|
|
4
6
|
intent = PurchaseKit::Purchase::Intent.create(
|
|
5
7
|
product_id: params[:product_id],
|
|
6
8
|
customer_id: params[:customer_id],
|
|
@@ -2,12 +2,15 @@ module PurchaseKit
|
|
|
2
2
|
module PaywallHelper
|
|
3
3
|
# Renders a paywall form that triggers native in-app purchases
|
|
4
4
|
#
|
|
5
|
-
# @param customer_id [String, Integer]
|
|
5
|
+
# @param customer_id [String, Integer] The identifier passed back in webhook
|
|
6
|
+
# events. With Pay, this must be `Pay::Customer.id` (the webhook handler
|
|
7
|
+
# does `Pay::Customer.find(customer_id)`). Without Pay, use your own user ID.
|
|
6
8
|
# @param success_path [String] Where to redirect after successful purchase
|
|
7
9
|
# @yield [PaywallBuilder] Builder for plan options and buttons
|
|
8
10
|
#
|
|
9
|
-
# Example:
|
|
10
|
-
#
|
|
11
|
+
# Example (with Pay):
|
|
12
|
+
# <% pay_customer = current_user.set_payment_processor(:purchasekit) %>
|
|
13
|
+
# <%= purchasekit_paywall customer_id: pay_customer.id, success_path: dashboard_path do |paywall| %>
|
|
11
14
|
# <%= paywall.plan_option product: @annual, selected: true do %>
|
|
12
15
|
# Annual - <%= paywall.price %>
|
|
13
16
|
# <% end %>
|
|
@@ -48,6 +51,7 @@ module PurchaseKit
|
|
|
48
51
|
selected,
|
|
49
52
|
id: input_id,
|
|
50
53
|
class: input_class,
|
|
54
|
+
required: true,
|
|
51
55
|
autocomplete: "off",
|
|
52
56
|
data: {
|
|
53
57
|
purchasekit__paywall_target: "planRadio",
|
data/lib/purchasekit/events.rb
CHANGED
|
@@ -119,6 +119,11 @@ module PurchaseKit
|
|
|
119
119
|
parse_time(payload[:ends_at])
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
# When the trial period ends (nil if no trial)
|
|
123
|
+
def trial_ends_at
|
|
124
|
+
parse_time(payload[:trial_ends_at])
|
|
125
|
+
end
|
|
126
|
+
|
|
122
127
|
# The success path you passed when creating the purchase intent.
|
|
123
128
|
# Use this for redirecting after purchase completion.
|
|
124
129
|
def success_path
|
|
@@ -21,6 +21,7 @@ module PurchaseKit
|
|
|
21
21
|
quantity: 1,
|
|
22
22
|
current_period_start: parse_time(event["current_period_start"]),
|
|
23
23
|
current_period_end: parse_time(event["current_period_end"]),
|
|
24
|
+
trial_ends_at: parse_time(event["trial_ends_at"]),
|
|
24
25
|
ends_at: parse_time(event["ends_at"]),
|
|
25
26
|
data: (subscription.data || {}).merge("store" => event["store"])
|
|
26
27
|
)
|
|
@@ -6,20 +6,31 @@ module PurchaseKit
|
|
|
6
6
|
include Turbo::Streams::ActionHelper
|
|
7
7
|
|
|
8
8
|
def call(event)
|
|
9
|
-
|
|
9
|
+
customer = ::Pay::Customer.find(event["customer_id"])
|
|
10
|
+
|
|
11
|
+
subscription = ::Pay::Purchasekit::Subscription.find_or_initialize_by(
|
|
12
|
+
customer: customer,
|
|
13
|
+
processor_id: event["subscription_id"]
|
|
14
|
+
)
|
|
15
|
+
subscription.name ||= event["subscription_name"] || ::Pay.default_product_name
|
|
16
|
+
subscription.quantity ||= 1
|
|
17
|
+
|
|
18
|
+
subscription.update!(
|
|
10
19
|
processor_plan: event["store_product_id"],
|
|
11
20
|
status: event["status"],
|
|
12
21
|
current_period_start: parse_time(event["current_period_start"]),
|
|
13
22
|
current_period_end: parse_time(event["current_period_end"]),
|
|
14
|
-
|
|
23
|
+
trial_ends_at: parse_time(event["trial_ends_at"]),
|
|
24
|
+
ends_at: parse_time(event["ends_at"]),
|
|
25
|
+
data: (subscription.data || {}).merge("store" => event["store"])
|
|
26
|
+
)
|
|
15
27
|
|
|
16
|
-
broadcast_redirect(event) if event["success_path"].present?
|
|
28
|
+
broadcast_redirect(customer, event) if event["success_path"].present?
|
|
17
29
|
end
|
|
18
30
|
|
|
19
31
|
private
|
|
20
32
|
|
|
21
|
-
def broadcast_redirect(event)
|
|
22
|
-
customer = ::Pay::Customer.find(event["customer_id"])
|
|
33
|
+
def broadcast_redirect(customer, event)
|
|
23
34
|
Turbo::StreamsChannel.broadcast_stream_to(
|
|
24
35
|
dom_id(customer),
|
|
25
36
|
content: turbo_stream_action_tag(:redirect, url: event["success_path"])
|
data/lib/purchasekit/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: purchasekit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joe Masilotti
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -225,7 +224,6 @@ metadata:
|
|
|
225
224
|
homepage_uri: https://purchasekit.com
|
|
226
225
|
source_code_uri: https://github.com/purchasekit/purchasekit
|
|
227
226
|
changelog_uri: https://github.com/purchasekit/purchasekit/blob/main/CHANGELOG.md
|
|
228
|
-
post_install_message:
|
|
229
227
|
rdoc_options: []
|
|
230
228
|
require_paths:
|
|
231
229
|
- lib
|
|
@@ -240,8 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
240
238
|
- !ruby/object:Gem::Version
|
|
241
239
|
version: '0'
|
|
242
240
|
requirements: []
|
|
243
|
-
rubygems_version:
|
|
244
|
-
signing_key:
|
|
241
|
+
rubygems_version: 4.0.3
|
|
245
242
|
specification_version: 4
|
|
246
243
|
summary: In-app purchase infrastructure for Rails
|
|
247
244
|
test_files: []
|