Menangani langganan, saldo, dan perubahan rencana harga [ditutup]

11

Preamble
Tujuan saya adalah membuat kode yang dapat digunakan kembali untuk beberapa proyek (dan juga menerbitkannya di github) untuk mengelola langganan. Saya tahu tentang penyedia penagihan stripe dan berulang, tapi bukan itu tujuan modul ini. Seharusnya hanya pembungkus / penolong untuk menghitung saldo akun, notifikasi mudah untuk memperbarui langganan, dan menangani perhitungan harga.

Ada negara yang Anda tidak dapat menggunakan penagihan berulang karena penyedia atau kemungkinan pembayaran memiliki dukungan yang buruk atau tidak ada atau terlalu mahal (pembayaran mikro). Dan ada orang yang tidak ingin menggunakan penagihan berulang tetapi membayar tagihan mereka secara manual / avingg faktur pada akhir tahun. Jadi tolong jangan menyarankan penagihan berulang paypal, layanan berulang atau serupa.

Situasi
Katakanlah Anda memiliki model yang dapat berlangganan paket berlangganan (mis User.). Model ini memiliki bidang yang menyimpan pengenal rencana berlangganan yang saat ini dilanggani. Jadi, pada setiap perubahan rencana, perubahan dicatat.

Ada model (misalnya SubscriptionPlanChanges) dengan bidang-bidang berikut merekam perubahan yang disebutkan:

  • subscriberberkaitan dengan model berlangganan ( Userdalam hal ini)
  • from_plan mendefinisikan pengidentifikasi rencana model sebelum berubah
  • to_plan mendefinisikan pengidentifikasi paket model yang telah dipilih sekarang
  • created_at adalah bidang tanggal waktu menyimpan perubahan
  • valid_until menyimpan tanggal sampai langganan yang sebenarnya valid
  • paid_at juga merupakan bidang tanggal yang menentukan apakah (dan kapan) langganan dibayar

Tentu saja, tata letak itu bisa didiskusikan.

Pertanyaan tentang saldo akun
Ketika seorang Pengguna mengubah paket langganannya, saya perlu membandingkan bidang paket, mendapatkan harga, dan menghitung potongan untuk paket baru berdasarkan paket saat ini valid_untildan harganya. Katakan: Anda berlangganan untuk satu tahun paket A tetapi setelah 6 bulan, Anda meningkatkan ke paket B, sehingga Anda mendapatkan potongan setengah dari harga yang dibayarkan untuk 6 bulan paket A.

Yang saya ingin tahu: Jika pengguna misalnya beralih ke paket gratis, ia memiliki kredit yang dapat dikurangkan jika pengguna ingin beralih lagi. Apakah Anda akan menyimpan nilai itu di bidang tambahan, atau menghitung semua catatan yang terkait dengan pengguna itu setiap waktu? Apakah Anda menambahkan / mengubah sesuatu tentang tata letak tabel?

Pertanyaan kelengkapan mudah
Ketika akhir periode berlangganan tiba, pengguna akan diberitahu dan memiliki kemungkinan untuk memperbarui langganannya dengan membayar lagi. Cara termudah adalah dengan hanya memperbarui paid_atdan valid_untildengan opsi berlangganan baru. Namun, saya tidak yakin apakah Anda menyimpan setiap data yang mungkin dibutuhkan seseorang, seperti riwayat pembayaran / berlangganan.

Pilihan lain adalah membuat catatan tambahan untuk ini, di mana from_plandan to_planmemiliki pengidentifikasi yang sama (dengan demikian melambangkan "tidak ada perubahan"). Tapi bukankah itu mengganggu menghitung saldo akun dengan cara tertentu?

Jika seseorang bisa mengarahkan saya ke arah yang benar tentang logika yang menangani langganan seperti itu, saya akan sangat menghargainya.


PEMBARUAN
Terima kasih atas bantuannya sekarang. Saya pikir pertanyaan saya terlalu kabur sehingga saya akan mencoba lebih tepatnya dengan menggunakan abstraksi yang lebih sedikit. Sayangnya, saya belum bisa menyelesaikan masalah saya.

Kasus A
User dapat memilih Subscription Plan A. Saat ini menyimpan SubscriptionPlanChangeuntuk melacaknya. Setelah misalnya 5 bulan, Userupgrade berlangganan untuk Subscription Plan B. Jadi dia membayar harga untuk langganan barunya, mengurangi harga paket untuk 7 bulan yang tidak digunakan.

Kasus B
Setelah 3 bulan, Userkembali ke miliknya Subscription Plan A. Dia tidak harus membayar tetapi menerima saldo untuk itu, sehingga pada akhir berlangganan, dia mendapatkan saldo itu dikurangi untuk langganan barunya.

Kasus C
User dapat memilih paket berlangganan untuk sub-layanan yang memiliki paket berlangganan independen. Sama Case Adan Case Bdapat berlaku untuk berlangganan sub-layanan itu.

_Case D_ Pengguna membatalkan salah satu langganannya. Ini menghasilkan top-up keseimbangannya.

Pertanyaan saya (saat ini, setidaknya) terutama tergantung pada bagaimana cara menyimpan data itu dengan benar sehingga saya dapat mereproduksi riwayat langganan untuk analisis bisnis dan menghitung saldo, mendapatkan pembayaran luar biasa berdasarkan langganan dll.

Saya juga tidak yakin apakah saldo harus disimpan dalam misalnya model pengguna itu sendiri, atau jika tidak disimpan tetapi dapat dihitung kapan saja berdasarkan data / sejarah yang disimpan.

