> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Sudafrica: verifica del titolare del conto bancario API

> Didit verifica il titolare del conto bancario in Sudafrica tramite database ufficiali. Da $0.40 per chiamata, senza contratti né minimi.

Conferma che un conto bancario sudafricano appartiene al titolare indicato, tramite il servizio interbancario Account Holder Verification. Didit espone questo servizio tramite `POST /v3/database-validation/`, così puoi verificare i dati inviati rispetto alla fonte autorevole e ricevere risultati di corrispondenza normalizzati.

## Copertura

* **Copertura:** –
* **Paese:** Sudafrica
* **ID servizio:** `zaf_bank_account_holder`
* **Dominio dei dati:** Finanziario
* **Categoria:** Bancario

## Input

| Campo | Obbligatorio | Esempio |
| - | -: | - |
| `national_id` | Sì | `8708150847085` |
| `bank_account_number` | Sì | `1234567890` |
| `bank_name` | Sì | `ABSA` |
| `account_type` | No | `current` |
| `first_name` | No | `John` |
| `last_name` | No | `Doe` |
| `initials` | No | `JD` |
| `email` | No | `john.doe@example.com` |
| `phone_number` | No | `+15550101000` |
| `vendor_data` | No | `user-1234` |

* **Input obbligatori:** `national_id`, `bank_account_number`, `bank_name`
* **Input facoltativi:** `account_type`, `first_name`, `last_name`, `initials`, `email`, `phone_number`, `vendor_data`
* **Consenso:** Obbligatorio
* **Disponibilità nel workflow:** Disponibile nel workflow con mappatura dei campi
* **Copertura:** –
* **Prezzo:** \$0.40 per query riuscita

In un workflow, `bank_account_number` e `bank_name` non sono stampati su un documento d'identità, quindi nessun passaggio li produce da solo. Raccoglili da una risposta di un Questionario, da un campo estratto da Document AI o da un valore che invii al momento della creazione della sessione, e mappa ciascuno nel passaggio Validazione su database. Finché non sono mappati, l'editor del workflow mostra questo servizio disabilitato e indica l'input mancante. In fase di esecuzione, un input mancante significa che il controllo viene saltato prima di qualsiasi query, quindi non ti viene mai addebitato un database che non è stato possibile interrogare.

## Parametri del body

**issuing\_state** `string` *required* (default: ZAF)

Codice paese ISO 3166-1 alpha-3 per questo servizio di database.

Esempio: `ZAF`

**services** `string` *required* (default: zaf\_bank\_account\_holder)

Array che contiene l'ID di questo servizio. Fissare il servizio mantiene la richiesta limitata a questo specifico database.

Esempio: `zaf_bank_account_holder`

**consent** `boolean` *required* (default: true)

Consenso esplicito dell'utente finale per questo servizio.

Esempio: `true`

**national\_id** `string` *required* (default: 8708150847085)

Numero di identità nazionale per questo servizio.

Esempio: `8708150847085`

**bank\_account\_number** `string` *required* (default: 1234567890)

Valore di `bank_account_number` richiesto da questo servizio di database.

Esempio: `1234567890`

**bank\_name** `string` *required* (default: ABSA)

Valore di `bank_name` richiesto da questo servizio di database.

Esempio: `ABSA`

**account\_type** `string` (default: current)

Valore di `account_type` richiesto da questo servizio di database.

Esempio: `current`

**first\_name** `string`

Nome di battesimo da validare.

Esempio: `John`

**last\_name** `string` (default: Doe)

Cognome da validare.

Esempio: `Doe`

**initials** `string` (default: JD)

Valore di `initials` richiesto da questo servizio di database.

Esempio: `JD`

**email** `string`

Indirizzo email.

Esempio: `john.doe@example.com`

**phone\_number** `string`

Valore di `phone_number` richiesto da questo servizio di database.

Esempio: `+15550101000`

**vendor\_data** `string` (default: user-1234)

Il tuo riferimento stabile per questa persona, ad esempio il tuo ID utente interno. Didit lo usa per collegare i controlli indipendenti allo stesso utente finale e ridurre il rumore del rilevamento dei duplicati.

Esempio: `user-1234`

## Regole di input e note sulla validazione

* `account_type` deve essere uno dei tipi di conto AVS sudafricani: `current`, `savings`, `transmission`, `subscriptionShare`, `notKnown`. La corrispondenza non distingue tra maiuscole e minuscole. Ometti il campo se non conosci il tipo di conto: Didit invia allora `notKnown` e il controllo incrociato del tipo di conto viene riportato come non confermato, invece di far fallire la richiesta.

## Come effettuare la chiamata

```bash cURL theme={null}
curl -X POST "https://verification.didit.me/v3/database-validation/" \
  -H "x-api-key: YOUR_API_KEY" \
  -F "issuing_state=ZAF" \
  -F "services=zaf_bank_account_holder" \
  -F "vendor_data=user-1234" \
  -F "consent=true" \
  -F "national_id=8708150847085" \
  -F "bank_account_number=1234567890" \
  -F "bank_name=ABSA" \
  -F "account_type=current" \
  -F "last_name=Doe" \
  -F "initials=JD"
```

