Langsung ke konten utama
Widget kepemilikan dompet adalah halaman yang di-hosting untuk membuktikan bahwa pelanggan Anda menguasai alamat dompet kripto tertentu. Berdasarkan EU TFR, VASP wajib memverifikasi kepemilikan dompet swakelola (unhosted) sebelum mengirim dana ke atau dari dompet tersebut yang melebihi ambang batas sunrise. Widget ini adalah cara Didit mengumpulkan bukti tersebut tanpa Anda perlu membangun alur penandatanganan sendiri. Bukti yang terverifikasi menandai entri buku alamat dompet yang sesuai dengan is_ownership_verified: true, yang memungkinkan transfer Travel Rule terkait berpindah keluar dari status UNCONFIRMED_OWNERSHIP.

Kapan Didit membuatnya untuk Anda

Anda jarang perlu membuat sesi sendiri. Saat auto_wallet_verification aktif di pengaturan Travel Rule Anda (nilai default), Didit otomatis membuat sesi widget ketika transaksi dibuat, setiap kali transfer memerlukan bukti kontrol dompet dari pengguna akhir:
  • Transfer berada di UNCONFIRMED_OWNERSHIP, karena dompet pihak lawan dinyatakan sebagai dompet swakelola saat pengajuan.
  • Transfer bersifat keluar dan berada di COUNTERPARTY_VASP_NOT_FOUND, karena tidak ada VASP pihak lawan yang dapat diidentifikasi, sehingga pembuktian kepemilikan menjadi jalur yang tersisa untuk menyelesaikan transfer.
Sesi yang dibuat otomatis dikembalikan dalam blok action_required pada transaksi (type: "wallet_ownership", dengan url yang akan dibuka), dan SDK meluncurkannya secara otomatis saat pengiriman dari sisi klien. Transfer masuk yang dibuat Didit untuk Anda (pendaftaran sunrise, inkuiri TRP masuk, atau segmen masuk pada jalur INTERNAL) tidak pernah mendapatkan sesi yang dibuat otomatis, meskipun transfer tersebut masuk ke UNCONFIRMED_OWNERSHIP. Buat sesi secara manual dengan POST /v3/travel-rule/widget-session/ jika Anda ingin memverifikasi dompet sebelum ada transfer, jika auto_wallet_verification dinonaktifkan, atau untuk salah satu transfer masuk tersebut.

Apa yang dibuktikan

Widget ini menawarkan hingga empat metode pembuktian. Metode yang muncul bergantung pada cara Anda membuat sesi dan pengaturan Travel Rule Anda:

Kontrak verifikasi penandatanganan pesan

Setelah tanda tangan dikirim, respons 200 dengan status: "VERIFIED" dikembalikan ketika tanda tangan membuktikan kendali atas dompet. Respons 400 dikembalikan dan pembuktian tetap terbuka, sehingga pelanggan dapat menandatangani ulang, dengan salah satu nilai code berikut:

Kontrak verifikasi tes Satoshi

Verifikasi deposit tes Satoshi bersifat asinkron, karena transaksinya harus terlihat on-chain lalu dikonfirmasi. Setelah txid deposit dikirim, respons 200 dengan status: "PENDING" dikembalikan selama deposit belum dikonfirmasi on-chain. txid disimpan, tidak dibuang. Respons 200 dengan status: "VERIFIED" dikembalikan setelah deposit dikonfirmasi. Respons 400 dengan status: "REJECTED" dikembalikan untuk deposit yang memang salah: dikirim dari dompet lain, jumlah yang dikirim ke alamat deposit bukan jumlah yang diharapkan, lebih lama dari tantangan, atau transaksi yang sudah membuktikan dompet lain. Pembuktian ditutup dan pelanggan dapat memulai pembuktian baru selama sesi masih memiliki sisa percobaan. Deposit yang belum diindeks juga mengembalikan 200 dengan status: "PENDING", dan pencarian yang gagal di sisi Didit mengembalikan 400 dengan kode DEPOSIT_LOOKUP_FAILED. Dalam kedua kasus, pembuktian tetap terbuka dan Didit terus memeriksa. Respons 410 dikembalikan jika jendela tes berakhir sebelum deposit yang valid terlihat. Setelah txid dikirim, job latar belakang memeriksa ulang deposit yang tertunda setiap lima menit dan menyelesaikan pembuktian setelah transaksi dikonfirmasi, sehingga pelanggan tidak perlu mengirim ulang txid. Ketika Anda menyertakan satoshi_deposit_address, expires_at milik sesi widget diperpanjang menjadi minimal jendela tes Satoshi 24 jam, sehingga deposit memiliki waktu untuk dikonfirmasi sebelum sesi itu sendiri kedaluwarsa.

