app/services/payments/processors/sepa.rb
# frozen_string_literal: true
module Payments
module Processors
class Sepa < Payments::Processor
def process_batch(orders_batch:, admin:)
@direct_debit = SEPA::DirectDebit.new(Settings.payments.processors.sepa.main)
return :aborted unless yield
form = DownloadForm.new(
person_id: orders_batch.processed_by.person_id,
file: { filename: "#{orders_batch.description.underscore}.xml", content: @direct_debit.to_xml, content_type: "application/xml" },
expires_at: Settings.payments.processors.sepa.file_lifespan.hours.from_now,
orders_batches: [orders_batch]
)
ret = :ok
::Downloads::CreateDownload.call(form: form, admin: admin) do
on(:invalid) { ret = :error }
on(:error) { ret = :error }
on(:ok) { ret = :ok }
end
ret
end
def process_order(order:, admin:)
decorated_order = order.decorate(context: { current_admin: admin })
@direct_debit.add_transaction(
name: debtor(decorated_order), # Name of the debtor (<= 70 chars)
iban: decorated_order.payment_method.iban, # International Bank Account Number of the debtor's account (<= 34 chars)
bic: decorated_order.payment_method.bic, # Business Identifier Code (SWIFT-Code) of the debtor's account (8 or 11 chars, optional)
amount: format_amount(decorated_order), # Amount, number with two decimal digit
currency: decorated_order.currency, # Currency (ISO 4217 standard, 3 chars)
instruction: internal_reference(decorated_order), # Instruction Identification, will not be submitted to the debtor (<= 35 chars, optional)
reference: internal_reference(decorated_order), # End-To-End-Identification, will be submitted to the debtor (<= 35 chars, optional)
remittance_information: decorated_order.description, # Unstructured remittance information, (<= 140 chars, optional)
mandate_id: format_order_id(decorated_order), # Mandate identification (<= 35 chars)
mandate_date_of_signature: decorated_order.date, # Mandate Date of signature
local_instrument: "CORE", # Local instrument ("CORE", "COR1" or "B2B")
sequence_type: sequence_type(decorated_order.payment_method) # Sequence type ("FRST", "RCUR", "OOFF" or "FNAL")
)
processed_order order: order, admin: admin, response_code: "OK"
end
private
def sequence_type(payment_method)
if payment_method.verified?
"RCUR"
else
"FRST"
end
end
def format_amount(order)
1.0 * order.amount / Settings.payments.fractions_per_unit
end
def debtor(order)
order.person.full_name
end
def internal_reference(order)
"#{order.date}-#{order.id.to_s.rjust(12, "0")}"
end
end
end
end