TURBOPULSA DEVELOPER API
Transaksi digital yang mudah diintegrasikan.
Satu alur untuk katalog, penawaran, pembayaran, dan status. Mulai dari sandbox; gunakan harga agen serta Saldo Rupiah ketika layanan produksi tersedia.
Sandbox memakai saldo dan hasil simulasi. Transaksi produksi mengikuti ketersediaan layanan TurboPulsa; membuka docs atau membuat key tidak mengaktifkan pembayaran.
MULAI DI SINI
Dari aplikasi Anda ke pelanggan.
Buat proyek dan key sandbox
Default key hanya membaca. Pilih izin quote/inquiry dan konfirmasi untuk mencoba alur lengkap.
Pilih kode dan isi tujuan
Gunakan metadata katalog. Nomor HP, ID pemain, nomor meter, dan ID pelanggan selalu berupa teks.
Bayar setelah persetujuan
Konfirmasi memakai token quote. Baca order yang sama atau terima webhook hingga hasil jelas.
Alamat API
https://api.turbopulsa.com/sandbox/v1https://api.turbopulsa.com/v1Deposit dilakukan di Isi Saldo Rupiah. API tidak menyediakan transfer, penarikan, atau konversi ke Kredit AI.
API KEY DAN KEAMANAN
Izin yang sesuai untuk setiap integrasi.
Authorization: Bearer tp_test_KEY_SANDBOX_ANDA
Accept: application/json
Idempotency-Key: UUID_UNTUK_USAHA_INIKey disimpan di environment server dan ditampilkan sekali ketika dibuat. Gunakan key sandbox dan produksi terpisah, batasi scope, pengeluaran, masa berlaku, serta IP/CIDR bila diperlukan.
Pembuatan key dengan izin pembayaran atau hasil sensitif memerlukan kata sandi dan autentikator bila aktif. Akun sosial dapat menyiapkan kata sandi melalui pemulihan email. Perubahan kata sandi, autentikator, atau pemulihan akun mencabut seluruh key TurboPulsa.
API key tidak ditempatkan di browser, APK, URL, analytics, atau log. JavaScript browser memanggil backend aplikasi Anda yang sudah memeriksa sesi, izin pengguna, dan CSRF.
ALUR TRANSAKSI
Quote dahulu, konfirmasi sesudahnya.
Ambil kode produk dari katalog. Tampilkan harga dan tujuan untuk persetujuan pengguna sebelum memanggil konfirmasi. Gunakan kode penyedia dan inquiry untuk tagihan; biaya admin sudah termasuk dalam total backend.
# Simpan API key di environment server. Pertahankan reference dan UUID untuk retry usaha yang sama.
curl --fail-with-body 'https://api.turbopulsa.com/sandbox/v1/quotes' \
-H "Authorization: Bearer $TURBOPULSA_API_KEY" \
-H 'Accept: application/json' \
-H "Idempotency-Key: $TURBOPULSA_REQUEST_UUID" \
-H 'Content-Type: application/json' \
--request POST --data '{
"product_code": "KODE_DARI_KATALOG",
"client_reference": "ORDER-CONTOH-1001",
"destination": {
"phone": "081200000000"
}
}'Contoh memakai kode dan tujuan ilustrasi. Ganti kode dengan katalog aktif, simpan UUID sebelum mengirim, dan pertahankan UUID yang sama ketika retry. Setiap pembelian mempunyai client_reference yang tetap, termasuk setelah rotasi key.
| Method | Resource | Fungsi |
|---|---|---|
| GET | /capabilities | Kemampuan dan batas integrasi |
| GET | /catalog | Katalog prabayar terbit |
| GET | /postpaid/catalog | Penyedia dan wilayah pascabayar |
| GET | /wallet | Saldo tersedia dan dana ditahan |
| POST | /quotes | Buat penawaran prabayar |
| POST | /postpaid/inquiries | Cek tagihan pascabayar |
| GET | /postpaid/inquiries/{id} | Status cek tagihan |
| GET | /orders | Riwayat integrasi |
| GET | /orders/{id} | Status order yang sama |
| POST | /orders/{id}/confirm | Konfirmasi dan bayar dari Saldo Rupiah |
| POST | /orders/{id}/cancel | Batalkan order yang belum diproses |
| GET | /orders/{id}/result | Hasil sukses yang privat |
| POST | /orders/{id}/resolve | Selesaikan simulasi pendingHanya sandbox |
| POST | /scenarios/reset | Reset saldo simulasi setelah semua hold selesaiHanya sandbox |
Saat status belum selesai
Diproses, pending, atau sedang diperiksa berarti order masih berjalan. Timeout tidak berarti pembelian gagal. Baca ID order atau referensi yang sama; jangan mengirim pembelian baru. HTTP 202 berarti diterima untuk diproses, bukan bukti transaksi berhasil.
Quote habis atau harga berubah membutuhkan penawaran serta persetujuan baru. Token konfirmasi, tujuan, dan produk harus tetap sesuai dengan penawaran yang dipilih.
Contoh lengkap di bawah mendukung prabayar dan pascabayar. Untuk tagihan, set TURBOPULSA_KIND=postpaid serta TURBOPULSA_CUSTOMER_NO, gunakan kode penyedia dari katalog pascabayar. Inquiry yang masih pending diperiksa dengan ID yang sama; konfirmasi menunggu total dan persetujuan pengguna. Simpan client_reference dan UUID sebelum request. Harga berubah atau quote habis harus diperiksa ulang.
WEBHOOK
Terima status, tanpa polling berlebihan.
Daftarkan URL HTTPS publik melalui pengelolaan integrasi. Setiap pengiriman membawa event ID dan versi order; webhook tidak berisi nomor pelanggan lengkap, token PLN, atau voucher. Ambil hasil sukses melalui endpoint hasil dengan scope khusus.
import crypto from 'node:crypto'
// Express: pasang express.raw({type: 'application/json'}) pada route webhook.
// Jangan parse JSON sebelum signature diverifikasi.
function verify(rawBody, signature, secret, now = Date.now()) {
const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(signature || '');
if (!match || Math.abs(now / 1000 - Number(match[1])) > 300) return false;
const expected = crypto.createHmac('sha256', secret)
.update(match[1] + '.').update(rawBody).digest();
return crypto.timingSafeEqual(expected, Buffer.from(match[2], 'hex'));
}
// Setelah valid: transaksi DB receiver dengan UNIQUE(event.id).
// Terapkan status hanya bila data.version > versi yang sudah disimpan.
// Balas 2xx untuk event yang sudah pernah diterima.
// Simpan event sebelum 2xx; jangan memicu pembelian baru dari webhook.
Signature dihitung dari timestamp + "." + rawBody. Verifikasi dengan perbandingan aman dan toleransi waktu 300 detik, lalu simpan event ID secara unik di database Anda. Event duplikat tetap dibalas 2xx; versi status lama tidak mengganti versi baru.
Pengiriman dapat berulang dan datang terlambat. Retry atau replay webhook hanya mengirim event yang sama, tidak membeli produk kembali. Endpoint tidak mengikuti redirect, dan tujuan jaringan privat ditolak pada setiap upaya.
ERROR DAN RETRY
Ketahui langkah berikutnya.
| Kode | HTTP | Tindakan |
|---|---|---|
invalid_api_key | 401 | Key dicabut, kedaluwarsa, atau lingkungan berbeda. |
scope_required | 403 | Tambahkan izin melalui key baru; default key hanya membaca. |
insufficient_balance | 402 | Isi Saldo Rupiah melalui website. |
idempotency_conflict | 409 | Gunakan UUID/payload awal untuk usaha yang sama. |
reference_consumed | 409 | Baca transaksi dengan referensi yang sudah dikonfirmasi. |
quote_changed / quote_expired | 409 | Periksa penawaran baru dan minta persetujuan ulang. |
request_processing | 409/503 | Periksa resource atau retry penawaran dengan UUID awal; jangan membuat pembelian kedua. |
service_unavailable | 503 | Katalog dapat dijelajahi; transaksi mengikuti status layanan. |
rate_limit_exceeded | 429 | Ikuti Retry-After; jangan retry tanpa batas. |
Gunakan request_id ketika meminta bantuan. Sertakan ID order/referensi tanpa key, kata sandi, OTP, token konfirmasi, atau serial hasil.