Soal 1Ketika kamu menerima pembayaran lewat penyedia layanan pembayaran, ke mana data kartu mengalir?
Cara Kerja Penagihan — Apa yang Ditangani Stripe dan Pemberian Hak Akses lewat Webhook
Artikel ini adalah bagian dari kursus Dasar-Dasar Teknologi Informasi, yang membangun dari nol pengetahuan TI praktis yang minimal kamu butuhkan untuk memprogram dan melakukan vibe coding.
Data kartu berhenti di penyedia layanan pembayaran dan tidak pernah melewati server kamu sendiri. Diagram menunjukkan mengapa notifikasi webhook menjadi dasar untuk membuka fitur berbayar.
Artikel ini membahas cara kerja penagihan.
Isinya terbagi menjadi 2 bagian: menjaga agar data kartu tidak pernah sampai ke server kamu sendiri, dan menerapkan hasil pembayaran ke dalam aplikasi kamu.
Nomor kartu berhenti di cabang atas dan tidak pernah sampai ke my-app.
Satu-satunya dasar untuk membuka fitur berbayar adalah notifikasi yang datang lewat cabang bawah.
Penerimaan nomor kartu dan pertukaran data dengan penerbit kartu sama-sama terjadi di sisi penyedia layanan pembayaran, dan yang tersisa untuk my-app hanyalah menulis hasilnya ke dalam catatan.
Yang menerima data kartu adalah penyedia layanan pembayaran, bukan server kamu sendiri
Memproses pembayaran memerlukan nomor kartu, tanggal kedaluwarsa, dan kode keamanan.
PCI DSS (Payment Card Industry Data Security Standard) adalah standar yang harus dipatuhi pihak yang menangani data kartu, dan penyedia layanan pembayaran (payment service provider) adalah layanan luar yang menangani pembayaran kartu untuk kamu.
Stripe dan PayPal adalah penyedia layanan pembayaran yang paling dikenal.
Tempat kamu meletakkan kolom isian menentukan ke mana nomor kartu mengalir.
| Tempat kolom isian berada | Ke mana nomor kartu mengalir | Termasuk cakupan PCI DSS |
|---|---|---|
| Diterima dan disimpan oleh my-app | my-app dan penyedia layanan pembayaran | my-app ikut tercakup |
| Diterima my-app lalu diteruskan | my-app dan penyedia layanan pembayaran | my-app ikut tercakup |
| Halaman penyedia layanan pembayaran | Hanya penyedia layanan pembayaran | Cakupan my-app paling kecil |
Hanya baris ketiga yang tidak melewatkan nomor kartu ke server my-app.
Dalam kasus itu my-app hanya menyimpan nilai yang menandai pembayaran, sedangkan dua baris pertama meninggalkan nomor kartunya sendiri atau catatan lalu lintasnya.
Sekalipun kamu hanya meneruskannya tanpa menyimpan, nilai itu tetap melewati server kamu sendiri, dan begitu nilai itu melewatinya, my-app ikut masuk ke dalam cakupan PCI DSS.
Agar area yang harus dilindungi my-app sekecil mungkin, kolom isiannya sendiri kamu serahkan kepada penyedia layanan pembayaran.
- Nomor kartu, tanggal kedaluwarsa, kode keamanan
- Catatan pertukaran dengan penerbit kartu
- Nilai yang menandai pembayaran, pay_88
- Nominal, dan apakah pembayarannya selesai
- Pembayaran ini milik pengguna yang mana (u_1024)
Nomor kartu tidak pernah melewati my-app
Kalau kamu tidak pernah menerima sendiri nomor kartunya, tanggung jawab melindunginya juga tidak pernah jatuh ke sisi kamu.
Baik disimpan maupun langsung diteruskan, tanggung jawab yang sama tetap berlaku begitu nomor itu melewati server kamu sendiri, jadi kolom isiannya sendiri kamu serahkan kepada penyedia layanan pembayaran, dan yang sampai ke my-app hanya fakta bahwa pembayarannya selesai.
Pembayaran berakhir di halaman pembayaran pada domain penyedia layanan pembayaran
Halaman pembayaran hosted (hosted checkout page) adalah layar pembayaran yang disiapkan penyedia layanan pembayaran dan ditampilkan di domainnya sendiri, yaitu layar pengisian yang sengaja ditaruh di tempat lain supaya data kartu tidak melewati server kamu sendiri.
Memindahkan pengguna ke halaman di domain lain disebut redirect.
Pada tahap kedua kamu mengirimkan nominal dan URL kembali, lalu penyedia layanan pembayaran mengembalikan URL halaman pembayaran khusus untuk pembayaran itu.
Pertukaran ini dilakukan dengan memanggil web API, dan kamu menyertakan API key.
- Halaman pendaftaran paket berbayar
- /thanks, yang dibuka setelah pembayaran
- Halaman pembayaran tempat nomor kartu dimasukkan
- my-app tidak bisa melihat isi halaman ini
Halaman pembayaran juga ditawarkan sebagai bingkai yang diletakkan di dalam halaman my-app sendiri.
Tampilannya berbeda, tetapi nilai yang dimasukkan tetap menuju tempat yang sama.
Halaman pembayaran disiapkan oleh penyedia layanan pembayaran
Halaman tempat nomor kartu dimasukkan dimiliki oleh penyedia layanan pembayaran, bukan oleh my-app.
Redirect memindahkan pengguna ke halaman itu, dan setelah pembayaran mereka kembali ke /thanks; sekalipun kamu meletakkannya sebagai bingkai di halaman sendiri, nilai yang dimasukkan tetap menuju tempat yang sama.
Dasar pemberian hak akses adalah notifikasi Webhook, bukan halaman tempat pengguna kembali
Yang memutuskan boleh atau tidaknya fitur berbayar ditampilkan adalah my-app, bukan penyedia layanan pembayaran, dan catatan itulah yang disebut hak akses (entitlement, yaitu catatan tentang cakupan fitur yang bisa dipakai pengguna yang sudah membayar).
Layar pengguna yang kembali ke /thanks saja belum memberi tahu my-app apakah pembayarannya selesai.
Lihat apa yang terjadi setelah pembayaran sebagai 2 jalur yang terpisah.
Jalur atas berhenti begitu saja kalau pengguna menutup browser tepat setelah membayar.
Jalur bawah berjalan antar server, jadi kalau notifikasinya tidak sampai, pengirimannya diulang sebanyak jumlah dan selama jangka waktu yang sudah ditentukan.
Tergantung jalur mana yang kamu jadikan dasar, tiga orang yang sama bisa berakhir dengan hak akses yang berbeda.
| Yang terjadi pada pengguna itu | Kalau dinilai dari /thanks | Kalau dinilai dari /webhook |
|---|---|---|
| Membayar dan membuka /thanks | Hak akses diberikan | Hak akses diberikan |
| Membayar, lalu langsung menutup browser | Hak akses tidak diberikan | Hak akses diberikan |
| Membuka /thanks tanpa membayar | Hak akses diberikan | Hak akses tidak diberikan |
Kalau dinilai dari /thanks, orang yang menutup browser tidak mendapat apa-apa, sedangkan orang yang tidak pernah membayar justru mendapat hak akses.
Satu-satunya dasar pemberian hak akses adalah notifikasi di jalur bawah.
Pada pembayaran, menerapkan notifikasi yang sama dua kali membuat masa berlakunya diperpanjang dua kali.
Catat nilai yang menandai setiap notifikasi, dan biarkan hak aksesnya tetap ketika notifikasi yang sama datang untuk kedua kalinya.
Notifikasi yang tanda tangannya tidak cocok dibuang tanpa mengubah hak akses.
Perbedaan antara dua sisanya hanyalah apakah notifikasi itu sudah diterapkan atau belum.
- Nilai yang menandai pengguna, u_1024
- Hash password
- Jenis paket (paid)
- Tanggal berakhir
- Milik pengguna yang mana (u_1024)
- Nilai yang menandai notifikasi, evt_7
- Kapan notifikasi itu diterapkan
Sekalipun kamu menyembunyikan tombol berbayar di halaman, kodenya tetap sampai ke perangkat pengguna.
Memeriksa hak akses di sisi server setiap kali adalah otorisasi yang sama seperti yang dibahas di Cara Kerja Fitur Login.
Nomor kartu berhenti di dalam kotak tengah dan tidak masuk ke kotak sebelah kanan.
Hak akses diberikan ketika notifikasi pada panah 2 tiba, bukan ketika browser pengguna kembali.
Yang mengabarkan pembayaran adalah notifikasi dari server
Yang mengabarkan bahwa pembayarannya sudah selesai adalah notifikasi yang tiba dari server penyedia layanan pembayaran, bukan halaman tempat pengguna kembali.
Kamu mencocokkan tanda tangan pada apa yang tiba, membiarkan hak aksesnya tetap kalau notifikasi itu sudah pernah diterapkan, menuliskan hasilnya ke database sendiri, lalu memutuskan dari situ apakah fitur berbayar ditampilkan.
Pada langganan, notifikasi tiba setiap periode dan hak aksesnya berubah
Kontrak yang ditagih bulanan atau tahunan disebut langganan (subscription, yaitu kontrak yang pembayarannya berulang secara otomatis pada jangka waktu tertentu).
Pembayaran yang berulang tidak selalu berhasil setiap kali.
Pada baris kegagalan, penyedia layanan pembayaran menunggu beberapa hari lalu mengulang tagihannya.
my-app yang memutuskan apakah aksesnya dibiarkan tetap terbuka selama masa itu atau langsung dihentikan.
Yang memungkinkan kamu memeriksa semuanya sebelum merilis adalah mode uji (test mode, yaitu keadaan yang disiapkan penyedia layanan pembayaran untuk memeriksa perilaku tanpa menimbulkan tagihan sungguhan).
API key untuk pengujian dan untuk produksi terpisah, jadi kamu berpindah di antara keduanya lewat nilai sebuah environment variable.
Tentukan notifikasi yang mencabut hak akses sebelum merilis
Pada langganan, pembayaran terjadi setiap kali periodenya tiba, dan notifikasi datang setiap kali itu pula.
Kalau kamu hanya menangani notifikasi yang memberi akses, pengguna yang pembayarannya sudah berhenti akan tetap bisa memakainya, jadi tentukan pemberian, perpanjangan, dan pencabutan untuk setiap notifikasi yang datang, lalu jalankan seluruh alurnya di mode uji sebelum merilis.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Mana di antara berikut ini yang kamu jadikan dasar untuk memutuskan bahwa pembayarannya selesai dan memberi hak akses kepada pengguna?
Soal 3Ketika notifikasi yang mengabarkan pembayaran gagal tiba pada penagihan berulang, mana yang dilakukan aplikasi kamu?