
🚨 The Problem with Standard Personal Payment Methods
In Oracle Fusion HCM, the Personal Payment Method (PPM) page is where employees add or update their salary bank account details.
While it includes built-in IBAN validation, it is missing two critical controls:
- 📎 Attachments – No option to upload supporting documents like a No Objection Certificate (NOC)
- ✅ Approvals – No workflow to route changes for review before they go live

This means employees can change bank details without oversight, creating compliance, fraud prevention, and payroll accuracy risks.
💡 The Challenge with Custom Pages
When you create a custom page for bank account changes using Document of Records (DoR), you can introduce attachments and approvals.
However, you lose the standard IBAN validation available in the PPM page.
The challenge was:
How can we deliver all three – Attachments, IBAN Validation and Approvals – in a single, seamless process inside Oracle Fusion?
🛠️ Our Workaround: One Solution, Three Fixes
We designed a solution that combines Document of Records, custom JavaScript IBAN validation, and a loopback integration to update the standard PPM page.
1️⃣ Attachments (via DoR)
We created a document type called Change Bank Account in DoR, allowing employees to:
- View their current bank account in read-only mode
- Enter new IBAN and bank details
- Upload the NOC from their bank using the standard DoR attachment functionality

Click to Enlarge Images for Detailed Insight
2️⃣ Approvals (via DoR)
Using DoR’s standard approval workflow, the request is routed automatically to the appropriate Area of Responsibility (AOR) approvers before any changes are applied.
3️⃣ IBAN Validation (Custom)
Since DoR does not support built-in IBAN checks, we added JavaScript-based validation in Visual Builder Studio to validate IBAN before submission.
Steps to Add JavaScript IBAN Validation to the DoR Page
- Open Visual Builder Studio
- Navigate to the Visual Builder project linked to your Oracle HCM environment.

Click to Enlarge Images for Detailed Insight
- Locate the DoR task flow or custom page containing your Change Bank Account form.

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight
- Identify the IBAN Field
- Locate the custom DFF field created in the DoR document type for IBAN entry.
- Note its technical field name for the script.

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight
- Add a Validation Rule
- Open the Rule Editor for the IBAN field.
- Create a new Condition rule to run before submission.

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight

