1、选用模板,获取模板 ID。
2、通过 form组件 获取 formId 或 tradeNo 属性。
formId: 页面的 组件,属性 report-submit 为 true 时,可以声明为需发模板消息,此时用户点击按钮提交表单可以获取 formId,用于发送表单类模板消息。
tradeNo: 当用户完成支付行为时,可以获取 tradeNo 用于发送交易类模板消息。
3、调用接口下发模板消息。
下发模板消息的接口名称为:alipay.open.app.mini.templatemessage.send
4、参考官方文档:模板消息
交易类: 当用户在小程序内完成支付行为,可允许开发者向付款用户在 7 天内推送有限条数的模板消息(同个订单号只能发送 3 条消息,不限制模板数),当开发者调用交易类的模板消息时,必须要传入 tradeNo 。
表单类: 当用户在小程序内发生过提交表单行为且该表单为要发模板消息的,可允许开发者向用户在 7 天内推送有限条数的模板消息( 1 次提交表单可下发 3 条,不限制模板数),当开发者调用表单类的模板消息时,必须要传入 formid 。
时效性: 开发者获取 formId 或 tradeNo 后,可在 7 天内向用户推送消息,超出后 formId 或 tradeNo 将失效,无法推送消息。
引入maven
<!-- 支付宝 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.7.11.ALL</version>
</dependency>
<dependency>
<groupId>com.alipay</groupId>
<artifactId>sdk-java</artifactId>
<version>20170612154830</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.0.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.48</version>
</dependency>
<!-- lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
配置application.properties
#小程序
alipay.push.message.template.appid=你的小程序appId
#开发者私钥,由开发者自己生成
alipay.push.message.template.privateKey=开发者私钥
#支付宝公钥,由支付宝生成
alipay.push.message.template.alipayPublicKey=支付宝公钥
#模板Id
alipay.push.message.template.id=你的模板Id
#支付宝网关(固定)
alipay.push.message.template.serverUrl=https://openapi.alipay.com/gateway.do
#商户生成签名字符串所使用的签名算法类型,目前仅支持 RSA2
alipay.push.message.template.signType=RSA2
模板消息实体类
@Data
public class AlipayTemplateParam {
/**
* 小程序app_id
*/
private String appId;
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String alipayPublicKey;
/**
* 要发送消息的用户
*/
private String to_user_id;
/**
* from_id
*/
private String form_id;
/**
* 模板Id
*/
private String user_template_id;
/**
* 点击消息通知卡片跳转的页面
*/
private String page;
/**
* 需要发送模板消息中自定义部分 {{keyworld1.value}}
*/
private String data;
}
配置类SysConfig
@Data
@Configuration
public class SysConfig {
/******************支付宝直连参数配置*********************/
@Value("${alipay.push.message.template.appid}")
private String appId;
@Value("${alipay.push.message.template.privateKey}")
private String privateKey;
@Value("${alipay.push.message.template.alipayPublicKey}")
private String alipayPublicKey;
@Value("${alipay.push.message.template.id}")
private String templateId;
@Value("${alipay.push.message.template.serverUrl}")
private String serverUrl;
@Value("${alipay.push.message.template.signType}")
private String signType;
}
模板消息推送完整实现类
@Component
public class AlipaySendTemplateServiceImpl implements AlipaySendTemplateService {
Logger logger = LoggerFactory.getLogger(AlipaySendTemplateServiceImpl.class);
@Autowired
private SysConfig sysConfig;
@Override
public void sendTemplateMessage(PaymentParam param) {
String appId = sysConfig.getAppId();
String privateKey = sysConfig.getPrivateKey();
String publicKey = sysConfig.getAlipayPublicKey();
AlipayTemplateParam templateParam = new AlipayTemplateParam();
templateParam.setTo_user_id(param.getUserId());
templateParam.setForm_id(param.getFormId());
templateParam.setUser_template_id(sysConfig.getTemplateId());
templateParam.setPage(param.getPage());
templateParam.setData(getTemplateDataJSON(param));
String paramJson = JSON.toJSONString(templateParam);
AlipayOpenAppMiniTemplatemessageSendRequest request = new AlipayOpenAppMiniTemplatemessageSendRequest();
request.setBizContent(paramJson);
logger.info("调用支付宝发送模版消息接口,request = {}",JSON.toJSONString(request));
AlipayOpenAppMiniTemplatemessageSendResponse response = null;
try{
response = getAlipayClient(request,appId,privateKey,publicKey);
if(response != null && response.isSuccess()){
logger.info("支付宝发送模版消息成功:response={}", JSON.toJSONString(response));
}else{
logger.info("支付宝发送模版消息异常:errorCode:{}, errorMsg:{}", response.getCode(), response.getSubMsg());
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 在 SDK 调用前需要进行初始化,获取lipayClient 只需要初始化一次,后续调用不同的 API 都可以使用同一个 alipayClient 对象
*
* @param request
* @param appId
* @param privateKey
* @param alipayPublicKey
* @param <T>
* @return
* @throws AlipayApiException
*/
private <T extends AlipayResponse> T getAlipayClient(AlipayRequest<T> request, String appId, String privateKey, String alipayPublicKey) throws AlipayApiException {
String serverUrl = sysConfig.getServerUrl();
String signType = sysConfig.getSignType();
AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, "json", "utf-8", alipayPublicKey, signType);
return alipayClient.execute(request);
}
/**
* 构建消息体
*
* @param param
* @return
*/
private String getTemplateDataJSON(PaymentParam param) {
Map<String, TemplateSendData> dataMap = new HashMap<>();
String keyword1 = param.getStoreName();
String keyword2 = param.getTakeOrderNo();
String keyword3 = param.getReminder();
String keyword4 = param.getKeyworld4();
String keyword5 = param.getKeyworld5();
if (StringUtils.isNotBlank(keyword1)) {
dataMap.put("keyword1", new TemplateSendData(keyword1));
}
if (StringUtils.isNotBlank(keyword1)) {
dataMap.put("keyword2", new TemplateSendData(keyword2));
}
if (StringUtils.isNotBlank(keyword1)) {
dataMap.put("keyword3", new TemplateSendData(keyword3));
}
if (StringUtils.isNotBlank(keyword1)) {
dataMap.put("keyword4", new TemplateSendData(keyword4));
}
if (StringUtils.isNotBlank(keyword1)) {
dataMap.put("keyword5", new TemplateSendData(keyword5));
}
String dataJson = JSON.toJSONString(dataMap);
return dataJson;
}
}