Flow

1

Terbitkan sesi widget

Panggil POST /v3/travel-rule/widget-session/ dengan dompet yang perlu diverifikasi. Secara opsional, tautkan sesi ke transfer agar transfer otomatis maju setelah kepemilikan terbukti.
2

Buka URL yang dikembalikan

Kirim pelanggan Anda ke url dari respons. Mereka menyelesaikan bukti di sana tanpa memerlukan akun Didit atau kunci API; token di URL berfungsi sebagai autentikasi.
3

Deteksi penyelesaian

Ketika bukti diverifikasi, widget menandai entri buku alamat sebagai terverifikasi dan, jika sesi ditautkan ke transfer, memajukan transfer tersebut. Pantau travel_rule.status.updated (untuk transfer yang ditautkan) atau lakukan polling pada konteks widget.

Terbitkan sesi widget

Contoh ini menautkan sesi ke transfer swakelola yang dideklarasikan dari panduan Travel Rule, sehingga wallet_address adalah dompet tujuan transfer tersebut. Sesi yang ditautkan ke transfer hanya menerima bukti untuk dompet pihak lawan transfer.
Selalu buka url yang dikembalikan dalam respons apa adanya. Jangan membuatnya sendiri.

Buka URL yang dikembalikan

Widget hanya tersedia di web pada rilis ini. Buka url di browser sistem atau tab kustom, jangan pernah di dalam webview SDK seluler Didit.Penandatanganan pesan berfungsi dengan dompet yang terpasang di browser pelanggan, yang ditemukan widget melalui protokol EIP-6963 dan Wallet Standard. Memasangkan aplikasi dompet seluler terpisah, misalnya dengan kode QR, belum tersedia saat ini, sehingga widget tidak mengalihkan ke aplikasi lain. Webview dalam aplikasi, seperti webview SDK Didit Web/Flutter/React Native/iOS/Android, tidak dapat menjangkau dompet browser pelanggan, sehingga widget yang dibuka di sana membuat pelanggan tidak memiliki cara untuk menandatangani.Di perangkat seluler, luncurkan url dengan browser sistem operasi (SFSafariViewController / Chrome Custom Tabs, atau browser default) alih-alih merendernya di webview. Di web, tab biasa atau popup sudah sesuai.

Deteksi penyelesaian

