Saltar al contingut principal
Els SDK de Didit poden enviar transaccions monitoritzades directament des del dispositiu de l’usuari final, incloses les transferències de la Travel Rule i el cribratge de criptoactius. El teu backend crea un token de vida curta limitat a un àmbit concret, i el SDK fa la resta. Afegeix automàticament la intel·ligència de dispositiu i, quan una transferència de la Travel Rule necessita una prova de control de la cartera, obre el flux d’aquesta prova a l’instant. Una sessió de verificació requerida no s’obre mai automàticament: es retorna a la resposta perquè la teva aplicació l’obri amb la seva pròpia integració de verificació de Didit; consulta més avall Accions obligatòries per a l’usuari.

Visió general

L’enviament des del costat del client es basa en tres garanties:
  • Vinculació del subjecte a prova de suplantació. El token es limita a un sol vendor_data (l’identificador del teu usuari) en el moment de la creació. La identitat del subjecte de cada transacció enviada amb el token s’imposa al servidor a partir d’aquesta vinculació, de manera que un client manipulat no pot enviar transaccions en nom d’un altre usuari, i el payload mai no ha de portar credencials.
  • Intel·ligència de dispositiu automàtica. El SDK recull una empremta digital del dispositiu i l’envia amb l’enviament, i Didit deriva al servidor l’adreça IP i l’agent d’usuari. El context combinat del dispositiu s’adjunta al subjecte de la transacció sense cap biblioteca addicional, sense cap token de dispositiu separat i sense cap infraestructura addicional per part teva. Alimenta les regles basades en el dispositiu i la correlació per dispositiu entre sessions i transaccions.
  • Prova de titularitat de la cartera oberta automàticament. Quan la transacció creada requereix que l’usuari final demostri el control d’una cartera, la resposta porta un bloc action_required de tipus wallet_ownership i el SDK obre aquest flux immediatament, i després actualitza la transacció quan acaba; no cal que construeixis tu bucles de sondeig ni l’enviament d’enllaços. Una acció verification_session obligatòria és diferent: no s’obre mai automàticament, i es retorna al mateix bloc perquè la teva aplicació l’obri amb la seva pròpia integració de verificació de Didit.
El POST /v3/transactions/ al servidor continua sent l’opció adequada quan no hi ha cap usuari final present: transferències administratives, importacions per lots o esdeveniments informats pels teus propis sistemes. Tots dos camins creen els mateixos registres de transacció, executen les mateixes regles i emeten els mateixos webhooks.

Flux

1

Crea un token de transacció

El teu backend crida POST /v3/transactions/sdk-token/ amb la teva clau d’API i el vendor_data de l’usuari, i lliura el sdk_token retornat a la teva aplicació.
2

Envia des del dispositiu

L’aplicació crida submitTransaction del SDK, que envia el payload a POST /v1/transactions/ amb la capçalera X-Transaction-Token i l’enriquiment automàtic del dispositiu.
3

Gestiona qualsevol acció requerida

Si action_required.type és wallet_ownership, el SDK obre el widget automàticament i després actualitza la transacció mitjançant GET /v1/transactions/{transaction_id}/. Si és verification_session, el SDK no obre res: llegeix action_required i inicia el teu propi flux de verificació amb el session_token corresponent (o amb url a la web).

Creació d’un token de transacció

Crea tokens des del servidor amb POST /v3/transactions/sdk-token/: s’utilitza la mateixa autenticació amb clau d’API que la resta d’endpoints de transaccions de /v3/.
Els àlies en camelCase (vendorData, ttlSeconds, maxUses) també s’accepten, com la resta de l’API /v3/.
Mai no incloguis la teva clau d’API en una aplicació. El teu backend conserva la clau d’API i crea tokens; només el sdk_token de vida curta arriba al dispositiu. Crea un token nou per a cada sessió d’usuari en lloc de reutilitzar-ne de llarga durada, i mantén max_uses ajustat quan es coneix el nombre d’enviaments esperats.

Enviament des del dispositiu

Els SDK envien una sol·licitud POST /v1/transactions/ amb el token a la capçalera X-Transaction-Token. El payload que es transmet utilitza camelCase; els mètodes submitTransaction el construeixen per tu, de manera que només cal que tractis directament amb ell quan cridis l’endpoint des del teu propi client HTTP:
Cada camp de primer nivell correspon al seu equivalent a POST /v3/transactions/: La resposta és el mateix detall de transacció en snake_case que els endpoints /v3/, més el bloc action_required:

Declarar una cartera autoallotjada

