当前位置: 首页 > news >正文

西海岸建设局网站连锁店网站建设

西海岸建设局网站,连锁店网站建设,无锡高端网站设计,济南行知网站建设SpringBoot中实现微信支付: 1.“微信支付”产品2.微信支付接入流程3.“微信小程序支付”时序图#xff1a;3.1 “商家端JSAPI下单” 接口3.2 “微信小程序端调起支付” 接口 4.微信支付准备工作#xff1a;4.1 获得微信支付平台证书、商户私钥文件4… SpringBoot中实现微信支付: 1.“微信支付”产品2.微信支付接入流程3.“微信小程序支付”时序图3.1 “商家端JSAPI下单” 接口3.2 “微信小程序端调起支付” 接口 4.微信支付准备工作4.1 获得微信支付平台证书、商户私钥文件4.2 获取临时域名 (内网穿透) ①下载且安装软件 : cpolar②获得 “Authtoken” 且配置 cpolar 生成“内网穿透”工具配置文件③启动服务临时获取到一个IP地址 (临时域名) 5.“微信小程序支付”代码OrderControlle.java (订单Controller)OrderService.javaOrderServiceImpl.java (包含 : 微信支付工具类)OrderMapper.javaOrderMapper.xmlUserMapper.javaPayNotifyController.java / 支付回调相关接口application.yml (springboot配置文件)application-dev.xml 1.“微信支付”产品 微信支付提供了多种产品即 微信支付多种支付的形式。如 付款码支付打开微信展示“微信支付”二维码页面让商家去扫。 JSAPI支付一般用于在H5页面进行微信支付。 JSAPI支付是指商户通过调用微信支付提供的JSAPI接口在支付场景中调起微信支付模块完成收款。 小程序支付在微信小程序中调用“微信支付”功能。 Native支付商家提供一个二维码我们用微信扫一扫功能来进行支付。 APP支付在手机应用中调起微信支付。 刷脸支付即刷脸完成付款。 “微信支付”产品详细介绍 微信支付产品 2.微信支付接入流程 3.“微信小程序支付”时序图 微信小程序支付时序图 微信小程序支付 主要内容为以下三个部分: “商家端JSAPI下单” 接口 / 微信下单接口 / 预下单接口“微信小程序端调起支付” 接口 / 调起微信支付推送支付结果 3.1 “商家端JSAPI下单” 接口 商户系统 调用 (小程序支付中的) JSAPI下单接口 在 微信支付服务后台 生成 预支付交易单。 “商家端JSAPI下单” 接口-详解 商家端通过 访问 https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi 接口来生成预支付交易单。 商家端JSAPI下单 / 生成预支付交易单 要访问的接口 请求示例 { mchid: 1900006XXX, out_trade_no: 1217752501201407033233368318, appid: wxdace645e0bc2cXXX, description: Image形象店-深圳腾大-QQ公仔, notify_url: https://www.weixin.qq.com/wxpay/pay.php, amount: {total: 1,currency: CNY }, payer: {openid: o4GgauInH_RCEdvrrNGrntXDuXXX} }返回示例 (正常示例) {prepay_id: wx26112221580621e9b071c00d9e093b0000 } 适用对象 直连商户 请求URLhttps://api.mch.weixin.qq.com/v3/pay/transactions/jsapi 请求方式POST 请求参数 请求参数-详解 参数名变量类型[长度限制]必填描述应用IDappidstring[1,32]是body 由微信生成的应用ID全局唯一。请求基础下单接口时请注意APPID的应用属性例如公众号场景下需使用应用属性为公众号的服务号APPID 示例值wxd678efh567hg6787直连商户号mchidstring[1,32]是body 直连商户的商户号由微信支付生成并下发。 示例值1230000109商品描述descriptionstring[1,127]是body 商品描述 示例值Image形象店-深圳腾大-QQ公仔通知地址notify_urlstring[1,256]是body异步接收微信支付结果通知的回调地址通知url必须为外网可访问的url不能携带参数。 公网域名必须为https如果是走专线接入使用专线NAT IP或者私有回调域名可使用http 示例值https://www.weixin.qq.com/wxpay/pay.php商户订单号out_trade_nostring[6,32]是body 商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一 示例值1217752501201407033233368018 订单金额amountobject是body 订单金额信息参数名变量类型[长度限制]必填描述总金额totalint是订单总金额单位为分。 示例值100货币类型currencystring[1,16]否CNY人民币境内商户号仅支持人民币。 示例值CNY 支付者payerobject是body 支付者信息参数名变量类型[长度限制]必填描述用户标识openidstring[1,128]是用户在直连商户appid下的唯一标识。 下单前需获取到用户的OpenidOpenid获取详见 示例值oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 返回参数 参数名变量类型[长度限制]必填描述预支付交易会话标识prepay_idstring[1,64]是预支付交易会话标识。用于后续接口调用中使用该值有效期为2小时 示例值wx201410272009395522657a690389285100 3.2 “微信小程序端调起支付” 接口 通过 JSAPI下单接口 获取到 发起支付 的必要参数 prepay_id然后使用微信支付平台提供的小程序方法 (wx.requestPayment(OBJECT) ) 来 调起小程序支付 (即完成小程序的微信支付) 。 “微信小程序端调起支付” 接口-详解 微信小程序通过调用wx.requestPayment(OBJECT) 发起微信支付。 请求示例 wx.requestPayment ({timeStamp: 1414561699,nonceStr: 5K8264ILTKCH16CQ2502SI8ZNMTM67VS,package: prepay_idwx201410272009395522657a690389285100,signType: RSA,paySign: oR9d8PuhnIcYZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/XQBhcCYL21N7cHCTUxbQEAt6UylwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuTCdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZVJSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8FuLozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2AehHvzn64GDmXxbXIOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg,success:function(res){},fail:function(res){},complete:function(res){}} )适用对象 直连商户 接口定义 此API无后台接口交互需要将列表中的数据签名。 参数名变量类型[长度限制]必填描述小程序IDappIdstring[1,32]是商户申请的小程序对应的appid由微信支付生成可在小程序后台查看 示例值wx8888888888888888时间戳timeStampstring[1,32]是时间戳标准北京时间时区为东八区自1970年1月1日 0点0分0秒以来的秒数。注意部分系统取到的值为毫秒级需要转换成秒(10位数字)。 示例值1414561699随机字符串nonceStrstring[1,32]是随机字符串不长于32位。推荐随机数生成算法。 示例值5K8264ILTKCH16CQ2502SI8ZNMTM67VS订单详情扩展字符串packagestring[1,128]是小程序下单接口返回的prepay_id参数值提交格式如prepay_id*** 示例值prepay_idwx201410272009395522657a690389285100签名方式signTypestring[1,32]是签名类型默认为RSA仅支持RSA。 示例值RSA签名paySignstring[1,512]是签名使用字段appId、timeStamp、nonceStr、package计算得出的签名值oR9d8PuhnIcYZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ/XQBhcCYL21N7cHCTUxbQEAt6UylwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuTCdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZVJSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8FuLozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2AehHvzn64GDmXxbXIOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq/xDg 调用wx.requestPayment(OBJECT)发起微信支付 接口名称 wx.requestPayment Object 参数说明 ( 这些需要用到的参数全都是后端计算好返回给微信小程序然后小程序直接使用这些参数来调用方法来就会弹出“微信支付”的窗口来完成微信支付。 ) 参数名变量类型[长度限制]必填描述时间戳timeStampstring[1,32]是当前的时间其他详见时间戳规则。 示例值1414561699随机字符串nonceStrstring[1,32]是随机字符串不长于32位。 示例值5K8264ILTKCH16CQ2502SI8ZNMTM67VS订单详情扩展字符串packagestring[1,128]是小程序下单接口返回的prepay_id参数值提交格式如prepay_id*** 示例值prepay_idwx201410272009395522657a690389285100签名方式signTypestring[1,32]是签名类型默认为RSA仅支持RSA。 示例值RSA签名paySignstring[1,512]是签名使用字段appId、timeStamp、nonceStr、package计算得出的签名值 示例值oR9d8PuhnIcYZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ/XQBhcCYL21N7cHCTUxbQEAt6UylwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuTCdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZVJSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8FuLozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2AehHvzn64GDmXxbXIOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq/xDg 回调结果 回调类型errMsg说明successrequestPayment:ok调用支付成功failrequestPayment:fail cancel用户取消支付failrequestPayment:fail (detail message)调用支付失败其中 detail message 为后台返回的详细失败原因 4.微信支付准备工作 要完成微信支付其中一个关键的步骤是需要在商户系统中来调用微信后台的微信下单接口 (“客户端JSAPI下单”接口) 来生成 预支付交易单。由于这个接口是与“支付”相关的所以这个接口的安全要求是非常高的同时”推送支付结果“的安全性要求也是非常高的。 如何保证调用过程的数据安全 对数据进行加密、解密、签名。 4.1 获得微信支付平台证书、商户私钥文件 获得微信支付平台证书、商户私钥文件 这两个文件是从微信的商户平台下载下来的程序开发过程中会使用到这两个文件。 ps 要获得这两个文件必须注册成商户。 4.2 获取临时域名 (内网穿透) 让当前 电脑能获取一个公网的IP地址让微信后台能调用到当前外卖系统的后端服务这样我们就需要来 获取临时域名。 这个临时域名对应的就是一个公网IP ①下载且安装软件 : cpolar 下载链接https://dashboard.cpolar.com/login cpolar软件下载安装包 (百度网盘下载链接)https://pan.baidu.com/s/10O1mK06ts-l37exniuTquw?pwdir23 提取码ir23 百度网盘获取cpolar安装包 ②获得 “Authtoken” 且配置 cpolar 生成“内网穿透”工具配置文件 ① 登录cpolar官网 : https://dashboard.cpolar.com/login 获得配置cpolar的cmd命令。 ② 在cpolar.exe的目录中敲cmd进入 cmd页面。 在命令行页面中输入 cpolar.exe authtoken 获得的Authtoken 该命令生成了一个 .yml文件 : 该文件是 当前“内网穿透工具”的配置文件。 ③启动服务临时获取到一个IP地址 (临时域名) 输入命令 cpolar.exe http 8080 5.“微信小程序支付”代码 OrderControlle.java (订单Controller) OrderController.java 中的代码 ( 订单Controller) RestController(userOrderController) //起别名 Slf4j RequestMapping(/user/order) Api(tags 用户端订单相关接口) public class OrderController {Autowiredprivate OrderService orderService;/*** 订单支付 ** param ordersPaymentDTO* return*/PutMapping(/payment)ApiOperation(订单支付)public ResultOrderPaymentVO payment(RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {log.info(订单支付{}, ordersPaymentDTO);OrderPaymentVO orderPaymentVO orderService.payment(ordersPaymentDTO);log.info(生成预支付交易单{}, orderPaymentVO);return Result.success(orderPaymentVO);} }OrderPaymentVO.Java : Data Builder NoArgsConstructor AllArgsConstructor public class OrderPaymentVO implements Serializable {private String nonceStr; //随机字符串private String paySign; //签名private String timeStamp; //时间戳private String signType; //签名算法private String packageStr; //统一下单接口返回的 prepay_id 参数值 }OrdersPaymentDTO.java : Data public class OrdersPaymentDTO implements Serializable {//订单号private String orderNumber;//付款方式private Integer payMethod; }OrderService.java OrderService.java public interface OrderService {/*** 订单支付* param ordersPaymentDTO* return*/OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception;/*** 支付成功修改订单状态* param outTradeNo*/void paySuccess(String outTradeNo); }OrdersPaymentDTO.java : Data public class OrdersPaymentDTO implements Serializable {//订单号private String orderNumber;//付款方式private Integer payMethod; }OrderPaymentVO.java : Data Builder NoArgsConstructor AllArgsConstructor public class OrderPaymentVO implements Serializable {private String nonceStr; //随机字符串private String paySign; //签名private String timeStamp; //时间戳private String signType; //签名算法private String packageStr; //统一下单接口返回的 prepay_id 参数值 }OrderServiceImpl.java (包含 : 微信支付工具类) OrderServiceImpl.java : Service //将该类加入到容器中成为bean public class OrderServiceImpl implements OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate OrderdetailMapper orderdetailMapper;Autowiredprivate AddressBookMapper addressBookMapper;Autowiredprivate ShoppingcartMapper shoppingcartMapper;Autowiredprivate WeChatPayUtil weChatPayUtil;Autowiredprivate UserMapper userMapper;/*** 订单支付** param ordersPaymentDTO* return*/public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {// 当前登录用户idLong userId BaseContext.getCurrentId();User user userMapper.getById(userId);//调用微信支付接口生成预支付交易单JSONObject jsonObject weChatPayUtil.pay(ordersPaymentDTO.getOrderNumber(), //商户订单号new BigDecimal(0.01), //支付金额单位 元苍穹外卖订单, //商品描述user.getOpenid() //微信用户的openid);if (jsonObject.getString(code) ! null jsonObject.getString(code).equals(ORDERPAID)) {throw new OrderBusinessException(该订单已支付);}OrderPaymentVO vo jsonObject.toJavaObject(OrderPaymentVO.class);vo.setPackageStr(jsonObject.getString(package));return vo;}/*** 支付成功修改订单状态** param outTradeNo*/public void paySuccess(String outTradeNo) {// 根据订单号查询订单Orders ordersDB orderMapper.getByNumber(outTradeNo);// 根据订单id更新订单的状态、支付方式、支付状态、结账时间Orders orders Orders.builder().id(ordersDB.getId()).status(Orders.TO_BE_CONFIRMED).payStatus(Orders.PAID).checkoutTime(LocalDateTime.now()).build();orderMapper.update(orders);} }BaseContext.class public class BaseContext { //该类对ThreadLocal对象本身其其下的三个方法进行了封装方便且更好的调用//创建 ThreadLocal 对象可在其中设置“线程局部变量”存储数据该独享的线程中后“该存入的数据”会被取出来public static ThreadLocalLong threadLocal new ThreadLocal();/*** 存入请求用户的id* (设置“线程局部变量”)* param id*/public static void setCurrentId(Long id) {//调用ThreadLocal对象的.set(T value) 设置线程局部变量 / 存储数据进该“请求”独享的“线程”中threadLocal.set(id);}/*** 获得请求用户的id* (获得“线程局部变量”)* return*/public static Long getCurrentId() {return threadLocal.get();}/*** 移除请求用户的id* (移除“线程局部变量”)*/public static void removeCurrentId() {threadLocal.remove();} }微信支付工具类 / WeChatPayUtil.java : *** 微信支付工具类*/ Component public class WeChatPayUtil {//微信支付下单接口地址public static final String JSAPI https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi;//申请退款接口地址public static final String REFUNDS https://api.mch.weixin.qq.com/v3/refund/domestic/refunds;Autowiredprivate WeChatProperties weChatProperties;/*** 获取调用微信接口的客户端工具对象** return*/private CloseableHttpClient getClient() {PrivateKey merchantPrivateKey null;try {//merchantPrivateKey商户API私钥如何加载商户API私钥请看常见问题merchantPrivateKey PemUtil.loadPrivateKey(new FileInputStream(new File(weChatProperties.getPrivateKeyFilePath())));//加载平台证书文件X509Certificate x509Certificate PemUtil.loadCertificate(new FileInputStream(new File(weChatProperties.getWeChatPayCertFilePath())));//wechatPayCertificates微信支付平台证书列表。你也可以使用后面章节提到的“定时更新平台证书功能”而不需要关心平台证书的来龙去脉ListX509Certificate wechatPayCertificates Arrays.asList(x509Certificate);WechatPayHttpClientBuilder builder WechatPayHttpClientBuilder.create().withMerchant(weChatProperties.getMchid(), weChatProperties.getMchSerialNo(), merchantPrivateKey).withWechatPay(wechatPayCertificates);// 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签CloseableHttpClient httpClient builder.build();return httpClient;} catch (FileNotFoundException e) {e.printStackTrace();return null;}}/*** 发送post方式请求** param url* param body* return*/private String post(String url, String body) throws Exception {CloseableHttpClient httpClient getClient();HttpPost httpPost new HttpPost(url);httpPost.addHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());httpPost.addHeader(Wechatpay-Serial, weChatProperties.getMchSerialNo());httpPost.setEntity(new StringEntity(body, UTF-8));CloseableHttpResponse response httpClient.execute(httpPost);try {String bodyAsString EntityUtils.toString(response.getEntity());return bodyAsString;} finally {httpClient.close();response.close();}}/*** 发送get方式请求** param url* return*/private String get(String url) throws Exception {CloseableHttpClient httpClient getClient();HttpGet httpGet new HttpGet(url);httpGet.addHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());httpGet.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());httpGet.addHeader(Wechatpay-Serial, weChatProperties.getMchSerialNo());CloseableHttpResponse response httpClient.execute(httpGet);try {String bodyAsString EntityUtils.toString(response.getEntity());return bodyAsString;} finally {httpClient.close();response.close();}}/*** jsapi下单** param orderNum 商户订单号* param total 总金额* param description 商品描述* param openid 微信用户的openid* return*/private String jsapi(String orderNum, BigDecimal total, String description, String openid) throws Exception {JSONObject jsonObject new JSONObject();jsonObject.put(appid, weChatProperties.getAppid());jsonObject.put(mchid, weChatProperties.getMchid());jsonObject.put(description, description);jsonObject.put(out_trade_no, orderNum);jsonObject.put(notify_url, weChatProperties.getNotifyUrl());JSONObject amount new JSONObject();amount.put(total, total.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());amount.put(currency, CNY);jsonObject.put(amount, amount);JSONObject payer new JSONObject();payer.put(openid, openid);jsonObject.put(payer, payer);String body jsonObject.toJSONString();return post(JSAPI, body);}/*** 小程序支付** param orderNum 商户订单号* param total 金额单位 元* param description 商品描述* param openid 微信用户的openid* return*/public JSONObject pay(String orderNum, BigDecimal total, String description, String openid) throws Exception {//统一下单生成预支付交易单String bodyAsString jsapi(orderNum, total, description, openid);//解析返回结果JSONObject jsonObject JSON.parseObject(bodyAsString);System.out.println(jsonObject);String prepayId jsonObject.getString(prepay_id);if (prepayId ! null) {String timeStamp String.valueOf(System.currentTimeMillis() / 1000);String nonceStr RandomStringUtils.randomNumeric(32);ArrayListObject list new ArrayList();list.add(weChatProperties.getAppid());list.add(timeStamp);list.add(nonceStr);list.add(prepay_id prepayId);//二次签名调起支付需要重新签名StringBuilder stringBuilder new StringBuilder();for (Object o : list) {stringBuilder.append(o).append(\n);}String signMessage stringBuilder.toString();byte[] message signMessage.getBytes();Signature signature Signature.getInstance(SHA256withRSA);signature.initSign(PemUtil.loadPrivateKey(new FileInputStream(new File(weChatProperties.getPrivateKeyFilePath()))));signature.update(message);String packageSign Base64.getEncoder().encodeToString(signature.sign());//构造数据给微信小程序用于调起微信支付JSONObject jo new JSONObject();jo.put(timeStamp, timeStamp);jo.put(nonceStr, nonceStr);jo.put(package, prepay_id prepayId);jo.put(signType, RSA);jo.put(paySign, packageSign);return jo;}return jsonObject;}/*** 申请退款** param outTradeNo 商户订单号* param outRefundNo 商户退款单号* param refund 退款金额* param total 原订单金额* return*/public String refund(String outTradeNo, String outRefundNo, BigDecimal refund, BigDecimal total) throws Exception {JSONObject jsonObject new JSONObject();jsonObject.put(out_trade_no, outTradeNo);jsonObject.put(out_refund_no, outRefundNo);JSONObject amount new JSONObject();amount.put(refund, refund.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());amount.put(total, total.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());amount.put(currency, CNY);jsonObject.put(amount, amount);jsonObject.put(notify_url, weChatProperties.getRefundNotifyUrl());String body jsonObject.toJSONString();//调用申请退款接口return post(REFUNDS, body);} }OrderBusinessException.java : public class OrderBusinessException extends BaseException {public OrderBusinessException(String msg) {super(msg);} }OrderMapper.java OrderMapper.java : Mapper public interface OrderMapper {/*** 根据订单号查询订单* param orderNumber*/Select(select * from orders where number #{orderNumber})Orders getByNumber(String orderNumber);/*** 修改订单信息* param orders*/void update(Orders orders); }Orders.java : /*** 订单*/ Data Builder NoArgsConstructor AllArgsConstructor public class Orders implements Serializable {/*** 订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消*/public static final Integer PENDING_PAYMENT 1;public static final Integer TO_BE_CONFIRMED 2;public static final Integer CONFIRMED 3;public static final Integer DELIVERY_IN_PROGRESS 4;public static final Integer COMPLETED 5;public static final Integer CANCELLED 6;/*** 支付状态 0未支付 1已支付 2退款*/public static final Integer UN_PAID 0;public static final Integer PAID 1;public static final Integer REFUND 2;private static final long serialVersionUID 1L;private Long id;//订单号private String number;//订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 7退款private Integer status;//下单用户idprivate Long userId;//地址idprivate Long addressBookId;//下单时间private LocalDateTime orderTime;//结账时间private LocalDateTime checkoutTime;//支付方式 1微信2支付宝private Integer payMethod;//支付状态 0未支付 1已支付 2退款private Integer payStatus;//实收金额private BigDecimal amount;//备注private String remark;//用户名private String userName;//手机号private String phone;//地址private String address;//收货人private String consignee;//订单取消原因private String cancelReason;//订单拒绝原因private String rejectionReason;//订单取消时间private LocalDateTime cancelTime;//预计送达时间private LocalDateTime estimatedDeliveryTime;//配送状态 1立即送出 0选择具体时间private Integer deliveryStatus;//送达时间private LocalDateTime deliveryTime;//打包费private int packAmount;//餐具数量private int tablewareNumber;//餐具数量状态 1按餐量提供 0选择具体数量private Integer tablewareStatus; }OrderMapper.xml OrderMapper.xml : ?xml version1.0 encodingUTF-8? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.sky.mapper.OrderMapperupdate idupdate parameterTypecom.sky.entity.Ordersupdate orderssetif testcancelReason ! null and cancelReason! cancel_reason#{cancelReason},/ifif testrejectionReason ! null and rejectionReason! rejection_reason#{rejectionReason},/ifif testcancelTime ! nullcancel_time#{cancelTime},/ifif testpayStatus ! nullpay_status#{payStatus},/ifif testpayMethod ! nullpay_method#{payMethod},/ifif testcheckoutTime ! nullcheckout_time#{checkoutTime},/ifif teststatus ! nullstatus #{status},/ifif testdeliveryTime ! nulldelivery_time #{deliveryTime}/if/setwhere id #{id}/update/mapperUserMapper.java UserMapper.java : Mapper public interface UserMapper {/*** 根据id查询数据*/Select(select * from user where id #{id})User getById(Long userId); }PayNotifyController.java / 支付回调相关接口 PayNotifyController.java / 支付回调相关接口: /*** 支付回调相关接口*/ RestController RequestMapping(/notify) Slf4j public class PayNotifyController {Autowiredprivate OrderService orderService;Autowiredprivate WeChatProperties weChatProperties;/*** 支付成功回调** param request*/RequestMapping(/paySuccess)public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {//读取数据String body readData(request);log.info(支付成功回调{}, body);//数据解密String plainText decryptData(body);log.info(解密后的文本{}, plainText);JSONObject jsonObject JSON.parseObject(plainText);String outTradeNo jsonObject.getString(out_trade_no);//商户平台订单号String transactionId jsonObject.getString(transaction_id);//微信支付交易号log.info(商户平台订单号{}, outTradeNo);log.info(微信支付交易号{}, transactionId);//业务处理修改订单状态、来单提醒orderService.paySuccess(outTradeNo);//给微信响应responseToWeixin(response);}/*** 读取数据** param request* return* throws Exception*/private String readData(HttpServletRequest request) throws Exception {BufferedReader reader request.getReader();StringBuilder result new StringBuilder();String line null;while ((line reader.readLine()) ! null) {if (result.length() 0) {result.append(\n);}result.append(line);}return result.toString();}/*** 数据解密** param body* return* throws Exception*/private String decryptData(String body) throws Exception {JSONObject resultObject JSON.parseObject(body);JSONObject resource resultObject.getJSONObject(resource);String ciphertext resource.getString(ciphertext);String nonce resource.getString(nonce);String associatedData resource.getString(associated_data);AesUtil aesUtil new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8));//密文解密String plainText aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);return plainText;}/*** 给微信响应* param response*/private void responseToWeixin(HttpServletResponse response) throws Exception{response.setStatus(200);HashMapObject, Object map new HashMap();map.put(code, SUCCESS);map.put(message, SUCCESS);response.setHeader(Content-type, ContentType.APPLICATION_JSON.toString());response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8));response.flushBuffer();} }application.yml (springboot配置文件) application.yml server:port: 8080spring:profiles:active: devmain:allow-circular-references: truedatasource:druid:driver-class-name: ${sky.datasource.driver-class-name}url: jdbc:mysql://${sky.datasource.host}:${sky.datasource.port}/${sky.datasource.database}?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8zeroDateTimeBehaviorconvertToNulluseSSLfalseallowPublicKeyRetrievaltrueusername: ${sky.datasource.username}password: ${sky.datasource.password}redis:host: ${sky.redis.host}port: ${sky.redis.port}password: ${sky.redis.password}database: ${sky.redis.database}mybatis:#mapper配置文件mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.sky.entityconfiguration:#开启驼峰命名map-underscore-to-camel-case: truelogging:level:com:sky:mapper: debugservice: infocontroller: infosky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: tokenuser-secret-key: itheimauser-ttl: 7200000user-token-name: authenticationalioss:endpoint: ${sky.alioss.endpoint}access-key-id: ${sky.alioss.access-key-id}access-key-secret: ${sky.alioss.access-key-secret}bucket-name: ${sky.alioss.bucket-name}wechat:appid: ${sky.wechat.appid}secret: ${sky.wechat.secret}mchid : ${sky.wechat.mchid}mchSerialNo: ${sky.wechat.mchSerialNo}privateKeyFilePath: ${sky.wechat.privateKeyFilePath}apiV3Key: ${sky.wechat.apiV3Key}weChatPayCertFilePath: ${sky.wechat.weChatPayCertFilePath}notifyUrl: ${sky.wechat.notifyUrl}refundNotifyUrl: ${sky.wechat.refundNotifyUrl}shop:address: 北京市海淀区上地十街10号baidu:ak: your-akapplication-dev.xml application-dev.xml sky:datasource:driver-class-name: com.mysql.cj.jdbc.Driverhost: localhostport: 3306database: sky_take_outusername: rootpassword: rootalioss:endpoint: oss-cn-beijing.aliyuncs.comaccess-key-id: your-access-key-idaccess-key-secret: your-access-key-secretbucket-name: your-bucket-nameredis:host: localhostport: 6379password: 123456database: 10wechat:appid: wxffb3637a228223b8secret: 84311df9199ecacdf4f12d27b6b9522dmchid : 1561414331mchSerialNo: 4B3B3DC35414AD50B1B755BAF8DE9CC7CF407606privateKeyFilePath: D:\pay\apiclient_key.pemapiV3Key: CZBK51236435wxpay435434323FFDuv3weChatPayCertFilePath: D:\pay\wechatpay_166D96F876F45C7D07CE98952A96EC980368ACFC.pemnotifyUrl: https://58869fb.r2.cpolar.top/notify/paySuccessrefundNotifyUrl: https://58869fb.r2.cpolar.top/notify/refundSuccess
http://www.w-s-a.com/news/339655/

