We love building payment applications! So after developing the DTAUS library for Ruby we move on with SEPA.
This gem implements the following two messages out of the ISO 20022 standard:
- Credit Transfer Initiation (
pain.001.003.03
,pain.001.002.03
andpain.001.001.03
) - Direct Debit Initiation (
pain.008.003.02
,pain.008.002.02
andpain.008.001.02
)
It handles the Specification of Data Formats v3.3 (2019-11-17).
BTW: pain is a shortcut for Payment Initiation.
- Ruby 2.7 or newer
- ActiveModel 4.2 or newer (including 7.0)
gem install sepa_king
How to create the XML for Direct Debit Initiation (in German: "Lastschriften")
# First: Create the main object
sdd = SEPA::DirectDebit.new(
# Name of the initiating party and creditor, in German: "Auftraggeber"
# String, max. 70 char
name: 'Gläubiger GmbH',
# OPTIONAL: Business Identifier Code (SWIFT-Code) of the creditor
# String, 8 or 11 char
bic: 'BANKDEFFXXX',
# International Bank Account Number of the creditor
# String, max. 34 chars
iban: 'DE87200500001234567890',
# Creditor Identifier, in German: Gläubiger-Identifikationsnummer
# String, max. 35 chars
creditor_identifier: 'DE98ZZZ09999999999'
)
# Second: Add transactions
sdd.add_transaction(
# Name of the debtor, in German: "Zahlungspflichtiger"
# String, max. 70 char
name: 'Zahlemann & Söhne GbR',
# OPTIONAL: Business Identifier Code (SWIFT-Code) of the debtor's account
# String, 8 or 11 char
bic: 'SPUEDE2UXXX',
# International Bank Account Number of the debtor's account
# String, max. 34 chars
iban: 'DE21500500009876543210',
# Amount
# Number with two decimal digit
amount: 39.99,
# OPTIONAL: Currency, EUR by default (ISO 4217 standard)
# String, 3 char
currency: 'EUR',
# OPTIONAL: Instruction Identification, will not be submitted to the debtor
# String, max. 35 char
instruction: '12345',
# OPTIONAL: End-To-End-Identification, will be submitted to the debtor
# String, max. 35 char
reference: 'XYZ/2013-08-ABO/6789',
# OPTIONAL: Unstructured remittance information, in German "Verwendungszweck"
# String, max. 140 char
remittance_information: 'Vielen Dank für Ihren Einkauf!',
# Mandate identifikation, in German "Mandatsreferenz"
# String, max. 35 char
mandate_id: 'K-02-2011-12345',
# Mandate Date of signature, in German "Datum, zu dem das Mandat unterschrieben wurde"
# Date
mandate_date_of_signature: Date.new(2011,1,25),
# Local instrument, in German "Lastschriftart"
# One of these strings:
# 'CORE' ("Basis-Lastschrift")
# 'COR1' ("Basis-Lastschrift mit verkürzter Vorlagefrist")
# 'B2B' ("Firmen-Lastschrift")
local_instrument: 'CORE',
# Sequence type
# One of these strings:
# 'FRST' ("Erst-Lastschrift")
# 'RCUR' ("Folge-Lastschrift")
# 'OOFF' ("Einmalige Lastschrift")
# 'FNAL' ("Letztmalige Lastschrift")
sequence_type: 'OOFF',
# OPTIONAL: Requested collection date, in German "Fälligkeitsdatum der Lastschrift"
# Date
requested_date: Date.new(2013,9,5),
# OPTIONAL: Enables or disables batch booking, in German "Sammelbuchung / Einzelbuchung"
# True or False
batch_booking: true
# OPTIONAL: Use a different creditor account
# CreditorAccount
creditor_account: SEPA::CreditorAccount.new(
name: 'Creditor Inc.',
bic: 'RABONL2U',
iban: 'NL08RABO0135742099',
creditor_identifier: 'NL53ZZZ091734220000'
)
# OPTIONAL: Specify the country & address of the debtor (REQUIRED for SEPA debits outside of EU. The individually required fields depend on the target country)
debtor_address: SEPA::DebtorAddress.new(
country_code: 'CH',
# Not required if individual fields are used
address_line1: 'Mustergasse 123a',
address_line2: '1234 Musterstadt'
# Not required if address_line1 and address_line2 are used
street_name: 'Mustergasse',
building_number: '123a',
post_code: '1234',
town_name: 'Musterstadt'
)
)
sdd.add_transaction ...
# Last: create XML string
xml_string = sdd.to_xml # Use schema pain.008.001.02
xml_string = sdd.to_xml('pain.008.002.02') # Use schema pain.008.002.02
How to create the XML for Credit Transfer Initiation (in German: "Überweisungen")
# First: Create the main object
sct = SEPA::CreditTransfer.new(
# Name of the initiating party and debtor, in German: "Auftraggeber"
# String, max. 70 char
name: 'Schuldner GmbH',
# OPTIONAL: Business Identifier Code (SWIFT-Code) of the debtor
# String, 8 or 11 char
bic: 'BANKDEFFXXX',
# International Bank Account Number of the debtor
# String, max. 34 chars
iban: 'DE87200500001234567890'
)
# Second: Add transactions
sct.add_transaction(
# Name of the creditor, in German: "Zahlungsempfänger"
# String, max. 70 char
name: 'Telekomiker AG',
# OPTIONAL: Business Identifier Code (SWIFT-Code) of the creditor's account
# String, 8 or 11 char
bic: 'PBNKDEFF370',
# International Bank Account Number of the creditor's account
# String, max. 34 chars
iban: 'DE37112589611964645802',
# Amount
# Number with two decimal digit
amount: 102.50,
# OPTIONAL: Currency, EUR by default (ISO 4217 standard)
# String, 3 char
currency: 'EUR',
# OPTIONAL: Instruction Identification, will not be submitted to the creditor
# String, max. 35 char
instruction: '12345',
# OPTIONAL: End-To-End-Identification, will be submitted to the creditor
# String, max. 35 char
reference: 'XYZ-1234/123',
# OPTIONAL: Unstructured remittance information, in German "Verwendungszweck"
# String, max. 140 char
remittance_information: 'Rechnung vom 22.08.2013',
# OPTIONAL: Requested execution date, in German "Ausführungstermin"
# Date
requested_date: Date.new(2013,9,5),
# OPTIONAL: Enables or disables batch booking, in German "Sammelbuchung / Einzelbuchung"
# True or False
batch_booking: true,
# OPTIONAL: Urgent Payment
# One of these strings:
# 'SEPA' ("SEPA-Zahlung")
# 'URGP' ("Taggleiche Eilüberweisung")
service_level: 'URGP'
# OPTIONAL: Unstructured information to indicate the purpose of the payment
# String, max. 4 char
category_purpose: 'SALA',
# OPTIONAL: Specify the country & address of the creditor (REQUIRED for SEPA debits outside of EU. The individually required fields depend on the target country)
creditor_address: SEPA::CreditorAddress.new(
country_code: 'CH',
# Not required if individual fields are used
address_line1: 'Mustergasse 123a',
address_line2: '1234 Musterstadt'
# Not required if address_line1 and address_line2 are used
street_name: 'Mustergasse',
building_number: '123a',
post_code: '1234',
town_name: 'Musterstadt'
)
)
sct.add_transaction ...
# Last: create XML string
xml_string = sct.to_xml # Use schema pain.001.001.03
xml_string = sct.to_xml('pain.001.002.03') # Use schema pain.001.002.03
You can rely on our internal validations, raising errors when needed, during message creation. To validate your models holding SEPA related information (e.g. BIC, IBAN, mandate_id) you can use our validator classes or rely on some constants.
Examples:
class BankAccount < ActiveRecord::Base
# IBAN validation, by default it validates the attribute named "iban"
validates_with SEPA::IBANValidator, field_name: :iban_the_terrible
# BIC validation, by default it validates the attribute named "bic"
validates_with SEPA::BICValidator, field_name: :bank_bic
end
class Payment < ActiveRecord::Base
validates_inclusion_of :sepa_sequence_type, in: SEPA::DirectDebitTransaction::SEQUENCE_TYPES
# Mandate ID validation, by default it validates the attribute named "mandate_id"
validates_with SEPA::MandateIdentifierValidator, field_name: :mandate_id
end
Beware: The SEPA::IBANValidator is strict - e.g. it does not allow any spaces in the IBAN.
Also see:
https://github.com/salesking/sepa_king/releases
https://github.com/salesking/sepa_king/graphs/contributors
Released under the MIT license
Copyright (c) 2013-2022 Georg Leciejewski (SalesKing), Georg Ledermann (https://github.com/ledermann)