SkillAgentSearch skills...

Bank4j

Generates ISO 20022 Payment Initiation XML messages and provides IBAN and BIC validation

Install / Use

/learn @inisos/Bank4j
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

License: MIT

bank4j

Easily generate XML Credit Transfers based on ISO 20022 Payments Initiation (pain):

  • pain.001.001.03
  • pain.001.001.03.ch.02
  • pain.001.001.09
  • pain.001.003.03

Provides IBAN, BIC and Character set (for reference elements) validation with annotations.

Using JAXB and iban4j.

Installation


<dependency>
    <groupId>io.inisos.bank4j</groupId>
    <artifactId>bank4j</artifactId>
    <version>4.1.0</version>
</dependency>
  • Use version 3+ for jarkarta.* dependencies (Java 11, JAXB 3+, Bean Validation 3+)
  • Use version 2 for javax.* dependencies (Java 8, JAXB 2, Bean Validation 2)

Usage

Validation

class MyRecord {
    
    @IBAN
    private String iban;

    @BIC
    private String bic;
    
    @Iso20022CharacterSet
    private String reference;
    
}

Only accepts valid IBAN, BIC8/BIC11 and valid ISO 20022 patterns.

Generation of XML messages

For Payments Initiation, simply provide bank account details and transactions.

Minimal example with V09 (omitted optional fields):

import io.inisos.bank4j.Bank;

import java.time.ZonedDateTime;

import static io.inisos.bank4j.CustomerCreditTransferInitiationVersion.V09;

class MyApp {

    public static void main(String... args) {

        // Debtor account
        BankAccount debtorAccount = Bank.simpleBankAccount()
                .iban("FR7610011000201234567890188") // IBAN
                .build();

        // Transactions
        Transaction transaction1 = Bank.simpleTransaction()
                .account(Bank.simpleBankAccount()   // Creditor account
                        .iban("FR7630001007941234567890185") // IBAN
                        .build())
                .amount("12.34")                                // Amount, converted to BigDecimal
                .currency("EUR")                                // Currency code
                .endToEndId("Transfer reference 1")             // End-to-end identifier
                .build();

        // Transfer
        CreditTransferOperation creditTransfer = Bank.jaxbCreditTransferSepa(V09) // version 09
                .debtorAccount(debtorAccount)                                // Mandatory debtor account
                .transaction(transaction1)                                   // At least 1 transaction
                .requestedExecutionDateTime(ZonedDateTime.now()              // Optional requested execution date and time,
                        .plusDays(1)                                         // defaults to tomorrow
                        .withSecond(0)
                        .withNano(0))                                        
                .build();

        // export to string
        String formattedOutput = creditTransfer.marshal(true); // true: enables formatting

        // or export to file
        creditTransfer.marshal(new FileWriter("myFile.xml")); // default: disables formatting
    }
}

Output with formatting:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
    <CstmrCdtTrfInitn>
        <GrpHdr>
            <MsgId>20251002092807</MsgId>
            <CreDtTm>2025-10-02T09:28:07.3573245</CreDtTm>
            <NbOfTxs>1</NbOfTxs>
            <CtrlSum>12.34</CtrlSum>
            <InitgPty/>
        </GrpHdr>
        <PmtInf>
            <PmtInfId>20251002092807</PmtInfId>
            <PmtMtd>TRF</PmtMtd>
            <BtchBookg>false</BtchBookg>
            <NbOfTxs>1</NbOfTxs>
            <CtrlSum>12.34</CtrlSum>
            <PmtTpInf>
                <SvcLvl>
                    <Cd>SEPA</Cd>
                </SvcLvl>
            </PmtTpInf>
            <ReqdExctnDt>
                <DtTm>2025-10-03T09:30:00+02:00</DtTm>
            </ReqdExctnDt>
            <Dbtr/>
            <DbtrAcct>
                <Id>
                    <IBAN>FR7610011000201234567890188</IBAN>
                </Id>
            </DbtrAcct>
            <DbtrAgt>
                <FinInstnId/>
            </DbtrAgt>
            <ChrgBr>SLEV</ChrgBr>
            <CdtTrfTxInf>
                <PmtId>
                    <EndToEndId>Transfer reference 1</EndToEndId>
                </PmtId>
                <Amt>
                    <InstdAmt Ccy="EUR">12.34</InstdAmt>
                </Amt>
                <Cdtr/>
                <CdtrAcct>
                    <Id>
                        <IBAN>FR7630001007941234567890185</IBAN>
                    </Id>
                </CdtrAcct>
            </CdtTrfTxInf>
        </PmtInf>
    </CstmrCdtTrfInitn>
