app/controllers/accept_preauthorized_conversations_controller.rb
class AcceptPreauthorizedConversationsController < ApplicationController
before_action do |controller|
controller.ensure_logged_in t("layouts.notifications.you_must_log_in_to_accept_or_reject")
end
before_action :fetch_transaction
before_action :fetch_listing
before_action :ensure_is_author
# Skip auth token check as current jQuery doesn't provide it automatically
skip_before_action :verify_authenticity_token
def accept
tx_id = params[:id]
tx = @current_community.transactions.find(tx_id)
if tx.current_state != 'preauthorized'
redirect_to person_transaction_path(person_id: @current_user.id, id: tx_id)
return
end
payment_type = tx.payment_gateway
case payment_type
when :paypal, :stripe
render_payment_form("accept", payment_type)
else
raise ArgumentError.new("Unknown payment type: #{payment_type}")
end
end
def reject
tx_id = params[:id]
tx = @current_community.transactions.find(tx_id)
if tx.current_state != 'preauthorized'
redirect_to person_transaction_path(person_id: @current_user.id, id: tx_id)
return
end
payment_type = tx.payment_gateway
case payment_type
when :paypal, :stripe
render_payment_form("reject", payment_type)
else
raise ArgumentError.new("Unknown payment type: #{payment_type}")
end
end
def accepted_or_rejected
tx_id = params[:id]
message = params[:transaction][:message_attributes][:content]
status = params[:transaction][:status].to_sym
sender_id = @current_user.id
tx = @current_community.transactions.find(tx_id)
if tx.current_state != 'preauthorized'
redirect_to person_transaction_path(person_id: @current_user.id, id: tx_id)
return
end
res = accept_or_reject_tx(@current_community.id, tx, status, message, sender_id)
if res[:success]
flash[:notice] = success_msg(res[:flow])
record_event(
flash,
status == (:paid || :paid_and_close) ? "PreauthorizedTransactionAccepted" : "PreauthorizedTransactionRejected",
{ listing_id: tx.listing_id,
listing_uuid: UUIDUtils.parse_raw(tx.listing_uuid).to_s,
transaction_id: tx.id })
redirect_to person_transaction_path(person_id: sender_id, id: tx_id)
else
flash[:error] = error_msg(res[:flow], tx)
redirect_to accept_preauthorized_person_message_path(person_id: sender_id , id: tx_id)
end
end
private
def accept_or_reject_tx(community_id, tx, status, message, sender_id)
if status == :paid
accept_tx(community_id, tx, message, sender_id)
elsif status == :paid_and_close
accept_tx_and_close(community_id, tx, message, sender_id)
elsif status == :rejected
reject_tx(community_id, tx, message, sender_id)
else
{ flow: :unknown, success: false }
end
end
def accept_tx_and_close(community_id, tx, message, sender_id)
result = accept_tx(community_id, tx, message, sender_id)
if result[:success]
tx.listing.update(open: false)
{ flow: :accept_and_close, success: true }
else
result
end
end
def accept_tx(community_id, tx, message, sender_id)
TransactionService::Transaction.complete_preauthorization(community_id: community_id,
transaction_id: tx.id,
message: message,
sender_id: sender_id)
.maybe()
.map { |_| {flow: :accept, success: true}}
.or_else({flow: :accept, success: false})
end
def reject_tx(community_id, tx, message, sender_id)
TransactionService::Transaction.reject(community_id: community_id,
transaction_id: tx.id,
message: message,
sender_id: sender_id)
.maybe()
.map { |_| {flow: :reject, success: true}}
.or_else({flow: :reject, success: false})
end
def success_msg(flow)
if flow == :accept
t("layouts.notifications.request_accepted")
elsif flow == :accept_and_close
t('layouts.notifications.request_accepted_and_closed')
elsif flow == :reject
t("layouts.notifications.request_rejected")
end
end
def error_msg(flow, tx)
payment_gateway = tx.payment_gateway
if flow == :accept
if payment_gateway == :paypal
t("error_messages.paypal.accept_authorization_error")
elsif payment_gateway == :stripe
t("error_messages.stripe.accept_authorization_error")
end
elsif flow == :reject
if payment_gateway == :paypal
t("error_messages.paypal.reject_authorization_error")
elsif payment_gateway == :stripe
t("error_messages.stripe.reject_authorization_error")
end
end
end
def ensure_is_author
unless @listing.author == @current_user
flash[:error] = "Only listing author can perform the requested action"
redirect_to (session[:return_to_content] || root)
end
end
def fetch_listing
@listing = @transaction.listing
end
def fetch_transaction
@transaction = @current_community.transactions.find(params[:id])
end
def render_payment_form(preselected_action, payment_type)
community_country_code = LocalizationUtils.valid_country_code(@current_community.country)
payment_details = TransactionService::Transaction.payment_details(@transaction)
total_price = if payment_details[:buyer_commission] && payment_details[:buyer_commission] > 0
payment_details[:total_price] - payment_details[:buyer_commission]
else
payment_details[:total_price]
end
render "accept", locals: {
listing: @listing,
sum: total_price + (payment_details[:payment_gateway_fee] || 0),
fee: @transaction.commission,
buyer_commission: payment_details[:buyer_commission],
gateway_fee: payment_details[:payment_gateway_fee],
seller_gets: payment_details[:total_price] - (payment_details[:charged_commission] || 0) - (payment_details[:buyer_commission] || 0),
form: @transaction,
form_action: acceptance_preauthorized_person_message_path(
person_id: @current_user.id,
id: @transaction.id
),
preselected_action: preselected_action,
paypal_fees_url: PaypalCountryHelper.fee_link(community_country_code),
stripe_fees_url: "https://stripe.com/#{community_country_code.downcase}/pricing",
paypal_commission: paypal_tx_settings[:commission_from_seller],
stripe_commission: stripe_tx_settings[:commission_from_seller]
}
end
def paypal_tx_settings
Maybe(TransactionService::API::Api.settings.get(community_id: @current_community.id, payment_gateway: :paypal, payment_process: :preauthorize))
.select { |result| result[:success] }
.map { |result| result[:data] }
.or_else({})
end
def stripe_tx_settings
Maybe(TransactionService::API::Api.settings.get(community_id: @current_community.id, payment_gateway: :stripe, payment_process: :preauthorize))
.select { |result| result[:success] }
.map { |result| result[:data] }
.or_else({})
end
end