access_token 管理
@Service
public class KuaishouService {
@Value("${ks.getTokenUrl}")
private String getTokenUrl;
@Value("${ks.appId}")
private String appId;
@Value("${ks.appSecret}")
private String appSecret;
private String accessToken;
private Date tokenExpire;
@Autowired
private RestTemplate restTemplate;
public String fetchToken() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap();
map.add("app_id", appId);
map.add("app_secret", appSecret);
map.add("grant_type", "client_credentials");
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity(map, headers);
KsAccess ksAccess = restTemplate.postForObject(getTokenUrl, requestEntity, KsAccess.class);
if (ksAccess.getResult() != 1) {
throw new RestfulException(ksAccess.getResult(), "获取 access_token 失败");
}
accessToken = ksAccess.getAccess_token();
long duration = ksAccess.getExpires_in() - 300;
tokenExpire = new Date(System.currentTimeMillis() + duration * 1000);
return accessToken;
}
public String getAccessToken() {
if (accessToken == null || tokenExpire == null || tokenExpire.before(new Date())) {
fetchToken();
}
return accessToken;
}
}
支付相关
@Service
public class KsPayService {
private static Logger logger = LogManager.getLogger(KsPayService.class.getName());
@Value("${ks.appId}")
private String appId;
@Value("${ks.appSecret}")
private String appSecret;
@Value("${ks.placeOrderUrl}")
private String placeOrderUrl;
@Value("${ks.orderQueryUrl}")
private String orderQueryUrl;
@Autowired
private RestTemplate restTemplate;
@Autowired
private KuaishouService kuaishouService;
/* 签名 */
public String sign(Map map) {
List<String> list = new ArrayList(map.keySet());
Collections.sort(list); // 字典排序
StringBuffer sb = new StringBuffer();
for (String key : list) {
if(sb.length() > 0){
sb.append("&");
}
sb.append(key + "=" + map.get(key)); // 拼接参数
}
sb.append(appSecret); // 拼上app_secret,注意不用拼接 &
return DigestUtils.md5Hex(sb.toString()); // MD5 摘要,并转大写
}
/* 统一下单 */
public JSONObject unifiedOrder(KsPay ksPay) throws DocumentException {
ksPay.setExpire_time(7200);
Map<String, String> dataMap = new HashMap<>();
dataMap.put("app_id", appId);
dataMap.put("out_order_no", ksPay.getOut_order_no()); // 订单号
dataMap.put("open_id", ksPay.getOpen_id()); // trade_type=JSAPI时,openid必填
dataMap.put("total_amount", "" + ksPay.getTotal_amount()); // 金额
dataMap.put("subject", ksPay.getSubject()); // 商品描述
dataMap.put("detail", ksPay.getDetail()); // 商品详情
dataMap.put("type", "" + ksPay.getType());
dataMap.put("expire_time", "" + ksPay.getExpire_time());
dataMap.put("notify_url", ksPay.getNotify_url()); // 回调地址
String sign = this.sign(dataMap); // 签名
ksPay.setSign(sign);
String url = String.format(placeOrderUrl, appId, kuaishouService.getAccessToken());
String jsonStr = restTemplate.postForObject(url, ksPay, String.class);
JSONObject response = JSON.parseObject(jsonStr);
response = this.preTreatResponse(response); // 处理响应
return response;
}
/* 校验 支付通知 */
public void notifyValidate(String sign, String request) {
String mySign = DigestUtils.md5Hex(request + appSecret);
if (!mySign.equals(sign)) { // 校验签名
throw new RestfulException("签名不正确");
}
}
/* 查询订单 */
public JSONObject queryOrder(String out_order_no) {
Map<String, String> dataMap = new HashMap<>();
dataMap.put("app_id", appId);
dataMap.put("out_order_no", out_order_no); // 订单号
String sign = this.sign(dataMap); // 签名
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
JSONObject request = new JSONObject();
request.put("out_order_no", out_order_no);
request.put("sign", sign);
HttpEntity<String> requestEntity = new HttpEntity(request.toJSONString(), headers);
String url = String.format(orderQueryUrl, appId, kuaishouService.getAccessToken());
String jsonStr = restTemplate.postForObject(url, requestEntity, String.class);
JSONObject response = JSON.parseObject(jsonStr);
response = this.preTreatResponse(response); // 处理响应
return response;
}
/* 预处理响应 */
public JSONObject preTreatResponse(JSONObject jsonObject) {
int result = jsonObject.getIntValue("result");
if (result != 1) {
result = result == 0 ? -1 : result;
throw new RestfulException(result, jsonObject.getString("error_msg"));
}
return jsonObject;
}
public String notifySuccess(String message_id) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("result", 1);
jsonObject.put("message_id", message_id);
return jsonObject.toJSONString();
}
}