Account Verifier
Account Verifier asks the card network whether the name you send matches the name the issuing bank has on file for the card (Visa and Mastercard Account Name Inquiry). It runs before the charge. When the bank says the name does not match, Paysio refuses the charge and no money moves.
Use it to stop people paying with a card that is not theirs, including a card that belongs to someone they know.
Turn it on
Go to Settings > Checkout > Card processing and switch on Account Verifier. The same switch covers hosted checkout, Quick Checkout and API charges. With the switch off, no check runs, whatever names you send.
What your integration has to do
The check compares the card against the name you send. Paysio does not make one up. Your server must:
- Send
first_nameandlast_nameon everyPOST /chargescall, including charges on a saved card (customer_idorpayment_method_id). Withoutlast_nameno check runs and the charge goes through unchecked. - Take the name from a source you trust, such as your own KYC or identity record, not from a field the buyer can edit. If the buyer can type any name, they can type the name on the card.
- Send the buyer's own
email(orcustomer_id). Each customer is identified by email, and the result of a check is stored per customer. See How results are reused.
POST /charges
{
"payment_token": "ptok_...", // or customer_id + payment_method_id for a saved card
"amount": 2999,
"email": "[email protected]",
"first_name": "Jane", // from your verified record
"last_name": "Smith", // from your verified record
"billing_address_1": "1 Main St",
"billing_city": "Austin",
"billing_state": "TX",
"billing_postal_code": "78701",
"billing_country": "US"
}Reading the result
Every POST /charges response carries data.name_check, whether the charge was approved (201) or declined (402). GET /transactions/:id returns the same object later, so a webhook handler can read it too.
"name_check": {
"status": "partial_match",
"blocked": false,
"card_verified": true,
"network_reference": "382017561234567"
}statusstring- The network's answer. Always one of the seven values in the table below.
blockedbooleantrueonly when Paysio refused the charge because of this check. Today that happens forno_matchonly.card_verifiedboolean | null- Whether the card is open and valid, from the same inquiry.
nullwhen the network did not say. network_referencestring | null- The card network's own id for the inquiry. Quote it as evidence when you respond to a chargeback.
name_check is null when no check ran: Account Verifier is off, the charge had no last_name, or it was not a card charge (an ACH debit, for example).
Every status
| status | Meaning | What happens to the charge | What to do |
|---|---|---|---|
| match | The bank confirmed the name | Goes on to the gateway | Nothing |
| partial_match | Part of the name matched, for example the last name only | Goes on to the gateway | Your call. Hold the order for review, or void the charge if you need an exact match |
| no_match | The bank says the name is not the cardholder's | Refused with 402, no money moved, blocked: true | Show your own message. Do not retry the card under another name |
| not_supported | The card network does not answer name checks (Amex, Discover) | Goes on to the gateway | Nothing. The name was not checked |
| not_performed | The issuing bank does not take part | Goes on to the gateway | Nothing. The name was not checked |
| unknown | The network answered, but with no name result | Goes on to the gateway | Nothing. The name was not checked |
| unavailable | The check could not run (a network or provider error) | Goes on to the gateway | Nothing. The name was not checked |
“Goes on to the gateway” means the name check did not stop the charge. The bank can still decline it for another reason. You then get a normal 402 with a different decline_code, and name_check is still there.
Example responses
Refused for a name mismatch. The refusal also carries decline_code: "name_mismatch", so either field works:
HTTP 402
{
"error": "Charge declined: The cardholder name does not match the card on file. (name_mismatch)",
"code": "payment_failed",
"decline_code": "name_mismatch",
"category": "unknown",
"reference_id": "8134729",
"data": {
"id": "...",
"status": "declined",
...
"name_check": { "status": "no_match", "blocked": true, "card_verified": true, "network_reference": "382017561234567" }
}
}Approved with a partial match:
HTTP 201
{
"data": {
"id": "...",
"status": "pending_settlement",
...
"name_check": { "status": "partial_match", "blocked": false, "card_verified": true, "network_reference": "382017561234567" }
}
}Handling every case
const body = await res.json()
const check = body.data?.name_check ?? null
if (!check) {
// No check ran (Account Verifier off, no last_name, or not a card).
} else if (check.status === 'no_match') {
// Refused (402). No money moved. Ask for a card in the buyer's own name.
} else if (check.status === 'match') {
// Name confirmed.
} else if (check.status === 'partial_match') {
// Charge went through. Review it, or void it if you need an exact match:
// POST /transactions/{body.data.id}/void
} else {
// not_supported, not_performed, unknown, unavailable:
// the charge went through and the name was NOT checked.
}The same result shows on each payment in the dashboard, under Cardholder name check.
Only a definite no match refuses a charge
A partial match is allowed, so a person with the same last name as the cardholder can get through unless you void it yourself. A missing answer never refuses a charge either: Paysio will not turn away a real buyer because their bank did not reply.
Which charges are checked
- Visa and Mastercard cards. American Express and Discover return no name result, so this check never refuses them.
- Card charges made with a card token (
ptok_) or a saved card. Bank debits (rail: "ach") are not checked. - Charges that carry
last_name. - Subscription renewals are never checked.
How results are reused
The result is stored on the saved card, for that one customer, along with the name it was checked against.
- Same card, same customer, same name: the stored result is used. A card that was refused stays refused, so retrying it does not get it through.
- Same card, different name, even for the same customer: checked again.
- Same card, different customer (a different email): that customer gets their own card record and their own check.
So the check applies per card, per customer, per name. Give each of your user accounts its own email on the charge. Otherwise two accounts share one customer and one stored result.
Testing
In test mode the network may not return a name result, and no result never refuses a charge. Build your handling from the 402 response above. See Errors for how failed charges are shaped in general.