之前写的技术介绍文档:
开发介绍文档
里边还包括微信端小程序相关功能开发流程的介绍。
微信开发代码梳理:
微信支付功能代码
相比于微信的开发流程来说,百度的支付功能相对简单,因为全程和百度平台没有交互,只有对账时比较麻烦。
controller层就不做介绍了,主要还是service层的代码逻辑。
经过新一轮的调试,bizInfo如果没有特殊需求(返回特定的页面信息)其实可以不用填写的,直接写{}也可以在前端调起收银台
public BaiDuOrderInfoVO generateOrderInfo(String fee) {
//生成商户订单号,百度没有规定格式,自行生成,参照微信订单号,时间+随机序列,长度32位,自己写个工具类
String tpOrderId = GenerateTradeNumberUtil.getTradeNumber(RewardConstants.BDTRADELENGTH);
BaiDuOrderInfoVO baiDuOrderInfoVO = buildInfo(fee, tpOrderId);
//利用私钥,生成签名,校验生成结果,使用的是百度提供的工具类
String sign = BaiDuSignUtil.generateSign(baiDuOrderInfoVO, BaiDuRSAKeyConstant.RSAPKCS8);
if (StringUtils.isBlank(sign)) {
log.error("BD generate sign error.");
throw new ServiceException(SystemCode.GENSIGN_FAIL, "BD generate sign error");
}
baiDuOrderInfoVO.setRsaSign(sign);
//生成BizInfo,订单详细信息
BaiDuBizInfoVO baiDuBizInfoVO = buildBiz(baiDuOrderInfoVO);
baiDuOrderInfoVO.setBaiDuBizInfo(baiDuBizInfoVO);
return baiDuOrderInfoVO;
}
/**
* 生成订单信息类,不包括签名以及BizInfo信息
*
* @return
*/
private BaiDuOrderInfoVO buildInfo(String fee, String tpOrderId) {
BaiDuOrderInfoVO baiDuOrderInfoVO = new BaiDuOrderInfoVO();
baiDuOrderInfoVO.setAppKey(payAppKey);
baiDuOrderInfoVO.setDealId(dealId);
baiDuOrderInfoVO.setDealTitle(RewardConstants.BDTITLE);
baiDuOrderInfoVO.setTotalAmount(fee);
baiDuOrderInfoVO.setTpOrderId(tpOrderId);
baiDuOrderInfoVO.setSignFieldsRange(RewardConstants.WITHFEE);
return baiDuOrderInfoVO;
}
/**
* 生成订单详细信息类,BizInfo
*/
private BaiDuBizInfoVO buildBiz(BaiDuOrderInfoVO baiDuOrderInfoVO) {
BaiDuBizInfoVO baiDuBizInfoVO = new BaiDuBizInfoVO();
baiDuBizInfoVO.setAppKey(appKey);
baiDuBizInfoVO.setDealld(dealId);
baiDuBizInfoVO.setTotalAmount(baiDuOrderInfoVO.getTotalAmount());
baiDuBizInfoVO.setTpOrderId(baiDuOrderInfoVO.getTpOrderId());
return baiDuBizInfoVO;
}
用到的包装类:
/**
* 百度订单信息类,见百度开发者文档
*
*/
@Data
public class BaiDuOrderInfoVO {
private String dealId;
private String appKey;
private String totalAmount;
private String tpOrderId;
private String dealTitle;
private String signFieldsRange;
private String rsaSign;
private String bizInfo;
/**
* 提供传入bizInfo对象来给this.bizInfo的值
*
* @param bizInfo
*/
public void setBaiDuBizInfo(BaiDuBizInfoVO bizInfo) {
String json = JsonUtil.toJson(bizInfo);
StringBuffer buffer = new StringBuffer("{\"tpData\":");
buffer.append(json);
buffer.append("}");
this.setBizInfo(buffer.toString());
}
}
/**
* 百度订单信息中的BizInfo,订单详细信息
*
*/
@Data
public class BaiDuBizInfoVO {
private String appKey;
private String dealld;
private String tpOrderId;
private String totalAmount;
}
将service层返回的信息转成JSON返给前端即可完成流程。
获取对账单的流程和百度的基本上一样,只不过多了一步获取token的步骤。
/**
* 每天定时下载对账单
*/
@Scheduled(cron = "0 0 10 * * ?")
public void bdDownloadBill() {
//首先调用给定的接口来获取accesstoken,利用token才能去获取前一天的账单
String accessToken = getToken();
//获取到token后,携带参数请求前一天的账单
String billTime = BaiDuPayUtil.getBillTime();
//携带参数请求账单下载URL
String downloadURL = getDownloadURL(accessToken, billTime);
//个人的业务逻辑
}
/**
* 请求获得token
*
* @return
*/
private String getToken() {
StringBuilder queryTotalUrl = new StringBuilder(RewardConstants.TOKENURL);
queryTotalUrl.append("grant_type=client_credentials");
queryTotalUrl.append("&client_id=" + appKey);
queryTotalUrl.append("&client_secret=" + appSecret);
queryTotalUrl.append("&scope=smartapp_snsapi_base");
UriComponents uriComponents = UriComponentsBuilder.fromUriString(queryTotalUrl.toString()).build();
URI uri = uriComponents.toUri();
ResponseEntity<Map> responseEntity = null;
try {
responseEntity = restTemplate.getForEntity(uri, Map.class);
} catch (Exception e) {
log.error("require access_token error!!!!");
;
}
Map body = responseEntity.getBody();
String token = (String) body.get("access_token");
return token;
}
/**
* 获取订单信息下载URL
*/
private String getDownloadURL(String accessToken, String billTime) {
StringBuilder downloadURL = new StringBuilder(RewardConstants.BDDOWNLOADBILLURL);
downloadURL.append("?access_token=" + accessToken);
downloadURL.append("&billTime=" + billTime);
UriComponents uriComponents = UriComponentsBuilder.fromUriString(downloadURL.toString()).build();
URI uri = uriComponents.toUri();
ResponseEntity<Map> responseEntity = null;
try {
responseEntity = restTemplate.getForEntity(uri, Map.class);
} catch (Exception e) {
System.out.println("error!!!!");
;
}
Map body = responseEntity.getBody();
Map<String, Object> data = (Map<String, Object>) body.get("data");
if(data==null){
return null;
}
List msg = (List) data.get("data");
Map<String, Object> param = (Map<String, Object>) msg.get(0);
//导出进度为100才可以去下载账单,否则意味着百度账单未生成
if (param.get("exportStatus").equals(100)) {
return (String) param.get("url");
}
return "FALSE" + param.get("url");
}
}
百度的功能还没来得及实验,但是整体上是没有问题的,前端能收到正确的返回结果,下载账单也可以下载解析。
转载请联系!!!!!
欢迎大家一起讨论