1. 前言
支付模塊不管在哪個(gè)系統(tǒng)都是重要的(跟錢有關(guān)系的能不重要嘛)。課程中使用的是yansongda/pay
的支付庫,集成了支付寶纯露、微信支付,使用方便代芜。支付模塊主要是按照支付通道的支付規(guī)則編碼實(shí)現(xiàn)埠褪,其實(shí)質(zhì)就是接口請(qǐng)求。課程中側(cè)重開發(fā)實(shí)現(xiàn)挤庇,介紹了支付拓展包的使用钞速。因此,支付集成的部分嫡秕,本章節(jié)暫且跳過渴语,只記錄學(xué)習(xí)點(diǎn)。
課程傳送門-支付集成
此外昆咽,課程中還實(shí)現(xiàn)了電商行業(yè)大熱分期付款驾凶。本章節(jié)主要梳理課程中對(duì)分期付款的實(shí)現(xiàn)方案。
課程傳送門-分期付款
2. 功能分析
2.1 支付集成
2.1.1 編碼學(xué)習(xí)
支付模塊單拎出來就很抗打掷酗,涉及到加解密调违、字符編碼的處理,代碼封裝泻轰。
- 實(shí)現(xiàn)過程
支付模塊比較有意思的是代碼實(shí)現(xiàn)部分技肩,不同支付通道支持的支付方式不同,傳遞的參數(shù)浮声、驗(yàn)證方式不同虚婿。怎么樣把不同支付通道的代碼封裝起來旋奢,方便統(tǒng)一處理調(diào)用值得去研究。 - 容器的使用
2.2 分期付款
分期付款可以看作是新的一種支付網(wǎng)關(guān)然痊,對(duì)于一個(gè)訂單來說至朗,它跟銀行卡支付、支付寶支付一樣玷过,都可以作為支付方式爽丹,只是它每一期分期付款還是依賴于真實(shí)的支付方式支付筑煮。
2.2.1 需求分析
分期付款的業(yè)務(wù)邏輯如下:
- 只有當(dāng)商品訂單總金額高于某個(gè)數(shù)值時(shí)才可以使用分期付款辛蚊;
- 用戶使用分期付款時(shí),需要選擇還款期限真仲,通常為 3 個(gè)月的倍數(shù)袋马;
- 使用分期付款需要支付手續(xù)費(fèi),不同的還款期限手續(xù)費(fèi)費(fèi)率不同秸应,還款期限越久費(fèi)率越高虑凛;
- 分期付款的手續(xù)費(fèi)與銀行貸款的利息不同,銀行貸款的利息會(huì)隨著還款而逐漸降低软啼,而分期付款的手續(xù)費(fèi)則是固定的桑谍;
- 使用分期付款后,用戶需要立即支付第一期的費(fèi)用祸挪,當(dāng)?shù)谝黄谫M(fèi)用支付成功后锣披,對(duì)應(yīng)的商品訂單狀態(tài)即變?yōu)橐阎Ц叮?/li>
- 用戶需每 30 天還款一次,如果在還款截止日期之后仍未還款贿条,需支付逾期費(fèi)雹仿,逾期費(fèi)按天計(jì)算;
- 逾期之后產(chǎn)生的逾期費(fèi)用最多不超過當(dāng)期的本金 + 手續(xù)費(fèi)整以;
- 每一期還款金額計(jì)算公式:(本金 + 手續(xù)費(fèi)) / 還款期數(shù) + 當(dāng)期逾期費(fèi)胧辽;
- 使用了分期付款的商品訂單如果發(fā)生退款,則退回所有已支付的本金公黑,手續(xù)費(fèi)與逾期費(fèi)不退回邑商。
2.2.2 實(shí)現(xiàn)邏輯
- 選擇分期付款下單:
- 在用戶選擇分期付款時(shí),按照分期期數(shù)和金額計(jì)算出每一期需要還款的本金凡蚜、手續(xù)費(fèi)人断、還款時(shí)間等還款信息;
- 再用一個(gè)定時(shí)腳本去計(jì)算當(dāng)期的逾期費(fèi)番刊;
- 分期還款支付:(請(qǐng)求支付和支付回調(diào)與普通商品的不一樣含鳞,需要單獨(dú)實(shí)現(xiàn))
- 請(qǐng)求支付祭玉,使用當(dāng)期的流水號(hào)兽埃、當(dāng)期支付金額、分期的回調(diào)地址和返回地址去請(qǐng)求第三方支付;
- 按照分期邏輯實(shí)現(xiàn)支付回調(diào)伦籍,更新當(dāng)期支付信息,若是第一期需更新訂單的狀態(tài)和支付信息姆钉,以及分期狀態(tài)愿卸;
-
分期退款:
分期的每一期批量退款,修改訂單退款狀態(tài)桅狠;
2.2.3 表設(shè)計(jì)
分期分款可以選擇還款期數(shù)讼载,需要計(jì)算每一期還款的本金、手續(xù)費(fèi)中跌、還款時(shí)間咨堤,以及需要保存每一期還款的具體支付方式和支付單號(hào)。因此漩符,我們需要用兩張表來分別保存分期信息和每期分期的詳細(xì)信息一喘。
具體表結(jié)構(gòu)如下:
# 分期表
CREATE TABLE `installments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, # 自增ID
`no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, # 分期單號(hào)
`user_id` int(10) unsigned NOT NULL, # 所屬用戶ID
`order_id` int(10) unsigned NOT NULL, # 對(duì)應(yīng)訂單ID
`total_amount` decimal(8,2) NOT NULL, # 總本金
`count` int(10) unsigned NOT NULL, # 還款期數(shù)
`fee_rate` double(8,2) NOT NULL, # 手續(xù)費(fèi)率
`fine_rate` double(8,2) NOT NULL, # 逾期費(fèi)率
`status` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending', # 還款狀態(tài),默認(rèn)未執(zhí)行
`created_at` timestamp NULL DEFAULT NULL, # 創(chuàng)建時(shí)間
`updated_at` timestamp NULL DEFAULT NULL, # 更新時(shí)間
PRIMARY KEY (`id`),
UNIQUE KEY `installments_no_unique` (`no`),
KEY `installments_user_id_foreign` (`user_id`),
KEY `installments_order_id_foreign` (`order_id`),
CONSTRAINT `installments_order_id_foreign` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE,
CONSTRAINT `installments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# 分期項(xiàng)表
CREATE TABLE `installment_items` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, # 自增ID
`installment_id` int(10) unsigned NOT NULL, # 分期ID
`sequence` int(10) unsigned NOT NULL, # 期數(shù)
`base` decimal(8,2) NOT NULL, # 當(dāng)期本金
`fee` decimal(8,2) NOT NULL, # 當(dāng)期手續(xù)費(fèi)
`fine` decimal(8,2) DEFAULT NULL, # 當(dāng)期逾期費(fèi)
`due_date` datetime NOT NULL, # 還款截止日期
`paid_at` datetime DEFAULT NULL, # 還款日期
`payment_method` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, # 還款支付方式
`payment_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, # 換的支付單號(hào)
`refund_status` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending', # 退款狀態(tài) 默認(rèn)未退款
`created_at` timestamp NULL DEFAULT NULL, # 創(chuàng)建時(shí)間
`updated_at` timestamp NULL DEFAULT NULL, # 更新時(shí)間
PRIMARY KEY (`id`),
KEY `installment_items_installment_id_foreign` (`installment_id`),
CONSTRAINT `installment_items_installment_id_foreign` FOREIGN KEY (`installment_id`) REFERENCES `installments` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
2.3.4 代碼借鑒
本章節(jié)業(yè)務(wù)邏輯有點(diǎn)復(fù)雜嗜暴,實(shí)現(xiàn)方案不算復(fù)雜凸克,學(xué)習(xí)到了以下幾點(diǎn):
- 浮點(diǎn)數(shù)的計(jì)算方式(使用 bcmath)
- 在處理大數(shù)據(jù)量的數(shù)據(jù)庫操作時(shí),使用chunkById減少內(nèi)存占用闷沥;