Verification of Payee (VOP)#
Verification of Payee (VOP) is an optional security feature that allows TPPs to verify that the payee name matches the account holder name before initiating a payment. This helps prevent payment fraud and misdirected payments.
When VOP is enabled for a payment initiation request, the system will check the provided payee name against the actual account holder name for the given IBAN. Based on the verification result, the payment may proceed automatically (for exact matches) or require explicit user confirmation (for fuzzy matches or no matches).
Note
VOP functionality requires authentication and the same headers as regular payment initiation. See the authentication documentation for the full list of required headers.
How VOP Works#
Payment Request with VOP: Include
"execute_verification_of_payee": truein your payment initiation requestName Verification: The system checks the provided payee name against the account holder name
Match Results:
Perfect Match: Payment proceeds automatically
Fuzzy Match/No Match: Payment requires user confirmation via a separate endpoint
POST /api/v2/payment-initiation/ with VOP#
To enable VOP verification, include the execute_verification_of_payee parameter in your payment request.
Example request with VOP enabled:
POST /api/v2/payment-initiation/ HTTP/1.1
Accept: application/json
Authorization: Bearer testJWTAccessToken
{
"payment_account": "b06d5478-0954-451a-a1e0-f1eeb25336be",
"amount": "100.00",
"unstructured_reference": "Concert ticket",
"execute_verification_of_payee": true,
"counterparty": {
"name": "John Doe",
"account_identifier": "FI7979977991294922",
"bic": "HOLVFIHH"
}
}
Perfect Match Response#
When the payee name perfectly matches the account holder name, the payment proceeds normally:
HTTP/1.1 201 CREATED
Vary: Accept
Content-Type: application/json
{
"uuid": "b923d102-127e-449a-a216-960836a229c5",
"amount": "100.00",
"currency": "EUR",
"method": "sepa",
"booking_date": null,
"due_date": null,
"execution_at": null,
"state": "unverified",
"direction": "out",
"is_credit": null,
"structured_reference": "",
"unstructured_reference": "Concert ticket",
"end_to_end_id": "",
"counterparty": {
"name": "John Doe",
"bic": "HOLVFIHH",
"account_identifier": "FI7979977991294922",
"account_identifier_type": "iban"
}
}
Fuzzy Match/No Match Response#
When the payee name doesn’t perfectly match, you’ll receive a different response requiring confirmation:
HTTP/1.1 202 ACCEPTED
Vary: Accept
Content-Type: application/json
{
"payment_initialization_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"vop_result": {
"request_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"match_result": "close-match",
"match_name": "Jon Doe",
"confidence_score": 0.85
},
"requires_confirmation": true
}
VOP Result Fields:
request_uuid: Unique identifier for the VOP verification requestmatch_result: One of"match","close-match", or"no-match"match_name: (optional) The actual name found for the account holderconfidence_score: (optional) Numeric confidence score for fuzzy matches
POST /api/v2/payment-initiation/{payment_initialization_id}/confirm-vop#
When VOP returns a fuzzy match or no match, use this endpoint to confirm and proceed with the payment after user review.
Example request:
POST /api/v2/payment-initiation/a1b2c3d4-e5f6-7890-abcd-ef1234567890/confirm-vop HTTP/1.1
Accept: application/json
Authorization: Bearer testJWTAccessToken
Example response:
HTTP/1.1 201 CREATED
Vary: Accept
Content-Type: application/json
{
"uuid": "b923d102-127e-449a-a216-960836a229c5",
"amount": "100.00",
"currency": "EUR",
"method": "sepa",
"booking_date": null,
"due_date": null,
"execution_at": null,
"state": "unverified",
"direction": "out",
"is_credit": null,
"structured_reference": "",
"unstructured_reference": "Concert ticket",
"end_to_end_id": "",
"counterparty": {
"name": "John Doe",
"bic": "HOLVFIHH",
"account_identifier": "FI7979977991294922",
"account_identifier_type": "iban"
}
}
Parameters#
Payment Initiation with VOP#
All standard payment initiation parameters apply, plus:
<boolean>execute_verification_of_payee: (optional) Set totrueto enable VOP verification. Defaults tofalse.
VOP Confirmation#
payment_initialization_id: The ID returned from the initial VOP payment request
Request Headers#
Same as standard payment initiation:
Host: Must bepsd2.holvi.comDate: Must follow the format described in section 7.1.1.1 of RFC 7231Digest: See authentication documentation for more detailsSignature: See authentication documentation for more detailsX-Holvi-Client-Id: Client ID provided by HolviX-Holvi-Client-Secret: Client secret provided by HolviAuthorization: JWT token to authenticate
Status Codes#
Payment Initiation with VOP#
201: Payment created successfully (perfect match or VOP disabled)202: VOP verification requires user confirmation400: VOP verification failed or invalid request401: Unsuccessful authentication403: Insufficient permissions503: Service unavailable
VOP Confirmation#
201: Payment confirmed and created successfully401: Unsuccessful authentication403: Insufficient permissions404: Payment initialization not found or not in confirmable state503: Service unavailable
Error Handling#
VOP Service Errors#
When the VOP service is unavailable or returns an error:
HTTP/1.1 400 BAD REQUEST
Vary: Accept
Content-Type: application/json
{
"error": "VOP verification failed",
"details": "VOP service unavailable: Connection timeout"
}
Missing Required Fields#
VOP requires both payee name and IBAN. If either is missing:
HTTP/1.1 400 BAD REQUEST
Vary: Accept
Content-Type: application/json
{
"error": "VOP verification failed",
"details": "Missing payee name or IBAN for VOP"
}
Implementation Notes#
Performance: VOP adds an additional verification step, which may increase payment initiation time by 1-2 seconds
User Experience: For fuzzy matches, implement a clear UI showing the expected vs. actual payee names
Confidence Scores: Use confidence scores to implement different thresholds for automatic acceptance vs. user confirmation
Audit Trail: All VOP requests are logged with unique request UUIDs for audit purposes