Click to Enlarge Images for Detailed Insight
- Insert the JavaScript Code
- Paste the IBAN validation JavaScript code into the rule, adjusting the field reference if required.
/* eslint-disable dot-notation */
define([], () => {
'use strict';
function runCondition(context) {
const { $fields } = context;
const IBAN_SPECS = {
AE: {
length: 23,
regex: /^[0-9]{19}$/,
bank: {
pos: 0,
len: 3,
codes: new Set([
'003','009','011','015','020','021','023','024','025',
'026','033','034','035','038','040','041','043','044',
'047','049','050','053','055','086','091','096'
])
}
},
AL: { length: 28, regex: /^[0-9]{8}[A-Z0-9]{16}$/ },
AD: { length: 24, regex: /^[0-9]{8}[A-Z0-9]{12}$/ },
AT: { length: 20, regex: /^[0-9]{16}$/ },
AZ: { length: 28, regex: /^[A-Z]{4}[A-Z0-9]{20}$/ },
BH: { length: 22, regex: /^[A-Z]{4}[A-Z0-9]{14}$/ },
BE: { length: 16, regex: /^[0-9]{12}$/ },
BA: { length: 20, regex: /^[0-9]{16}$/ },
BR: { length: 29, regex: /^[0-9]{23}[A-Z][A-Z0-9]$/ },
BG: { length: 22, regex: /^[A-Z]{4}[0-9]{6}[A-Z0-9]{8}$/ },
CR: { length: 21, regex: /^[0-9]{17}$/ },
HR: { length: 21, regex: /^[0-9]{17}$/ },
CY: { length: 28, regex: /^[0-9]{8}[A-Z0-9]{16}$/ },
CZ: { length: 24, regex: /^[0-9]{20}$/ },
DK: { length: 18, regex: /^[0-9]{14}$/ },
DO: { length: 28, regex: /^[A-Z]{4}[0-9]{20}$/ },
EE: { length: 20, regex: /^[0-9]{16}$/ },
FI: { length: 18, regex: /^[0-9]{14}$/ },
FR: { length: 27, regex: /^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$/ },
GE: { length: 22, regex: /^[A-Z]{2}[0-9]{16}$/ },
DE: { length: 22, regex: /^[0-9]{18}$/ },
GI: { length: 23, regex: /^[A-Z]{4}[A-Z0-9]{15}$/ },
GR: { length: 27, regex: /^[0-9]{7}[A-Z0-9]{16}$/ },
GL: { length: 18, regex: /^[0-9]{14}$/ },
GT: { length: 28, regex: /^[A-Z0-9]{4}[A-Z0-9]{20}$/ },
HU: { length: 28, regex: /^[0-9]{24}$/ },
IS: { length: 26, regex: /^[0-9]{22}$/ },
IE: { length: 22, regex: /^[A-Z]{4}[0-9]{14}$/ },
IL: { length: 23, regex: /^[0-9]{19}$/ },
IT: { length: 27, regex: /^[A-Z][0-9]{10}[A-Z0-9]{12}$/ },
JO: { length: 30, regex: /^[A-Z]{4}[0-9]{4}[A-Z0-9]{18}$/ },
KZ: { length: 20, regex: /^[0-9]{3}[A-Z0-9]{13}$/ },
KW: { length: 30, regex: /^[A-Z]{4}[0-9]{22}$/ },
LV: { length: 21, regex: /^[A-Z]{4}[A-Z0-9]{13}$/ },
LB: { length: 28, regex: /^[0-9]{4}[A-Z0-9]{20}$/ },
LI: { length: 21, regex: /^[0-9]{5}[A-Z0-9]{12}$/ },
LT: { length: 20, regex: /^[0-9]{16}$/ },
LU: { length: 20, regex: /^[0-9]{3}[A-Z0-9]{13}$/ },
MT: { length: 31, regex: /^[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$/ },
MR: { length: 27, regex: /^[0-9]{23}$/ },
MU: { length: 30, regex: /^[A-Z]{4}[0-9]{2}[0-9]{2}[A-Z0-9]{16}[A-Z]{3}$/ },
MD: { length: 24, regex: /^[A-Z0-9]{2}[A-Z0-9]{18}$/ },
MC: { length: 27, regex: /^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$/ },
ME: { length: 22, regex: /^[0-9]{18}$/ },
NL: { length: 18, regex: /^[A-Z]{4}[0-9]{10}$/ },
NO: { length: 15, regex: /^[0-9]{11}$/ },
PK: { length: 24, regex: /^[A-Z]{4}[0-9]{16}$/ },
PS: { length: 29, regex: /^[A-Z]{4}[0-9]{21}$/ },
PL: { length: 28, regex: /^[0-9]{24}$/ },
PT: { length: 25, regex: /^[0-9]{21}$/ },
QA: { length: 29, regex: /^[A-Z]{4}[A-Z0-9]{21}$/ },
RO: { length: 24, regex: /^[A-Z]{4}[A-Z0-9]{16}$/ },
SM: { length: 27, regex: /^[A-Z][0-9]{10}[A-Z0-9]{12}$/ },
SA: { length: 24, regex: /^[0-9]{2}[A-Z0-9]{18}$/ },
RS: { length: 22, regex: /^[0-9]{18}$/ },
SK: { length: 24, regex: /^[0-9]{20}$/ },
SI: { length: 19, regex: /^[0-9]{15}$/ },
ES: { length: 24, regex: /^[0-9]{20}$/ },
SE: { length: 24, regex: /^[0-9]{20}$/ },
CH: { length: 21, regex: /^[0-9]{5}[A-Z0-9]{12}$/ },
TN: { length: 24, regex: /^[0-9]{20}$/ },
TR: { length: 26, regex: /^[0-9]{5}[0-9][A-Z0-9]{16}$/ },
GB: { length: 22, regex: /^[A-Z]{4}[0-9]{14}$/ },
VG: { length: 24, regex: /^[A-Z]{4}[0-9]{16}$/ }
};
let input = $fields.documentRecords.documentRecordsDFF.ibanNumber.$value();
if (!input) return true;
const iban = input.replace(/[^A-Za-z0-9]/g, '').toUpperCase();
const country = iban.slice(0, 2);
const spec = IBAN_SPECS[country];
if (!spec || iban.length !== spec.length) return true;
const bban = iban.slice(4);
if (!spec.regex.test(bban)) return true;
if (country === 'AE') {
const code = bban.substr(spec.bank.pos, spec.bank.len);
if (!spec.bank.codes.has(code)) return true;
}
const rearr = bban + iban.slice(0, 4);
let remainder = 0;
for (let ch of rearr) {
const num = /[A-Z]/.test(ch) ? ch.charCodeAt(0) - 55 : ch;
for (let digit of num.toString()) {
remainder = (remainder * 10 + +digit) % 97;
}
}
return remainder !== 1;
}
return { runCondition };
});

Click to Enlarge Images for Detailed Insight
- Save and Publish
- Save changes in Visual Builder Studio.
- Redeploy the updated DoR page to your target environment.
- Test the Validation
- Enter an invalid IBAN → Error message displays, blocking submission.
- Enter a valid IBAN → Form allows submission.

Click to Enlarge Images for Detailed Insight



🔁 Updating the Standard PPM Page
Once approved, an HCM Extract loopback integration runs every 6 to 8 hours to:
- Pick up approved DoR records
- Update the standard PPM page with the new bank details
- Apply Oracle’s native backend validations before committing the change
🎯 Key Benefits of This Workaround
- 📎 Attachments for compliance with NOC requirement
- ✅ Approvals for control before applying changes
- 🧠 Custom IBAN validation to prevent incorrect bank details
- 🔄 Seamless sync with standard PPM backend
- 🌍 Scalable for multiple countries and IBAN formats
🏢 Best Fit For
| Industry | Why It Matters |
|---|---|
| BFSI | Strengthens payment security and fraud prevention |
| Government | Creates an audit trail for sensitive payroll data |
| Manufacturing | Controls bank changes during site transfers |
| IT Services | Meets compliance for remote and multi-country payroll |
🏁 Final Thoughts
By combining Document of Records, custom IBAN validation, and loopback integration, we addressed three major limitations in one go.
This low-effort, high-impact workaround gives HR and payroll teams full control over bank account changes in Oracle Fusion, while retaining the benefits of the standard PPM page.






Leave a Reply