L’exemple anterior declara la destinació com la cartera autoallotjada de l’usuari: el paymentMethod.type de la contrapart és unhosted_wallet. Aquesta declaració canvia la manera com s’executa l’intercanvi de Travel Rule:
  • Didit omet per complet l’encaminament cap a la VASP contrapart, perquè no hi ha cap VASP darrere d’una cartera autoallotjada, i crea la transferència directament en estat UNCONFIRMED_OWNERSHIP.
  • Quan auto_wallet_verification està activat a la teva configuració de Travel Rule (per defecte, ho està), es crea automàticament una sessió del widget de titularitat de la cartera i es retorna a action_required, exactament com a la resposta anterior.
  • El SDK obre el widget automàticament; quan l’usuari demostra que controla la cartera, la transferència executa la comparació de noms i passa a COMPLETED, o a COUNTERPARTY_MISMATCHED_DATA quan el nom no coincideix amb el titular de l’adreça de la cartera en la seva llibreta d’adreces.
Sense la declaració, Didit prova primer els canals en ordre i només recorre al flux de titularitat si no es troba cap VASP contrapart. Declara la cartera sempre que el teu producte ja sàpiga que la destinació de la retirada és la cartera pròpia de l’usuari: t’estalvia l’intent d’encaminament fallit i porta l’usuari directament al flux de prova.

Imposició del subjecte

Hi ha tres coses que sempre decideix el token, mai el payload:
  • L’aplicació sota la qual es crea la transacció.
  • La identitat del subjecte: subject.externalUserId del payload s’ignora i se substitueix pel vendor_data del token.
  • El context del dispositiu del subjecte (vegeu més avall); els camps derivats del servidor tenen prioritat en cas de conflicte amb qualsevol cosa que s’indiqui a subject.device.
Un 401 d’aquest endpoint significa que el token ha estat rebutjat: falta, és desconegut, està revocat, ha superat el seu max_uses o ha caducat. Les respostes per token caducat sempre contenen la paraula expired al detall de l’error, que és com els SDK distingeixen els errors expired_token dels errors invalid_token.

Llegir la transacció de nou

GET /v1/transactions/{transaction_id}/ retorna el mateix detall amb la mateixa autenticació X-Transaction-Token. Els SDK el criden automàticament quan acaba un flux d’acció iniciat o quan es tanca la seva finestra, de manera que l’estat final mai depèn d’un únic esdeveniment o notificació. Utilitza-ho tu mateix per tornar a comprovar status i action_required en qualsevol moment mentre el token sigui vàlid; des del teu backend, GET /v3/transactions/{transaction_id}/ retorna el mateix registre.

Intel·ligència automàtica del dispositiu

Cada enviament porta intel·ligència del dispositiu sense cap feina d’integració per la teva part:
  • El SDK recull una empremta digital del dispositiu que respecta la privacitat (l’esquema didit-fp-v2: senyals de plataforma i del navegador, un identificador persistent del dispositiu, una puntuació de bot i un hash compost) i l’envia amb la sol·licitud.
  • Didit deriva al servidor l’adreça, l’agent d’usuari i l’accept-language a partir de la mateixa connexió, de manera que el payload no els pot falsificar.
El resultat combinat es normalitza en el context del dispositiu del participant que és el subjecte i es crea o s’actualitza al graf de dispositius, el mateix que alimenten les sessions de KYC. Això fa que les transaccions siguin correlacionables per dispositiu a tota la base d’usuaris («relacionades per dispositiu»), alimenta els senyals de dispositiu i de xarxa a les regles i a l’enriquiment d’IP, i apareix al detall de la transacció a la Console. Les transaccions /v3/ enviades des del servidor poden continuar enviant objectes device_context explícits per participant; en la via del SDK obtens una versió més completa de les mateixes dades sense cap cost addicional.

Accions requerides de l’usuari

Algunes transaccions necessiten que l’usuari final faci alguna cosa abans de poder liquidar-se: una regla pot exigir una sessió de verificació, o un traspàs de Travel Rule pot exigir una prova que la cartera de destinació és realment de l’usuari. Els dos casos apareixen al mateix lloc: el bloc action_required de la resposta de l’enviament (i de cada lectura posterior de la transacció):
Si tots dos podrien aplicar-se a la mateixa transacció, wallet_ownership té prioritat, perquè la prova de titularitat que falta bloqueja el propi intercanvi de Travel Rule. action_required passa a ser null quan l’acció pendent es resol. El camp remediation existent es conserva per compatibilitat amb versions anteriors; action_required és el bloc canònic.

