Gambaran integrasi
Cekkas dipasang di aplikasi Anda sebagai mini-app / webview yang memuat halaman cekkas.com/embed/…. Di dalamnya user melihat dashboard keuangannya sendiri: saldo, pemasukan, pengeluaran, budget, utang, dan tabungan. Pencatatan hariannya tetap lewat chat WhatsApp — mini-app adalah jendela bacanya.
Yang Anda bangun hanyalah pintu masuk: menu atau ikon di aplikasi Anda yang membuka satu URL Cekkas. Ada dua cara Cekkas mengenali user Anda, dipilih satu per partner saat onboarding:
| Mode HMAC | Mode auth-code | |
|---|---|---|
| Cara kerja | Backend Anda menandatangani token berisi nomor HP user, lalu webview membuka URL SSO Cekkas | Shell mini program mengambil authCode dari SDK platform, mengirimkannya ke Cekkas, lalu Cekkas menukarnya ke server Anda |
| Cocok untuk | Partner yang sudah KYC nomor HP user (telco, bank, e-wallet, koperasi) | Platform mini program (DANA, GoPay/Midtrans, dan sejenisnya) yang tidak membagikan nomor HP |
| Yang Anda siapkan | Penandatangan token di backend (± 20 baris kode) | Endpoint exchange auth-code di server Anda + kredensialnya |
| Yang Cekkas berikan | Slug partner + secret HMAC (sekali, lewat kanal aman) | Slug partner + URL endpoint Cekkas |
Kedua mode berakhir sama: user mendarat di cekkas.com/embed/dashboard dengan sesi yang sudah terpasang.
Sebelum mulai
Checklist onboarding — selesaikan bersama tim Cekkas sebelum tanggal go-live disepakati:
- Whitelist domain. Daftarkan
cekkas.com(beserta subdomainnya) di konfigurasi webview/mini program platform Anda. Tanpa ini halaman Cekkas tidak akan terbuka di dalam aplikasi. - Webview atau iframe. Konfirmasi tertulis. Webview adalah jalur standar yang kami rekomendasikan — cookie sesi first-party jauh lebih andal di Safari/Chrome mobile. Iframe tetap bisa, tapi origin Anda harus didaftarkan dulu di sisi Cekkas (lihat bagian 06).
- Mode auth & kredensial. HMAC → Cekkas menerbitkan secret partner dan menyerahkannya sekali lewat kanal aman; simpan hanya di backend. Auth-code → Anda menyerahkan spesifikasi endpoint exchange + kredensial sandbox (bagian 04).
- KYC nomor HP (mode HMAC). Anda menyatakan bahwa nomor HP yang dikirim di token sudah terverifikasi milik user tersebut. Seluruh model kepercayaan SSO bertumpu pada ini.
- Kontak teknis. Satu nama + kanal (email/WhatsApp) di tiap pihak untuk integrasi dan insiden, plus jam respons yang disepakati.
- Uji end-to-end di sandbox sesuai checklist di bagian 09.
Mode HMAC
Format token
token = base64url(payload_JSON) + "." + hex(HMAC_SHA256(base64url_string, secret))Dua bagian dipisah satu titik:
- Payload — objek JSON yang di-encode base64url tanpa padding (karakter
=membuat token ditolak). - Signature — HMAC-SHA256 atas string base64url tersebut apa adanya memakai secret partner, ditulis heksadesimal (huruf besar/kecil diterima; rekomendasi: huruf kecil).
⚠️ Tanda tangani byte yang persis sama dengan yang dikirim. Jangan meng-encode payload lalu menandatangani hasil serialize ulang JSON-nya — urutan key atau spasi yang berbeda menghasilkan signature yang berbeda. Alurnya selalu: serialize sekali → base64url → tanda tangani string itu → kirim string itu.
Field payload
{
"partner": "namapartner",
"phone": "628123456789",
"partner_user_id": "opsional-id-user-di-sisi-partner",
"name": "opsional-nama-user",
"iat": 1755590000,
"exp": 1755590120,
"nonce": "c0ffee-sekali-pakai"
}| Field | Wajib | Ketentuan |
|---|---|---|
| partner | Ya | Slug partner yang diberikan Cekkas saat onboarding. |
| phone | Ya | Nomor HP user yang sudah Anda verifikasi. Format 08…, 62…, atau +62… diterima; Cekkas menormalkannya ke 62…. Panjang 10–15 digit, hanya nomor Indonesia. |
| partner_user_id | Opsional | ID user di sisi Anda; disimpan untuk atribusi dan pelaporan agregat. |
| name | Opsional | Nama tampilan — dipakai bila akun baru dibuat. |
| iat | Ya | Waktu terbit, epoch detik (bukan milidetik). |
| exp | Ya | Kedaluwarsa, epoch detik. exp − iat harus lebih dari 0 dan maksimal 300 detik — token berumur lebih panjang ditolak seketika, bukan sekadar dianggap kedaluwarsa. Rekomendasi: iat + 120. Toleransi selisih jam server ±60 detik — pastikan server Anda ber-NTP. |
| nonce | Ya | String acak sekali pakai (mis. UUID). Token dengan nonce yang pernah masuk langsung ditolak — satu URL SSO tidak bisa diputar ulang. Buat token tepat sebelum membuka webview; jangan pernah di-cache. |
Endpoint
GET https://cekkas.com/api/partner/sso?token=<base64url(payload)>.<hex(hmac)>URL ini harus dibuka sebagai navigasi (webview membuka URL-nya), bukan dipanggil via fetch/XHR — response-nya redirect yang sekaligus memasang cookie sesi di webview. Sukses → 303 ke /embed/dashboard dengan cookie sesi terpasang; gagal → 303 ke halaman error netral /embed/error (lihat bagian 07).
Contoh implementasi
const crypto = require("crypto");
// Secret dari Cekkas — hanya boleh hidup di backend Anda.
const PARTNER_SLUG = "namapartner";
const SSO_SECRET = process.env.CEKKAS_SSO_SECRET;
function buildCekkasSsoUrl(phone, opts = {}) {
const now = Math.floor(Date.now() / 1000);
const payload = {
partner: PARTNER_SLUG,
phone, // 08… / 62… / +62…
partner_user_id: opts.userId, // opsional
name: opts.name, // opsional
iat: now,
exp: now + 120, // maksimal 300 detik dari iat
nonce: crypto.randomUUID(), // sekali pakai
};
const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
const signature = crypto.createHmac("sha256", SSO_SECRET).update(encoded).digest("hex");
return `https://cekkas.com/api/partner/sso?token=${encoded}.${signature}`;
}function buildCekkasSsoUrl(string $phone, ?string $userId = null, ?string $name = null): string
{
$secret = getenv('CEKKAS_SSO_SECRET');
$now = time();
$payload = array_filter([
'partner' => 'namapartner',
'phone' => $phone,
'partner_user_id' => $userId,
'name' => $name,
'iat' => $now,
'exp' => $now + 120,
'nonce' => bin2hex(random_bytes(16)),
], fn ($v) => $v !== null);
// base64url TANPA padding — karakter '=' membuat token ditolak.
$encoded = rtrim(strtr(base64_encode(json_encode($payload)), '+/', '-_'), '=');
$signature = hash_hmac('sha256', $encoded, $secret);
return "https://cekkas.com/api/partner/sso?token={$encoded}.{$signature}";
}import base64, hashlib, hmac, json, os, time, uuid
def build_cekkas_sso_url(phone, user_id=None, name=None):
secret = os.environ["CEKKAS_SSO_SECRET"].encode()
now = int(time.time())
payload = {"partner": "namapartner", "phone": phone,
"iat": now, "exp": now + 120, "nonce": uuid.uuid4().hex}
if user_id:
payload["partner_user_id"] = user_id
if name:
payload["name"] = name
# base64url tanpa padding — karakter '=' membuat token ditolak.
encoded = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b"=").decode()
signature = hmac.new(secret, encoded.encode(), hashlib.sha256).hexdigest()
return f"https://cekkas.com/api/partner/sso?token={encoded}.{signature}"Kesalahan integrasi yang paling sering
| Gejala | Penyebab umum |
|---|---|
| Selalu mendarat di halaman error, padahal payload benar | Signature dihitung atas JSON mentah (bukan string base64url), atau payload di-serialize ulang sebelum ditandatangani. |
| Kadang berhasil, kadang tidak | Nonce dipakai ulang (URL di-cache / user menekan back lalu reload), atau jam server melenceng lebih dari 60 detik. |
| Ditolak walau baru dibuat | exp − iat melebihi 300 detik, iat/exp dalam milidetik (bukan detik), atau base64 masih mengandung padding = / karakter + /. |
| Berhasil tapi sesi tidak terpasang | URL dipanggil via fetch/XHR alih-alih navigasi webview — cookie dari redirect tidak tersimpan. |
Mode auth-code
Dipakai saat platform tidak membagikan nomor HP user, hanya kode otorisasi berumur pendek. Alurnya:
- Shell mini program memanggil API otorisasi platform (misalnya
my.getAuthCodedi DANA) dan menerimaauthCodeberumur pendek. - Shell membuka URL Cekkas sambil membawa kode tersebut.
- Cekkas menukar kode itu ke server Anda memakai kredensial yang disimpan per partner, dan menerima identitas tetap user —
customerId. customerIdsudah pernah tertaut → sesi langsung terbentuk, user masuk ke/embed/dashboard. Baru → Cekkas membuatkan akun lalu mengarahkan user ke/embed/linkuntuk menautkan WhatsApp (bagian 05).
Cara memanggil dari shell
GET https://cekkas.com/api/partner/authcode/<slug>?auth_code=<authCode>
POST https://cekkas.com/api/partner/authcode/<slug>
Content-Type: application/json
{ "authCode": "<authCode>" }Parameter authCode di query string juga diterima. Keduanya berakhir sebagai redirect 303, jadi panggil sebagai navigasi webview, bukan fetch/XHR. Bila kredensial exchange belum dipasang (masa pra-approval) atau endpoint Anda error, permintaan ditolak rapi ke halaman error netral — Cekkas tidak pernah menebak identitas user.
Endpoint exchange yang Anda sediakan
Saat onboarding, serahkan ke tim Cekkas:
| Yang diserahkan | Keterangan |
|---|---|
| URL endpoint | Endpoint tukar authCode → identitas user (sandbox + produksi). |
| Method & format body | Default POST + JSON; x-www-form-urlencoded juga didukung. Beri tahu di field mana authCode diletakkan (boleh bersarang — mis. pola SNAP). |
| Kredensial / header | API key, client id/secret, atau header khusus yang harus Cekkas kirim. |
| Bentuk response | JSON. Beri tahu path field-nya, misalnya response.body.customerId. |
Ketentuan response:
customerIdwajib dan harus stabil — ID yang sama untuk user yang sama di setiap login. Ini kunci pencocokan akun; ID yang berubah berarti user kehilangan akses ke datanya.nicknamedan nomor tersamar (mis.62812•••890) opsional — dipakai untuk nama tampilan dan konfirmasi visual di halaman penautan.- Balas dalam ≤ 10 detik dengan HTTP 200 + JSON. Status non-200, body non-JSON, atau timeout diperlakukan sebagai gagal.
- Jika platform membutuhkan skema khusus yang tidak muat di pola request/response biasa (mis. tanda tangan RSA per-request), sampaikan saat onboarding — Cekkas menyiapkan adapter khusus di sisinya.
Penautan WhatsApp
Pencatatan Cekkas berjalan lewat chat WhatsApp, jadi akun yang masuk lewat jalur auth-code (Cekkas belum tahu nomornya) perlu dikawinkan dengan nomor WhatsApp user — sekali saja.
- Setelah SSO pertama, user melihat halaman
/embed/linkberisi kode 8 karakter yang berlaku 15 menit (karakter yang mirip seperti O/0 dan I/1 tidak dipakai). - User mengirim pesan ke bot WhatsApp Cekkas:
HUBUNGKAN A7KQ2M9P - Nomor pengirim sudah terdaftar di Cekkas → akun WhatsApp itu ditautkan; user melihat seluruh data lamanya. Belum terdaftar → nomor diklaim untuk akun tersebut, user bisa langsung mencatat lewat chat (termasuk trial 7 hari — dilacak per nomor, sekali seumur hidup). Kode sekali pakai dan kedaluwarsa otomatis.
Notifikasi keamanan first-link. Saat akun Cekkas yang sudah ada pertama kali tertaut ke sebuah partner, pemiliknya menerima WhatsApp: “Akun Cekkas kamu baru saja dihubungkan ke [Nama Partner]…”. Balasan BLOKIR PARTNER memutus seluruh tautan partner akun itu seketika. Tidak perlu penanganan apa pun di sisi Anda — cukup diketahui agar tim support Anda tidak kaget.
Menyematkan halaman
- Webview (direkomendasikan). Buka URL SSO sebagai navigasi penuh di webview. Cookie sesi bersifat first-party terhadap
cekkas.com, jadi berfungsi normal di iOS/Android. - Iframe. Halaman
/embed/*dilindungi headerContent-Security-Policy: frame-ancestors. Origin aplikasi Anda harus didaftarkan di sisi Cekkas terlebih dulu — tanpa itu browser menolak me-render iframe-nya. Uji ekstra perilaku cookie pihak ketiga di Safari. - Halaman yang dimuat:
/embed/dashboard— dashboard baca (saldo, ringkasan, transaksi terakhir). Tombol upgrade di dalamnya mengarahkan user ke WhatsApp, bukan ke checkout di dalam webview — tidak ada alur pembayaran yang berjalan di dalam aplikasi Anda.
Sukses & error
Semua respons endpoint partner berbentuk redirect 303. Kegagalan selalu berakhir di halaman error yang netral — alasan teknis (signature salah, nonce terpakai, config kosong, dst.) sengaja tidak dibocorkan ke URL maupun ke layar, supaya tidak bisa dipakai sebagai alat probing dan tidak menakuti user.
| Redirect tujuan | Artinya | Yang dilakukan shell Anda |
|---|---|---|
| /embed/dashboard | Sukses, sesi terpasang | — |
| /embed/link?code=… | Sukses (auth-code), user perlu menautkan WhatsApp | Biarkan halaman tampil; user mengikuti instruksi di layar |
| /embed/error?reason=token | Token/tautan tidak berlaku (kedaluwarsa, cacat, atau sudah dipakai) | Ulangi alur dari awal dengan token baru — jangan membuka ulang URL yang sama |
| /embed/error?reason=disabled | Akses partner sedang dinonaktifkan dari sisi Cekkas | Hubungi kontak teknis Cekkas |
| /embed/error (lainnya) | Kendala di sisi Cekkas / integrasi | Coba lagi; jika menetap, hubungi kontak teknis Cekkas |
Halaman error menyediakan tombol coba-lagi dan tautan bantuan WhatsApp untuk user, jadi shell Anda tidak wajib menangani apa pun — cukup jangan meng-cache URL SSO. Untuk debugging saat integrasi, koordinasikan dengan tim Cekkas: log server kami mencatat alasan spesifik setiap penolakan lengkap dengan slug partner.
Keamanan & data
- Secret HMAC dibuat acak 32 byte di server Cekkas, ditampilkan satu kali, diserahkan lewat kanal aman. Simpan hanya di backend (environment variable / secret manager) — jangan pernah di aplikasi mobile, kode front-end, atau repository.
- Rotasi secret berlaku seketika: token bertanda tangan secret lama langsung ditolak. Jadwalkan di jam sepi atau siapkan deploy bersamaan. Bila ada kecurigaan kebocoran, akses partner bisa dinonaktifkan dulu dari sisi Cekkas (kill-switch, tanpa deploy) sambil menunggu rotasi.
- Anti-replay berlapis: umur token maksimal 5 menit dan nonce sekali pakai — URL SSO yang bocor lewat log atau riwayat browser tidak bisa membuka sesi siapa pun.
- Data yang dibagi ke partner: status tautan (punya akun Cekkas / tidak) dan angka agregat untuk pelaporan. Tidak ada transaksi, saldo, kategori, atau isi catatan keuangan user yang dikirim ke partner. Arah sebaliknya, Cekkas hanya menerima nomor HP atau ID user Anda — bukan data transaksi di sisi Anda. Kesepakatan tertulis mengikuti UU PDP.
- Akun tidak pernah dobel: pencocokan memakai nomor HP (HMAC) atau customerId (auth-code). Nomor yang sudah terdaftar masuk ke akun lamanya beserta seluruh riwayat.
Checklist uji
Jalankan di sandbox sebelum go-live, minimal:
- User baru — SSO pertama kali membuat akun dan mendarat di dashboard (HMAC) atau halaman penautan (auth-code).
- User lama — nomor/ID yang sudah terdaftar masuk ke akun lamanya, data historis tampil.
- Token kedaluwarsa — token dengan exp lewat ditolak ke halaman error.
- Token diputar ulang — URL SSO yang sama dibuka dua kali; yang kedua ditolak.
- Signature salah — token dengan secret keliru ditolak.
- TTL kepanjangan — token dengan exp − iat lebih dari 300 detik ditolak.
- Partner dinonaktifkan — saat Cekkas mematikan akses, semua token langsung ditolak.
- (Auth-code) Alur HUBUNGKAN end-to-end: kode tampil → kirim di WhatsApp → buka ulang mini-app → dashboard berisi data. Kode kedaluwarsa / terpakai ditolak dengan instruksi ulang yang jelas.
- Notifikasi first-link diterima pemilik akun lama, dan BLOKIR PARTNER memutus tautan.
FAQ
Apakah user bisa mencatat transaksi dari dalam mini-app?
Untuk rilis pertama, mini-app adalah jendela baca (dashboard + ringkasan). Input tetap lewat chat WhatsApp — teks, foto struk, atau voice note.
Bolehkah token dibuat di aplikasi mobile langsung?
Tidak. Secret hanya boleh hidup di backend Anda. Aplikasi meminta URL SSO ke backend Anda, backend menandatangani, aplikasi tinggal membuka URL-nya.
Berapa lama sesi user bertahan di webview?
Sesi diperpanjang otomatis selama user aktif. Bila kedaluwarsa, user cukup membuka ulang menu Cekkas dari aplikasi Anda — alur SSO berjalan lagi tanpa terasa.
Server exchange kami (auth-code) sedang down — lalu?
User melihat halaman error netral dan bisa mencoba lagi. Tidak ada akun yang dibuat atau ditebak saat exchange gagal.
Bisakah kami pindah mode HMAC ↔ auth-code?
Bisa — mode diatur per partner di sisi Cekkas dan bisa diubah tanpa deploy dari pihak mana pun. Perpindahan disepakati lewat kontak teknis.
Tertarik jadi partner Cekkas?
Hubungi kami untuk membicarakan model kerja sama, kredensial sandbox, dan jadwal integrasi.