相关文章:

  • 建立网站的目的和意义网站建设寻求
  • 邢台手机网站建设设计师培训心得
  • 营销网站怎么做丽水微信网站建设哪家好
  • 南昌定制网站开发多少钱东阿县城市建设局网站
  • 浙江网站建设公司南昌seo招聘
  • 工业软件有哪些专业seo站长工具全面查询网站
  • 山东兴华建设集团有限公司网站和京东一样做电子产品的网站
  • 网站建设谢辞关于h5的网站模板
  • 网站改版提交WordPress360收录
  • 省级网站 开发建设 资质在国外怎么做网站
  • 中商华兴建设有限公司网站我的世界查找建筑网站
  • 广东网站设计公司百度推广免费送网站
  • 高密做网站哪家好网站建设预算
  • 免费wordpress网站模板重庆如何做聚政网站
  • 人才网站app建设建议系统开发生命周期法的优点表现
  • 门户网站想要微信登录怎么做湖南网站seo推广
  • 襄阳 网站建设管理系统网站
  • 重庆工程建设招标投标交易信息网广州外贸seo优化
  • 一个一起做网站东莞设计兼职网站建设
  • 杭州网站程序开发公司在哪个公司建设网站好
  • 网店的网站设计方案济南手机建站价格
  • 网站做了301重定向域名会自动跳转吗唐山地方志网站建设
  • 学校网站建设说明书海南省建设执业资格注册管理中心网站
  • 东莞哪家网站建设好网站风格设定
  • 自驾游网站模板搭建wordpress步骤
  • wordpress视频网站上传视频提升学历是什么意思
  • 江西省城乡建设厅建设网站浙江建设
  • 网站联系我们页面临平做网站
  • 如何用网站做cpa交互比较好的网站
  • 一家只做特卖的网站wordpress修改模板教程