支付宝小程序 快速示例·现金红包
现金红包为商家的小程序提供了现金红包发放功能,主要应用于企业、商家给用户发放支付宝红包的应用场景;用户领取后,红包金额可以提现到支付宝余额。
商家可以配合使用多种红包策略和玩法,如随机金额,指定金额范围等,并且红包还可以分享到支付宝端外使用。
应用案例
- 收藏类领取红包:商家可以通过现金红包为自己的生活号引流,用户在关注小程序关联的生活号后,可以领取相应数额的现金红包。
- 分享类领取红包:在小程序的营销场景下,开发者可以用红包的形式鼓励用户转发小程序,通过社交裂变提高小程序的访问量。
- 积分制领取红包:在符合相关规定的前提下,开发者可以在小程序内建立一定的积分体系,用户可以用积分兑换红包,并在余额中查看。
前提条件
获取模板
开发者在打开小程序开发者工具时,选择 模板选取 > 开放能力 > 现金红包 demo,即可进入现金红包的开发模板。
整体流程
使用现金红包模板进行快速开发的整体流程如下图所示:
开发准备
签约现金红包功能
- 登录 小程序开发中心,在 我的小程序 中,选择相应的小程序,进入该小程序详情页。
- 在小程序详情开发管理页面的 功能列表 中,点击右下角 添加功能 按钮,添加 现金红包 功能。
添加引入 SDK 依赖
请在 AlipaySDK JAVA 下载引入 AlipaySDK 开发使用。
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>
使用步骤
关注类领取红包
功能
商家可以通过现金红包为自己的生活号引流,用户在关注小程序关联的生活号后,可以领取相应数额的现金红包。
现金红包 DEMO 领取示例:
实现
关注生活号组件
以 DEMO 中为例,首先为了让用户有关注生活号的入口,需要首先在页面添加关注生活号组件,具体可以参考 lifestyle 组件文档,在此不赘述。
用户未关注生活号时 isCollected 参数为 false,页面按钮会显示 关注生活号领取红包;点击该按钮,触发点击事件 onClickCollect() 会弹出弹窗提示用户需要先关注生活号。
用户点击右上角关注按钮后 isCollected 参数会被赋为 true 此时用户界面会显示 已关注,领取红包 点击此按钮触发 onClickCollect() 事件且会调用 handleRedPacket() 函数获取红包;获取成功后会在用户界面显示红包信息。
关注生活号前后 Button 显示变化逻辑
在 index.js 中,小程序页面加载时,将 收藏状态(是否关注生活号) isCollected 初始化,默认值为 false,即用户未关注该生活号。
//.js
data: {
isCollected: false, //收藏状态
},
小程序 axml中 关注生活号领取红包 按钮显示内容使用三目运算符通过判断用户是否关注生活号或分享转发来动态显示 button 内容,当用户点击右上角关注按钮后 isCollected 参数会被赋为 true。button 中内容则会改变为 已经关注,领取红包 ,点击即可领取红包。
<!-- .axml --><view class="redpacket-button">
<button type="ghost" onTap="onClickCollect">
{{ isCollected ? '已经关注,领取红包' : '关注生活号领红包'}}
</button>
<view class="desc">
关注生活号后可以领取红包
</view>
转发类红包
功能
在小程序的营销场景下,开发者可以用红包的形式鼓励用户转发小程序,通过社交裂变提高小程序的访问量。 现金红包 DEMO 领取示例:
实现
用户点击小程序页面的 分享领红包 按钮 ,该按钮中定义了点击事件 onClickShare(),该函数会判断 isShared 参数的值以此确定用户是否完成转发,默认 isShared 参数当前值为 false ,会调用 my.showSharePanel 唤起分享页面。
DEMO中当分享面板展开即判定用户转发成功,具体业务场景请按照需求实现。此时会将 isShared 的值被赋为
true ,用户页面的按钮信息会变为 已经分享,领取红包 ;
分享小程序前后 Button 显示变化逻辑
在 index.js 中,小程序页面加载时,将 分享状态(是否分享小程序) isShared 初始化,默认值为 false,即用户未分享该小程序。
//.js
data: {
isShared: false, //分享状态
},
小程序 axml 中 分享领红包 按钮显示内容使用三目运算符通过判断用户是否分享小程序显示 button 内容,当用户点击 分享领红包 按钮后,用户界面会弹出分享面板,此时 isShared 参数会被赋为 true 。button 中内容则会改变为 已经分享,领取红包 ,点击即可领取红包。
<!-- .axml --><view class="redpacket-button">
<button type="ghost" onTap="onClickShare">
{{ isShared ? '已经分享,领取红包' : '分享领红包' }}
</button><view class="desc">
积分制领取红包
功能
在符合相关规定的前提下,开发者可以在小程序内建立一定的积分体系,用户可以用积分兑换红包,并在余额中查看,如下图所示。
现金红包 DEMO 领取示例:
实现
DEMO 中默认用户积分 point 值为 9999,点击 消耗积分进行红包兑换 按钮,该按钮中定义了点击事件 onClickPoint() ,该函数封装了 JSAPI my.confirm 用于弹窗提示用户是否确定使用积分获取红包,当用户点击 立即兑换 同意后调用 usePoint() 函数用于获取积分兑换红包结果,该函数中封装了 JSAPI my.request 用于向后台发送请求和接收返回信息。当返回业务处理成功时会调用 handleRedPacket() 函数领取红包,领取成功后用户界面会显示红包信息。
在 index.js 中,小程序页面加载时,将用户积分信息 Point 初始化,默认值为 9999(仅测试使用,具体积分定义请开发者考虑实际场景实现)。
//.js
data: {
point:9999 //积分信息
},
后台 controller 中使用 PointsExchangeMockImpl 实现 PointsExchangeMock 接口进行积分兑换红包的业务操作,demo中直接返回 mock 信息,开发者需要根据实际情况实现。
public Object pointsExchangeMock(HttpResponse response) throws Exception {
Response alipayResponse = new Response();
try {
//积分兑换接口Mock,开发者可以根据自己实际的业务需要去实现积分兑换功能,此Demo这里直接Mock返回结果
alipayResponse.setCode("10000");
alipayResponse.setSuccess(true);
alipayResponse.setMsg("Success");
alipayResponse.setBody("Mock业务系统返回内容");
return alipayResponse;
}catch (Exception e) {
alipayResponse.setCode("40000");
alipayResponse.setSuccess(false);
alipayResponse.setMsg("false");
alipayResponse.setBody("Mock业务系统返回异常");
return alipayResponse;
}
}
领取红包(通用代码逻辑)
关注类、转发类和积分制红包在发放时,都需要设置以下的红包发放逻辑:
小程序领取红包函数 handleRedPacket() 函数逻辑:
//.js
// 点击领取红包
async handleRedPacket() {
try {
const auth = await this.getAuthCode('auth_user');
if (auth && auth.authCode) {
let res = null;
if (configObj === 'dev') {//参见 configObj 参数值参见 config/index.js
res = await this.getRedPacket(auth.authCode);
} else {
res = { ...mockRedPacketData }; //模拟数据
}
if (res && res.success) {
this.setData({
isShowRedPacket: true
})
}
}
} catch (error) {
my.showToast({
content: error.message
});
}
},
handleRedPacket() 函数会先获取用户授权情况,调用 this.getAuthCode('auth_user') 函数,传入参数为用户授权类型,该函数中封装了小程序 JSAPI my.getAuthCode 用于获取用户授权码;
//.js /**
* @name getAuthCode
* @description 获取用户授权
* @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: '获取用户授权失败' });
}
});
});
},
获取到用户授权后 调用 getRedPacket(authCode) 函数像商户后台发起请求获取红包,该函数需要传入authCode 用于后台换取 accessToken 和 user_id,该函数中封装了小程序JSAPI my.request 用于向后台发送和接收返回数据,此处用 POST 方式将要传给后台的 authCode 值放在 data 中传递给后台。
//.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: '红包领取失败'
});
}
resolve(result.data);
},
fail: (error) => {
reject({
...error,
message: '红包领取异常'
});
}
})
})
},
当后台处理完成业务逻辑后会将红包信息返回( DEMO 中不做具体处理,请根据具体业务环境解析使用数据),当业务处理成功时会将 isShowRedPacket 参数赋为 true (DEMO中将信息定义在axml中的 modal 标签中) 用户界面就会显示领取红包的信息。
<!-- .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">领取现金红包</view>
此为示例demo,请按文档对接。
<view slot="footer">我知道了</view>
</modal>
说明:为了良好的用户体验,用户领取红包后请注意红包页面定义点击隐藏事件。
后台处理红包业务代码:
java 代码中请注意使用支付宝的 OpenAPI 向支付宝服务器发送请求,都需要构造 AlipayClient 且需要配置的各项参数,例如 小程序的公钥,私钥,网关地址,请求格式,字符集,签名类型等参数,建议与 DEMO 中类似编写配置信息的工具类并且将配置信息放在 properties 文件中方便后期修改,减小代码改动。参考 DEMO 中 config 包与 resource 包中的 Application.properties 文件。
DEMO 中使用 server/src/main/java/com/controller/rest 下的 AlipayFundTransUniTransferControllerImpl 类实现 AlipayFundTransUniTransferControllerl 接口,用于处理获取红包业务,此处需要获取前端发回的 auth_code 用户授权码。
调用自定义的 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;
}
}
调用 getAccessToken(auth_code) 方法传入 auth_code:
在该方法中调用 OpenAPI alipay.system.oauth.token (换取授权访问令牌)对象 request 并使用 AlipayClient 的certificateExecute(request) 方法获取 AlipaySystemOauthTokenResponse 返回,该返回类型中包含了换取 accessToken 状态以及支付宝用户的 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);
}
商户处理完成业务将信息封装到 JSON 中 并且使用 OpenAPI 统一转账接口 (alipay.fund.trans.uni.transfer)创建 AlipayFundTransUniTransferRequest 对象 request 并且将数据使用 request.setBizContent() 方法保存,调用 AlipayClient 的certificateExecute(request) 方法传入该 request 对象,向支付宝服务器发送请求处理。
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", "现金红包测试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);
最后将处理结果返回给前端页面解析显示。
小程序发布
代码编写完成后,开发者可以参考小程序 发布流程,提交开发完成的小程序。