-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpayment.rb
More file actions
93 lines (71 loc) · 2.85 KB
/
Copy pathpayment.rb
File metadata and controls
93 lines (71 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class Payment < ApplicationRecord
# See: https://github.com/rails/rails/issues/31234#issuecomment-446629054
# Because of the open enum-state a payment needs to be able to be in (Mollie requirement),
# we're undefining #open before defining it with the enum.
class << self
undef_method :open
end
# See: https://docs.mollie.com/payments/status-changes
enum :status, { open: 0, pending: 1, paid: 2, failed: 3, canceled: 4, expired: 5 }
COMPLETE_STATUSES = %w[paid failed canceled expired].freeze
belongs_to :user, optional: true
belongs_to :invoice, optional: true
validates :status, presence: true
validates :amount, presence: true
validate :user_xor_invoice
validate :user_amount
validate :invoice_amount
scope :not_completed, -> { where.not(status: COMPLETE_STATUSES) }
after_save :process_complete_payment!
def completed?
COMPLETE_STATUSES.include?(status)
end
def self.create_with_mollie(description, attributes = nil)
obj = create(attributes)
return obj unless obj.valid?
mollie_payment = Mollie::Payment.create(
amount: { value: format('%<amount>.2f', amount: attributes[:amount]), currency: 'EUR' },
description:,
redirect_url: "http://#{Rails.application.config.x.sofia_host}/payments/#{obj.id}/callback"
)
obj.update(mollie_id: mollie_payment.id)
obj
end
def mollie_payment
Mollie::Payment.get(mollie_id)
end
def process_complete_payment!
return unless status_previously_was != 'paid' && status == 'paid'
process_user! if user
process_invoice! if invoice
end
def process_user!
mutation = CreditMutation.create(user:,
amount:,
description: 'iDEAL inleg', created_by: user)
UserCreditMailer.new_credit_mutation_mail(mutation).deliver_later
end
def process_invoice!
CreditMutation.create(user: invoice.user,
amount:,
description: "Betaling factuur #{invoice.human_id}", created_by: invoice.user)
invoice.update(status: 'paid')
InvoiceMailer.invoice_paid(invoice).deliver_later
end
private
def user_xor_invoice
errors.add(:payment, 'must belong to a user xor invoice') unless user.present? ^ invoice.present?
end
def user_amount
return unless user
min_amount = Rails.application.config.x.min_payment_amount
max_amount = 1000
errors.add(:amount, "must be bigger than or equal to €#{format('%.2f', min_amount)}") unless amount && (amount >= min_amount)
errors.add(:amount, "must be less than or equal to €#{format('%.2f', max_amount)}") unless amount && (amount <= max_amount)
end
def invoice_amount
return unless invoice
min_amount = 1
errors.add(:amount, "must be bigger than or equal to €#{format('%.2f', min_amount)}") unless amount && (amount >= min_amount)
end
end