Outgoing Payment Field Mapping
ISO20022 pain.001.001.03 - Customer Credit Transfer Initiation
This document defines the mapping between ProBill database fields and ISO20022 XML structure for outgoing payments (utbetalningar).
1. GROUP HEADER (GrpHdr) - File Level
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| @FileID parameter | GrpHdr/MsgId | REQUIRED | String(35) | Unique message identifier for the file |
| SYSDATETIME() | GrpHdr/CreDtTm | REQUIRED | DateTime | ISO8601 format: YYYY-MM-DDTHH:MM:SS |
| COUNT all transactions | GrpHdr/NbOfTxs | REQUIRED | Integer | Total number of payment transactions in file |
| SUM(Amount) all transactions | GrpHdr/CtrlSum | REQUIRED | Decimal | Total of all transaction amounts (control sum) |
| Swedbank: \ PaymentAccount.SwedbankAgreementID \ \ Nordea: \ PaymentAccount.NordeaSignerID | GrpHdr/InitgPty/Id/OrgId/Othr/Id | REQUIRED | String(35) | Bank-specific initiating party identifier |
| Swedbank: 'BANK' \ Nordea: 'CUST' | GrpHdr/InitgPty/Id/OrgId/Othr/SchmeNm/Cd | REQUIRED | String(4) | Identification scheme code |
2. PAYMENT INFORMATION (PmtInf) - Batch Level
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| @FileID parameter | PmtInf/PmtInfId | REQUIRED | String(35) | Payment information identifier |
| Based on PayoutTypeID: \ • 'TRF' = Transfers (1,3,4) \ • 'CHK' = Money orders (2) | PmtInf/PmtMtd | REQUIRED | String(3) | Payment method code |
| COUNT in batch | PmtInf/NbOfTxs | REQUIRED | Integer | Number of transactions in this payment batch |
| SUM(Amount) in batch | PmtInf/CtrlSum | REQUIRED | Decimal | Control sum for this payment batch |
| Literal: 'NORM' | PmtInf/PmtTpInf/InstrPrty | REQUIRED | String(4) | Instruction priority (Normal) |
| Literal: 'MPNS' | PmtInf/PmtTpInf/SvcLvl/Prtry | REQUIRED | String(35) | Proprietary service level (mandatory for BG/PG) |
| Literal: 'SUPP' | PmtInf/PmtTpInf/CtgyPurp/Cd | REQUIRED | String(4) | Category purpose code (Supplier payment) |
| CONVERT(VARCHAR(12), SYSDATETIME(), 23) | PmtInf/ReqdExctnDt | REQUIRED | Date | Requested execution date: YYYY-MM-DD |
| PaymentAccount.CustomerNumber | PmtInf/Dbtr/Nm | REQUIRED | String(140) | Debtor name (company/organization name) |
| Literal: 'SE' | PmtInf/Dbtr/PstlAdr/Ctry | REQUIRED | String(2) | Debtor country code (ISO 3166-1 alpha-2) |
| Nordea: \ PaymentAccount.NordeaOrgID \ Fallback: \ PaymentAccount.PayoutOrgID | PmtInf/Dbtr/Id/OrgId/Othr/Id | REQUIRED | String(35) | Debtor organization number |
| Literal: 'BANK' | PmtInf/Dbtr/Id/OrgId/Othr/SchmeNm/Cd | REQUIRED | String(4) | Organization ID scheme code |
| REPLACE(PaymentAccount.IBAN, ' ', '') | PmtInf/DbtrAcct/Id/IBAN | CONDITIONAL | String(34) | REQUIRED if using IBAN \ Mutually exclusive with Othr/Id |
| Swedbank: \ REPLACE(PaymentAccount.OutBankgiroNumber, '-', '') \ Nordea/Others: \ REPLACE(PaymentAccount.OutPlusgiroNumber, '-', '') | PmtInf/DbtrAcct/Id/Othr/Id | CONDITIONAL | String(34) | REQUIRED if not using IBAN \ Account number (cleaned) |
| 'BBAN' (if not BG) | PmtInf/DbtrAcct/Id/Othr/SchmeNm/Cd | CONDITIONAL | String(4) | When using Othr/Id with BBAN format |
| 'BGNR' (if Bankgiro) | PmtInf/DbtrAcct/Id/Othr/SchmeNm/Prtry | CONDITIONAL | String(35) | When using Bankgiro as debtor account |
| Currency.ExternalID \ Default: 'SEK' | PmtInf/DbtrAcct/Ccy | REQUIRED | String(3) | Debtor account currency (ISO 4217) |
| PaymentAccount.BIC | PmtInf/DbtrAgt/FinInstnId/BIC | REQUIRED | String(11) | Bank Identifier Code (SWIFT) |
| Literal: 'SE' | PmtInf/DbtrAgt/FinInstnId/PstlAdr/Ctry | REQUIRED | String(2) | Bank country code |
3. CREDIT TRANSFER TRANSACTION (CdtTrfTxInf) - Per Payment
3.1 Payment Identification & Amount
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| LedgerPayout.ID | CdtTrfTxInf/PmtId/EndToEndId | REQUIRED | String(35) | Unique transaction identifier for tracking |
| Currency.ExternalID | CdtTrfTxInf/Amt/InstdAmt/@Ccy | REQUIRED | String(3) | Currency attribute (e.g., "SEK", "EUR") |
| ISNULL(LedgerPayout.CurrencyAmount, LedgerPayout.Amount) | CdtTrfTxInf/Amt/InstdAmt | REQUIRED | Decimal(18,2) | Instructed amount (use CurrencyAmount if foreign currency) |
3.2 Creditor Agent (Recipient Bank)
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| Based on PayoutTypeID: \ • 'SESBA' if PG/BG/Bank with clearing | CdtTrfTxInf/CdtrAgt/FinInstnId/ClrSysMmbId/ClrSysId/Cd | CONDITIONAL | String(5) | Swedish Banking Association clearing system |
| Based on PayoutTypeID: \ • '9900' = Bankgiro (4) \ • '9960' = Plusgiro (3) \ • 4-digit = Bank clearing (1) \ • NULL = Money order (2) | CdtTrfTxInf/CdtrAgt/FinInstnId/ClrSysMmbId/MmbId | CONDITIONAL | String(35) | Clearing member ID \ Extracted via FnPrGetClearingsNrFromAccountNr() |
3.3 Creditor (Recipient)
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| {{COALESCE( \ CustomerContactInformation.Name, \ Customer.DispName1 \ )}} | CdtTrfTxInf/Cdtr/Nm | REQUIRED | String(140) | Creditor/recipient name |
| {{ISNULL( \ CustomerContactInformation.Address, \ Customer.DispAddress \ )}} | CdtTrfTxInf/Cdtr/PstlAdr/StrtNm | CONDITIONAL | String(70) | REQUIRED for money orders (TypeID=2 only) |
| {{REPLACE( \ ISNULL( \ CustomerContactInformation.Zipcode, \ Customer.Zipcode \ ), ' ', '' \ )}} | CdtTrfTxInf/Cdtr/PstlAdr/PstCd | CONDITIONAL | String(16) | REQUIRED for money orders (TypeID=2 only) \ Spaces removed |
| {{ISNULL( \ CustomerContactInformation.City, \ Customer.City \ )}} | CdtTrfTxInf/Cdtr/PstlAdr/TwnNm | CONDITIONAL | String(35) | REQUIRED for money orders (TypeID=2 only) |
| {{COALESCE( \ Country.IsoCode, \ 'SE' \ )}} | CdtTrfTxInf/Cdtr/PstlAdr/Ctry | REQUIRED | String(2) | Creditor country code |
3.4 Creditor Account (Recipient Account)
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| Money order (TypeID=2): \ Literal: 'NOTPROVIDED' \ \ Others: \ {{FnPrCleanPayoutAccountNumber( \ COALESCE( \ BillLocation.PayoutAccount, \ Customer.PayoutAccount, \ LedgerPayout.AccountNumber \ ) \ )}} | CdtTrfTxInf/CdtrAcct/Id/Othr/Id | REQUIRED | String(34) | Recipient account number \ Cleaned of dashes, spaces, special chars \ Money orders use literal 'NOTPROVIDED' |
| 'BBAN' if Bank (1) or PG (3) | CdtTrfTxInf/CdtrAcct/Id/Othr/SchmeNm/Cd | CONDITIONAL | String(4) | Account scheme code for BBAN format |
| 'BGNR' if Bankgiro (4) | CdtTrfTxInf/CdtrAcct/Id/Othr/SchmeNm/Prtry | CONDITIONAL | String(35) | Proprietary scheme for Bankgiro |
3.5 Remittance Information (Payment Reference)
Structured Remittance (for Plusgiro/Bankgiro)
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| Swedbank: \ 'CINV' (if invoice exists) \ \ Nordea: \ 'SCOR' (if invoice exists) | Swedbank: \ CdtTrfTxInf/RmtInf/Strd/RfrdDocInf/Tp/CdOrPrtry/Cd \ \ Nordea: \ CdtTrfTxInf/RmtInf/Strd/CdtrRefInf/Tp/CdOrPrtry/Cd | OPTIONAL | String(4) | Document type code (if invoice reference provided) |
| {{COALESCE( \ CAST(Invoice.InvoiceNumber AS VARCHAR(100)), \ CAST(Invoice2.InvoiceNumber AS VARCHAR(100)), \ CAST(Payment.ReferenceID AS VARCHAR(100)) \ )}} | Swedbank: \ CdtTrfTxInf/RmtInf/Strd/RfrdDocInf/Nb \ \ Nordea: \ CdtTrfTxInf/RmtInf/Strd/CdtrRefInf/Ref | OPTIONAL | String(25/35) | Invoice/reference number \ Swedbank: max 25 chars \ Nordea: max 35 chars |
| Currency.ExternalID | CdtTrfTxInf/RmtInf/Strd/RfrdDocAmt/RmtdAmt/@Ccy | OPTIONAL | String(3) | Currency attribute for remitted amount |
| {{ISNULL( \ LedgerPayout.CurrencyAmount, \ LedgerPayout.Amount \ )}} | CdtTrfTxInf/RmtInf/Strd/RfrdDocAmt/RmtdAmt | OPTIONAL | Decimal(18,2) | Remitted document amount |
Unstructured Remittance (for Bank accounts)
| ProBill Source | ISO20022 XML Path | Required | Data Type | Notes |
|---|---|---|---|---|
| {{COALESCE( \ CAST(Invoice.InvoiceNumber AS VARCHAR(100)), \ CAST(Invoice2.InvoiceNumber AS VARCHAR(100)), \ CAST(Payment.ReferenceID AS VARCHAR(100)) \ )}} | CdtTrfTxInf/RmtInf/Ustrd | OPTIONAL | String(140) | Unstructured remittance information \ Shown only for bank account transfers |
4. PayoutTypeID Logic & Account Format Rules
Payment Type Mapping
| TypeID | Swedish Name | Description | Account Format | Special Rules |
|---|---|---|---|---|
| 1 | Kontoinsättning | Bank Account Transfer | Clearing (4 digits) + Account number | • Requires valid clearing number \ • CdtrAgt/ClrSysMmbId required \ • SchmeNm: 'BBAN' |
| 2 | Kontantutbetalning | Money Order / Check | Literal: 'NOTPROVIDED' | • REQUIRES full postal address \ • PmtMtd: 'CHK' \ • No account number needed \ • Swedbank: Separate PmtInf segment |
| 3 | Plusgiroinsättning | Plusgiro Transfer | Plusgiro number (no dashes) | • ClrSysMmbId: '9960' \ • SchmeNm: 'BBAN' \ • Structured remittance supported |
| 4 | Bankgiroinsättning | Bankgiro Transfer | Bankgiro number (no dashes) | • ClrSysMmbId: '9900' \ • SchmeNm/Prtry: 'BGNR' \ • Structured remittance supported |
| 5 | Autogiro | Direct Debit (AG) | N/A | • Handled separately \ • Uses spPrExpDirectDebitPayout \ • Not included in pain.001 file |
Account Number Cleaning Function
-- FnPrCleanPayoutAccountNumber removes: • Dashes (-) • Spaces ( ) • Slashes (/, \) • Dots (.) • Special characters Result: Pure numeric string for Swedish accounts
Clearing Number Extraction
-- FnPrGetClearingsNrFromAccountNr extracts: For Bank Accounts (TypeID=1): • First 4 digits of account number • Used in CdtrAgt/FinInstnId/ClrSysMmbId/MmbId For Plusgiro (TypeID=3): • Returns fixed value: '9960' For Bankgiro (TypeID=4): • Returns fixed value: '9900' For Money Orders (TypeID=2): • Returns NULL (not applicable)
5. Bank-Specific Variations
Swedbank Implementation
Key Differences:
- Uses SwedbankAgreementID for InitgPty identification
- Requires OutBankgiroNumber field in PaymentAccount
- Creates separate <PmtInf> segments for TRF and CHK methods:
- PmtInfId = @FileID for TRF transactions
- PmtInfId = @FileID + 1 for CHK transactions (money orders)
- Uses 'CINV' code in structured remittance (RfrdDocInf/Tp/CdOrPrtry/Cd)
- Reference number in RfrdDocInf/Nb (max 25 characters)
Required Configuration:
PaymentAccount.SwedbankAgreementID -- NOT NULL PaymentAccount.OutBankgiroNumber -- NOT NULL PaymentAccount.BIC -- NOT NULL PaymentAccount.PayoutOrgID -- NOT NULL
Nordea Implementation
Key Differences:
- Uses NordeaSignerID for InitgPty identification
- Prefers IBAN format for DbtrAcct/Id/IBAN
- Falls back to OutPlusgiroNumber/OutBankgiroNumber if no IBAN
- Uses 'SCOR' code in structured remittance (CdtrRefInf/Tp/CdOrPrtry/Cd)
- Reference number in CdtrRefInf/Ref (max 35 characters)
- Single <PmtInf> segment for all payment methods
- Optional secure envelope wrapping via spPrSecureEnvelope
Required Configuration:
PaymentAccount.NordeaSignerID -- NOT NULL PaymentAccount.NordeaSenderID -- NOT NULL (if using secure envelope) PaymentAccount.BIC -- NOT NULL PaymentAccount.IBAN -- Preferred, or fallback to PG/BG PaymentAccount.NordeaOrgID -- Preferred, or fallback to PayoutOrgID
6. Validation Rules & Business Logic
Amount Validation
✓ Amount must be > 0 ✓ Use CurrencyAmount if LedgerPayout.CurrencyID is set ✓ CtrlSum must match SUM of all transaction amounts ✓ NbOfTxs must match COUNT of all transactions
Date Handling
• ReqdExctnDt calculated with weekend adjustment: - Friday → Monday (+3 days) - Saturday → Monday (+2 days) - Sunday → Monday (+1 day) - Weekday → Next day (+N days based on AppSetting 'PayoutPlacementDateDays')
Account Number Rules
Swedish Format Requirements: • Bank: 4-digit clearing + 7-12 digit account • Plusgiro: 1-8 digits (may include control digit) • Bankgiro: 7-8 digits (format: XXXX-XXXX) • All cleaned before export (no formatting chars)
Currency Handling
Domestic (SEK): • CurrencyID = 4 (or NULL defaults to SEK) • Amount field used directly • Currency/@Ccy = 'SEK' Foreign Currency: • CurrencyID set to non-SEK currency • CurrencyAmount must be populated • Use CurrencyAmount for Amt/InstdAmt • Currency/@Ccy = Currency.ExternalID (e.g., 'EUR', 'USD')
Address Requirements for Money Orders
All three fields REQUIRED when PayoutTypeID = 2: ✓ Cdtr/PstlAdr/StrtNm (Street address) ✓ Cdtr/PstlAdr/PstCd (Postal code, no spaces) ✓ Cdtr/PstlAdr/TwnNm (Town/city name) Missing any field → Payment rejected/error logged
Reference Number Rules
Structured Remittance (PG/BG): • Swedbank: Max 25 characters in RfrdDocInf/Nb • Nordea: Max 35 characters in CdtrRefInf/Ref • Used for invoice numbers or payment references Unstructured Remittance (Bank accounts): • Max 140 characters in Ustrd • Typically shows first 12 chars in practice • Used when PayoutTypeID NOT IN (3, 4)
7. Error Handling & Status Tracking
LedgerPayout Status Flow
StatusID = 0 → Ej behandlad (Not processed)
↓
StatusID = 1 → Utbetalning skickad (Payment sent to bank)
↓
StatusID = 2 → Utbetalning utförd (Payment completed)
OR
StatusID = 3 → Utbetalning nekad (Payment rejected)
Validation Failures
When validation fails, payment is removed from batch and logged:
• ErrorData field populated with error description • StatusID remains 0 (not processed) • PrSys.ExtUpdate notified for client refresh • Examples: - "Utbetalningstyp och Konto, utbetalning ej komplett uppsatt" - "Ingen BIC i PaymentAccount" - "Inget PlusGiro, BankGiro eller IBAN i PaymentAccount"
File Generation Tracking
LedgerPayout.FileID = @FileID → Links payment to export file LedgerPayout.Handled = GETDATE() → Timestamp of export LedgerEvent.StatusID updated based on PayoutAwaitResponse setting
8. Database Tables & Relationships
Primary Tables
LedgerPayout (Main payout record)
ID INT -- Used as EndToEndId in XML LedgerEventID INT -- Link to accounting event BillLocationID INT -- Link to billing location CustomerID INT -- Link to customer Amount NUMERIC(18,2) -- Base amount (SEK) CurrencyAmount NUMERIC(18,2) -- Foreign currency amount CurrencyID SMALLINT -- Foreign currency ID TypeID INT -- PayoutTypeID (1-5) StatusID INT -- Processing status AccountNumber NVARCHAR(40) -- Recipient account Name/CareOf/Address/Zipcode/City -- Recipient address info FileID INT -- Export file reference TransactionDate DATE -- Transaction/placement date
PaymentAccount (Sender configuration)
ID INT CustomerNumber NVARCHAR(80) -- Company name (Dbtr/Nm) BIC VARCHAR(11) -- Bank BIC IBAN VARCHAR(34) -- Debtor IBAN OutPlusgiroNumber VARCHAR(20) -- Outgoing Plusgiro OutBankgiroNumber VARCHAR(50) -- Outgoing Bankgiro (NEW) PayoutOrgID VARCHAR(20) -- Organization number NordeaOrgID VARCHAR(36) -- Nordea org ID NordeaSignerID VARCHAR(50) -- Nordea signer NordeaSenderID VARCHAR(50) -- Nordea sender SwedbankAgreementID VARCHAR(35) -- Swedbank agreement CompanyGroupID INT -- Links to Company.GroupID
Customer / BillLocation (Recipient info)
-- Recipient details hierarchy: 1. CustomerContactInformation (ContactInformationTypeID=3) - Name, Address, Zipcode, City 2. Customer (fallback) - DispName1, DispAddress, Zipcode, City 3. BillLocation (account override) - PayoutAccount, PayoutTypeID
Key Relationships
LedgerPayout ├─> LedgerEvent (accounting) ├─> BillLocation (PayoutAccount override, PayoutTypeID) ├─> Customer (recipient info, PayoutAccount, PayoutTypeID) ├─> Currency (foreign currency) └─> Invoice (via LedgerEvent, for remittance info) PaymentAccount └─> Company.GroupID (multi-company support)
9. Sample SQL Query for Data Extraction
-- Example: Extract data for payment batch export SELECT -- Transaction ID lp.ID AS EndToEndId, -- Amount ISNULL(lp.CurrencyAmount, lp.Amount) AS Amount, ISNULL(cu.ExternalID, 'SEK') AS Currency, -- Recipient Info COALESCE(cci.Name, c.DispName1) AS CreditorName, COALESCE(bl.PayoutAccount, c.PayoutAccount, lp.AccountNumber) AS CreditorAccount, ISNULL(bl.PayoutTypeID, c.PayoutTypeID) AS PayoutTypeID, -- Recipient Address (for money orders) ISNULL(cci.Address, c.DispAddress) AS StreetName, REPLACE(ISNULL(cci.Zipcode, c.Zipcode), ' ', '') AS PostalCode, ISNULL(cci.City, c.City) AS TownName, COALESCE(co.IsoCode, 'SE') AS Country, -- Remittance Info COALESCE(i.InvoiceNumber, i2.InvoiceNumber, p.ReferenceID) AS Reference, -- Payment Account Info pa.CustomerNumber AS DebtorName, pa.BIC, pa.IBAN, pa.OutBankgiroNumber, pa.OutPlusgiroNumber, pa.PayoutOrgID FROM dbo.LedgerPayout lp INNER JOIN dbo.LedgerEvent le ON le.ID = lp.LedgerEventID INNER JOIN dbo.BillLocation bl ON bl.ID = lp.BillLocationID INNER JOIN dbo.V_RepCustomer c ON c.ID = lp.CustomerID INNER JOIN dbo.PaymentAccount pa ON pa.ID = @PaymentAccountID LEFT JOIN dbo.Currency cu ON cu.ID = lp.CurrencyID LEFT JOIN dbo.CustomerContactInformation cci ON cci.CustomerID = c.ID AND cci.ContactInformationTypeID = 3 AND cci.IsDeleted = 0 LEFT JOIN dbo.Country co ON co.ID = ISNULL(cci.CountryID, c.CountryID) LEFT JOIN dbo.Payment p ON p.ID = le.PaymentID LEFT JOIN dbo.Invoice i ON i.ID = le.ReferencedInvoiceID LEFT JOIN dbo.Invoice i2 ON i2.ID = p.InvoiceID WHERE lp.StatusID = 0 -- Not processed AND le.StatusID = 4 -- Approved for payout AND lp.TypeID != 5 -- Exclude Autogiro AND ISNULL(lp.CurrencyID, 4) = @CurrencyID ORDER BY lp.ID
10. Configuration Checklist
Before First Export
PaymentAccount Setup (per company/bank)
- CustomerNumber populated
- BIC code configured
- Organization number (PayoutOrgID) set
- Bank-specific IDs configured (SwedbankAgreementID or NordeaSignerID)
- At least one account number set (IBAN, OutPlusgiroNumber, or OutBankgiroNumber)
System Settings (PrSys.AppSetting)
- PayoutPlacementDateDays = Days ahead for placement (default: 0)
- PayoutAwaitResponse = Wait for bank confirmation? (0/1)
- EventForDeleteAndPayout = Create offsetting ledger events? (0/1)
Customer/BillLocation Data Quality
- PayoutTypeID set correctly (1-5)
- PayoutAccount populated when PayoutTypeID requires it
- Both fields set together (PayoutTypeID + PayoutAccount)
- Address complete for money order recipients (TypeID=2)
Currency Configuration
- Currency.ExternalID uses ISO 4217 codes (SEK, EUR, USD, etc.)
- CurrencyAmount populated when using foreign currency
- Default currency ID = 4 (SEK) in your installation
11. Reference Information
ISO20022 Message Standards
- pain.001.001.03 - Customer Credit Transfer Initiation
- Namespace: urn:iso:std:iso:20022:tech:xsd:pain.001.001.03
- Schema validation recommended before bank submission
Swedish Payment System Codes
- SESBA - Swedish Bankers' Association clearing system
- 9900 - Standard clearing code for all Bankgiro numbers
- 9960 - Standard clearing code for all Plusgiro numbers
- BBAN - Basic Bank Account Number (domestic format)
- BGNR - Bankgiro Number (proprietary Swedish format)
Contact & Support
For questions about implementation or field mapping, reference:
- ProBill stored procedure: dbo.spPrPayoutCreate
- Swedbank variant: dbo.spPrPayoutCreate_Swedbank
- Helper functions: dbo.FnPrCleanPayoutAccountNumber, dbo.FnPrGetClearingsNrFromAccountNr
Document Version: 1.0
Last Updated: 2026-01-30
Based on: ProBillDB version 2.0.4751.0+
------------------------------------------------------------------------------------------------------------------------
Incoming Payments Mapping
ProBill handles AutoGiro, TotalIN, BgMax, and Camt.054 files for incoming payments.
Autogiro (if BIS will have an AG flow):
Flow description: Flöde autogiro i ProBill.xlsx
Old file layout according to: https://www.bankgirot.se/globalassets/dokument/tekniska-manualer/autogiro_tekniskmanual_sv.pdf
Requirements Specification – CAMT.054 Payments in ProBill
Date: 2026-03-04 | Scope: Incoming payments and CAMT.054 outgoing payments. Pain.002 handling is covered by this specification above in this page.
1. Purpose and Scope
This requirements specification describes how ProBill interprets and stores payments from CAMT.054 files (ISO 20022 standard, message type BkToCstmrDbtCdtNtfctn, version camt.054.001.02).
Included:
- Identification of incoming and outgoing payment files
- Which XML tags are read
- Logic for calculating key variables (incoming payments)
- Mapping to
dbo.Payment(incoming payments) - Mapping to
dbo.LedgerPayoutResult(outgoing payments) - Error handling and status assignment (incoming payments)
2. Identification of File Type
A file is identified as CAMT.054 if the XML content contains the element name BkToCstmrDbtCdtNtfctn.
XML namespace: urn:iso:std:iso:20022:tech:xsd:camt.054.001.02
The file type is then determined by GrpHdr/AddtlInf:
| Condition | File type | Target table |
|---|---|---|
GrpHdr/AddtlInf does not contain DEBT | Incoming payment | dbo.Payment |
GrpHdr/AddtlInf contains DEBT | Outgoing payment | dbo.LedgerPayoutResult |
3. XML Structure and Tags Read
The CAMT.054 file has a hierarchical structure with three levels that are read:
Document/BkToCstmrDbtCdtNtfctn
├── GrpHdr ← Message header (one per file)
└── Ntfctn ← Notification / account (one or more per file)
├── Id
├── CreDtTm
├── Acct ← Receiver account
└── Ntry ← Transaction / entry (one or more per Ntfctn)
├── BookgDt/Dt
├── ValDt/Dt
└── NtryDtls/TxDtls ← Transaction details
├── Refs
├── AmtDtls
├── RltdPties ← Involved parties
├── Purp
├── RltdDts
└── RmtInf ← Remittance information
├── Ustrd
└── Strd ← Structured remittance (one or more)3.1 Message Header – GrpHdr
Read once per file from /Document/BkToCstmrDbtCdtNtfctn.
| XML tag | Description |
|---|---|
GrpHdr/MsgId | Unique message ID |
GrpHdr/CreDtTm | Message creation date and time |
GrpHdr/AddtlInf | Additional information. Used to distinguish incoming payments (no DEBT) from outgoing payments (DEBT present). |
3.2 Account Information – Ntfctn
Read per Ntfctn node. Represents the receiving account (seller's account).
| XML tag | Description |
|---|---|
Ntfctn/Id | Unique notification ID. Mandatory per standard. |
Ntfctn/CreDtTm | Notification creation date and time |
Ntfctn/Acct/Id/IBAN | Receiver account IBAN number |
Ntfctn/Acct/Id/Othr/Id | Receiver account BBAN (e.g. bankgiro number) |
Ntfctn/Acct/Id/Othr/SchmeNm/Cd | Account scheme code (e.g. BBAN) |
Ntfctn/Acct/Ownr/Id/OrgId/Othr/Id | Account owner organisation ID |
Note: A CAMT.054 file may contain multiple Ntfctn nodes. Each Ntfctn has a unique Id used to ensure each transaction is linked to the correct account.
3.3 Transaction Details – Ntry / TxDtls / Strd
Read per transaction. An Ntfctn can have multiple Ntry nodes, and each Ntry can have multiple TxDtls and/or Strd nodes. Transactions without a Strd element are still included (e.g. Swish payments).
| XML tag | Description |
|---|---|
Ntfctn/Ntry/BookgDt/Dt | Booking date |
Ntfctn/Ntry/ValDt/Dt | Value date |
TxDtls/Refs/AcctSvcrRef | Bank's internal transaction ID |
TxDtls/Refs/EndToEndId | End-to-end reference. Used for Swish to identify the mobile number. |
TxDtls/AmtDtls/TxAmt/Amt | Transaction amount |
TxDtls/AmtDtls/TxAmt/Amt/@Ccy | Currency code for the transaction amount (XML attribute) |
TxDtls/RltdPties/Dbtr/Nm | Payer name |
TxDtls/RltdPties/Dbtr/PstlAdr/StrtNm | Payer street address |
TxDtls/RltdPties/Dbtr/PstlAdr/PstCd | Payer postal code |
TxDtls/RltdPties/Dbtr/PstlAdr/TwnNm | Payer city |
TxDtls/RltdPties/Dbtr/Id/OrgId/Othr/Id | Payer organisation number |
TxDtls/RltdPties/DbtrAcct/Id/IBAN | Payer account number (IBAN) |
TxDtls/RltdPties/DbtrAcct/Id/Othr/Id | Payer account number (BBAN or other). Also used as Swish mobile number. |
TxDtls/RltdPties/DbtrAcct/Id/Othr/SchmeNm/Prtry | Account scheme name for payer's account |
TxDtls/RltdPties/UltmtDbtr/Nm | Ultimate debtor name (if different from Dbtr) |
TxDtls/RltdPties/UltmtDbtr/PstlAdr/StrtNm | Ultimate debtor street address |
TxDtls/RltdPties/UltmtDbtr/PstlAdr/PstCd | Ultimate debtor postal code |
TxDtls/RltdPties/UltmtDbtr/PstlAdr/TwnNm | Ultimate debtor city |
TxDtls/RltdPties/UltmtDbtr/Id/OrgId/Othr/Id | Ultimate debtor organisation number |
TxDtls/RltdPties/Cdtr/Nm | Payee (creditor) name |
TxDtls/RltdPties/CdtrAcct/Id/IBAN | Payee IBAN |
TxDtls/RltdPties/CdtrAcct/Id/Othr/Id | Payee BBAN (bankgiro) |
TxDtls/Purp/Cd | Payment purpose code. Swish: WEBI, SUPP or REFU. |
TxDtls/RltdDts/AccptncDtTm | Acceptance date/time |
TxDtls/RmtInf/Ustrd | Unstructured remittance message (free text) |
RmtInf/Strd/RfrdDocInf/Nb | Invoice number |
RmtInf/Strd/RfrdDocAmt/CdtNoteAmt | Credit note amount |
RmtInf/Strd/RfrdDocAmt/CdtNoteAmt/@Ccy | Currency for credit note amount (XML attribute) |
RmtInf/Strd/RfrdDocAmt/RmtdAmt | Remitted amount (actual amount paid) |
RmtInf/Strd/RfrdDocAmt/RmtdAmt/@Ccy | Currency for remitted amount (XML attribute) |
RmtInf/Strd/CdtrRefInf/Ref | OCR reference |
RmtInf/Strd/AddtlRmtInf | Additional remittance information. May appear multiple times – all repetitions are concatenated. Used for Swish payments (contains OrderID:). |
4. Logic for Key Variables
4.1 Swish Identification (IsSwish)
A payment is classified as Swish (IsSwish = 1) if both of the following conditions are met:
Condition 1 – Prerequisite: TxDtls/Refs/EndToEndId is NOT NULL
Condition 2 – At least one of:
| Check | XML source | Condition |
|---|---|---|
| Free text contains order ID | RmtInf/Strd/AddtlRmtInf | Contains the string 'OrderID:' |
| Purpose code is a Swish code | TxDtls/Purp/Cd | Is one of: WEBI, SUPP, REFU |
If EndToEndId is NULL, IsSwish = 0 is always returned.
4.2 ReferenceID
| Priority | Source | Comment |
|---|---|---|
| 1 | RmtInf/Strd/CdtrRefInf/Ref | OCR reference |
| 2 | RmtInf/Strd/RfrdDocInf/Nb | Invoice number |
| 3 | Extracted from RmtInf/Strd/AddtlRmtInf | Only if IsSwish = 1: text between 'OrderID: ' and '-' |
| 4 | RmtInf/Strd/AddtlRmtInf (if not Swish) | Used as reference if none of the above are present |
| 5 | RmtInf/Ustrd | Unstructured message as last resort |
4.3 Amount
| Priority | Source | Comment |
|---|---|---|
| 1 | RmtInf/Strd/RfrdDocAmt/RmtdAmt | Remitted amount – actual payment |
| 2 | - + RmtInf/Strd/RfrdDocAmt/CdtNoteAmt | Credit note stored with negative sign |
| 3 | TxDtls/AmtDtls/TxAmt/Amt | Transaction amount |
| 4 | 0 | Fallback |
4.4 EntryDate
EntryDate = Ntfctn/Ntry/BookgDt/Dt (NULL if empty)
4.5 PaymentDate
| Priority | Source |
|---|---|
| 1 | TxDtls/RltdDts/AccptncDtTm |
| 2 | Ntfctn/Ntry/ValDt/Dt |
| 3 | Ntfctn/Ntry/BookgDt/Dt |
5. Incoming Payments – Mapping to dbo.Payment
| Column | XML source / Logic |
|---|---|
FileID | File ID (link to source file) |
Created | Ntfctn/CreDtTm – converted to DATETIME2. Fallback: 1900-01-01. |
SellerReference | Ntfctn/Acct/Ownr/Id/OrgId/Othr/Id |
SellerAccount | IBAN prefixed with [IBAN], otherwise BBAN prefixed with scheme code |
EntryDate | See §4.4. Fallback: 1900-01-01. |
PaymentDate | See §4.5. Fallback: 1900-01-01. |
ArchiveID | TxDtls/Refs/AcctSvcrRef |
ReferenceID | See §4.2. Only if numeric – otherwise NULL. |
Comment | (1) Non-numeric reference value, (2) Swish: 'Swish från mobilnummer 0' + mobile number, (3) otherwise NULL |
OCRMessage | RmtInf/Strd/AddtlRmtInf – raw additional info. NULL if empty. |
PayeeName | UltmtDbtr/Nm if present, otherwise Dbtr/Nm |
PayeeAddress | UltmtDbtr/PstlAdr/StrtNm if present, otherwise Dbtr/PstlAdr/StrtNm |
PayeeZipCode | UltmtDbtr/PstlAdr/PstCd if present, otherwise Dbtr/PstlAdr/PstCd. Spaces removed. |
PayeeCity | UltmtDbtr/PstlAdr/TwnNm if present, otherwise Dbtr/PstlAdr/TwnNm |
PayeeOrgNumber | UltmtDbtr/Id/OrgId/Othr/Id if present, otherwise Dbtr/Id/OrgId/Othr/Id |
PaymentAccount | (1) CdtrAcct/Id/IBAN, (2) CdtrAcct/Id/Othr/Id, (3) fallback to SellerAccount |
PayeeAccount | (1) [IBAN] + DbtrAcct/Id/IBAN, (2) scheme + DbtrAcct/Id/Othr/Id, (3) DbtrAcct/Id/Othr/Id |
Amount | See §4.3. NOT NULL. |
Currency | RmtdAmt/@Ccy → CdtNoteAmt/@Ccy → TxAmt/@Ccy |
CurrencyID | Lookup on currency code |
ReturnMaterialCode | NULL |
RecordCode | 6 if IsSwish = 1, otherwise 3 |
CorrectionCode | 0 (fixed) |
SourceID | 1 if debt collection/post-watch account, otherwise 0 |
ErrorID | See §6.1 |
StatusID | See §6.2 |
Handled | See §6.3 |
6. Incoming Payments – Error Handling and Status Assignment
6.1 ErrorID – Error Code
| Priority | Condition | ErrorID | Description |
|---|---|---|---|
| 1 | ReferenceID missing/non-numeric and Amount = 0 | 1 | Invoice not found |
| 2 | ReferenceID missing or non-numeric | 6 | Incorrect reference number |
| 3 | Amount = 0 | 38 | Unreasonable amount |
| 4 | SellerAccount is a post-watch account | 8 | Post-watch |
| 5 | EntryDate missing | 43 | Booking date missing |
| 6 | PaymentDate missing | 44 | Payment date missing |
| 7 | No errors | NULL | – |
6.2 StatusID – Status
| Condition | StatusID | Status |
|---|---|---|
| ReferenceID missing/non-numeric, or Amount = 0, or EntryDate missing, or PaymentDate missing | 2 | Error |
| None of the above | 0 | New |
6.3 Handled – Direct Flagging
Records with an identified error are marked as handled immediately upon import (Handled = current timestamp). Records are flagged immediately if: ReferenceID is missing/non-numeric, Amount = 0, EntryDate is missing, or PaymentDate is missing. All other records are left unflagged (Handled = NULL).
7. Outgoing Payments – Mapping to dbo.LedgerPayoutResult
7.1 Identification
A record is treated as an outgoing payment if GrpHdr/AddtlInf contains the string DEBT.
7.2 Link to LedgerPayout
The outgoing payment is linked via TxDtls/Refs/EndToEndId cast as integer → matched against LedgerPayout.ID. CustomerID is retrieved from the matching record.
7.3 Mapping
| Column | XML source / Logic |
|---|---|
FileID | File ID (link to source file) |
Inserted | Current timestamp at import |
Handled | NULL on INSERT |
StatusID | 2 (= Payout executed) |
FileDate | Ntfctn/CreDtTm – converted to DATETIME |
PayerAccount | Ntfctn/Acct/Id/IBAN if present, otherwise Ntfctn/Acct/Id/Othr/Id |
Reason | NULL |
Amount | (1) RmtdAmt, (2) -CdtNoteAmt, (3) TxAmt/Amt |
PayoutDate | ValDt/Dt if present, otherwise BookgDt/Dt |
Name | TxDtls/RltdPties/Cdtr/Nm |
PayeeAccount | CdtrAcct/Id/IBAN if present, otherwise CdtrAcct/Id/Othr/Id |
PayoutID | TxDtls/Refs/EndToEndId cast as integer |
CustomerID | Retrieved from matching LedgerPayout record via PayoutID |
7.4 Post-processing
After INSERT, each outgoing payment record is marked as handled (Handled = current timestamp). If outgoing payment records were inserted, a subsequent process for result handling is triggered.
Based on existing implementation in ProBill version: 2.0.4833.0. XML standard: ISO 20022 camt.054.001.02.