Integrasi Mobile•Security & API

API Signature (init-linkage)

Endpoint /api/init-linkage adalah gerbang utama yang menerbitkan token identitas terenkripsi (Signature) sebelum WebView dibuka. Signature mengikat data pengguna dan parameter fisik perangkat secara kriptografis.

Spesifikasi Endpoint

POST{BASE_URL_SEAMLESS}/api/init-linkage
Header Request
ParameterTipe DataStatusDeskripsi & Contoh
Content-TypestringWajib
Format media pengiriman data.
Contoh: application/json
Body Request (JSON Object)
ParameterTipe DataStatusDeskripsi & Contoh
userFullnamestringWajib
Nama lengkap user sesuai data aplikasi mitra (akan tampil di profil webview).
Contoh: ERWIN RUDIYANTO
userPhonestringWajib
Nomor handphone akun pengguna.
Contoh: 081234567890
deviceIdstringWajib
UUID unik perangkat fisik asli. Wajib stabil dan tidak boleh berganti-ganti antar sesi.
Contoh: a8f9c2d1-e5b7-4a6c-9f8d-1234567890ab
installIdstringWajib
FCM registration token atau instance ID instalasi aplikasi pada perangkat.
Contoh: fcm_token_client_12345
deviceBrandstringWajib
Merek perangkat pengguna (maksimal 100 karakter).
Contoh: samsung / apple / xiaomi
deviceModelstringWajib
Model perangkat pengguna (maksimal 100 karakter).
Contoh: SM-G991B / iPhone16,1
clientTypestringOpsional
Tipe aplikasi client mitra. Default bernilai 'QoinApp' bila tidak dikirim.
Contoh: QoinApp
clientIdstringWajib
Kredensial Client ID yang diberikan oleh Qoin.
clientSecretstringWajib
Kredensial rahasia Client Secret yang diberikan oleh Qoin.

Spesifikasi Respon & Kode Status HTTP

API mengembalikan string signature terenkripsi RSA-OAEP-SHA256 (Base64) saat seluruh parameter dan kredensial berhasil diverifikasi.

Data Respon Sukses (HTTP 200 OK)
ParameterTipe DataStatusDeskripsi & Contoh
signaturestringWajib
String token terenkripsi RSA-OAEP-SHA256 (Base64) yang membungkus kredensial dan metadata perangkat pengguna.
Contoh: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDp7...
{
  "signature": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDp7qWq..."
}

Kamus Kode Status HTTP

HTTP StatusKondisi / PenyebabTindakan Mitra
200 OKKredensial dan format data valid. Token signature berhasil diterbitkan.Simpan string signature ke secure storage aplikasi untuk disuntikkan ke WebView via postMessage.
400 Bad RequestField wajib belum lengkap, panjang brand/model melebihi 100 karakter, atau kombinasi clientId & clientSecret tidak cocok di IdentityServer.Periksa kembali kelengkapan field body dan pastikan kredensial client sudah diverifikasi aktif oleh tim Qoin.
503 Service UnavailableLayanan validasi kredensial IdentityServer sedang dalam pemeliharaan atau tidak dapat dijangkau (fail-closed security gate).Lakukan retry beberapa saat lagi atau hubungi Technical Support Qoin.
500 Internal ErrorKegagalan internal enkripsi kriptografi RSA server.Hubungi tim integrasi Qoin jika kendala berlanjut.

Rekomendasi Arsitektur: Panggilan Server-to-Server (S2S)

Mengingat request ini membutuhkan clientSecret, sangat tidak disarankan melakukan pemanggilan ini langsung dari aplikasi mobile:

Pola Aliran Server-to-Server (Direkomendasikan)
  1. Aplikasi mobile client mengumpulkan data perangkat fisik (deviceId, deviceBrand, dll).
  2. Aplikasi mobile mengirimkan data perangkat tersebut ke Backend Server Client sendiri.
  3. Backend Server Client menambahkan clientId & clientSecret, lalu menembak POST /api/init-linkage ke Qoin.
  4. Backend Server Client menerima string signature dan mengembalikannya ke aplikasi mobile.
  5. Aplikasi mobile menyimpan signature tersebut di local secure storage dan menyuntikkannya ke WebView.

Cara Mengambil Parameter Perangkat di Tiap Platform

import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';

Future<Map<String, String>> getDeviceInfo() async {
  final deviceInfo = DeviceInfoPlugin();
  if (Platform.isAndroid) {
    final android = await deviceInfo.androidInfo;
    return {
      'deviceId': android.id, // ID unik Android hardware
      'deviceBrand': android.brand,
      'deviceModel': android.model,
    };
  } else if (Platform.isIOS) {
    final ios = await deviceInfo.iosInfo;
    return {
      'deviceId': ios.identifierForVendor ?? 'unknown',
      'deviceBrand': 'apple',
      'deviceModel': ios.utsname.machine,
    };
  }
  return {};
}