mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-01 12:24:28 +01:00
[bug] wallet usage is noted on subscription invoices even if wallet was not used + use payment confirm API for subscriptions only (sca)
This commit is contained in:
parent
4d0ac9b3ca
commit
ac0489a496
@ -246,6 +246,14 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
// Used in wallet info template to interpolate some translations
|
||||
$scope.numberFilter = $filter('number');
|
||||
|
||||
// Cart items
|
||||
$scope.cartItems = {
|
||||
coupon_code: ((coupon ? coupon.code : undefined)),
|
||||
subscription: {
|
||||
plan_id: selectedPlan.id
|
||||
}
|
||||
};
|
||||
|
||||
// retrieve the CGV
|
||||
CustomAsset.get({ name: 'cgv-file' }, function (cgv) { $scope.cgv = cgv.custom_asset; });
|
||||
|
||||
@ -254,29 +262,8 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
* Handle the stripe's card tokenization process response and save the subscription to the API with the
|
||||
* card token just created.
|
||||
*/
|
||||
$scope.payment = function (status, response) {
|
||||
if (response.error) {
|
||||
growl.error(response.error.message);
|
||||
} else {
|
||||
$scope.attempting = true;
|
||||
Subscription.save({
|
||||
coupon_code: ((coupon ? coupon.code : undefined)),
|
||||
subscription: {
|
||||
plan_id: selectedPlan.id,
|
||||
user_id: member.id,
|
||||
card_token: response.id
|
||||
}
|
||||
}
|
||||
, function (data) { // success
|
||||
$uibModalInstance.close(data);
|
||||
}
|
||||
, function (data, status) { // failed
|
||||
$scope.alerts = [];
|
||||
$scope.alerts.push({ msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' });
|
||||
$scope.attempting = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
$scope.onPaymentSuccess = function (response) {
|
||||
$uibModalInstance.close(response);
|
||||
};
|
||||
}
|
||||
]
|
||||
@ -367,7 +354,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
|
||||
}
|
||||
]
|
||||
}).result['finally'](null).then(function (reservation) {
|
||||
}).result['finally'](null).then(function (subscription) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
$scope.ctrl.member = null;
|
||||
|
@ -19,28 +19,32 @@ class API::PaymentsController < API::ApiController
|
||||
end
|
||||
|
||||
# Compute the price
|
||||
reservable = cart_items_params[:reservable_type].constantize.find(cart_items_params[:reservable_id])
|
||||
price_details = Price.compute(false,
|
||||
current_user,
|
||||
reservable,
|
||||
cart_items_params[:slots_attributes] || [],
|
||||
cart_items_params[:plan_id],
|
||||
cart_items_params[:nb_reserve_places],
|
||||
cart_items_params[:tickets_attributes],
|
||||
coupon_params[:coupon_code])
|
||||
|
||||
# Subtract wallet amount from total
|
||||
total = price_details[:total]
|
||||
wallet_debit = get_wallet_debit(current_user, total)
|
||||
if params[:cart_items][:reservation]
|
||||
reservable = cart_items_params[:reservable_type].constantize.find(cart_items_params[:reservable_id])
|
||||
price_details = Price.compute(false,
|
||||
current_user,
|
||||
reservable,
|
||||
cart_items_params[:slots_attributes] || [],
|
||||
cart_items_params[:plan_id],
|
||||
cart_items_params[:nb_reserve_places],
|
||||
cart_items_params[:tickets_attributes],
|
||||
coupon_params[:coupon_code])
|
||||
|
||||
# Subtract wallet amount from total
|
||||
total = price_details[:total]
|
||||
wallet_debit = get_wallet_debit(current_user, total)
|
||||
amount = total - wallet_debit
|
||||
elsif params[:cart_items][:subscription]
|
||||
amount = 2000 # TODO
|
||||
end
|
||||
# Create the PaymentIntent
|
||||
intent = Stripe::PaymentIntent.create(
|
||||
payment_method: params[:payment_method_id],
|
||||
amount: total - wallet_debit,
|
||||
amount: amount,
|
||||
currency: Rails.application.secrets.stripe_currency,
|
||||
confirmation_method: 'manual',
|
||||
confirm: true,
|
||||
customer: current_user.stp_customer_id,
|
||||
customer: current_user.stp_customer_id
|
||||
)
|
||||
elsif params[:payment_intent_id].present?
|
||||
intent = Stripe::PaymentIntent.confirm(params[:payment_intent_id])
|
||||
@ -48,20 +52,26 @@ class API::PaymentsController < API::ApiController
|
||||
rescue Stripe::CardError => e
|
||||
# Display error on client
|
||||
render(status: 200, json: { error: e.message }) and return
|
||||
rescue InvalidCouponError
|
||||
render(json: { coupon_code: 'wrong coupon code or expired' }, status: :unprocessable_entity) and return
|
||||
end
|
||||
|
||||
if intent.status == 'succeeded'
|
||||
if params[:cart_items][:reservation]
|
||||
render(on_reservation_success(intent)) and return
|
||||
elsif params[:cart_items][:subscription]
|
||||
render(on_subscription_success(intent)) and return
|
||||
end
|
||||
end
|
||||
|
||||
render(on_payment_success(intent)) and return if intent.status == 'succeeded'
|
||||
render generate_payment_response(intent)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def on_payment_success(intent)
|
||||
# TODO create subscription is needed
|
||||
user_id = params[:cart_items][:reservation][:user_id]
|
||||
|
||||
def on_reservation_success(intent)
|
||||
@reservation = Reservation.new(reservation_params)
|
||||
is_reserve = Reservations::Reserve.new(user_id, current_user.invoicing_profile.id)
|
||||
is_reserve = Reservations::Reserve.new(current_user.id, current_user.invoicing_profile.id)
|
||||
.pay_and_save(@reservation, coupon: coupon_params[:coupon_code], payment_intent_id: intent.id)
|
||||
Stripe::PaymentIntent.update(
|
||||
intent.id,
|
||||
@ -75,8 +85,23 @@ class API::PaymentsController < API::ApiController
|
||||
else
|
||||
{ json: @reservation.errors, status: :unprocessable_entity }
|
||||
end
|
||||
rescue InvalidCouponError
|
||||
{ json: { coupon_code: 'wrong coupon code or expired' }, status: :unprocessable_entity }
|
||||
end
|
||||
|
||||
def on_subscription_success(intent)
|
||||
@subscription = Subscription.new(subscription_params)
|
||||
is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, current_user.id)
|
||||
.pay_and_save(@subscription, coupon: coupon_params[:coupon_code], invoice: true, payment_intent_id: intent.id)
|
||||
|
||||
Stripe::PaymentIntent.update(
|
||||
intent.id,
|
||||
description: "Invoice reference: #{@subscription.invoices.first.reference}"
|
||||
)
|
||||
|
||||
if is_subscribe
|
||||
{ template: 'api/subscriptions/show', status: :created, location: @subscription }
|
||||
else
|
||||
{ json: @subscription.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
|
||||
def generate_payment_response(intent)
|
||||
@ -110,6 +135,10 @@ class API::PaymentsController < API::ApiController
|
||||
slots_attributes: %i[id start_at end_at availability_id offered])
|
||||
end
|
||||
|
||||
def subscription_params
|
||||
params[:cart_items].require(:subscription).permit(:plan_id)
|
||||
end
|
||||
|
||||
def cart_items_params
|
||||
params[:cart_items].require(:reservation).permit(:reservable_id, :reservable_type, :plan_id, :user_id, :nb_reserve_places,
|
||||
tickets_attributes: %i[event_price_category_id booked],
|
||||
|
@ -57,7 +57,7 @@ class API::ReservationsController < API::ApiController
|
||||
end
|
||||
|
||||
def reservation_params
|
||||
params.require(:reservation).permit(:message, :reservable_id, :reservable_type, :card_token, :plan_id, :nb_reserve_places,
|
||||
params.require(:reservation).permit(:message, :reservable_id, :reservable_type, :plan_id, :nb_reserve_places,
|
||||
tickets_attributes: %i[event_price_category_id booked],
|
||||
slots_attributes: %i[id start_at end_at availability_id offered])
|
||||
end
|
||||
|
@ -16,7 +16,7 @@ class API::SubscriptionsController < API::ApiController
|
||||
|
||||
@subscription = Subscription.new(subscription_params)
|
||||
is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, user_id)
|
||||
.pay_and_save(@subscription, coupon_params[:coupon_code], true)
|
||||
.pay_and_save(@subscription, coupon: coupon_params[:coupon_code], invoice: true)
|
||||
|
||||
if is_subscribe
|
||||
render :show, status: :created, location: @subscription
|
||||
@ -51,7 +51,7 @@ class API::SubscriptionsController < API::ApiController
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
def subscription_params
|
||||
params.require(:subscription).permit(:plan_id, :card_token)
|
||||
params.require(:subscription).permit(:plan_id)
|
||||
end
|
||||
|
||||
def coupon_params
|
||||
@ -61,12 +61,4 @@ class API::SubscriptionsController < API::ApiController
|
||||
def subscription_update_params
|
||||
params.require(:subscription).permit(:expired_at)
|
||||
end
|
||||
|
||||
# TODO, refactor subscriptions logic and move this in model/validator
|
||||
def valid_card_token?(token)
|
||||
Stripe::Token.retrieve(token)
|
||||
rescue Stripe::InvalidRequestError => e
|
||||
@subscription.errors[:card_token] << e.message
|
||||
false
|
||||
end
|
||||
end
|
||||
|
@ -18,7 +18,7 @@ class Reservation < ActiveRecord::Base
|
||||
validate :machine_not_already_reserved, if: -> { reservable.is_a?(Machine) }
|
||||
validate :training_not_fully_reserved, if: -> { reservable.is_a?(Training) }
|
||||
|
||||
attr_accessor :card_token, :plan_id, :subscription
|
||||
attr_accessor :plan_id, :subscription
|
||||
|
||||
after_commit :notify_member_create_reservation, on: :create
|
||||
after_commit :notify_admin_member_create_reservation, on: :create
|
||||
|
@ -13,8 +13,6 @@ class Subscription < ActiveRecord::Base
|
||||
validates_presence_of :plan_id
|
||||
validates_with SubscriptionGroupValidator
|
||||
|
||||
attr_accessor :card_token
|
||||
|
||||
# creation
|
||||
after_save :notify_member_subscribed_plan
|
||||
after_save :notify_admin_subscribed_plan
|
||||
@ -22,7 +20,7 @@ class Subscription < ActiveRecord::Base
|
||||
|
||||
# @param invoice if true then only the subscription is payed, without reservation
|
||||
# if false then the subscription is payed with reservation
|
||||
def save_with_payment(operator_profile_id, invoice = true, coupon_code = nil)
|
||||
def save_with_payment(operator_profile_id, invoice = true, coupon_code = nil, payment_intent_id = nil)
|
||||
return false unless valid?
|
||||
|
||||
set_expiration_date
|
||||
@ -35,7 +33,7 @@ class Subscription < ActiveRecord::Base
|
||||
# debit wallet
|
||||
wallet_transaction = debit_user_wallet
|
||||
|
||||
invoc = generate_invoice(operator_profile_id, coupon_code)
|
||||
invoc = generate_invoice(operator_profile_id, coupon_code, payment_intent_id)
|
||||
if wallet_transaction
|
||||
invoc.wallet_amount = @wallet_amount_debit
|
||||
invoc.wallet_transaction_id = wallet_transaction.id
|
||||
@ -45,7 +43,7 @@ class Subscription < ActiveRecord::Base
|
||||
true
|
||||
end
|
||||
|
||||
def generate_invoice(operator_profile_id, coupon_code = nil)
|
||||
def generate_invoice(operator_profile_id, coupon_code = nil, payment_intent_id = nil)
|
||||
coupon_id = nil
|
||||
total = plan.amount
|
||||
|
||||
@ -65,7 +63,8 @@ class Subscription < ActiveRecord::Base
|
||||
statistic_profile: user.statistic_profile,
|
||||
total: total,
|
||||
coupon_id: coupon_id,
|
||||
operator_profile_id: operator_profile_id
|
||||
operator_profile_id: operator_profile_id,
|
||||
stp_payment_intent_id: payment_intent_id
|
||||
)
|
||||
invoice.invoice_items.push InvoiceItem.new(
|
||||
amount: plan.amount,
|
||||
@ -194,7 +193,7 @@ class Subscription < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def debit_user_wallet
|
||||
return unless @wallet_amount_debit.present? || @wallet_amount_debit.zero?
|
||||
return if !@wallet_amount_debit.present? || @wallet_amount_debit.zero?
|
||||
|
||||
amount = @wallet_amount_debit / 100.0
|
||||
WalletService.new(user: user, wallet: user.wallet).debit(amount, self)
|
||||
|
@ -9,11 +9,11 @@ class Subscriptions::Subscribe
|
||||
@operator_profile_id = operator_profile_id
|
||||
end
|
||||
|
||||
def pay_and_save(subscription, coupon, invoice)
|
||||
def pay_and_save(subscription, coupon: nil, invoice: nil, payment_intent_id: nil)
|
||||
return false if user_id.nil?
|
||||
|
||||
subscription.statistic_profile_id = StatisticProfile.find_by(user_id: user_id).id
|
||||
subscription.save_with_payment(operator_profile_id, invoice, coupon)
|
||||
subscription.save_with_payment(operator_profile_id, invoice, coupon, payment_intent_id)
|
||||
end
|
||||
|
||||
def extend_subscription(subscription, new_expiration_date, free_days)
|
||||
|
Loading…
Reference in New Issue
Block a user