diff --git a/app/controllers/api/payments_controller.rb b/app/controllers/api/payments_controller.rb index 06e49ed47..ec3b2faa4 100644 --- a/app/controllers/api/payments_controller.rb +++ b/app/controllers/api/payments_controller.rb @@ -39,7 +39,7 @@ class API::PaymentsController < API::ApiController post_save(gateway_item_id, gateway_item_type, res[:payment]) res[:payment].render_resource.merge(status: :created) else - { json: res[:errors], status: :unprocessable_entity } + { json: res[:errors].drop_while(&:empty?), status: :unprocessable_entity } end end end diff --git a/app/controllers/api/stripe_controller.rb b/app/controllers/api/stripe_controller.rb index 7ef820ccf..c46f20e6d 100644 --- a/app/controllers/api/stripe_controller.rb +++ b/app/controllers/api/stripe_controller.rb @@ -69,10 +69,10 @@ class API::StripeController < API::PaymentsController render json: { id: @intent.id, client_secret: @intent.client_secret } end - def create_subscription + def setup_subscription cart = shopping_cart cart.items.each do |item| - raise InvalidSubscriptionError unless item.valid?(@items) + raise InvalidSubscriptionError unless item.valid?(cart.items) raise InvalidSubscriptionError unless item.to_object.errors.empty? end @@ -90,12 +90,15 @@ class API::StripeController < API::PaymentsController def confirm_subscription key = Setting.get('stripe_secret_key') - subscription = Stripe::Subscription.retrieve(params[:subscription_id], api_key: key) + subscription = Stripe::Subscription.retrieve( + { id: params[:subscription_id], expand: %w[latest_invoice.payment_intent] }, + { api_key: key } + ) cart = shopping_cart if subscription&.status == 'active' - res = on_payment_success(subscription, cart) - render generate_payment_response(subscription, res) + res = on_payment_success(subscription.latest_invoice.payment_intent, cart) + render generate_payment_response(subscription.latest_invoice.payment_intent, 'subscription', res) end rescue Stripe::InvalidRequestError => e render json: e, status: :unprocessable_entity diff --git a/app/models/shopping_cart.rb b/app/models/shopping_cart.rb index 0a90a7161..f586d3708 100644 --- a/app/models/shopping_cart.rb +++ b/app/models/shopping_cart.rb @@ -64,8 +64,9 @@ class ShoppingCart payment.post_save(payment_id) end - success = objects.map(&:errors).flatten.map(&:empty?).all? && items.map(&:errors).map(&:empty?).all? + success = !payment.nil? && objects.map(&:errors).flatten.map(&:empty?).all? && items.map(&:errors).map(&:empty?).all? errors = objects.map(&:errors).flatten.concat(items.map(&:errors)) + errors.push('Unable to create the PaymentDocument') if payment.nil? { success: success, payment: payment, errors: errors } end diff --git a/config/routes.rb b/config/routes.rb index 7fa9c69b0..fe1b8a66e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -182,7 +182,7 @@ Rails.application.routes.draw do post 'stripe/confirm_payment' => 'stripe/confirm_payment' get 'stripe/online_payment_status' => 'stripe/online_payment_status' get 'stripe/setup_intent/:user_id' => 'stripe#setup_intent' - post 'stripe/create_subscription' => 'stripe/create_subscription' + post 'stripe/setup_subscription' => 'stripe/setup_subscription' post 'stripe/confirm_subscription' => 'stripe#confirm_subscription' post 'stripe/update_card' => 'stripe#update_card' diff --git a/lib/stripe/service.rb b/lib/stripe/service.rb index bb94db78f..05a2dab67 100644 --- a/lib/stripe/service.rb +++ b/lib/stripe/service.rb @@ -12,12 +12,13 @@ class Stripe::Service < Payment::Service price_details = shopping_cart.total payment_schedule = price_details[:schedule][:payment_schedule] + payment_schedule.payment_schedule_items = price_details[:schedule][:items] first_item = price_details[:schedule][:items].min_by(&:due_date) subscription = shopping_cart.items.find { |item| item.class == CartItem::Subscription } reservable_stp_id = shopping_cart.items.find { |item| item.is_a?(CartItem::Reservation) }.to_object .reservable&.payment_gateway_object&.gateway_object_id - WalletService.debit_user_wallet(payment_schedule, payment_schedule.invoicing_profile.user, transaction: false) + WalletService.debit_user_wallet(payment_schedule, shopping_cart.customer, transaction: false) handle_wallet_transaction(payment_schedule) price = create_price(first_item.details['recurring'], @@ -26,8 +27,10 @@ class Stripe::Service < Payment::Service # other items (not recurring) items = subscription_invoice_items(payment_schedule, subscription, first_item, reservable_stp_id) + + stripe_key = Setting.get('stripe_secret_key') Stripe::Subscription.create({ - customer: payment_schedule.invoicing_profile.user.payment_gateway_object.gateway_object_id, + customer: shopping_cart.customer.payment_gateway_object.gateway_object_id, cancel_at: (payment_schedule.payment_schedule_items.max_by(&:due_date).due_date + 1.month).to_i, add_invoice_items: items, coupon: payment_schedule.coupon&.code, @@ -39,12 +42,11 @@ class Stripe::Service < Payment::Service }, { api_key: stripe_key }) end - def create_subscription(payment_schedule, subscription_id) + def create_subscription(payment_schedule, payment_intent_id) stripe_key = Setting.get('stripe_secret_key') - handle_wallet_transaction(payment_schedule) - - stp_subscription = Stripe::Subscription.retrieve(subscription_id, api_key: stripe_key) + pi = Stripe::PaymentIntent.retrieve({ id: payment_intent_id, expand: %w[invoice] }, { api_key: stripe_key }) + stp_subscription = Stripe::Subscription.retrieve(pi.invoice.subscription, api_key: stripe_key) pgo = PaymentGatewayObject.new(item: payment_schedule) pgo.gateway_object = stp_subscription pgo.save!