Payout Validator
The Payout Validator request checks whether a payout request will succeed before you debit your customer’s account or call the Transfer Money request.
It uses the same request body as the Transfer Money request, but instead of creating a transaction, it returns a validation result with details on any issues found.
Business impact
The Payout Validator request lets you confirm whether a payout will succeed before debiting your customer’s account or calling the Transfer Money request. This gives customers upfront visibility into why a transaction might fail—improving their experience and reducing support queries.
For example, you can wait to debit a customer’s account until the Payout Validator returns a success response. This prevents unnecessary debit/credit cycles and lowers operational overhead.
Differentiation
Validator responses are grouped into error categories (such as field_missing, incorrect_format, and not_allowed).
By handling errors at the category level, your integration stays compatible as new error codes and descriptions are added. This reduces long-term maintenance and ensures consistent validation behavior across requests.
Scope & control
The Validator checks more than field formats. It also validates:
- Corridor and rail rules
- Source currency configurations
- Platform limits (such as remittance thresholds and FX setup)
These validations mirror the checks performed by the Transfer Money request, so payouts that pass the validator are far less likely to fail at execution.
Development
Traditional requests often return error codes that change or expand over time. The Validator simplifies this by standardizing responses into categories, such as:
field_missing: Required field not provided.incorrect_format: Wrong regex/length/checksum.incorrect_value: Value outside allowed range.unsupported_field: Field not valid for this corridor.invalid_combination: Fields conflict.not_allowed: Client lacks entitlement.
By coding once against these categories, applications remain stable even as new error codes are introduced—reducing rework and keeping integrations consistent.
API request
POST /api/v1/client/{clientHashId}/customer/{customerHashId}/wallet/{walletHashId}/remittance/validate
Content-Type: application/json
Authorization: Bearer <token>
Responses
200 valid
{
"valid": true,
"issues": []
}
200 not valid
{
"valid": false,
"issues": [
{
"code": "field_missing",
"category": "field_missing",
"description": "Beneficiary account number is required for USD payouts",
"field": "beneficiary.account_number",
"action": "Provide a valid account number"
},
{
"code": "incorrect_format",
"category": "incorrect_format",
"description": "IBAN must be 22 characters starting with 'DE'",
"field": "beneficiary.iban",
"regex": "^[A-Z]{2}[0-9]{20}$"
}
]
}
400
{
"errors": [
{
"code": "invalid_client_hash_id",
"description": "The clientHashId provided is invalid"
}
]
}
Field definitions
| Field | Description |
|---|---|
valid |
|
issues | An array of validation findings. |
code | Category identifier (field_missing,incorrect_format). |
field | Dot-notation path to the field with the issue (beneficiary.account_number). |
description | Human-readable explanation of the issue. |
action | Recommended fix for the client or developer. |
regex | Regex pattern used for validation (optional; for developer use). |
Error categories
The Payout Validator groups errors into categories so you can handle them consistently.
- User-fixable errors: Should be surfaced to the end user, so they can correct inputs and retry.
- Config-only errors: Internal issues related to client setup or entitlements. These should not be exposed to end users; instead, route internally to support or ops teams.
| Category | When it applies | Example Issue | Client Handling | Developer Tip |
|---|---|---|---|---|
| field_missing (User-fixable) | A required field (including conditional ones) is not provided. | beneficiary.accountNumber is required for USD payouts. | Prompt the user to provide the missing field; highlight the input. | Map to your own “required field” validation so users see this inline before submission. |
| incorrect_format (User-fixable) | A field is present but fails validation for format, length, charset, or checksum. | beneficiary.accountNumber must be 22 characters starting with 'DE'. | Validate client-side and display the correct format. | Reuse regex or format hints in your form validation to avoid unnecessary server calls. |
| incorrect_value (User-fixable) | A field is correctly formatted but violates business rules (range, allowed values, corridor support). | currency EUR not supported for this route. | Show allowed values or ranges for correction. | Use Nium’s Supported Corridors request to fetch corridor and currency lists dynamically instead of hardcoding. |
| unsupported_field (User-fixable) | A field is provided but not permitted for the corridor or client configuration. | proxy_identifier not supported in US payouts. | Hide or remove this field in the client UI for the given context. | Use Nium’s Supported Corridors request to fetch mandatory/optional fields dynamically instead of hardcoding. |
| invalid_combination (User-fixable) | Fields are valid individually but conflict when used together. | Provide either bankCode or routingCode, not both. | Highlight both fields and guide the user to choose one. | Implement combination rules in client validation so users see this inline before submission. |
| not_allowed (Config-only) | Input is valid in general but blocked by entitlements, role, or client setup. | KRW payouts not enabled for this account. | Do not show this to the end user; treat as a configuration-only issue. | Flag as a config error so it’s routed to support or ops. Contact Nium Support if the feature must be enabled. |
| validation_error (Config-only) | Catch-all for issues not covered by other categories (temporary or edge-case errors). | Transaction object failed validation. | Show a generic error if needed; escalate to Nium Support if recurring. | Treat as a fallback: log for monitoring, alert ops, and raise to Nium Support if recurring. |
Integrating Payout Validator
Step 1: Call the Payout Validator request
- Send the payout request to the Payout Validator endpoint.
- Do not use the Transfer Money request to debit funds from the sender's account yet.
response = call(PayoutValidator, payoutRequest)
if response.valid == false:
handle(response.issues)
stop here
Step 2: Handle issues by category
Group errors by category rather than individual error codes.
This keeps your integration stable as Nium introduces new error codes.
for each issue in response.issues:
if issue.category in ["field_missing", "incorrect_format", "incorrect_value", "unsupported_field", "invalid_combination"]:
highlightField(issue.field, issue.description)
else if issue.category == "not_allowed":
flagInternalConfig(issue)
else:
log("Validator issue", issue)
showBanner("error", "We couldn't validate this payout.")
Step 3: If valid is true, debit funds and Transfer Money
When response.valid is true:
- Create a payout and debit the customer's account.
- Submit the payout using the Transfer Money request.
if response.valid == true:
debit(customerAccount, payout.amount)
call(TransferMoney, payoutRequest)
Best practices
- Use the Payout Validator request before debiting funds to prevent reversals.
- Log the
codefor easier debugging with Nium Support. - Cache corridor-level details: (for example, supported methods) briefly to reduce repeat validations.
- Show messages inline in the UI: for quick correction, and use banners or logs as fallback for system errors.