> ## 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.

# Pemecahan Masalah Pemantauan Transaksi (KYT): Masalah & Solusi Umum

> Solusi Didit untuk masalah KYT umum: tabrakan txn_id, aturan tak terpicu, timeout AML, webhook tak cocok, mata uang—beserta penyebab & perbaikan.

Referensi masalah umum Pemantauan Transaksi, dengan gejala, penyebab, dan solusinya.

## Error `txn_id` duplikat

**Gejala.** Saat mengirim transaksi, respons berisi `400` dengan `A transaction with this transaction_id already exists.` pada kolom `transaction_id`, atau `409` ketika dua permintaan identik terjadi bersamaan.

**Penyebab.** `txn_id` (`transaction_id` yang Anda kirim) bersifat unik per aplikasi.
Didit menolak transaksi kedua dengan `transaction_id` yang sama dan tidak mengembalikan catatan yang sudah ada.

**Solusi.**

* Hasilkan `txn_id` secara deterministik di sisi Anda (misalnya, gunakan ID database transaksi Anda sendiri).
* Jika menerima `400` atau `409` untuk `transaction_id` duplikat saat mencoba lagi, cari transaksi yang sudah ada alih-alih mengirim ulang: baca dengan [`GET /v3/transactions/{uuid}/`](https://docs.didit.me/id/management-api/transactions/get) menggunakan `uuid` dari respons pertama, atau gunakan `transaction_id` (uuid Didit) yang dibawa oleh webhook `transaction.created` di samping `txn_id` Anda.
* Jika permintaan bukan percobaan ulang, berikan transaksi baru `transaction_id`-nya sendiri.

## Aturan tidak terpicu

**Gejala.** Anda membuat aturan yang seharusnya cocok, tetapi tidak ada transaksi yang menampilkannya di `rule_runs[]` dengan `matched: true`.

**Penyebab dan solusi.**

* **Aplikasi berada dalam mode sandbox**: aplikasi sandbox melewati evaluasi aturan, skrining AML, penagihan, serta webhook `transaction.created` dan `transaction.status.updated`. Pertukaran Travel Rule tetap berjalan saat diaktifkan, terhadap [Didit Test VASP](https://docs.didit.me/id/transaction-monitoring/travel-rule-sandbox.md), dan mengirimkan webhook `travel_rule.status.updated` yang ditandai `environment: sandbox`. `rule_runs` dikembalikan kosong dan skor tetap `0`, apa pun mode aturan Anda, dan transaksi tetap `APPROVED` kecuali transfer Travel Rule yang kedaluwarsa menerapkan `timeout_outcome` Anda. Periksa `environment` pada respons transaksi: `"sandbox"` berarti transaksi tidak pernah dievaluasi. Lihat [Pemantauan Transaksi di sandbox](https://docs.didit.me/id/integration/sandbox-testing.md#pemantauan-transaksi-di-sandbox) untuk cara memvalidasi aturan sebelum digunakan di lingkungan produksi.
* **Mode aturan adalah `DISABLED` atau `TEST`**: periksa *Rules → \[rule] → Mode*. Hanya aturan `ACTIVE` yang berkontribusi pada penilaian. Aturan `TEST` tetap dievaluasi tetapi tidak memengaruhi status.
* **Filter scope mengecualikan transaksi**: misalnya, scope yang diatur ke `transaction_type = finance` tidak akan cocok dengan transaksi `travelRule`.
* **Jendela agregasi lebih pendek dari yang diperlukan**: aturan "20 transaksi dalam 30 hari" tidak akan cocok setelah hanya 15 transaksi.
* **Kolom kondisi bernilai null**: misalnya, aturan Anda memeriksa `counterparty.country_code`, tetapi Anda tidak mengirim pihak lawan.
* **Konversi mata uang**: ambang batas aturan diterapkan pada `amount_in_default_currency`. Jika mata uang default aplikasi Anda berbeda dengan mata uang transaksi, jumlah yang dikonversi mungkin berada di bawah ambang batas.

Gunakan fitur *Rules → \[rule] → Backtest* untuk memutar ulang transaksi lama dan melihat mengapa aturan terpicu atau tidak.

## Aturan terpicu pada semua transaksi

**Gejala.** Sebuah aturan terpicu pada 90%+ transaksi, dan antrean peninjauan Anda membludak.

**Penyebab.** Kondisinya terlalu luas, atau ambang batasnya terlalu rendah.

**Solusi.**

* Tambahkan filter `scope` untuk mempersempit cakupan (misalnya, hanya transaksi keluar, atau hanya jenis transaksi tertentu).
* Naikkan ambang batas (jumlah dan frekuensi transaksi).
* Atur aturan ke mode `TEST` selama seminggu, lalu analisis `rule_runs` untuk melihat tingkat kecocokan dan perketat kondisi sebelum mengaktifkannya kembali.

## Skrining kripto melewati batas waktu

**Gejala.** Transaksi selesai dengan `status: APPROVED`, tetapi larik `provider_results[]` menampilkan `status: FAILED` untuk sebuah dompet, hash transaksi, atau penyedia skrining kripto.

**Penyebab.**

* API penyedia sempat tidak tersedia.
* Waktu kueri habis (biasanya sekitar 10 detik).

**Solusi.**

* Transaksi tidak pernah gagal karena masalah penyedia. Pengayaan dilakukan dengan upaya terbaik.
* Jika penyedia tertentu terus gagal, periksa halaman statusnya atau buka tiket dukungan.
* Pertimbangkan mengonfigurasi preferensi penyedia di *Settings → Transaction Monitoring → Providers* untuk mengarahkan permintaan ke penyedia alternatif.

## Pengayaan IP tidak ada

**Gejala.** `applicant.ip_enrichment` pada transaksi tidak ada atau tidak lengkap.

**Penyebab.**

* Tidak ada `applicant.device.ip` dalam permintaan.
* IP bersifat privat atau dicadangkan (tidak dapat dirutekan).
* Semua penyedia pengayaan sementara tidak tersedia.

**Solusi.**

* Ambil IP pengirim di klien atau server Anda, dan sertakan pada setiap transaksi.
* Gunakan hanya IP yang dapat dirutekan. Didit melewati rentang privat tanpa pemberitahuan.
* Periksa *Settings → Status* di konsol untuk melihat status kesehatan penyedia.

## Tanda tangan webhook tidak cocok

**Gejala.** Endpoint Anda menolak event karena tanda tangannya tidak cocok.

**Penyebab.**

* Body mentah permintaan telah diubah (JSON di-stringify ulang dengan spasi yang berbeda).
* Rahasia yang salah.
* Beberapa tujuan dengan URL yang sama. Tanda tangan berbeda untuk setiap tujuan.

**Solusi.**

* **Tanda tangani body permintaan mentah**, bukan JSON yang sudah diurai. Banyak kerangka kerja menyediakan middleware raw-body.
* Rotasi rahasia jika bocor: *Webhook destinations → \[destination] → Rotate secret*.
* Gunakan satu tujuan per URL untuk menghindari kebingungan rahasia.

## Webhook tidak diterima

**Gejala.** Transaksi dibuat, tetapi webhook tidak pernah sampai.

**Penyebab.**

* `enabled` pada tujuan bernilai `false`.
* URL tidak dapat dijangkau secara publik.
* Tujuan dinonaktifkan otomatis setelah kegagalan berulang.
* Event tidak ada di `subscribed_events`.

**Solusi.**

* Kirim event uji: *Webhook destinations → \[destination] → Send test*.
* Periksa pengiriman terbaru: *Webhooks → \[destination] → Deliveries*. Lihat respons 4xx/5xx beserta body dan header-nya.
* Aktifkan kembali tujuan yang dinonaktifkan.

## Konversi mata uang tampak salah

**Gejala.** `amount_in_default_currency` tidak sesuai dengan kurs yang Anda harapkan.

**Penyebab.**

* Kurs FX adalah kurs pasar tengah pada `txn_date`.
* Transaksi dengan tanggal mundur menggunakan kurs historis pada tanggal tersebut.
* Beberapa mata uang (FX eksotis) memiliki interval pembaruan yang lebih jarang.

**Solusi.**

* Gunakan `amount` dan `currency` (asli) untuk tampilan.
* Gunakan `amount_in_default_currency` hanya untuk penerapan ambang batas aturan internal.
* Untuk audit, catatan transaksi mencatat kurs konversi yang digunakan pada saat evaluasi.

## Counterparty tidak cocok dengan daftar blokir saya

**Gejala.** Anda sudah memasukkan bisnis ke daftar blokir menggunakan `vendor_data`, tetapi transaksi dengan pihak lawan tersebut tetap berhasil.

**Penyebab.**

* Pihak lawan dalam payload transaksi tidak memiliki `vendor_data`, sehingga data disimpan sebagai snapshot eksternal.
* Penulisan huruf besar dan kecil pada `vendor_data` berbeda.

**Solusi.**

* Selalu kirimkan `counterparty.vendor_data` jika pihak lawan adalah entitas di platform Anda.
* Gunakan penulisan huruf yang sama di semua tempat. `vendor_data` bersifat peka huruf besar-kecil.

## Transaksi AWAITING\_USER tertahan

**Gejala.** Transaksi tertahan di `AWAITING_USER` karena pengguna tidak pernah menyelesaikan sesi remediasi.

**Penyebab.**

* Pengguna tidak membuka URL sesi remediasi.
* Sesi remediasi sudah kedaluwarsa.
* Transaksi merupakan transfer Travel Rule yang dipindahkan ke `AWAITING_USER` oleh aturan library, seperti `travel-rule-pending-action`. Didit tidak membuat sesi remediasi default untuk transaksi Travel Rule, sehingga kecuali aturan tersebut menentukan alur kerja remediasinya sendiri, tidak ada tautan yang bisa dikirimkan.

**Solusi.**

* `remediation_session_url` pada respons transaksi adalah tautan yang harus dikirimkan. Kirim ulang tautan tersebut kepada pengguna.
* Untuk transaksi Travel Rule, selesaikan transfer dari tab **Travel Rule**, lalu ubah status transaksi secara manual. Menyelesaikan transfer saja tidak otomatis memindahkan transaksi keluar dari `AWAITING_USER`.
* Sesi remediasi mengikuti pola yang sama dengan [panduan mulai cepat KYC](https://docs.didit.me/id/getting-started/quick-start.md). Berlangganan webhook penyelesaian.
* Atur batas waktu di sistem Anda sendiri agar transaksi yang tidak lagi aktif kedaluwarsa jika remediasi tidak pernah selesai.

## Batas laju saat membuat transaksi

**Gejala.** `429 Too Many Requests` muncul saat lonjakan trafik yang besar.

**Solusi.**

* Patuhi header `Retry-After`.
* Batasi laju permintaan di sisi klien saat terjadi lonjakan trafik.
* Hubungi dukungan untuk meminta batas yang lebih tinggi berdasarkan volume produksi yang sudah terbukti.

Lihat [batas laju](https://docs.didit.me/id/integration/rate-limiting.md).

## Langkah berikutnya

> [card] [Panduan integrasi](https://docs.didit.me/id/transaction-monitoring/integration-guide.md)
>
> Pola integrasi lengkap.

> [card] [Aturan](https://docs.didit.me/id/transaction-monitoring/rules.md)
>
> Cara kerja evaluasi aturan.

> [card] [Webhook](https://docs.didit.me/id/transaction-monitoring/webhooks.md)
>
> Mekanisme webhook.


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