130 lines
4.2 KiB
Ruby
130 lines
4.2 KiB
Ruby
class Contributions::DonationsController < ApplicationController
|
|
include BtcpayHelper
|
|
|
|
before_action :authenticate_user!
|
|
before_action :set_donation_methods, only: [:index, :create]
|
|
before_action :require_donation_method_enabled, only: [:create]
|
|
before_action :validate_donation_params, only: [:create]
|
|
before_action :set_donation, only: [:confirm_btcpay]
|
|
|
|
# GET /contributions/donations
|
|
def index
|
|
@current_section = :contributions
|
|
@donations_completed = current_user.donations.completed.order('paid_at desc')
|
|
@donations_pending = current_user.donations.processing.order('created_at desc')
|
|
|
|
if Setting.lndhub_enabled?
|
|
begin
|
|
lndhub_authenticate
|
|
lndhub_fetch_balance
|
|
rescue
|
|
@balance = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
# POST /contributions/donations
|
|
def create
|
|
if params[:currency] == "sats"
|
|
fiat_amount = nil
|
|
fiat_currency = nil
|
|
amount_sats = params[:amount]
|
|
else
|
|
fiat_amount = params[:amount].to_i
|
|
fiat_currency = params[:currency]
|
|
amount_sats = nil
|
|
end
|
|
|
|
@donation = current_user.donations.create!(
|
|
donation_method: params[:donation_method],
|
|
payment_method: nil,
|
|
paid_at: nil,
|
|
amount_sats: amount_sats,
|
|
fiat_amount: (fiat_amount.nil? ? nil : fiat_amount * 100), # store in cents
|
|
fiat_currency: fiat_currency,
|
|
public_name: params[:public_name]
|
|
)
|
|
|
|
case params[:donation_method]
|
|
when "btcpay"
|
|
res = BtcpayManager::CreateInvoice.call(
|
|
amount: fiat_amount || (amount_sats.to_f / 100000000),
|
|
currency: fiat_currency || "BTC",
|
|
redirect_url: confirm_btcpay_contributions_donation_url(@donation)
|
|
)
|
|
|
|
@donation.update! btcpay_invoice_id: res["id"]
|
|
|
|
redirect_to btcpay_checkout_url(res["id"]), allow_other_host: true
|
|
else
|
|
redirect_to contributions_donations_url, flash: {
|
|
error: "Donation method currently not available"
|
|
}
|
|
end
|
|
end
|
|
|
|
def confirm_btcpay
|
|
redirect_to contributions_donations_url and return if @donation.completed?
|
|
|
|
invoice = BtcpayManager::FetchInvoice.call(invoice_id: @donation.btcpay_invoice_id)
|
|
|
|
if @donation.amount_sats.present?
|
|
# TODO make default fiat currency configurable and/or determine from user's
|
|
# i18n browser settings
|
|
@donation.fiat_currency = "EUR"
|
|
exchange_rate = BtcpayManager::FetchExchangeRate.call(fiat_currency: @donation.fiat_currency)
|
|
@donation.fiat_amount = (((@donation.amount_sats.to_f / 100000000) * exchange_rate) * 100).to_i
|
|
else
|
|
amt_str = invoice["paymentMethods"].first["amount"]
|
|
@donation.amount_sats = amt_str.tr(".","").sub(/0*$/, "").to_i
|
|
end
|
|
|
|
case invoice["status"]
|
|
when "Settled"
|
|
@donation.paid_at = DateTime.now
|
|
@donation.payment_status = "settled"
|
|
@donation.save!
|
|
flash_message = { success: "Thank you!" }
|
|
when "Processing"
|
|
unless @donation.processing?
|
|
@donation.payment_status = "processing"
|
|
@donation.save!
|
|
flash_message = { success: "Thank you! We will send you an email when the payment is confirmed." }
|
|
BtcpayCheckDonationJob.set(wait: 20.seconds).perform_later(@donation)
|
|
end
|
|
when "Expired"
|
|
flash_message = { warning: "The payment request for this donation has expired" }
|
|
else
|
|
flash_message = { warning: "Could not determine status of payment" }
|
|
end
|
|
|
|
redirect_to contributions_donations_url, flash: flash_message
|
|
end
|
|
|
|
private
|
|
|
|
def set_donation
|
|
@donation = current_user.donations.find_by(id: params[:id])
|
|
http_status :not_found unless @donation.present?
|
|
end
|
|
|
|
def set_donation_methods
|
|
@donation_methods = []
|
|
@donation_methods.push :btcpay if Setting.btcpay_enabled?
|
|
@donation_methods.push :lndhub if Setting.lndhub_enabled?
|
|
@donation_methods.push :opencollective if Setting.opencollective_enabled?
|
|
end
|
|
|
|
def require_donation_method_enabled
|
|
http_status :forbidden unless @donation_methods.include?(
|
|
params[:donation_method].to_sym
|
|
)
|
|
end
|
|
|
|
def validate_donation_params
|
|
if !%w[EUR USD sats].include?(params[:currency]) || (params[:amount].to_i <= 0)
|
|
http_status :unprocessable_entity
|
|
end
|
|
end
|
|
end
|