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:
subscriber
berkaitan dengan model berlangganan (User
dalam hal ini)from_plan
mendefinisikan pengidentifikasi rencana model sebelum berubahto_plan
mendefinisikan pengidentifikasi paket model yang telah dipilih sekarangcreated_at
adalah bidang tanggal waktu menyimpan perubahanvalid_until
menyimpan tanggal sampai langganan yang sebenarnya validpaid_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_until
dan 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_at
dan valid_until
dengan 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_plan
dan to_plan
memiliki 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 SubscriptionPlanChange
untuk melacaknya. Setelah misalnya 5 bulan, User
upgrade 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, User
kembali 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 A
dan Case B
dapat 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 sebabnyaSubscriber
polimorfik Plans
tidak harus harus berupa rencana, tetapi bisa misalnyaMagazines
seperti disebutkan. Itulah yang saya dijelaskan dengan Kasus C dan Kasus D .
sumber
Jawaban:
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:
Dengan cara ini, Anda mengizinkan beberapa paket untuk pelanggan yang sama yang bisa tumpang tindih. Bidang lain termasuk:
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.
sumber
valid_until
adalah terminologi saya untuk Andapaid_until
. Tidak ada panjang maksimum rencana berlangganan.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 ...
sumber