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.

Ke mana data kartu mengalir, dan apa yang menjadi dasar pemberian hak akses
Pengguna mengisidata kartuJasa pembayaranmenerimanyaHasil datanglewat notifikasiNomor kartuberhenti di sinimy-app mencatathak akses
Cabang atas adalah data kartu, yang berhenti di dalam penyedia layanan pembayaran. Cabang bawah adalah hasil pembayaran, dan my-app hanya melihat cabang ini untuk membuka fitur berbayar.

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 beradaKe mana nomor kartu mengalirTermasuk cakupan PCI DSS
Diterima dan disimpan oleh my-appmy-app dan penyedia layanan pembayaranmy-app ikut tercakup
Diterima my-app lalu diteruskanmy-app dan penyedia layanan pembayaranmy-app ikut tercakup
Halaman penyedia layanan pembayaranHanya penyedia layanan pembayaranCakupan 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.

Dalam satu kali pembayaran, sejauh mana tiap data sampai
Satu pembayaran (pay_88)
Hanya tinggal di dalam penyedia pembayaran
  • Nomor kartu, tanggal kedaluwarsa, kode keamanan
  • Catatan pertukaran dengan penerbit kartu
Sampai ke my-app
  • Nilai yang menandai pembayaran, pay_88
  • Nominal, dan apakah pembayarannya selesai
  • Pembayaran ini milik pengguna yang mana (u_1024)
Kotak luar adalah satu pembayaran, pay_88. Data kartu hanya tinggal di dalam kotak atas. my-app hanya menyimpan fakta bahwa pembayarannya selesai dan nilai yang menandainya.

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.

Dua domain yang terbuka di browser selama pembayaran
Browser pengguna
Domain my-app
  • Halaman pendaftaran paket berbayar
  • /thanks, yang dibuka setelah pembayaran
Domain penyedia layanan pembayaran
  • Halaman pembayaran tempat nomor kartu dimasukkan
  • my-app tidak bisa melihat isi halaman ini
Kotak luar adalah browser pengguna. Kotak atas adalah halaman my-app dan kotak bawah adalah halaman penyedia layanan pembayaran; redirect memindahkan dari kotak atas ke kotak bawah lalu kembali lagi.

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.

Dua cara peletakan: apa yang berubah dan apa yang tidak
Pindah kehalaman terpisahURL memakaidomain penyediaSetelah bayar,kembali ke /thanksMenaruh bingkaidi halamanURL memakaidomain my-appSetelah bayar,halaman tetapPada kedua bentukNomor kartu menujujasa pembayaranmy-app hanya tahupembayaran selesai
Dua baris teratas adalah perbedaan antara kedua cara peletakan, dan baris paling bawah adalah hal yang tetap sama pada keduanya. Dari kiri ke kanan: cara peletakannya, URL yang tampil di browser, dan apa yang terjadi setelah pembayaran.

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.

Dua jalur menuju my-app setelah pembayaran selesai
Browser pindahke /thanksLayar menampilkanstatus selesaiJika ditutup,tidak sampaiPembayaran usaidi halaman bayarServer memanggil/webhookNotifikasi datangbertanda tanganDikirim ulangsampai batas waktu
Dua jalur bercabang dari satu pembayaran. Jalur atas melewati browser dan bisa berhenti di tengah jalan; jalur bawah berjalan antar server dan berlanjut sampai mendapat balasan berhasil.

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 ituKalau dinilai dari /thanksKalau dinilai dari /webhook
Membayar dan membuka /thanksHak akses diberikanHak akses diberikan
Membayar, lalu langsung menutup browserHak akses tidak diberikanHak akses diberikan
Membuka /thanks tanpa membayarHak akses diberikanHak 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.

Bagaimana my-app memilah apa yang tiba di /webhook
Notifikasi dengantanda tangan salahevt_7 yang datangpertama kalievt_7 yangdikirim ulang/webhookmenerimanyaDibuang; hak aksestidak berubahBeri hak akses,catat evt_7Sudah tercatat,tidak diproses
Ketiga hal di kiri sama-sama tiba di /webhook yang sama. Semuanya diterima bersama di tengah, lalu tanda tangan dan nilai yang menandai notifikasi memilahnya menjadi tiga hal di kanan.

Notifikasi yang tanda tangannya tidak cocok dibuang tanpa mengubah hak akses.

Perbedaan antara dua sisanya hanyalah apakah notifikasi itu sudah diterapkan atau belum.

Tiga jenis catatan yang disimpan di database my-app
Database my-app
Catatan pengguna
  • Nilai yang menandai pengguna, u_1024
  • Hash password
Catatan hak akses
  • Jenis paket (paid)
  • Tanggal berakhir
  • Milik pengguna yang mana (u_1024)
Catatan notifikasi yang diterima
  • Nilai yang menandai notifikasi, evt_7
  • Kapan notifikasi itu diterapkan
Kotak luar adalah database my-app. Catatan hak akses di tengah menyimpan jenis paket dan tanggal berakhirnya akses. Catatan notifikasi di bawah itulah yang mencegah notifikasi kiriman ulang diterapkan dua kali.

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).

Antara pembayaran sekali bayar dan langganan, yang berubah adalah berapa kali notifikasi tiba
Bentuk pembayaranBayar sekali sajaNotifikasi 1 kaliMasa berlaku haktidak berubahLanggananDatang berulangtiap periodeBerlaku sampaipembayaran berikut
Kolom kiri adalah bentuk pembayarannya. Jalur atas adalah sekali bayar, jalur bawah adalah langganan. Pada keduanya notifikasi Webhook tetap menjadi dasar hak akses; yang berbeda adalah berapa kali notifikasi tiba dan masa berlakunya.

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.

QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Ketika kamu menerima pembayaran lewat penyedia layanan pembayaran, ke mana data kartu mengalir?

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?