</Document>

Eg. with V03 and optional fields:

import io.inisos.bank4j.Bank;

class MyApp {

    public static void main(String... args) {

        // Optional debtor identification
        Party debtor = Bank.simpleParty()
                .name("Debtor Name") // Optional name
                .build();

        // Debtor account
        BankAccount debtorAccount = Bank.simpleBankAccount()
                .iban("FR7610011000201234567890188") // IBAN
                .bic("PSSTFRPP")                     // Optional BIC
                .build();

        // Transactions
        Transaction transaction1 = Bank.simpleTransaction()
                .party(Bank.simpleParty()           // Optional creditor identification
                        .name("BANQUE DE FRANCE")                 // Optional name
                        .postalAddress(Bank.simplePostalAddress() // Optional postal address
                                .addressLine("1, rue de La Vrillière")
                                .addressLine("75001 PARIS")
                                .country("FR")
                                .build())
                        .build())
                .account(Bank.simpleBankAccount()   // Creditor account
                        .iban("FR7630001007941234567890185") // IBAN
                        .bic("BDFEFRPP")                     // Optional BIC
                        .build())
                .amount("12.34")                                // Amount, converted to BigDecimal
                .currency("EUR")                                // Currency code
                .endToEndId("Transfer reference 1")             // End to end identifier
                .id("Optional identifier 1")                    // Optional Transaction identifier
                .chargeBearer(ChargeBearer.CRED)                // Optional charge bearer code defines who is bearing the charges of the transfer
                .batchBooking(true)                             // Optional batch booking, defaults to false
                .remittanceInformationUnstructured("Your remittance information")   // Unstructured Remittance Information 
                .build();
        Transaction transaction2 = Bank.simpleTransaction()
                .party(Bank.simpleParty()           // Optional creditor identification
                        .name("Creditor Name")               // Optional name
                        .build())
                .account(Bank.simpleBankAccount()   // Creditor account
                        .otherId("1234567890")               // Other identification
                        .bic("BDFEFRPP")                     // BIC
                        .build())
                .amount(new BigDecimal("56.78"))    // Amount as BigDecimal
                .currency("EUR")                    // Currency code
                .endToEndId("Transfer reference 2") // End to end identifier
                .id("Optional identifier 2")        // Optional transaction identifier
                .chargeBearerCode(ChargeBearer.DEBT)   // Optional charge bearer code defines who is bearing the charges of the transfer
                .intermediaryAgent(Bank.simpleBankAccount() // Optional intermediary agent 1
                        .name("BNP PARIBAS")                 // Optional name
                        .otherId("12345")                    // Optional other identification
                        .bic("BNPAFRPP")                     // Optional BIC
                        .build())
                .intermediaryAgent(Bank.simpleBankAccount() // Optional intermediary agent 2
                        .name("BNP PARIBAS")                 // Optional name
                        .otherId("67890")                    // Optional other identification
                        .bic("BNPAFRPP")                     // Optional BIC
                        .build())
                .intermediaryAgent(Bank.simpleBankAccount() // Optional intermediary agent 3
                        .name("BNP PARIBAS")                 // Optional name
                        .otherId("00000")                    // Optional other identification
                        .bic("BNPAFRPP")                     // Optional BIC
                        .build())
                .build();

        // Transfer
        CreditTransferOperation creditTransfer = Bank.jaxbCreditTransferSepa() // defaults to V03
                .instructionPriority(Priority.HIGH)                  // Optional instruction priority
                .debtor(debtor)                                      // Optional debtor
                .debtorAccount(debtorAccount)                        // Mandatory debtor account
                .transaction(transaction1)                           // At least 1 transaction
                .transaction(transaction2)                           // Optional additional transaction
                .creationDateTime(LocalDateTime.now())               // Optional message creation date and time, defaults to now
                .requestedExecutionDate(LocalDate.now().plusDays(1)) // Optional requested execution date, defaults to tomorrow
                .id("MYID")                              
View on GitHub
GitHub Stars17
CategoryDevelopment
Updated1mo ago
Forks9

Languages

Java

Security Score

95/100

Audited on Feb 18, 2026

No findings