Contracte d’inici automàtic

autoLaunchAction (per defecte true) inicia automàticament només l’acció wallet_ownership:
  • Web - s’obre al propi modal superposat del SDK, i la finalització es detecta mitjançant missatgeria amb validació d’origen i una consulta acotada de la transacció (mai una dependència d’un únic esdeveniment).
  • iOS / Android (i els embolcalls de React Native i Flutter, que deleguen en els SDK natius) - es presenta com a experiència nativa de titularitat de la cartera del SDK (SwiftUI / Jetpack Compose) quan useNativeWalletOwnership és true (el valor per defecte), amb opció de reserva a SFSafariViewController / una Chrome Custom Tab i, finalment, al navegador per defecte. Quan el flux es tanca o l’aplicació torna al primer pla, el SDK torna a llegir la transacció automàticament.
Una acció verification_session mai s’inicia automàticament: sempre torna a action_required perquè la vostra aplicació l’iniciï amb la pròpia integració de verificació de Didit.
El widget de titularitat de la cartera no s’ha de renderitzar mai dins d’un webview integrat en un dispositiu mòbil: els enllaços profunds de les carteres no poden sortir-ne i el flux de prova queda bloquejat. Els SDK ja utilitzen la superfície de navegador correcta quan s’inicien automàticament; mantingueu aquesta regla si gestioneu vosaltres el url. Consulteu la guia del widget de titularitat de la cartera per obtenir més detalls.
Quan el flux de titularitat de la cartera iniciat automàticament pel propi SDK es completa o es tanca, el SDK torna a llegir la transacció i passa el resultat actualitzat al vostre callback onActionCompleted. Una acció verification_session no forma part d’aquest cicle, perquè la vostra aplicació l’inicia - consulteu la secció següent.

Iniciar una sessió de verificació

Quan action_required.type és verification_session, llegiu el bloc de result.actionRequired i passeu-lo a la integració de verificació de Didit que ja teniu:
Quan el flux de verificació acabi, feu una crida a GET /v1/transactions/{transaction_id}/ (o espereu el webhook de transacció) per obtenir l’estat actualitzat de la transacció.

Exemple: reverificació biomètrica per a una retirada d’alt valor

Aquest és el flux en la seva millor versió: protegeix les transaccions de risc - imports elevats, beneficiaris nous, dispositius nous - amb una nova comprovació biomètrica de la mateixa persona que vau verificar en l’alta. La usurpació de comptes es veu exactament així: contrasenya correcta, codi 2FA correcte (obtingut per phishing o mitjançant una suplantació de la SIM), i una retirada cap a una cartera que mai no havíeu vist. En aquest punt, totes les defenses basades en credencials ja han fallat. Però el rostre no falla: l’atacant no pot superar una selfie amb prova de vida que ha de coincidir amb la cara capturada durant l’alta KYC del titular legítim.
1

Crea la regla una vegada, a la consola

Transactions → Rules → Create Rule: condició amount gte 5000, acció Change status → AWAITING_USER, i seleccioneu el vostre flux de treball Biometric Authentication a l’acció. Afegiu les altres condicions de risc que vulgueu - contrapart per primera vegada, nova empremta digital del dispositiu, canvi de país de la IP - com a condicions addicionals o com a regles addicionals.
2

Envia la retirada com de costum

El vostre codi d’enviament no canvia. Quan s’activa la regla, la resposta inclou status: "AWAITING_USER" i un bloc action_required de tipus verification_session:
3

Inicia la nova comprovació

Passeu el session_token (o el url) a la vostra integració de verificació de Didit existent, tal com s’explica a Iniciar una sessió de verificació. Com que la sessió es crea per al mateix vendor_data que el subjecte de la transacció, Didit ja disposa de la cara de referència verificada de l’usuari de l’alta - la selfie de prova de vida aprovada, la foto del xip del passaport o el retrat del document. L’usuari fa una selfie en directe; Didit executa una prova de vida i una coincidència facial 1:1 amb aquesta referència emmagatzemada. Sense tornar a escanejar el document ni tornar a fer l’alta - uns segons de fricció, només en les transaccions que ho mereixen.
4

Resol segons el resultat

