diff --git a/Gemfile b/Gemfile index 34c26d262..5fff1dbdd 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,9 @@ gem 'impressionist', github: 'charlotte-ruby/impressionist' # rests calls for mailgun gem 'rest-client' +# mollie +gem 'mollie-api-ruby' + gem 'responders' # pagination diff --git a/Gemfile.lock b/Gemfile.lock index 679b14960..8f2b3933a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,6 +179,7 @@ GEM mini_mime (1.1.2) mini_portile2 (2.7.1) minitest (5.15.0) + mollie-api-ruby (4.13.0) netrc (0.11.0) nio4r (2.5.8) nokogiri (1.13.1) @@ -352,6 +353,7 @@ DEPENDENCIES impressionist! listen mimemagic (= 0.3.9) + mollie-api-ruby pagy pg pg_search diff --git a/app/controllers/members/payments_controller.rb b/app/controllers/members/payments_controller.rb index 04238f40a..18adbbc22 100644 --- a/app/controllers/members/payments_controller.rb +++ b/app/controllers/members/payments_controller.rb @@ -35,10 +35,10 @@ def pay_activities redirect_to(member_payments_path) return end + payment = Payment.new( description: description, amount: amount, - issuer: transaction_params[:bank], member: member, payment_type: :ideal, transaction_id: unpaid.pluck(:activity_id), @@ -97,13 +97,12 @@ def add_funds description: description, amount: amount, member: member, - issuer: transaction_params[:bank], payment_type: :ideal, - transaction_id: nil, transaction_type: :checkout, redirect_uri: member_payments_path ) + if payment.save redirect_to(payment.payment_uri) else @@ -115,6 +114,6 @@ def add_funds private def transaction_params - params.permit(:amount, :bank, :activity_ids, :payment_type) + params.permit(:amount, :activity_ids, :payment_type) end end diff --git a/app/models/payment.rb b/app/models/payment.rb index 4ea4ad10f..012809283 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -1,7 +1,5 @@ #:nodoc: class Payment < ApplicationRecord - require 'request' - self.primary_key = :token attr_accessor :issuer, :payment_uri, :message @@ -12,6 +10,7 @@ class Payment < ApplicationRecord validates :payment_type, presence: true enum status: { failed: 0, in_progress: 1, successful: 2 } + # Keep payconiq_online because it is still present in the database enum payment_type: { ideal: 0, payconiq_online: 1, pin: 3 } enum transaction_type: { checkout: 0, activity: 1 } @@ -26,6 +25,7 @@ class Payment < ApplicationRecord after_validation :request_payment, on: :create include PgSearch::Model + pg_search_scope :search_by_name, against: [:trxid], associated_against: { @@ -47,7 +47,6 @@ def request_payment case payment_type.to_sym when :ideal - http = ConstipatedKoala::Request.new(ENV['MOLLIE_DOMAIN']) self.token = Digest::SHA256.hexdigest("#{ member.id }#{ Time.now.to_f }#{ redirect_uri }") webhook_url = if Rails.env.development? @@ -55,30 +54,21 @@ def request_payment else Rails.application.routes.url_helpers.mollie_hook_url end - - request = http.post("/#{ ENV['MOLLIE_VERSION'] }/payments", - amount: amount, - description: description, - - method: 'ideal', - issuer: issuer, - - metadata: { - member: member.name, - transaction_type: transaction_type, - transaction_id: transaction_id - - }, - webhookUrl: webhook_url, - redirectUrl: Rails.application.routes.url_helpers.payment_redirect_url(token: token)) - - request['Authorization'] = "Bearer #{ ENV['MOLLIE_TOKEN'] }" - response = http.send!(request) - - self.trxid = response.id - self.payment_uri = response.links.paymentUrl + redirect_url = Rails.application.routes.url_helpers.payment_redirect_url(token: token) + + payment = Mollie::Payment.create( + amount: { value: format('%.2f', amount), currency: 'EUR' }, + method: 'ideal', # only ideal for now + description: description, + webhook_url: webhook_url, + redirect_url: redirect_url + ) + + self.trxid = payment.id + self.payment_uri = payment._links['checkout']['href'] self.status = :in_progress - # pin payment shouldn't have any extra work + + # pin payment shouldn't have any extra work when :pin end end @@ -86,15 +76,11 @@ def request_payment def update_transaction! case payment_type.to_sym when :ideal - http = ConstipatedKoala::Request.new(ENV['MOLLIE_DOMAIN']) @status = status - request = http.get("/#{ ENV['MOLLIE_VERSION'] }/payments/#{ trxid }") - request['Authorization'] = "Bearer #{ ENV['MOLLIE_TOKEN'] }" - - response = http.send!(request) + payment = Mollie::Payment.get(trxid) - status_update(response.status) + status_update(payment.status) save! @@ -156,21 +142,6 @@ def transaction_fee end end - def self.ideal_issuers - # cache the payment issuers for 12 hours, don't request it to often. Stored in tmp/cache - return [] if ENV['MOLLIE_TOKEN'].blank? - - Rails.cache.fetch('mollie_issuers', expires_in: 12.hours) do - http = ConstipatedKoala::Request.new(ENV['MOLLIE_DOMAIN']) - - request = http.get("/#{ ENV['MOLLIE_VERSION'] }/issuers") - request['Authorization'] = "Bearer #{ ENV['MOLLIE_TOKEN'] }" - - response = http.send!(request) - response.data.map { |issuer| [issuer.name, issuer.id] } - end - end - def activities Activity.find(transaction_id) if activity? end @@ -178,10 +149,10 @@ def activities private def status_update(new_status) - self.status = case new_status.downcase - when "succeeded", "paid" + self.status = case new_status + when "paid", "authorized" :successful - when "expired", "canceled", "failed", "cancelled", "authorization_failed" + when "expired", "failed", "canceled" :failed else :in_progress diff --git a/app/views/members/payments/index.html.haml b/app/views/members/payments/index.html.haml index 6caacf8c5..a22d943d5 100644 --- a/app/views/members/payments/index.html.haml +++ b/app/views/members/payments/index.html.haml @@ -42,13 +42,10 @@ %tr %td %td - .ideal-activities - = I18n.t("members.payments.unpaid_activity.footer.bank") - .float-xl-right= f.select :bank, options_for_select(Payment::ideal_issuers), {}, {style: '', class:'ideal-activities'} %td %div = I18n.t("members.payments.unpaid_activity.footer.transactioncosts") - %span.transaction_cost_activities.ideal-activities{:price =>@transaction_costs}= number_to_currency(@transaction_costs, :unit => '€') + %span.transaction_cost_activities.ideal-activities{:price => @transaction_costs}= number_to_currency(@transaction_costs, :unit => '€') %tr %td %td diff --git a/config/application.rb b/config/application.rb index 46a103944..ba0381127 100644 --- a/config/application.rb +++ b/config/application.rb @@ -75,3 +75,8 @@ class Application < Rails::Application config.middleware.use(I18n::JS::Middleware) end end + +# Mollie configuration +Mollie::Client.configure do |config| + config.api_key = ENV['MOLLIE_TOKEN'] +end diff --git a/gemset.nix b/gemset.nix index 9de9c6cf0..25b4447d8 100644 --- a/gemset.nix +++ b/gemset.nix @@ -713,6 +713,16 @@ }; version = "5.15.0"; }; + mollie-api-ruby = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0z4z0cf5lq3bmdbjsdzjj2spvg351b32nzwrn9rf3zqm9rldai6w"; + type = "gem"; + }; + version = "4.13.0"; + }; netrc = { groups = ["default"]; platforms = []; diff --git a/sample.env b/sample.env index abeb5472b..d5afb53aa 100644 --- a/sample.env +++ b/sample.env @@ -76,8 +76,6 @@ MAILCHIMP_TEACHER_ID= NGROK_HOST=http # MOLLIE credentials for the iDEAL integration. -MOLLIE_DOMAIN=https://api.mollie.nl -MOLLIE_VERSION=v1 MOLLIE_TOKEN= # Secret for error reporting.