Beberapa hal yang perlu diperhatikan, meskipun saya tidak berpikir mereka harus menimbulkan masalah:

  • Itu tidak harus menjadi User, itu bisa apa saja, itu sebabnya Subscriberpolimorfik
  • Planstidak harus harus berupa rencana, tetapi bisa misalnya Magazinesseperti disebutkan. Itulah yang saya dijelaskan dengan Kasus C dan Kasus D .
pduersteler
sumber
1
Satu hal yang pasti bisa Anda lakukan adalah menetapkan harga masing-masing masalah (yang dapat bergantung pada rencana sehingga kombinasi [rencana, masalah] peta ke [harga masalah]), dan kemudian cukup melacak saldo masing-masing pelanggan per majalah (atau istilah apa pun yang Anda inginkan).
CVn
Terima kasih semuanya, saya perlu memperbarui pertanyaan karena saya belum dapat menyelesaikan masalah saya.
pduersteler
1
Bolehkah saya bertanya bagaimana Anda akhirnya menerapkan ini?
JCM

Jawaban:

6

Sayangnya, jawaban untuk masalah yang rumit biasanya rumit. Saran saya kepada Anda adalah hanya menyimpan informasi yang relevan, kemudian gunakan model untuk membangun gambaran yang lebih besar.

Dengan kata lain, tabel SubscriptionPlanChanges Anda akan memiliki informasi berikut untuk kuncinya:

  • pelanggan
  • rencana
  • berlaku dari

Dengan cara ini, Anda mengizinkan beberapa paket untuk pelanggan yang sama yang bisa tumpang tindih. Bidang lain termasuk:

  • Berlaku hingga
  • dibayar sampai
  • rate (juga 0 jika gratis)

Perhatikan bahwa tidak ada "rencana dari" atau "rencana ke". Meskipun Anda dapat memilikinya, informasi tersebut berlebihan dan dapat dihitung sendiri (menyimpan informasi tersebut berarti Anda memiliki tugas tambahan agar tetap konsisten). Ketika rencana baru dimulai, daripada harus memodifikasi rencana yang ada, Anda meninggalkannya dan hanya menambahkan catatan baru. Jika ada rencana tumpang tindih lain setelah rencana baru, Anda dapat memutuskan ingin menghapusnya (lebih intuitif dengan cara ini). Saat Anda memuat paket ini untuk pelanggan, Anda mengurutkannya berdasarkan tanggal "valid dari" mereka.

Setelah Anda memperoleh ini, menghitung kredit pengguna relatif sederhana. Jika dua paket tidak dapat tumpang tindih, Anda hanya perlu mengambil dua tanggal yang lebih kecil antara tanggal "valid hingga" dari paket sebelumnya dan "valid dari" paket saat ini untuk menentukan tanggal akhir. Tanggal mulai adalah yang lebih besar dari dua tanggal antara tanggal "valid dari" dan tanggal "dibayar sampai" (jika ditentukan). Pembayaran (atau kredit) kemudian dapat dihitung pada kurs yang dikalikan dengan interval waktu antara tanggal awal dan akhir yang disebutkan di atas dari paket tersebut.

Dengan cara ini, secara teori Anda dapat menghitung apa pun yang perlu Anda ketahui. Saya menyarankan agar Anda tidak mencoba menyimpan nilai yang dihitung, karena akan berubah ketika catatan yang ada diubah, ditambahkan, atau dihapus.

Variasi cara Anda menghitung nilai-nilai ini dapat dikelola dengan menambahkan bidang tipe tambahan. Dalam kode Anda, Anda bisa membuat penangan khusus untuk mengelola logika penghitungan rencana tertentu untuk menjaga algoritma utama Anda relatif bersih dari perhitungan yang rumit. Lebih baik lagi jika Anda berhasil membuat penangan untuk kasus di mana tidak ada jenis yang ditentukan sehingga yang harus Anda lakukan adalah memanggil penangan yang sesuai sesuai dengan jenisnya untuk membuat segala jenis perhitungan yang Anda butuhkan.

Saya harap itu menjawab pertanyaan Anda.

Neil
sumber
Banyak terima kasih, itu memberi sedikit cahaya! Meskipun saya merasa tidak jelas tentang bidang yang "valid". valid_untiladalah terminologi saya untuk Anda paid_until. Tidak ada panjang maksimum rencana berlangganan.
pduersteler
@pduersteler Ah kesalahanku. Itu hanya membuat perhitungan lebih mudah, karena tanggal "akhir" hanyalah awal dari rencana baru.
Neil
1
Nilai apakah jumlah yang dibayarkan? Jika ya, maka ini bisa berupa entitas lain, Faktur misalnya, apakah saya benar?
JCM
3

Selain jawaban di atas, saya akan membuat tabel dengan kredit, di mana kredit akan sama dengan mata uang saat ini. Setiap kali pengguna berganti rencana ke alternatif yang lebih murah, saldo yang tidak digunakan masuk sebagai kredit. Setiap kali pengguna memiliki sesuatu untuk dibayar, Anda akan menggunakan kredit terlebih dahulu dan hanya meminta pembayaran jika kredit habis atau tidak ada. Jika menggunakan alternatif ini, buat tabel sebagai daftar transaksi untuk dapat mereproduksi skenario penggunaan jika pernah terjadi perselisihan. Contoh:

ID, UserId, TransactionDate, Credit (positif ketika Anda memberikan kredit pengguna dan negatif ketika pengguna menggunakan kredit)

Jumlahkan kredit untuk pengguna untuk menunjukkan kepadanya saldo.

Semoga ini bermanfaat bagi Anda ...

Lars Hofvander
sumber