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#

  1. Payment Request with VOP: Include "execute_verification_of_payee": true in your payment initiation request

  2. Name Verification: The system checks the provided payee name against the account holder name

  3. 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 request

  • match_result: One of "match", "close-match", or "no-match"

  • match_name: (optional) The actual name found for the account holder

  • confidence_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 to true to enable VOP verification. Defaults to false.

VOP Confirmation#

  • payment_initialization_id: The ID returned from the initial VOP payment request

Request Headers#

Same as standard payment initiation:

  • Host: Must be psd2.holvi.com

  • Date: Must follow the format described in section 7.1.1.1 of RFC 7231

  • Digest: See authentication documentation for more details

  • Signature: See authentication documentation for more details

  • X-Holvi-Client-Id: Client ID provided by Holvi

  • X-Holvi-Client-Secret: Client secret provided by Holvi

  • Authorization: JWT token to authenticate

Status Codes#

Payment Initiation with VOP#

  • 201: Payment created successfully (perfect match or VOP disabled)

  • 202: VOP verification requires user confirmation

  • 400: VOP verification failed or invalid request

  • 401: Unsuccessful authentication

  • 403: Insufficient permissions

  • 503: Service unavailable

VOP Confirmation#

  • 201: Payment confirmed and created successfully

  • 401: Unsuccessful authentication

  • 403: Insufficient permissions

  • 404: Payment initialization not found or not in confirmable state

  • 503: 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#

  1. Performance: VOP adds an additional verification step, which may increase payment initiation time by 1-2 seconds

  2. User Experience: For fuzzy matches, implement a clear UI showing the expected vs. actual payee names

  3. Confidence Scores: Use confidence scores to implement different thresholds for automatic acceptance vs. user confirmation

  4. Audit Trail: All VOP requests are logged with unique request UUIDs for audit purposes