FEATURE: Allow one-time purchases on products (#18)

Building off the foundation of using the Prices API, this PR adds the ability to create a one-time purchase plan for any product, which then can add a user to the specified plan group.

Some things to be aware of:

    One-time purchases cannot have trials.
    One-time purchases use the Invoice API instead of Subscriptions. Invoices are created then charged immediately.
    Users should receive emails for these invoices directly from Stripe just like subscriptions.
This commit is contained in:
Justin DiRose
2020-07-22 11:06:34 -05:00
committed by GitHub
parent fcc90e4fcc
commit 587661fafb
31 changed files with 272 additions and 533 deletions
@@ -19,7 +19,6 @@ module DiscourseSubscriptions
end
render_json_dump subscriptions
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
@@ -29,36 +28,48 @@ module DiscourseSubscriptions
begin
plan = ::Stripe::Price.retrieve(params[:plan])
if plan[:metadata] && plan[:metadata][:trial_period_days]
trial_days = plan[:metadata][:trial_period_days]
recurring_plan = plan[:type] == 'recurring'
if recurring_plan
trial_days = plan[:metadata][:trial_period_days] if plan[:metadata] && plan[:metadata][:trial_period_days]
transaction = ::Stripe::Subscription.create(
customer: params[:customer],
items: [{ price: params[:plan] }],
metadata: metadata_user,
trial_period_days: trial_days
)
else
invoice_item = ::Stripe::InvoiceItem.create(
customer: params[:customer],
price: params[:plan]
)
invoice = ::Stripe::Invoice.create(
customer: params[:customer]
)
transaction = ::Stripe::Invoice.pay(invoice[:id])
end
@subscription = ::Stripe::Subscription.create(
customer: params[:customer],
items: [ { price: params[:plan] } ],
metadata: metadata_user,
trial_period_days: trial_days
)
if transaction_ok(transaction)
group = plan_group(plan)
group = plan_group(plan)
group.add(current_user) if group
if subscription_ok && group
group.add(current_user)
customer = Customer.create(
user_id: current_user.id,
customer_id: params[:customer],
product_id: plan[:product]
)
if transaction[:object] == 'subscription'
Subscription.create(
customer_id: customer.id,
external_id: transaction[:id]
)
end
end
customer = Customer.create(
user_id: current_user.id,
customer_id: params[:customer],
product_id: plan[:product]
)
Subscription.create(
customer_id: customer.id,
external_id: @subscription[:id]
)
render_json_dump @subscription
render_json_dump transaction
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
@@ -70,8 +81,8 @@ module DiscourseSubscriptions
{ user_id: current_user.id, username: current_user.username_lower }
end
def subscription_ok
['active', 'trialing'].include?(@subscription[:status])
def transaction_ok(transaction)
%w[active trialing paid].include?(transaction[:status])
end
end
end