1:在平台申请支付功能,设置回调接口,token

2:服务端支付下单

加密工具类

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
*加密工具类
*/
public class DouYinUtil {// 支付密钥值private static final String SALT = "担保交易设置中的SALT";// paramsMap 参数含义解释同 golangpublic static String getSign(Map<String, Object> paramsMap) {List<String> paramsArr = new ArrayList<>();for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {String key = entry.getKey();if (key.equals("other_settle_params")) {continue;}String value = entry.getValue().toString();value = value.trim();if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {value = value.substring(1, value.length() - 1);}value = value.trim();if (value.equals("") || value.equals("null")) {continue;}switch (key) {case "app_id":case "thirdparty_id":case "sign":break;default:paramsArr.add(value);break;}}paramsArr.add(SALT);Collections.sort(paramsArr);StringBuilder signStr = new StringBuilder();String sep = "";for (String s : paramsArr) {signStr.append(sep).append(s);sep = "&";}return md5FromStr(signStr.toString());}public static String md5FromStr(String inStr) {MessageDigest md5;try {md5 = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {e.printStackTrace();return "";}byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8);byte[] md5Bytes = md5.digest(byteArray);StringBuilder hexValue = new StringBuilder();for (byte md5Byte : md5Bytes) {int val = ((int) md5Byte) & 0xff;if (val < 16) {hexValue.append("0");}hexValue.append(Integer.toHexString(val));}return hexValue.toString();}public static String getSha1(String str) {if (str == null || str.length() == 0) {return null;}char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f'};try {MessageDigest mdTemp = MessageDigest.getInstance("SHA1");mdTemp.update(str.getBytes(PublicFinal.S_UTF_8));byte[] md = mdTemp.digest();int j = md.length;char[] buf = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];buf[k++] = hexDigits[byte0 >>> 4 & 0xf];buf[k++] = hexDigits[byte0 & 0xf];}return new String(buf);} catch (Exception e) {// TODO: handle exceptionreturn null;}}
}

支付下单/支付回调

