diff --git a/CHANGELOG.md b/CHANGELOG.md index 37119913..22a10468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Add `Pay.sync(params)` for automatically syncing Stripe Checkout Sessions and Paddle Billing transactions. * Lock Pay::Customer record when creating or updating Stripe customer to handle race conditions. #1027 * LemonSqueezy & Paddle Billing will now find Customers by email since they do not allow duplicates. #1043 +* Add `Pay::Stripe::Customer#customer_session` for creating pricing tables, etc ### 7.3.0 diff --git a/Gemfile.lock b/Gemfile.lock index 31ad4a46..7789530b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -181,7 +181,7 @@ GEM psych (5.1.2) stringio public_suffix (6.0.1) - puma (6.4.2) + puma (6.4.3) nio4r (~> 2.0) racc (1.8.1) rack (3.1.7) diff --git a/app/models/pay/stripe/customer.rb b/app/models/pay/stripe/customer.rb index c714233f..74981207 100644 --- a/app/models/pay/stripe/customer.rb +++ b/app/models/pay/stripe/customer.rb @@ -232,10 +232,28 @@ def billing_portal(**options) ::Stripe::BillingPortal::Session.create(args.merge(options), stripe_options) end + def customer_session(**options) + api_record unless processor_id? + args = {customer: processor_id} + ::Stripe::CustomerSession.create(args.merge(options), stripe_options) + end + def authorize(amount, options = {}) charge(amount, options.merge(capture_method: :manual)) end + # Creates a meter event to bill for usage + # + # create_meter_event(:api_request, value: 1) + # create_meter_event(:api_request, token: 7) + def create_meter_event(event_name, payload: {}, **options) + api_record unless processor_id? + ::Stripe::Billing::MeterEvent.create({ + event_name: event_name, + payload: {stripe_customer_id: processor_id}.merge(payload) + }.merge(options)) + end + private # Options for Stripe requests diff --git a/app/models/pay/stripe/subscription.rb b/app/models/pay/stripe/subscription.rb index 75899a67..e89a935e 100644 --- a/app/models/pay/stripe/subscription.rb +++ b/app/models/pay/stripe/subscription.rb @@ -301,21 +301,6 @@ def swap(plan, **options) raise Pay::Stripe::Error, e end - # Creates a meter event to bill for usage - # - # create_meter_event(:api_request, value: 1) - # create_meter_event(:api_request, token: 7) - def create_meter_event(event_name, **payload) - api_record unless processor_id? - ::Stripe::Billing::MeterEvent.create({ - event_name: event_name, - payload: { - stripe_customer_id: processor_id, - **payload - } - }) - end - # Creates a metered billing usage record # # Uses the first subscription_item ID unless `subscription_item_id: "si_1234"` is passed diff --git a/docs/stripe/5_webhooks.md b/docs/stripe/5_webhooks.md index 8fdfb9ce..789f2dd5 100644 --- a/docs/stripe/5_webhooks.md +++ b/docs/stripe/5_webhooks.md @@ -54,6 +54,8 @@ checkout.session.completed checkout.session.async_payment_succeeded ``` +[Click here](https://dashboard.stripe.com/webhooks/create?events=charge.succeeded%2Ccharge.refunded%2Cpayment_intent.succeeded%2Cinvoice.upcoming%2Cinvoice.payment_action_required%2Ccustomer.subscription.created%2Ccustomer.subscription.updated%2Ccustomer.subscription.deleted%2Ccustomer.subscription.trial_will_end%2Ccustomer.updated%2Ccustomer.deleted%2Cpayment_method.attached%2Cpayment_method.updated%2Cpayment_method.automatically_updated%2Cpayment_method.detached%2Caccount.updated%2Ccheckout.session.completed%2Ccheckout.session.async_payment_succeeded) to create a new Stripe webhook with all the events pre-filled. + ## Next See [Metered Billing](6_metered_billing.md) diff --git a/docs/stripe/6_metered_billing.md b/docs/stripe/6_metered_billing.md index b995e6c4..41e67f9b 100644 --- a/docs/stripe/6_metered_billing.md +++ b/docs/stripe/6_metered_billing.md @@ -9,7 +9,7 @@ Metered billing are subscriptions where the price fluctuates monthly. For exampl This will create a new metered billing subscription. You can then create meter events to bill for usage: ```ruby -pay_subscription.create_meter_event(:api_request, value: 1) +@user.payment_processor.create_meter_event(:api_request, payload: { value: 1 }) ``` If your price is using the legacy usage records system, you will need to use the below method: diff --git a/lib/pay/receipts.rb b/lib/pay/receipts.rb index 09ceb87a..2b11c6b6 100644 --- a/lib/pay/receipts.rb +++ b/lib/pay/receipts.rb @@ -1,9 +1,5 @@ module Pay module Receipts - def product - Pay.application_name - end - def receipt_filename "receipt-#{created_at.strftime("%Y-%m-%d")}.pdf" end @@ -21,6 +17,10 @@ def receipt_details ] end + def pdf_product_name + Pay.application_name + end + def pdf_line_items items = [ [ @@ -45,7 +45,7 @@ def pdf_line_items end end else - items << [product, 1, Pay::Currency.format(amount, currency: currency), Pay::Currency.format(amount, currency: currency)] + items << [pdf_product_name, 1, Pay::Currency.format(amount, currency: currency), Pay::Currency.format(amount, currency: currency)] end # If no subtotal, we will display the total @@ -155,7 +155,7 @@ def invoice_pdf(**options) company: { name: Pay.business_name, address: Pay.business_address, - email: Pay.support_email.address, + email: Pay.support_email&.address, logo: Pay.business_logo }, line_items: pdf_line_items