Quan la sessió es completa, la transacció es torna a avaluar automàticament: APPROVED si s’ha superat la nova comprovació, DECLINED si no, amb un webhook transaction.status.updated en qualsevol dels dos casos (reason: remediation_completed a la cronologia de la transacció). La vostra aplicació rep el resultat mitjançant callbacks del tipus onActionCompleted, GET /v1/transactions/{transaction_id}/ o el webhook.
Això funciona perquè l’alta KYC, la recomprovació biomètrica i la decisió sobre la transacció s’executen a la mateixa plataforma: la cara capturada durant l’alta és la referència per a la verificació addicional, el graf de dispositius vincula la sessió amb la transacció i el motor de regles ho connecta tot. Sense codi d’integració de proveïdors, sense exportació d’imatges facials i sense un contracte biomètric separat. La recomprovació es factura com a funcionalitat estàndard d’Autenticació biomètrica ($0.10) només quan realment s’executa.

Web SDK

submitTransaction està disponible avui al singleton del Web SDK:
El resultat és { transactionId, status, travelRuleStatus?, actionRequired? }. Al payload del nivell del SDK escriu category, details i customProperties; el SDK els mapeja automàticament als àlies del protocol (type, info i props). Els errors es tipifiquen mitjançant DiditTransactionError:

SDK natius

L’API nativa submitTransaction s’inclou a l’SDK d’iOS i Android 4.1.0 (i a les versions de React Native i Flutter que fixen aquesta versió). A diferència del Web SDK, els payloads natius usen directament els noms de camp del protocol: type, info i props.
Tots els SDK també exposen getTransaction(transactionToken, transactionId) per tornar a llegir la transacció amb el mateix token: els SDK la criden per tu després d’un flux d’acció iniciat, i tu pots cridar-la tu mateix en qualsevol moment. Al mòbil, el transport de l’empremta del dispositiu ja s’aplica a totes les crides de xarxa del SDK, de manera que els enviaments de transaccions porten automàticament la mateixa intel·ligència de dispositiu.

Sense els SDK

Tot el que fan els SDK és HTTPS simple; aquí no cal cap d’ells. Hi ha dues formes d’integració equivalents: Només del servidor (sense cap token). Envia la transacció amb POST /v3/transactions/ des del teu backend amb la teva clau d’API. La resposta (i cada GET /v3/transactions/{transaction_id}/ posterior) inclou el mateix bloc action_required. També pots passar el context device explícit per a cada participant, ja que no hi ha cap SDK que el reculli per tu. Del costat del client amb la teva pròpia pila HTTP. Genera un token amb POST /v3/transactions/sdk-token/ i després crida POST /v1/transactions/ i GET /v1/transactions/{transaction_id}/ des del dispositiu amb la capçalera X-Transaction-Token: s’apliquen la mateixa vinculació de subjecte i la mateixa derivació d’IP i user-agent al servidor. A continuació, gestiona tu mateix action_required: I detecta la finalització sense cap callback del client:
  • Webhooks (recomanat). transaction.status.updated s’activa quan l’acció pendent resol la transacció, i travel_rule.status.updated s’activa en cada transició de l’intercanvi; tots dos inclouen prou informació per actualitzar els teus registres sense fer sondeig.
  • Sondeig. Torna a llegir la transacció (/v3/ des del teu backend, o /v1/ amb el token mentre sigui vàlid): action_required torna a null quan es resol, i status / travel_rule.status porten el resultat.
En aquest disseny no hi ha dependències que només funcionin una vegada: el widget, la sessió de verificació i el teu backend convergeixen tots al mateix estat persistent de la transacció, de manera que una pestanya tancada o un webhook perdut sempre es pot recuperar tornant a llegir la transacció.

Webhooks

El teu backend no necessita que l’aplicació li notifiqui res. Quan una transacció enviada requereix una acció de l’usuari, el webhook de transacció (transaction.created o transaction.status.updated) inclou el mateix bloc action_required, de manera que els teus sistemes coneixen l’acció pendent encara que l’aplicació es tanqui abans d’acabar el flux. Una acció verification_session arriba amb l’estat AWAITING_USER, però una acció wallet_ownership no canvia per si sola l’estat de la transacció; per tant, llegeix action_required en lloc de l’estat. Les transicions de Travel Rule emeten a més travel_rule.status.updated.

Següents passos

Enviament de transaccions

L’API de creació de transaccions del servidor i la referència completa del payload.

Travel Rule

L’intercanvi gestionat entre l’ordenant i el beneficiari, la configuració i el cicle de vida.

Widget de titularitat de cartera

El flux allotjat de prova de control que hi ha darrere de les accions wallet_ownership.

Webhooks

transaction.created, transaction.status.updated i la verificació de la signatura.

Regles

Accions de regla, incloses les que creen sessions de verificació.

Estats

Què significa AWAITING_USER al cicle de vida de la transacció.
Darrera modificació el 7 de novembre del 2026