W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
現(xiàn)金紅包為商家的小程序提供了現(xiàn)金紅包發(fā)放功能,主要應(yīng)用于企業(yè)、商家給用戶發(fā)放支付寶紅包的應(yīng)用場(chǎng)景;用戶領(lǐng)取后,紅包金額可以提現(xiàn)到支付寶余額。
商家可以配合使用多種紅包策略和玩法,如隨機(jī)金額,指定金額范圍等,并且紅包還可以分享到支付寶端外使用。
開發(fā)者在打開小程序開發(fā)者工具時(shí),選擇 模板選取 > 開放能力 > 現(xiàn)金紅包 demo,即可進(jìn)入現(xiàn)金紅包的開發(fā)模板。
使用現(xiàn)金紅包模板進(jìn)行快速開發(fā)的整體流程如下圖所示:
請(qǐng)?jiān)?AlipaySDK JAVA 下載引入 AlipaySDK 開發(fā)使用。
DEMO 中使用如下配置:
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --><dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.8.56.ALL</version></dependency>
商家可以通過(guò)現(xiàn)金紅包為自己的生活號(hào)引流,用戶在關(guān)注小程序關(guān)聯(lián)的生活號(hào)后,可以領(lǐng)取相應(yīng)數(shù)額的現(xiàn)金紅包。
現(xiàn)金紅包 DEMO 領(lǐng)取示例:
關(guān)注生活號(hào)組件
以 DEMO 中為例,首先為了讓用戶有關(guān)注生活號(hào)的入口,需要首先在頁(yè)面添加關(guān)注生活號(hào)組件,具體可以參考 lifestyle 組件文檔,在此不贅述。
用戶未關(guān)注生活號(hào)時(shí) isCollected 參數(shù)為 false,頁(yè)面按鈕會(huì)顯示 關(guān)注生活號(hào)領(lǐng)取紅包;點(diǎn)擊該按鈕,觸發(fā)點(diǎn)擊事件 onClickCollect() 會(huì)彈出彈窗提示用戶需要先關(guān)注生活號(hào)。
用戶點(diǎn)擊右上角關(guān)注按鈕后 isCollected 參數(shù)會(huì)被賦為 true 此時(shí)用戶界面會(huì)顯示 已關(guān)注,領(lǐng)取紅包 點(diǎn)擊此按鈕觸發(fā) onClickCollect() 事件且會(huì)調(diào)用 handleRedPacket() 函數(shù)獲取紅包;獲取成功后會(huì)在用戶界面顯示紅包信息。
關(guān)注生活號(hào)前后 Button 顯示變化邏輯
在 index.js 中,小程序頁(yè)面加載時(shí),將 收藏狀態(tài)(是否關(guān)注生活號(hào)) isCollected 初始化,默認(rèn)值為 false,即用戶未關(guān)注該生活號(hào)。
//.js
data: {
isCollected: false, //收藏狀態(tài)
},
小程序 axml中 關(guān)注生活號(hào)領(lǐng)取紅包 按鈕顯示內(nèi)容使用三目運(yùn)算符通過(guò)判斷用戶是否關(guān)注生活號(hào)或分享轉(zhuǎn)發(fā)來(lái)動(dòng)態(tài)顯示 button 內(nèi)容,當(dāng)用戶點(diǎn)擊右上角關(guān)注按鈕后 isCollected 參數(shù)會(huì)被賦為 true。button 中內(nèi)容則會(huì)改變?yōu)?已經(jīng)關(guān)注,領(lǐng)取紅包 ,點(diǎn)擊即可領(lǐng)取紅包。
<!-- .axml --><view class="redpacket-button">
<button type="ghost" onTap="onClickCollect">
{{ isCollected ? '已經(jīng)關(guān)注,領(lǐng)取紅包' : '關(guān)注生活號(hào)領(lǐng)紅包'}}
</button>
<view class="desc">
關(guān)注生活號(hào)后可以領(lǐng)取紅包
</view>
在小程序的營(yíng)銷場(chǎng)景下,開發(fā)者可以用紅包的形式鼓勵(lì)用戶轉(zhuǎn)發(fā)小程序,通過(guò)社交裂變提高小程序的訪問(wèn)量。 現(xiàn)金紅包 DEMO 領(lǐng)取示例:
用戶點(diǎn)擊小程序頁(yè)面的 分享領(lǐng)紅包 按鈕 ,該按鈕中定義了點(diǎn)擊事件 onClickShare(),該函數(shù)會(huì)判斷 isShared 參數(shù)的值以此確定用戶是否完成轉(zhuǎn)發(fā),默認(rèn) isShared 參數(shù)當(dāng)前值為 false ,會(huì)調(diào)用 my.showSharePanel 喚起分享頁(yè)面。
DEMO中當(dāng)分享面板展開即判定用戶轉(zhuǎn)發(fā)成功,具體業(yè)務(wù)場(chǎng)景請(qǐng)按照需求實(shí)現(xiàn)。此時(shí)會(huì)將 isShared 的值被賦為
true ,用戶頁(yè)面的按鈕信息會(huì)變?yōu)?已經(jīng)分享,領(lǐng)取紅包 ;
分享小程序前后 Button 顯示變化邏輯
在 index.js 中,小程序頁(yè)面加載時(shí),將 分享狀態(tài)(是否分享小程序) isShared 初始化,默認(rèn)值為 false,即用戶未分享該小程序。
//.js
data: {
isShared: false, //分享狀態(tài)
},
小程序 axml 中 分享領(lǐng)紅包 按鈕顯示內(nèi)容使用三目運(yùn)算符通過(guò)判斷用戶是否分享小程序顯示 button 內(nèi)容,當(dāng)用戶點(diǎn)擊 分享領(lǐng)紅包 按鈕后,用戶界面會(huì)彈出分享面板,此時(shí) isShared 參數(shù)會(huì)被賦為 true 。button 中內(nèi)容則會(huì)改變?yōu)?已經(jīng)分享,領(lǐng)取紅包 ,點(diǎn)擊即可領(lǐng)取紅包。
<!-- .axml --><view class="redpacket-button">
<button type="ghost" onTap="onClickShare">
{{ isShared ? '已經(jīng)分享,領(lǐng)取紅包' : '分享領(lǐng)紅包' }}
</button><view class="desc">
在符合相關(guān)規(guī)定的前提下,開發(fā)者可以在小程序內(nèi)建立一定的積分體系,用戶可以用積分兌換紅包,并在余額中查看,如下圖所示。
現(xiàn)金紅包 DEMO 領(lǐng)取示例:
DEMO 中默認(rèn)用戶積分 point 值為 9999,點(diǎn)擊 消耗積分進(jìn)行紅包兌換 按鈕,該按鈕中定義了點(diǎn)擊事件 onClickPoint() ,該函數(shù)封裝了 JSAPI my.confirm 用于彈窗提示用戶是否確定使用積分獲取紅包,當(dāng)用戶點(diǎn)擊 立即兌換 同意后調(diào)用 usePoint() 函數(shù)用于獲取積分兌換紅包結(jié)果,該函數(shù)中封裝了 JSAPI my.request 用于向后臺(tái)發(fā)送請(qǐng)求和接收返回信息。當(dāng)返回業(yè)務(wù)處理成功時(shí)會(huì)調(diào)用 handleRedPacket() 函數(shù)領(lǐng)取紅包,領(lǐng)取成功后用戶界面會(huì)顯示紅包信息。
在 index.js 中,小程序頁(yè)面加載時(shí),將用戶積分信息 Point 初始化,默認(rèn)值為 9999(僅測(cè)試使用,具體積分定義請(qǐng)開發(fā)者考慮實(shí)際場(chǎng)景實(shí)現(xiàn))。
//.js
data: {
point:9999 //積分信息
},
后臺(tái) controller 中使用 PointsExchangeMockImpl 實(shí)現(xiàn) PointsExchangeMock 接口進(jìn)行積分兌換紅包的業(yè)務(wù)操作,demo中直接返回 mock 信息,開發(fā)者需要根據(jù)實(shí)際情況實(shí)現(xiàn)。
public Object pointsExchangeMock(HttpResponse response) throws Exception {
Response alipayResponse = new Response();
try {
//積分兌換接口Mock,開發(fā)者可以根據(jù)自己實(shí)際的業(yè)務(wù)需要去實(shí)現(xiàn)積分兌換功能,此Demo這里直接Mock返回結(jié)果
alipayResponse.setCode("10000");
alipayResponse.setSuccess(true);
alipayResponse.setMsg("Success");
alipayResponse.setBody("Mock業(yè)務(wù)系統(tǒng)返回內(nèi)容");
return alipayResponse;
}catch (Exception e) {
alipayResponse.setCode("40000");
alipayResponse.setSuccess(false);
alipayResponse.setMsg("false");
alipayResponse.setBody("Mock業(yè)務(wù)系統(tǒng)返回異常");
return alipayResponse;
}
}
關(guān)注類、轉(zhuǎn)發(fā)類和積分制紅包在發(fā)放時(shí),都需要設(shè)置以下的紅包發(fā)放邏輯:
小程序領(lǐng)取紅包函數(shù) handleRedPacket() 函數(shù)邏輯:
//.js
// 點(diǎn)擊領(lǐng)取紅包
async handleRedPacket() {
try {
const auth = await this.getAuthCode('auth_user');
if (auth && auth.authCode) {
let res = null;
if (configObj === 'dev') {//參見(jiàn) configObj 參數(shù)值參見(jiàn) config/index.js
res = await this.getRedPacket(auth.authCode);
} else {
res = { ...mockRedPacketData }; //模擬數(shù)據(jù)
}
if (res && res.success) {
this.setData({
isShowRedPacket: true
})
}
}
} catch (error) {
my.showToast({
content: error.message
});
}
},
handleRedPacket() 函數(shù)會(huì)先獲取用戶授權(quán)情況,調(diào)用 this.getAuthCode('auth_user') 函數(shù),傳入?yún)?shù)為用戶授權(quán)類型,該函數(shù)中封裝了小程序 JSAPI my.getAuthCode 用于獲取用戶授權(quán)碼;
//.js /**
* @name getAuthCode
* @description 獲取用戶授權(quán)
* @param {string} [scopeCode='auth_user']
* @returns {object}
*/
getAuthCode(scopeCode = 'auth_user') {
return new Promise((resolve, reject) => {
my.getAuthCode({
scopes: scopeCode,
success: (auth) => {
resolve(auth);
},
fail: (err) => {
reject({ ...err, message: '獲取用戶授權(quán)失敗' });
}
});
});
},
獲取到用戶授權(quán)后 調(diào)用 getRedPacket(authCode) 函數(shù)像商戶后臺(tái)發(fā)起請(qǐng)求獲取紅包,該函數(shù)需要傳入authCode 用于后臺(tái)換取 accessToken 和 user_id,該函數(shù)中封裝了小程序JSAPI my.request 用于向后臺(tái)發(fā)送和接收返回?cái)?shù)據(jù),此處用 POST 方式將要傳給后臺(tái)的 authCode 值放在 data 中傳遞給后臺(tái)。
//.js/**
* @name getRedPacket
* @description 紅包接口邏輯
* @param {string} authCode
* @returns {object}
*/
getRedPacket(authCode) {
return new Promise((resolve, reject) => {
my.request({
url: `${URL}/alipay/demo/redpacket`,
data: {
authCode: authCode
},
success: (result) => {
if (!result.data.success) {
reject({
...result.data,
message: '紅包領(lǐng)取失敗'
});
}
resolve(result.data);
},
fail: (error) => {
reject({
...error,
message: '紅包領(lǐng)取異常'
});
}
})
})
},
當(dāng)后臺(tái)處理完成業(yè)務(wù)邏輯后會(huì)將紅包信息返回( DEMO 中不做具體處理,請(qǐng)根據(jù)具體業(yè)務(wù)環(huán)境解析使用數(shù)據(jù)),當(dāng)業(yè)務(wù)處理成功時(shí)會(huì)將 isShowRedPacket 參數(shù)賦為 true (DEMO中將信息定義在axml中的 modal 標(biāo)簽中) 用戶界面就會(huì)顯示領(lǐng)取紅包的信息。
<!-- .axml --><modal
class="redpacket-modal"
show="{{isShowRedPacket}}"
onModalClick="onModalClick"
onModalClose="onModalClose"
topImage="https://gw.alipayobjects.com/mdn/rms_283d8e/afts/img/A*7AtMQac46wYAAAAAAAAAAABkARQnAQ">
<view slot="header">領(lǐng)取現(xiàn)金紅包</view>
此為示例demo,請(qǐng)按文檔對(duì)接。
<view slot="footer">我知道了</view>
</modal>
說(shuō)明:為了良好的用戶體驗(yàn),用戶領(lǐng)取紅包后請(qǐng)注意紅包頁(yè)面定義點(diǎn)擊隱藏事件。
后臺(tái)處理紅包業(yè)務(wù)代碼:
java 代碼中請(qǐng)注意使用支付寶的 OpenAPI 向支付寶服務(wù)器發(fā)送請(qǐng)求,都需要構(gòu)造 AlipayClient 且需要配置的各項(xiàng)參數(shù),例如 小程序的公鑰,私鑰,網(wǎng)關(guān)地址,請(qǐng)求格式,字符集,簽名類型等參數(shù),建議與 DEMO 中類似編寫配置信息的工具類并且將配置信息放在 properties 文件中方便后期修改,減小代碼改動(dòng)。參考 DEMO 中 config 包與 resource 包中的 Application.properties 文件。
DEMO 中使用 server/src/main/java/com/controller/rest 下的 AlipayFundTransUniTransferControllerImpl 類實(shí)現(xiàn) AlipayFundTransUniTransferControllerl 接口,用于處理獲取紅包業(yè)務(wù),此處需要獲取前端發(fā)回的 auth_code 用戶授權(quán)碼。
調(diào)用自定義的 isBlank 方法判斷 auth_code 的值;
public static boolean isBlank(String str) {
int length;
if (str != null && (length = str.length()) != 0) {
for(int i = 0; i < length; ++i) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
} else {
return true;
}
}
調(diào)用 getAccessToken(auth_code) 方法傳入 auth_code:
在該方法中調(diào)用 OpenAPI alipay.system.oauth.token (換取授權(quán)訪問(wèn)令牌)對(duì)象 request 并使用 AlipayClient 的certificateExecute(request) 方法獲取 AlipaySystemOauthTokenResponse 返回,該返回類型中包含了換取 accessToken 狀態(tài)以及支付寶用戶的 user_id。
private AlipaySystemOauthTokenResponse getAccessToken(String authCode) throws AlipayApiException {
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode(authCode);
request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
return alipayClient.certificateExecute(request);
}
商戶處理完成業(yè)務(wù)將信息封裝到 JSON 中 并且使用 OpenAPI 統(tǒng)一轉(zhuǎn)賬接口 (alipay.fund.trans.uni.transfer)創(chuàng)建 AlipayFundTransUniTransferRequest 對(duì)象 request 并且將數(shù)據(jù)使用 request.setBizContent() 方法保存,調(diào)用 AlipayClient 的certificateExecute(request) 方法傳入該 request 對(duì)象,向支付寶服務(wù)器發(fā)送請(qǐng)求處理。
String userId = alipaySystemOauthTokenResponse.getUserId();
Map<String, Object> payeeInfo = new HashMap<String, Object>();
payeeInfo.put("identity", userId);
payeeInfo.put("identity_type", "ALIPAY_USER_ID");
Map<String, Object> params = new HashMap<String, Object>();
params.put("out_biz_no", System.currentTimeMillis());
params.put("trans_amount", "0.01");
params.put("product_code", "STD_RED_PACKET");
params.put("biz_scene", "DIRECT_TRANSFER");
params.put("order_title", "現(xiàn)金紅包測(cè)試Demo");
params.put("payee_info", payeeInfo);
params.put("business_params", "{\"sub_biz_scene\":\"REDPACKET\"}");
Object obj = JSONObject.toJSON(params);
AlipayFundTransUniTransferRequest alipayRequest = new AlipayFundTransUniTransferRequest();
alipayRequest.setBizContent(obj.toString());
AlipayFundTransUniTransferResponse alipayResponse = alipayClient.certificateExecute(alipayRequest);
最后將處理結(jié)果返回給前端頁(yè)面解析顯示。
代碼編寫完成后,開發(fā)者可以參考小程序 發(fā)布流程,提交開發(fā)完成的小程序。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: