1.背景
18年快年底的時候,有一天突然想要不要做一個搶紅包的小程序春節(jié)期間玩玩节吮,但是又不能直接跟微信一樣直接搶吧浪谴,后面想著就引入答題這種模式道盏,答對一次搶一次紅包,答對可一直搶到最后移国,答錯則結(jié)束搶紅包吱瘩,大概就是這樣一個玩法,看著挺簡單的一個功能迹缀,其實全流程下來要考慮的點也是不少使碾,下面就簡單做一個思路的介紹:
2. 資質(zhì)相關(guān)的一些問題
1.申請小程序:
小程序個人蜜徽、企業(yè)都可以申請,但是因為需要包紅包涉及到支付功能票摇,必須企業(yè)資質(zhì)拘鞋,所以找代理注冊了一家公司,注冊公司全流程也還是挺多事的矢门,這里不細講盆色,反正有了公司后,又進行了微信公眾號認證祟剔,然后用企業(yè)資質(zhì)申請小程序隔躲,微信支付等。
2.小程序服務(wù)類目:
紅包類小程序因為涉及到用戶資金物延,按照規(guī)范服務(wù)類目應(yīng)該使用社交紅包宣旱,但是該類目下同樣要求《增值電信業(yè)務(wù)經(jīng)營許可證》,該證辦理也比較麻煩叛薯,如果正式商業(yè)化建議還是辦理浑吟,我們暫時使用的其它類目。
3.核心功能
1.包紅包
包紅包的時候設(shè)置題目案训、金額买置、數(shù)量,其中題目可自定義或者隨機强霎,自定義是用戶自己設(shè)置題干忿项,選項,答案等城舞,隨機題使用的我們的題庫轩触,生成紅包后可分享小程序。
- 搶紅包
用戶點開小程序家夺,會隨機獲取一個題目脱柱,自定義題則從用戶自定義題庫里選,隨機題則從系統(tǒng)題庫中選拉馋,用戶答對后則獲得一個紅包榨为,繼續(xù)答下一題,答錯則結(jié)束搶紅包煌茴。 -
提現(xiàn)
搶到紅包后可馬上進行提現(xiàn)随闺,提現(xiàn)功能使用的微信支付“企業(yè)付款到零錢功能”,該功能開通有一個坑就是T+1結(jié)算周期入駐需滿90天蔓腐,且最近30天連續(xù)不間斷保持交易矩乐,對于新開的商戶肯定不滿足的,所以我們的結(jié)算周期用的T+7的,當(dāng)然結(jié)算周期其實是看微信支付商戶開通的時候選擇的行業(yè)來的散罕,不是自己決定的分歇。
企業(yè)付款到零錢
4.風(fēng)險點考慮
做跟錢打交道的功能,就一定要考慮風(fēng)險欧漱,比如是否會被攻擊职抡,羊毛黨是否能褥羊毛,上線第一天就被攻擊了一波硫椰,當(dāng)時有個漏洞差點就被褥了繁调。
- 搶紅包金額和數(shù)量不能搶到負數(shù)
假設(shè)群里面一百人搶最后一個紅包,那只能讓一個人搶到靶草,或者別人惡意攻擊時蹄胰,大并發(fā)流量搶紅包。
解決方式:數(shù)據(jù)庫在減金額或者數(shù)量的時候where 后面加條件奕翔,如果寫的代碼里面先從數(shù)據(jù)庫查出來裕寨,發(fā)現(xiàn)金額或者數(shù)量滿足,就直接去減了派继,并發(fā)數(shù)高的時候宾袜,可能一百個請求去查的時候都是滿足的,但是最后數(shù)據(jù)庫去執(zhí)行的時候只一個滿足驾窟,沒控制好數(shù)據(jù)庫金額和數(shù)量就會減到負數(shù)庆猫。 - 提現(xiàn)的時候不能提現(xiàn)到負數(shù)
同樣的別人假設(shè)惡意攻擊,同時一百并發(fā)提現(xiàn)绅络,不能讓金額提現(xiàn)到負數(shù)月培,防止惡意提現(xiàn)。
解決方案:同樣是在數(shù)據(jù)更新的時候加where條件恩急,不能只在代碼里面校驗杉畜。 - 生成紅包金額算法
算法是參考的網(wǎng)上的,實時計算紅包金額衷恭,沒有提前去生成各個紅包金額此叠,實時計算規(guī)則每次生成紅包金額為[0.01,剩余紅包金額平均值*2),右邊是開區(qū)間随珠。
/**
* 獲取隨機金額灭袁,注意剩余金額不能小于0.01*remainNum
* @param remainMoney 剩余金額
* @param remainNum 剩余數(shù)量
* @return
*/
public static BigDecimal getRandomMoney(BigDecimal remainMoney, Integer remainNum) {
// remainSize 剩余的紅包數(shù)量
// remainMoney 剩余的錢
if (remainNum == 1) {
//如果只剩一個,則返回所有金額
return remainMoney;
}
Random r = new Random();
double min = 0.01; //
double max = remainMoney.doubleValue() / remainNum * 2;
double money = r.nextDouble() * max;
money = money <= min ? 0.01: money;
money = Math.floor(money * 100) / 100;
return new BigDecimal(money);
}
5.關(guān)于性能
對性能要求高的就是搶紅包這塊窗看,如果真的是大規(guī)模用戶用简卧,搶紅包這塊的設(shè)計就很重要,我們有用到redis烤芦,但redis只是做了比如題目的緩存,搶紅包這塊目前還是寫db析校,如果要提升性能的化构罗,搶紅包過程可以全部走redis铜涉,異步更新到數(shù)據(jù)庫,有考慮這塊的設(shè)計遂唧,但時間問題當(dāng)時沒有去實現(xiàn)芙代。
最后放個小程序碼,有興趣的可以體驗一下盖彭。