@Autowired
private RestTemplate restTemplate;/*** 获取支付的请求参数*/@ApiOperation(value = "获取支付的请求参数")@GetMapping("prepay")public Object payPrepay(Integer orderId) {logger.info("---------orderId:{}",orderId);Map<String, Object> parame = new LinkedHashMap<>();//抖音小程序appparame.put("app_id", "appid");// 商户订单编号parame.put("out_order_no", "订单号,需平台唯一");//支付金额parame.put("total_amount", new BigDecimal(1).multiply(new BigDecimal(100)).intValue());// 商品标题parame.put("subject","商品名称");// 商品描述(不能为空)parame.put("body", "商品描述");// 回调地址(与支付设置中一致)parame.put("notify_url", "担保交易设置中的回调地址");// 时间parame.put("valid_time",900);// 支付密钥String sign = DouYinUtil.getSign(parame);logger.info("支付下单密钥签名:{}",sign);// 数字签证parame.put("sign", sign);String res = restTemplate.postForObject("https://developer.toutiao.com/api/apps/ecpay/v1/create_order",parame,String.class);logger.info("res-----------:{}",res);JSONObject sessionData1 = JSON.parseObject(res);if ("0".equalsIgnoreCase(sessionData1.getString("err_no"))) {logger.info("支付成功");JSONObject sessionData = sessionData1.getJSONObject("data");Map<String, Object> resultObj = new HashMap();String prepayId = sessionData.getString("order_id");resultObj.put("err_no",sessionData1.getString("err_no"));resultObj.put("order_id",prepayId);resultObj.put("order_token",sessionData.getString("order_token"));return resultObj;}else{logger.info("支付失败");Map<String, Object> resultObj = new HashMap<>();resultObj.put("err_no",sessionData1.getString("err_no"));return resultObj;}}@ApiOperation(value = "抖音微信订单回调接口")@RequestMapping(value = "/notify", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")@ResponseBodypublic Object dynotify(HttpServletRequest request, HttpServletResponse response) {try {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=UTF-8");response.setHeader("Access-Control-Allow-Origin", "*");InputStream in = request.getInputStream();ByteArrayOutputStream out = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = in.read(buffer)) != -1) {out.write(buffer, 0, len);}out.close();in.close();String responseJson = new String(out.toByteArray(),"utf-8");logger.info("responseJson:{}",responseJson);JSONObject jsonObject = JSONObject.parseObject(responseJson);JSONObject msgJson = jsonObject.getJSONObject("msg");String resultCode = jsonObject.getString("type");if ("payment".equalsIgnoreCase(resultCode)) {List<String> sortedString = new ArrayList<>();//tokensortedString.add("token");//时间戳sortedString.add(jsonObject.getString("timestamp"));//随机数sortedString.add(jsonObject.getString("nonce"));//msgsortedString.add(jsonObject.getString("msg"));Collections.sort(sortedString);StringBuilder sb = new StringBuilder();sortedString.forEach(sb::append);String msg_signature = jsonObject.getString("msg_signature");String sign = DouYinUtil.getSha1(sb.toString().trim());logger.info("支付回调接口密钥签名:{}",sign);if(!sign.equals(msg_signature)) {//判断签名JSONObject resultJson = new JSONObject();resultJson.put("err_no",8);resultJson.put("err_tips","error");return resultJson.toString();}JSONObject resultJson = new JSONObject();resultJson.put("err_no",0);resultJson.put("err_tips","success");return resultJson.toString();} else {//订单编号String outTradeNo = msgJson.getString("cp_orderno");logger.error("订单" + outTradeNo + "支付失败");JSONObject resultJson = new JSONObject();resultJson.put("err_no",0);resultJson.put("err_tips","error");return resultJson.toString();}} catch (Exception e) {e.printStackTrace();JSONObject resultJson = new JSONObject();resultJson.put("err_no",8);resultJson.put("err_tips","error");return resultJson.toString();}}

注意:支付下单签名加密方式为Md5,支付回调接口签名为Sha1,加密参数顺序不能乱

Java实现字节小程序微信担保支付及回调超详细相关推荐

  1. .NET 小程序微信用户支付

    微信支付有两种模式:微信用户主动发起的支付.签约委托支付协议后自动支付. 自动支付又分为两种:首次支付时签约.纯签约. 首次支付时签约和纯签约在后续周期若需要发起自动扣款时,需要在应用服务中发起申请扣 ...

  2. java整合快手小程序(登陆,支付,结算,退款,手机号授权登陆)

    快手小程序官方文档 快手小程序官网地址 快手小程序后台配置回调域名 代码部分 KSUrlConstants(请求地址常量) 商品类目编号根据业务自行替换 package com.dfjs.consta ...

  3. [转]微信小程序 c#后台支付结果回调

    本文转自:http://www.cnblogs.com/weizhiing/p/7700723.html 又为大家带来简单的c#后台支付结果回调方法,首先还是要去微信官网下载模板(WxPayAPI), ...

  4. php快手小程序微信H5支付

    这里写自定义目录标题 快手接入流程 快手微信支付 签名快手 获取微信H5支付url 支付签名 组装xml postcurl请求 解析xml unit时间戳 快手接入流程 添加链接描述 快手微信支付 p ...

  5. 微信小程序云函数使用教程【超详细】

    背景需求 在本人的项目中,需要调用一个http的接口,而微信小程序所有的网络请求都得使用https,因而需要一个中转站,使得在正式发布的时候可以使用http接口.(在调试环境下,只要在本地设置里勾选& ...

  6. 微信小程序 - 页面插入添加 Banner 广告超详细教程(支持自定义样式、位置、大小等)及注意事项

    前言 如果您需要点击弹出的广告,请访问: 微信小程序 - 页面插入广告(激励式广告). 本文将从 0-1 完成整个过程,您只需要按照步骤操作即可, 代码干净整洁注释详细,快速将代码移植到您的微信小程序 ...

  7. 微信小程序实现搜索功能以及效果(超详细)

    我们先来看一下实现哪些功能: 1 搜索历史记录以及清空历史记录 2 热门搜索推荐以及更新推荐内容 3 根据输入框输入的内容来自动搜索相关查询,后台逻辑是模糊查询,后台就先不扯了 这里我用的是自己定义的 ...

  8. uniapp 微信小程序小票打印机打印教程(超详细讲解) 完整代码,下载后可直接使用

    天梦星官网 (tmxkj.top)https://tmxkj.top/#/  编程资源 直接上代码: ly_text:"点击搜索",connected_ly:false,//蓝牙按 ...

  9. 微信小程序1:豆瓣评分(超详细版)

    项目展示:                                   首先,自定义组件searchbar.stars,以及search组件 记小本本哦: (1)自定义组件:searchbar ...

最新文章

  1. C#实现rabbitmq 延迟队列功能
  2. 利用OpenCV实现人眼的检测与跟踪
  3. python3.6打包成exe可执行文件、已解决方案_Python 3.6打包成EXE可执行程序的实现...
  4. 【渝粤教育】电大中专新媒体营销实务 (11)作业 题库
  5. Contest2162 - 2019-3-28 高一noip基础知识点 测试5 题解版
  6. java 守护进程 linux_Java实现Linux下服务器程序的双守护进程
  7. Doris之故障恢复(重点)
  8. linux优化服务器,Linux服务器优化
  9. 关于int main(int argc,char* argv[])详解
  10. gcc for linux安装失败,安装错误的gcc导致一些错误
  11. HttpUtils工具类
  12. STC芯片在Keil中的添加与使用
  13. qq说说时间轴php实现,QQ说说时间 qq说说时间轴
  14. 读【选修计算机专业的伤与痛】
  15. 基于JavaWeb的C2C网上购物平台系统设计
  16. React+Antd兼容ie浏览器,360安全浏览器兼容模式
  17. Dynamics CRM IFD部署如何更换SSL证书
  18. 微信小程序开发基础知识2(黑马)
  19. Python脚本下载TCGA大数据,非常简单,开放源代码
  20. 原创图片可以进行版权登记吗?

热门文章

  1. 深富策略航运股持续走强
  2. 计算机房设计方案,机房设计要求方案
  3. GDOUCTF web
  4. 向量范数:1-范数、2-范数、无穷范数;矩阵范数;欧几里得度量
  5. CSS超出用……表示并隐藏
  6. 03 【PMP】组织结构类型的优缺点和适用范围包括哪些
  7. 硬质合金牌号及切削刀片型号的表示方法
  8. 嵌入式 QT 基于mplayer的音乐播放器
  9. MySQL空间清理的几种具体方法
  10. matlab结构体数组定义方法