Widget menyediakan endpoint publik untuk membaca status yang menggunakan token sebagai kunci. Lakukan polling untuk melihat progres, atau andalkan webhook ketika sesi ditautkan ke transfer:
  • completed_at berisi nilai non-null setelah bukti diverifikasi.
  • Setiap entri dalam proofs memuat kolom yang dibutuhkan metodenya: bukti SATOSHI_TEST menambahkan deposit_address, expected_amount, dan expires_at-nya sendiri; bukti MESSAGE_SIGNING menambahkan challenge, teks yang ditandatangani pelanggan.
  • Bukti SATOSHI_TEST dapat berada pada status: "PENDING" ketika depositnya terlihat on-chain tetapi belum dikonfirmasi, tanpa tindakan apa pun dari Anda atau pelanggan. Lihat kontrak verifikasi Satoshi test di atas.
  • Ketika sesi diterbitkan dengan transaction_id, memverifikasi bukti akan memajukan transfer yang ditautkan, dan pada aplikasi produksi webhook travel_rule.status.updated akan terpicu. Utamakan webhook daripada polling. Permintaan TRP masuk disetujui kembali ke pengirim dan berpindah ke COMPLETED setelah persetujuan tersebut terkirim. Transfer lain dalam UNCONFIRMED_OWNERSHIP (atau transfer masuk yang ON_HOLD) berpindah ke COMPLETED, atau ke COUNTERPARTY_MISMATCHED_DATA ketika nama penerima tidak cocok dengan pemegang dompet, dan deposit sunrise yang telah diselesaikan akan terus berlanjut ke FINISHED. Transfer keluar dalam COUNTERPARTY_VASP_NOT_FOUND berpindah ke COMPLETED.
  • Bukti SCREENSHOT tetap berstatus status: "PENDING" dalam konteks ini bahkan setelah Anda mengonfirmasi kepemilikan. Anda menyetujuinya dengan POST .../travel-rule/ownership/, yang hanya menerima transfer yang menunggu konfirmasi kepemilikan. Oleh karena itu, bukti screenshot tidak memiliki jalur persetujuan pada sesi tanpa transfer tertaut, atau pada sesi yang ditautkan ke transfer keluar dalam COUNTERPARTY_VASP_NOT_FOUND: nonaktifkan allow_screenshot_proof jika sesi-sesi tersebut tidak boleh menawarkannya.
  • Setelah bukti ditolak, sesi memberikan percobaan baru selama percobaan masih tersisa. max_attempts, attempts_used, dan attempts_remaining melaporkan jumlahnya, bukti yang ditolak memuat rejection_reason, dan ketika attempts_remaining bernilai 0, memulai bukti lain akan menghasilkan 409 dan Anda harus menerbitkan sesi baru.
  • Endpoint konteks mengembalikan 404 untuk token yang tidak dikenal dan 410 setelah sesi kedaluwarsa tanpa diselesaikan.
Tidak ada dependensi sekali jalan di sini: widget dan backend Anda sama-sama menuju status persisten yang sama (entri buku alamat terverifikasi dan status transfer), sehingga webhook yang terlewat atau tab yang ditutup selalu dapat dipulihkan dengan membaca ulang transfer atau konteks widget.

Lokalisasi dan branding

Widget ditampilkan dalam 54 bahasa, mengikuti jalur bahasa pada tautan (atau bahasa default browser). Jika White Label diaktifkan untuk aplikasi Anda, widget otomatis mewarisi branding alur verifikasi Anda: logo, warna merek, gaya tombol dan panel, font kustom, favicon, serta nama publik aplikasi Anda di judul. Tidak ada konfigurasi terpisah yang perlu dilakukan. Kustomisasi yang Anda atur untuk sesi KYC juga berlaku di sini. Pengguna yang kembali ke tautan yang sudah selesai akan melihat layar penyelesaian lagi. Jika Anda meneruskan callback_url, widget akan mengarahkan mereka ke sana. Tautan yang sudah kedaluwarsa menampilkan layar kedaluwarsa dengan branding yang meminta pengguna mengajukan tautan baru. Buat sesi baru untuk mereka dengan POST /v3/travel-rule/widget-session/. Mengirim ulang transfer dengan action: "resend" tidak membuat sesi.

Langkah selanjutnya

Travel Rule

Siklus hidup pertukaran lengkap, jalur, pengaturan, dan alur penerimaan.

Buku alamat dompet

Daftarkan dompet yang Anda kendalikan agar transfer masuk dicocokkan dengan dompet tersebut.

Webhook

Berlangganan travel_rule.status.updated agar dapat merespons saat bukti menyebabkan transfer berlanjut.

SDK native

Buka URL widget dengan browser sistem, bukan webview SDK.
Terakhir diubah pada 7 November 2026