Skip to content

Compliance & KYC

Every safeguard the BCC and FATF require is enforced at the API boundary. Skipping a field is not an option — the request is rejected with a clear error code, not silently degraded.

FATF R.16 (Recommendation 16 — wire transfers)

FATF R.16 requires accurate and meaningful originator + beneficiary information on every cross-border transfer.

Fields Moko enforces from FATF R.16

FieldWhere
sender_first_name, sender_last_name/inbound required
sender_nationality/inbound required
sender_birthdate/inbound required
identity_number/inbound required
sender_document_type (enum)/inbound required — one of PASSPORT, NATIONAL_ID, DRIVING_LICENCE, VOTER_CARD, OTHER
receiver_first_name, receiver_last_name/inbound required
receiver_nationality/inbound required
receiver_birthdate/inbound required
reason_of_transaction (enum)/inbound required — see enum below
source_of_funds (enum)/inbound required — see enum below
expected_receiver_name/inbound required — fuzzy-matched against the telco subscriber record

reason_of_transaction enum (23 values)

FAMILY_SUPPORT, EDUCATION, MEDICAL, BUSINESS_PAYMENT, SALARY, GIFT, SAVINGS, PROPERTY_PURCHASE, TRAVEL, LOAN_REPAYMENT, INVESTMENT, CONSTRUCTION, RENT, GENERAL, FUEL, REPAIRS, PERSONAL_CARE, FOOD_AND_GROCERIES, TRANSPORT, SHOPPING, ENTERTAINMENT, DONATIONS, OTHER.

Invalid value → RMT-1016.

source_of_funds enum

SALARY, BUSINESS_INCOME, SAVINGS, INVESTMENT, PENSION, GIFT, LOAN, SALE_OF_ASSET, INHERITANCE, OTHER.

Invalid value → RMT-1017.

Name-match on /inbound

Moko does a fuzzy match between the merchant's declared expected_receiver_name and the actual telco subscriber name.

  • Case-insensitive
  • Token-set based (order and casing ignored, but tokens must overlap)
  • Rejects abbreviated or truncated names (a 2-char first name like Ab for Abdullah is rejected at the sanction-defense layer with RMT-1010 before the name-match even runs)

If your declared name does not match the telco record, you receive RMT-4006 with the telco name and a match score. Fix the expected_receiver_name and re-submit — the reference is idempotent so a retry does not duplicate the transaction.

BCC RTS Art.66 Instr.15

DRC's central bank regulation on cross-border remittance record-keeping. Requires extended KYC and address information on both legs.

Fields Moko enforces from BCC RTS Art.66

FieldWhere
sender_birthplace/inbound required
receiver_current_address or receiver_permanent_address/inbound required — at least one. RMT-1018 if both missing.
receiver_document_type/inbound required
receiver_document_number/inbound required

ScreenShield (sanctions screening)

Every sender and every receiver is screened against the Vodacom AML feed in real time.

  • Match found on the receiver → transaction rejected up-front
  • Match found on the sender → transaction accepted but placed on Hold status; Moko compliance reviews and surfaces the outcome in the partner portal
  • No match → transaction proceeds

Data protection

  • PII columns are Fernet-encrypted at rest
  • Pickup codes are hashed
  • Merchant secrets are stored as scrypt hashes
  • Callbacks are HMAC-SHA256 signed and delivered only over TLS 1.2+

What NOT to do

  • Do not fake sender_birthplace, receiver_document_number, or any other KYC field to pass the schema check. Moko audits inbound payloads; systematic fake data on a merchant account is a Go Live-blocking issue.
  • Do not re-use the same reference for two different transactions. The API is idempotent on reference, so we return the first result.
  • Do not forward the raw sender document image to Moko — we do not accept it. All KYC is field-based.

Operated by SODOTECH SARL (RCCM CD/KNG/RCCM/24-B-00910). Documentation is versioned alongside the API. Confidential — for integration partners.