Verified Pay-ins

Verify the source of funds and allow your user to pay in a single flow

Verified Pay-ins checks that the person paying owns the bank account they pay from.

  • You send the customer's full name to Lean.
  • Lean compares it with the account holder name the bank returns.
  • On a match, the payment goes ahead. On a mismatch, Lean stops the flow and sends you a webhook.
Payment typeStatus
Account-on-File (AoF)Available
Single Instant Payments (SIP)Coming soon
📘

Opt-in feature

Verified Pay-ins is enabled per application by Lean. It is priced as pay-ins plus name verification. Contact your Account Manager to turn it on and agree your matching threshold.


Verified Pay-ins with Account-on-File

Lean verifies the name once per consent, when the customer authorises it. Payments made later under an authorised consent are not verified again.

Before you start

Step 1 — Pass the account holder name

Send full_name in one of these places:

{
  "app_user_id": "user_001",
  "full_name": "Jane Doe"
}
🚧

The stored name takes priority

If the customer already has a full_name, Lean keeps it and ignores the full_name sent at consent creation. To change it, use PUT /customers/v1/{customer_id}.

{
  "full_name": "Jane Mary Doe"
}

Step 2 — Create and authorise the consent

Create the AoF consent as usual. You can add immediate_payment to take the first payment in the same flow.

{
  "customer_id": "acc176ca-7716-4fbb-a735-d0e3dec24b40",
  "destination_account_id": "911f30d8-8fc8-4fe9-86a1-3f9fea11a674",
  "currency": "AED",
  "reference": "ACME-ACCOUNT-LINK-001",
  "purpose": "GDS",
  "full_name": "Jane Doe",
  "control_parameters": {
    "type": "VariableOnDemand",
    "period_type": "Day",
    "max_individual_amount": 1000
  },
  "immediate_payment": {
    "amount": 250.00,
    "reference": "ACME-FIRST-PAYMENT-001"
  }
}

Then launch the consent authorisation flow as described in Integrating Account-on-file Payments. Your SDK integration stays the same.

Step 3 — Handle the verification outcome

After the customer authorises the consent at their bank, Lean checks the name and sends a consent.status.updated webhook.

Outcomestatusgranular_status_codeWhat happens
Name matchesAUTHORISED—The consent is active. Any immediate_payment is initiated.
Name does not matchREJECTEDACCOUNT_OWNERSHIP_MISMATCHLean revokes the consent at the bank. No payment is initiated.
{
  "type": "consent.status.updated",
  "message": "A payment consent has been updated.",
  "payload": {
    "id": "f8668fb8-62fa-4dae-b8a6-ac6a5d5a88eb",
    "status": "REJECTED",
    "granular_status_code": "ACCOUNT_OWNERSHIP_MISMATCH",
    "customer_id": "69b33353-79f8-42ca-9bfe-a3d742cc353c",
    "consent_type": "PAYMENT",
    "updated_at": "2026-10-07T14:17:34.342847Z"
  },
  "timestamp": "2026-10-07T14:17:35.691593783Z",
  "event_id": "cce42859-055b-4271-b4c0-b94d54a3b894"
}
❗️

Handling a mismatch

  • A rejected consent can't be reused. Create a new consent to try again.
  • If your stored name was wrong, update it with PUT /customers/v1/{customer_id} before you retry.
  • Show the customer a clear message, e.g. "We could not verify that this account is in your name. Please try again with an account you own."

Step 4 — Initiate payments

Once the consent is AUTHORISED, initiate payments with POST /payments/v1/account-on-file as usual. These payments are not verified again.


Verified Pay-ins with Single Instant Payments

📘

Coming soon

Verified Pay-ins for SIP is in development. This section will be updated at launch.


Related pages


Did this page help you?