Ogni chiamata riuscita restituisce HTTP `200`. Il campo **`outcome_code`** indica cosa è realmente accaduto, distinguendo ad esempio una vera mancata corrispondenza biometrica (`BIOMETRIC_NO_MATCH`) da un selfie che non è stato possibile leggere (`BIOMETRIC_IMAGE_UNUSABLE`). Lo `status` mostrato è lo stato predefinito della funzionalità; le [azioni configurate per Partial Match / No Match](https://docs.didit.me/it/core-technology/database-validation/database-validation-warnings.md) possono sostituirlo.

**`MATCH`**: il registro ha confermato l'identità e ogni campo verificato corrisponde.

```json 200 OK — MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "Approved",
  "issuing_state": "ZAF",
  "match_type": "full_match",
  "validations": [
    {
      "outcome_code": "MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": true,
        "accepts_debits": true,
        "account_found": true,
        "account_number_length_valid": true,
        "account_open": true,
        "account_type_match": true,
        "id_match": true,
        "identification_number": "SAMPLE-ID-12345",
        "initials_match": true,
        "surname_match": true
      },
      "validation": {
        "full_name": "full_match",
        "identification_number": "full_match"
      }
    }
  ]
}
```

**`PARTIAL_MATCH`**: il numero di identificazione è stato trovato, ma uno o più campi personali (di solito nome o data di nascita) non corrispondono completamente.

```json 200 OK — PARTIAL_MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "In Review",
  "issuing_state": "ZAF",
  "match_type": "partial_match",
  "validations": [
    {
      "outcome_code": "PARTIAL_MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": true,
        "accepts_debits": true,
        "account_found": true,
        "account_number_length_valid": false,
        "account_open": true,
        "account_type_match": true,
        "id_match": true,
        "identification_number": "SAMPLE-ID-12345",
        "initials_match": true,
        "surname_match": false
      },
      "validation": {
        "full_name": "partial_match",
        "identification_number": "full_match"
      }
    }
  ]
}
```

**`NO_MATCH`**: il registro non ha restituito alcuna corrispondenza per i dati inviati.

```json 200 OK — NO_MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "Declined",
  "issuing_state": "ZAF",
  "match_type": "no_match",
  "validations": [
    {
      "outcome_code": "NO_MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": false,
        "accepts_debits": false,
        "account_found": false,
        "account_number_length_valid": false,
        "account_open": false,
        "account_type_match": false,
        "id_match": false,
        "identification_number": "NO_MATCH",
        "initials_match": false,
        "surname_match": false
      },
      "validation": {
        "identification_number": "no_match"
      }
    }
  ]
}
```

## Dati restituiti

I campi esatti esposti in `source_data` dipendono da ciò che restituisce il registro. L'esempio generato per `zaf_bank_account_holder` documenta attualmente questa struttura normalizzata:

* `accepts_credits`
* `accepts_debits`
* `account_found`
* `account_number_length_valid`
* `account_open`
* `account_type_match`
* `id_match`
* `identification_number`
* `initials_match`
* `surname_match`

## Prezzi e SLA

Le query di verifica del titolare del conto bancario in Sudafrica vengono fatturate solo quando Didit riceve un risultato conclusivo dalla fonte di validazione.

* **Prezzo per chiamata:** \$0.40 USD.
* **Fatturazione:** per query riuscita. Non ti viene addebitato nulla quando il registro non è raggiungibile, quando mancano campi obbligatori o quando la richiesta viene respinta prima di raggiungere la fonte.
* **Latenza:** p95 tipico \< 2 s.
* **Disponibilità:** 99.9% per trimestre dal lato di Didit; la disponibilità della fonte a valle varia in base al paese e al dataset.

## Cosa conferma un MATCH

La Verifica del titolare del conto (AVS) è un insieme di controlli incrociati sì/no, non una ricerca di record. La fonte non restituisce mai un nome, un numero di identificazione o il saldo di un conto: prende i dati che invii, li confronta con quelli che la banca possiede per quel conto e risponde a ciascun confronto con un flag. `source_data` contiene questi flag:

* **`account_found`**: la banca possiede un conto con questo numero. Tutto il resto non ha significato quando questo valore è `false`.
* **`account_open`**: il conto è aperto. Un conto può essere trovato ma chiuso.
* **`id_match`**: il conto è intestato al titolare dell'identificativo nazionale che hai inviato. È il controllo per cui esiste il servizio.
* **`initials_match`**, **`surname_match`**: `initials` e `last_name` inviati corrispondono al titolare del conto registrato.
* **`account_type_match`**: `account_type` inviato corrisponde al tipo reale del conto.
* **`email_match`**, **`phone_match`**: `email` e `phone_number` inviati corrispondono ai recapiti che la banca possiede.
* **`accepts_debits`**, **`accepts_credits`**: il conto può ricevere ordini di addebito diretto e accredito.
* **`account_number_length_valid`**: il numero di conto ha la lunghezza prevista dalla banca.

Il codice di esito riassume questi flag:

* **`MATCH`**: il conto esiste e ogni campo inviato corrisponde, incluso `id_match`.
* **`PARTIAL_MATCH`**: il conto è intestato al titolare dell'identificativo nazionale inviato, ma almeno un altro campo inviato non corrisponde (ad esempio un cognome scritto diversamente nei registri della banca). `outcome_detail` indica i campi che non hanno superato il controllo.
* **`NO_MATCH`**: la banca non possiede alcun conto con questo numero, oppure il conto esiste ma appartiene a un'altra persona. Entrambe sono risposte conclusive sulla persona.

Un controllo incrociato che non hai richiesto non viene né conteggiato né riportato. AVS risponde `N` per ogni campo non fornito, quindi `surname_match`, `initials_match`, `email_match`, `phone_match` e `account_type_match` compaiono in `source_data` solo quando hai inviato il dato corrispondente. Inviare solo `national_id`, `bank_account_number` e `bank_name` produce quindi comunque un `MATCH` completo.

## Valori accettati per bank\_name e account\_type

`bank_name` e `account_type` sono enumerazioni. Un valore che non compare in uno dei due elenchi viene rifiutato prima dell'esecuzione della query, quindi un errore di battitura ti costa un ulteriore scambio di richiesta e risposta anziché un addebito.

`account_type` è facoltativo e accetta, senza distinzione tra maiuscole e minuscole:

`current` · `savings` · `transmission` · `subscriptionShare` · `notKnown`

Omettilo quando non conosci il tipo di conto. Didit invia quindi `notKnown`, la richiesta va a buon fine e `account_type_match` restituisce `false` perché non c'era nulla da confrontare. Qualsiasi altro valore, come `checking`, `cheque` o `bond`, viene rifiutato con un `400` che elenca l'insieme dei valori accettati.

`bank_name` è obbligatorio e questi valori sono confermati come accettati (senza distinzione tra maiuscole e minuscole):

`ABSA` · `Capitec` · `FNB` · `Nedbank` · `Standard Bank` · `Investec` · `African Bank` · `Discovery Bank` · `Old Mutual` · `Bank Zero` · `Tyme` · `Grindrod`

I conti dei consumatori presso tutte queste banche rientrano nell'ambito, Capitec incluso. Invia la forma abbreviata esattamente come elencata: `Capitec`, non `Capitec Bank`; `Tyme`, non `TymeBank`. Una banca non riconosciuta restituisce un esito `REGISTRY_ERROR` il cui `outcome_detail` indica il campo rifiutato dalla fonte.

## Distinguere un conto inesistente da una fonte non disponibile

Si tratta di esiti HTTP diversi, quindi non serve analizzare stringhe di errore:

* **Il conto non esiste**: `200 OK`, `match_type: "no_match"`, `outcome_code: "NO_MATCH"`, `source_data.account_found: false`. È una risposta reale della banca. Viene fatturata e si applica la tua azione per il caso di mancata corrispondenza.
* **La fonte non ha risposto**: `502 Bad Gateway` con `validation_errors[].code` = `empty_provider_response` e `retryable: true`. Non è stato accertato nulla sulla persona, non viene addebitato nulla e la richiesta può essere ripetuta in sicurezza.
* **La fonte ha rifiutato di eseguire la query**: `400 Bad Request` con `validation_errors[].code` = `provider_rejected_input` e `retryable: false`. La fonte non ha mai effettuato la ricerca, perché non avrebbe accettato ciò che le è stato inviato. Correggi i dati: ripetere la richiesta con gli stessi valori non può riuscire. Non viene addebitato nulla.
* **La fonte ha risposto e ha rifiutato il tuo input**: `502 Bad Gateway` con `validation_errors[].code` = `provider_invalid_input` (ad esempio un numero di conto che non supera il controllo di formato della banca). Ripetere la richiesta non ha senso finché l'input non viene corretto; non viene addebitato nulla.
* **La richiesta non ha mai lasciato Didit**: `400 Bad Request`, con l'elenco del campo da correggere. Non viene addebitato nulla.

Solo il primo di questi esiti è una risposta sulla persona. Tratta un `502` come transitorio: AVS inoltra la richiesta alla banca del titolare del conto anziché leggere un registro, per questo è il più lento tra i servizi sudafricani, quindi riprova aumentando progressivamente l'intervallo tra i tentativi.

## Continua a leggere

* [Panoramica della Validazione su database per il Sudafrica](https://docs.didit.me/api-reference/database-validation/south-africa.md)
* [Panoramica della Validazione su database](https://docs.didit.me/it/core-technology/database-validation/overview.md)
* [Codici di esito](https://docs.didit.me/it/core-technology/database-validation/database-validation-outcome-codes.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.