---
title: Enforce payment password uniqueness
summary: Rejects a candidate payment password that matches either the currently stored payment password or the user's login password.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Security.SystemUser
reference_type: package
operation_id: OP-SU-10
trigger: Caller calls clsSystemUser.IsUniquePaymentPWD(inPaymentPwd, inPlatform)
---

# Enforce payment password uniqueness

`IsUniquePaymentPWD` guards against a user setting their payment password to the same value as either their existing payment password or their AD login password. It composes [Validate payment password](validate-payment-password.md) with a live authentication attempt to check the login-password condition.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-SU-10 |
| **Trigger** | Caller calls `clsSystemUser.IsUniquePaymentPWD(inPaymentPwd, inPlatform)` |
| **Inputs** | `inPaymentPwd` candidate payment password; `inPlatform` a `clsSecurityPrincipal.Platform` value used to construct a temporary authentication context |
| **Outputs** | `Boolean` uniqueness result |
| **Primary components** | `clsSystemUser.IsUniquePaymentPWD(...)`, `clsSystemUser.CheckPaymentPWD(...)`, `clsSecurityPrincipal` |
| **Entry point** | `Business\SAIF.Business.Security.SystemUser\clsSystemUser.vb` |

## Steps

1. **Check against the stored payment password.** `isUnique` is initialized by negating the result of [Validate payment password](validate-payment-password.md) (`Not CheckPaymentPWD(inPaymentPwd)`) — a match against the stored payment password immediately makes the candidate non-unique ([BR-009](../business-rules.md#br-009-payment-passwords-must-differ-from-the-stored-payment-password)).
2. **Short-circuit on a payment-password match.** If step 1 already found the candidate matches the stored payment password (`isUnique = False`), the login-password check in the next step is skipped entirely.
3. **Check against the login password.** If `isUnique` is still `True`, the method constructs a temporary `clsSecurityPrincipal(inPlatform)`, sets its `Domain` to the current object's domain, its `UserName` to the current `UserID`, and its `Password` to the candidate payment password.
4. **Attempt authentication.** The temporary principal's `IsAuthenticated` result is evaluated. A successful authentication means the candidate payment password also works as the login password, so `isUnique` is set to `Not tempSecPrinc.IsAuthenticated` ([BR-010](../business-rules.md#br-010-payment-passwords-must-differ-from-the-login-password)).
5. **Discard the temporary principal.** `tempSecPrinc` is set to `Nothing` after the authentication attempt.
6. **Return the outcome.** The method returns `isUnique` — `True` only when the candidate matches neither the stored payment password nor the login password.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Caller calls IsUniquePaymentPWD]) --> CheckPay[CheckPaymentPWD candidate]
	CheckPay --> PayMatch{Matches stored payment password?}
	PayMatch -->|Yes| NotUnique([Return False - matches payment password])
	PayMatch -->|No| BuildPrinc[Build temporary clsSecurityPrincipal with candidate as password]
	BuildPrinc --> Auth[Attempt IsAuthenticated]
	Auth --> LoginMatch{Authenticated as login password?}
	LoginMatch -->|Yes| NotUniqueLogin([Return False - matches login password])
	LoginMatch -->|No| Unique([Return True - unique])
```

## Failure and edge-case behavior

- The login-password check performs a live authentication attempt against the directory using the candidate as a password; this has the same latency and dependency characteristics as a normal login and will fail closed (non-unique treated as `False`... actually returns unique `True`) only when authentication genuinely does not succeed.*
- If the payment-password check alone already disqualifies the candidate, the method never attempts the authentication call — the two checks are not always both executed.
- The temporary `clsSecurityPrincipal` construction depends on `inPlatform` being a valid value recognized by the framework; an unsupported platform value's effect on the authentication attempt is not defined in this method.**

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources

- `Business\SAIF.Business.Security.SystemUser\clsSystemUser.vb`
