|
|
@@ -0,0 +1,470 @@
|
|
|
+package com.uas.service.donate.controller;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
|
|
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
|
|
+import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
|
|
|
+import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
|
|
|
+import com.github.binarywang.wxpay.constant.WxPayConstants;
|
|
|
+import com.github.binarywang.wxpay.exception.WxPayException;
|
|
|
+import com.github.binarywang.wxpay.util.SignUtils;
|
|
|
+import com.uas.platform.core.util.HttpUtil;
|
|
|
+import com.uas.service.donate.api.WxPayApi;
|
|
|
+import com.uas.service.donate.config.WxConfig;
|
|
|
+import com.uas.service.donate.model.ProjectRecode;
|
|
|
+import com.uas.service.donate.model.WechatOrder;
|
|
|
+import com.uas.service.donate.service.ProjectRecodeService;
|
|
|
+import com.uas.service.donate.service.WechatOrderService;
|
|
|
+import com.uas.service.donate.util.QrcodeUtils;
|
|
|
+import com.uas.service.donate.util.StringUtils;
|
|
|
+import com.uas.service.donate.util.WxCheckoutUtil;
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Controller;
|
|
|
+import org.springframework.ui.ModelMap;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
|
+import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.PrintWriter;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Created by 黄诚天 on 2017-10-27.
|
|
|
+ */
|
|
|
+@Controller
|
|
|
+@RequestMapping("/wxpay")
|
|
|
+public class WxpayController {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ protected HttpServletRequest request;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ protected HttpServletResponse response;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ protected WxPayApi wxPayApi;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ protected WechatOrderService wechatOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ProjectRecodeService projectRecodeService;
|
|
|
+
|
|
|
+ private Logger logger = LoggerFactory.getLogger(WxpayController.class);
|
|
|
+ private static String redirectUrl = "http://5087452.nat123.cc/wxpay/redirectUrl";
|
|
|
+ //private String orderNumber = NumberGenerator.generateId();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 扫码支付 @RequestParam ProjectRecode projectRecode
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping(value = "/pcPay", method = RequestMethod.POST)
|
|
|
+ public void pcPay(@RequestParam("jsonStr") String jsonStr, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
|
+ ProjectRecode projectRecode= null;
|
|
|
+ try {
|
|
|
+ projectRecode = this.createProjectRecode(jsonStr);
|
|
|
+ } catch (Exception e) {
|
|
|
+ response.getWriter().write(e.getMessage());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.NATIVE);
|
|
|
+ unifiedOrder(wxPayUnifiedOrderRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 公众号支付 网页支付JSAPI即公众号支付是用户在微信中打开商户的H5页面
|
|
|
+ * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping(value = "/webPay", method = RequestMethod.POST)
|
|
|
+ public ModelMap appPay(@RequestParam("jsonStr") String jsonStr, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
|
+ ModelMap map = new ModelMap();
|
|
|
+
|
|
|
+ ProjectRecode projectRecode= null;
|
|
|
+ try {
|
|
|
+ projectRecode = this.createProjectRecode(jsonStr);
|
|
|
+ } catch (Exception e) {
|
|
|
+ response.getWriter().write(e.getMessage());
|
|
|
+ map.put("error", "参数错误");
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.JSAPI);
|
|
|
+
|
|
|
+ //配置网页授权url
|
|
|
+ String openId = getOpenId(request);
|
|
|
+ if (StringUtils.isEmpty(wxPayApi.getConfig().getSubAppId())) {
|
|
|
+ wxPayUnifiedOrderRequest.setOpenid(openId);//否是 trade_type=JSAPI,此参数必传,用户在主商户appid下的唯一标识。openid和sub_openid可以选传其中之一,如果选择传sub_openid,则必须传sub_appid。
|
|
|
+ } else {
|
|
|
+ wxPayUnifiedOrderRequest.setSubOpenid(openId);//否是 trade_type=JSAPI,此参数必传,用户在子商户appid下的唯一标识。openid和sub_openid可以选传其中之一,如果选择传sub_openid,则必须传sub_appid。
|
|
|
+ }
|
|
|
+
|
|
|
+ String prepayId = unifiedOrder(wxPayUnifiedOrderRequest);
|
|
|
+ if (StringUtils.isEmpty(prepayId)) {
|
|
|
+ //TODO 预下单失败处理
|
|
|
+ map.put("error", "支付失败,请重试");
|
|
|
+ } else {
|
|
|
+ //TODO 将prepayId返回给js
|
|
|
+ map.put("appId", wxPayApi.getConfig().getAppId());
|
|
|
+ map.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
|
|
|
+ map.put("nonceStr", wxPayUnifiedOrderRequest.getNonceStr());//String.valueOf(System.currentTimeMillis()
|
|
|
+ map.put("package", "prepay_id=" + prepayId);
|
|
|
+ map.put("signType", "MD5");
|
|
|
+ //预付订单再次签名
|
|
|
+ String packageSign = SignUtils.createSign(map, WxPayConstants.SignType.MD5, wxPayApi.getConfig().getMchKey(), false);
|
|
|
+ map.put("paySign", packageSign);
|
|
|
+ }
|
|
|
+
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * H5支付 商户在微信客户端外的移动端网页
|
|
|
+ * https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4 应让用户去点击按钮触发查单操作
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping(value = "/wapPay", method = RequestMethod.POST)
|
|
|
+ public ModelMap wapPay(@RequestParam("jsonStr") String jsonStr, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
|
+ ModelMap map = new ModelMap();
|
|
|
+
|
|
|
+ ProjectRecode projectRecode= null;
|
|
|
+ try {
|
|
|
+ projectRecode = this.createProjectRecode(jsonStr);
|
|
|
+ } catch (Exception e) {
|
|
|
+ response.getWriter().write(e.getMessage());
|
|
|
+ map.put("error", "参数错误");
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.MWEB);
|
|
|
+ String mwebUrl = unifiedOrder(wxPayUnifiedOrderRequest);
|
|
|
+ if (StringUtils.isEmpty(mwebUrl)) {
|
|
|
+ //TODO 预下单失败处理
|
|
|
+ map.put("error", "支付失败,请重试");
|
|
|
+ } else {
|
|
|
+ map.put("mwebUrl", mwebUrl); //通过mweb_url调起微信支付中间页 重定向mweb_url
|
|
|
+ }
|
|
|
+
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //通过统一下单接口发起请求,获得prepay_id(预支付交易会话标识),这个标示是微信提交支付的关键数据
|
|
|
+ public String unifiedOrder(WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest) throws Exception {
|
|
|
+ WxPayUnifiedOrderResult wxPayUnifiedOrderResult = null;
|
|
|
+ try {
|
|
|
+ wxPayUnifiedOrderResult = wxPayApi.unifiedOrder(wxPayUnifiedOrderRequest);
|
|
|
+
|
|
|
+ if (WxPayConstants.TradeType.MWEB.equals(wxPayUnifiedOrderRequest.getTradeType())) {
|
|
|
+ /*H5支付开发步骤:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4*/
|
|
|
+ String mwebUrl = wxPayUnifiedOrderResult.getMwebUrl() + "&redirect_url=" + URLEncoder.encode(redirectUrl,"UTF-8");
|
|
|
+ return mwebUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+ QrcodeUtils.encode(wxPayUnifiedOrderResult.getCodeURL(),response.getOutputStream());
|
|
|
+ return wxPayUnifiedOrderResult.getPrepayId();
|
|
|
+ //byte[] arr = wxPayApi.createScanPayQrcodeMode2(wxPayUnifiedOrderResult.getCodeURL(),null,null);
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ logger.error("微信支付失败!订单号:{},原因:{}", wxPayUnifiedOrderRequest.getOutTradeNo(), e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询
|
|
|
+ * @param transactionId
|
|
|
+ * @param outTradeNo
|
|
|
+ */
|
|
|
+ public void queryOrder(String transactionId, String outTradeNo){
|
|
|
+ try {
|
|
|
+ WxPayOrderQueryResult wxPayOrderQueryResult =wxPayApi.queryOrder(transactionId, outTradeNo);
|
|
|
+ wxPayOrderQueryResult.getTradeState();
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,
|
|
|
+ * 如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,
|
|
|
+ * 要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
|
|
|
+ * 特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,
|
|
|
+ * 防止数据泄漏导致出现“假通知”,造成资金损失。
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping("/notifyUrl")
|
|
|
+ public synchronized String payNotify(HttpServletRequest request, HttpServletResponse response) {
|
|
|
+ ModelMap map = new ModelMap();
|
|
|
+ String returnResult = null;
|
|
|
+ try {
|
|
|
+ String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
|
|
|
+ WxPayOrderNotifyResult result = wxPayApi.parseOrderNotifyResult(xmlResult);
|
|
|
+ if ("SUCCESS".equals(result.getReturnCode())) {
|
|
|
+ if ("SUCCESS".equals(result.getResultCode())) {
|
|
|
+ returnResult = setXml("SUCCESS", "OK");
|
|
|
+ WechatOrder wechatOrder = wechatOrderService.getByTransactionId(result.getTransactionId());
|
|
|
+ //微信在数据库中订单存在且状态已处理
|
|
|
+ if (wechatOrder != null && wechatOrder.getStatus() == 1) {
|
|
|
+ logger.info("系统已对该笔交易进行处理,交易订单号" + wechatOrder.getOutTradeNo() + "微信交易号" + wechatOrder.getTransactionId());
|
|
|
+ returnResult = setXml("SUCCESS", "OK");
|
|
|
+ } else {
|
|
|
+ // 自己处理订单的业务逻辑
|
|
|
+
|
|
|
+ //校验返回的订单金额是否与商户侧的订单金额一致
|
|
|
+ //TODO 先注释这两句
|
|
|
+// ProjectRecode projectRecode = projectRecodeService.findOne(Long.parseLong(result.getOutTradeNo()));
|
|
|
+// if (!(projectRecode != null && ((int) (projectRecode.getAmount()*100)) == result.getTotalFee().intValue())) {
|
|
|
+ if (false) {
|
|
|
+ logger.warn("防止数据泄漏导致出现“假通知”,以免造成资金损失");
|
|
|
+ map.put("warning", "防止数据泄漏导致出现“假通知”,以免造成资金损失");
|
|
|
+ returnResult = setXml("FAIL", "商户侧的订单金额与返回的订单金额不一致");
|
|
|
+ } else {
|
|
|
+ WxPayOrderQueryResult wxPayOrderQueryResult = wxPayApi.queryOrder(result.getTransactionId(),null);//二选一填
|
|
|
+ if (wxPayOrderQueryResult != null) {
|
|
|
+ map.put("tradeState", wxPayOrderQueryResult.getTradeState());
|
|
|
+ map.put("tradeStateDesc", wxPayOrderQueryResult.getTradeStateDesc());
|
|
|
+ }
|
|
|
+ wechatOrder = wechatOrderService.save(WechatOrder.WxPayOrderNotifyResultToConvert(result, (short) 1, wxPayOrderQueryResult));
|
|
|
+ returnResult = setXml("SUCCESS", "OK");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //String totalFee = WxPayBaseResult.feeToYuan(result.getTotalFee());
|
|
|
+ } else {
|
|
|
+ logger.info("微信支付业务处理失败:" + result.getErrCodeDes());
|
|
|
+ returnResult = setXml("FAIL", "微信支付业务处理失败");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logger.info("微信支付返回错误状态码(通信错误),错误信息:" + result.getReturnMsg());
|
|
|
+ returnResult = setXml("FAIL", "微信支付返回错误状态码(通信错误)");
|
|
|
+ }
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ logger.error("微信回调结果异常,异常原因{}", e.getMessage());
|
|
|
+ map.put("error", e.getMessage());
|
|
|
+ returnResult = setXml("FAIL", "签名失败");
|
|
|
+ } finally {
|
|
|
+ //TODO map
|
|
|
+ return returnResult;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping("/redirectUrl")
|
|
|
+ public String redirectUrl() {
|
|
|
+ /*由于设置redirect_url后,回跳指定页面的操作可能发生在:1,微信支付中间页调起微信收银台后超过5秒
|
|
|
+ 2,用户点击“取消支付“或支付完成后点“完成”按钮。因此无法保证页面回跳时,支付流程已结束,
|
|
|
+ 所以商户设置的redirect_url地址不能自动执行查单操作,应让用户去点击按钮触发查单操作。*/
|
|
|
+ //效果图可以参考: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4 最下面
|
|
|
+
|
|
|
+ return "h5支付回调";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否是微信浏览器发起的请求,如果是返回true,反正返回false
|
|
|
+ * @param req
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping("/isWechat")
|
|
|
+ public boolean isWechatBrowser(HttpServletRequest req){
|
|
|
+ String ua = req.getHeader("user-agent").toLowerCase();
|
|
|
+ if (ua.indexOf("micromessenger") >= 0) {// 是微信浏览器
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取token 公众号支付模式也不需要 先放着
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public String getAccessToken() throws Exception {
|
|
|
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + WxConfig.APPID + "&secret=" + WxConfig.APPSECRET;
|
|
|
+ HttpUtil.Response response = HttpUtil.sendGetRequest(url,null);
|
|
|
+ if (response.getStatusCode() == 200) {
|
|
|
+ return response.getResponseText();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户基本信息 静默获取 无需用户同意 只有公众号模式需要
|
|
|
+ * https://mp.weixin.qq.com/advanced/advanced?action=table&token=719542712&lang=zh_CN
|
|
|
+ * 网页授权添加url 需icp备案
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String getOpenId(HttpServletRequest request){
|
|
|
+ try {
|
|
|
+ //TODO 授权方式 是否需要电话号码 名字等信息
|
|
|
+ //TODO 获取code
|
|
|
+ String code = request.getParameter("code");
|
|
|
+ //String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
|
|
|
+ return wxPayApi.authcode2Openid(code);
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证token
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ */
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping("/checkToken")
|
|
|
+ public void checkToken(HttpServletRequest request, HttpServletResponse response) {
|
|
|
+ boolean isGet = request.getMethod().toLowerCase().equals("get");
|
|
|
+ boolean isPost = request.getMethod().toLowerCase().equals("post");
|
|
|
+ PrintWriter print;
|
|
|
+ if (isGet) {
|
|
|
+ // 微信加密签名
|
|
|
+ String signature = request.getParameter("signature");
|
|
|
+ // 时间戳
|
|
|
+ String timestamp = request.getParameter("timestamp");
|
|
|
+ // 随机数
|
|
|
+ String nonce = request.getParameter("nonce");
|
|
|
+ // 随机字符串
|
|
|
+ String echostr = request.getParameter("echostr");
|
|
|
+ // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
|
|
|
+ if (signature != null && WxCheckoutUtil.checkSignature(signature, timestamp, nonce)) {
|
|
|
+ try {
|
|
|
+ print = response.getWriter();
|
|
|
+ print.write(echostr);
|
|
|
+ print.flush();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (isPost) {
|
|
|
+ //核心逻辑
|
|
|
+ }
|
|
|
+ }
|
|
|
+//
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// /**
|
|
|
+// * 获取验签秘钥API
|
|
|
+// * https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=23_1
|
|
|
+// * mch_id 商户号
|
|
|
+// * partnerKey 商户平台设置的密钥key
|
|
|
+// * @return {String}
|
|
|
+// */
|
|
|
+// @ResponseBody
|
|
|
+// @RequestMapping("/getsignkey")
|
|
|
+// public String getsignkey() throws Exception {
|
|
|
+// Map<String, String> map =new HashMap<String, String>();
|
|
|
+// String mch_id = "";
|
|
|
+// String partnerKey = "";//商户平台设置的密钥key
|
|
|
+// String nonce_str = String.valueOf(System.currentTimeMillis());
|
|
|
+// map.put("mch_id", mch_id);//商户号
|
|
|
+// map.put("nonce_str", nonce_str);//随机字符串
|
|
|
+// map.put("sign", WxSign.createSign(map, partnerKey));
|
|
|
+//
|
|
|
+// String url = null;
|
|
|
+// if (isSandBox) {
|
|
|
+// url = WXPayConstants.SANDBOX_GETSINGKEY_URL;
|
|
|
+// }else {
|
|
|
+// //url = WXPayConstants.UGETSINGKEY_URL;
|
|
|
+// }
|
|
|
+// HttpUtil.Response result = HttpUtil.sendPostRequest(url, map);
|
|
|
+//
|
|
|
+// return result.getResponseText();
|
|
|
+// }
|
|
|
+//
|
|
|
+
|
|
|
+ private WxPayUnifiedOrderRequest createWxPayUnifiedOrderRequest(HttpServletRequest request, ProjectRecode projectRecode, String tradeType) {
|
|
|
+ //Project project = projectRecode.getProject();
|
|
|
+ WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
|
|
|
+ wxPayUnifiedOrderRequest.setDeviceInfo("WEB");//否 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB
|
|
|
+ wxPayUnifiedOrderRequest.setNonceStr(String.valueOf(System.currentTimeMillis()));//是 随机字符串,不长于32位。
|
|
|
+ //wxPayUnifiedOrderRequest.setSign("xixihahxixhahaha");//是 签名
|
|
|
+ //wxPayUnifiedOrderRequest.setSignType(null);//否 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
|
|
|
+
|
|
|
+
|
|
|
+ //商品描述交易字段格式根据不同的应用场景按照以下格式:(1)PC网站——传入浏览器打开的网站主页title名-实际商品名称,例如:腾讯充值中心-QQ会员充值;(2) 公众号——传入公众号名称-实际商品名称,例如:腾讯形象店- image-QQ公仔;(3) H5——应用在浏览器网页上的场景,传入浏览器打开的移动网页的主页title名-实际商品名称,例如:腾讯充值中心-QQ会员充值;(4) 线下门店——门店品牌名-城市分店名-实际商品名称,例如: image形象店-深圳腾大- QQ公仔)(5) APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
|
|
|
+ if (WxPayConstants.TradeType.MWEB.equals(tradeType)) {
|
|
|
+ //H5——应用在浏览器网页上的场景,传入浏览器打开的移动网页的主页title名-实际商品名称,例如:腾讯充值中心-QQ会员充值;
|
|
|
+ wxPayUnifiedOrderRequest.setBody("一元捐-" + projectRecode.getProjectName());
|
|
|
+ } else if (WxPayConstants.TradeType.JSAPI.equals(tradeType)) {
|
|
|
+ if (StringUtils.isEmpty(wxPayApi.getConfig().getSubAppId())) {
|
|
|
+ wxPayUnifiedOrderRequest.setOpenid(null);//否是 trade_type=JSAPI,此参数必传,用户在主商户appid下的唯一标识。openid和sub_openid可以选传其中之一,如果选择传sub_openid,则必须传sub_appid。
|
|
|
+ } else {
|
|
|
+ wxPayUnifiedOrderRequest.setSubOpenid(null);//否是 trade_type=JSAPI,此参数必传,用户在子商户appid下的唯一标识。openid和sub_openid可以选传其中之一,如果选择传sub_openid,则必须传sub_appid。
|
|
|
+ }
|
|
|
+
|
|
|
+ //公众号——传入公众号名称-实际商品名称,例如:腾讯形象店- image-QQ公仔;
|
|
|
+ wxPayUnifiedOrderRequest.setBody("优软科技-" + projectRecode.getProjectName());
|
|
|
+ } else if (WxPayConstants.TradeType.NATIVE.equals(tradeType)) {
|
|
|
+ //PC网站——传入浏览器打开的网站主页title名-实际商品名称,例如:腾讯充值中心-QQ会员充值;
|
|
|
+ wxPayUnifiedOrderRequest.setBody("一元捐-" + projectRecode.getProjectName());
|
|
|
+ }
|
|
|
+
|
|
|
+ //wxPayUnifiedOrderRequest.setDetail("");//否 商品详细描述,对于使用单品优惠的商户,改字段必须按照规范上传,详见“单品优惠参数说明”
|
|
|
+
|
|
|
+
|
|
|
+ wxPayUnifiedOrderRequest.setAttach("这是附加数据");//否 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
|
|
|
+
|
|
|
+ wxPayUnifiedOrderRequest.setOutTradeNo(projectRecode.getId().toString());//是 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
|
|
|
+
|
|
|
+ //wxPayUnifiedOrderRequest.setFeeType("CNY");//否 符合ISO 4217标准的三位字母代码,默认人民币:CNY
|
|
|
+ wxPayUnifiedOrderRequest.setTotalFee((int)(projectRecode.getAmount() * 100));//是 订单总金额,只能为整数
|
|
|
+
|
|
|
+ //wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtils.getIpFromRequest(request));//是 APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
|
|
|
+ wxPayUnifiedOrderRequest.setSpbillCreateIp("218.17.158.219");
|
|
|
+
|
|
|
+ //wxPayUnifiedOrderRequest.setTimeStart(null);//否 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。
|
|
|
+ //wxPayUnifiedOrderRequest.setTimeExpire(null);//否 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
|
|
+ //wxPayUnifiedOrderRequest.setGoodsTag(null);//否 订单优惠标记,代金券或立减优惠功能的参数
|
|
|
+ //wxPayUnifiedOrderRequest.setNotifyURL();//是 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
|
|
|
+ wxPayUnifiedOrderRequest.setTradeType(tradeType); //是 取值如下:JSAPI,NATIVE,APP
|
|
|
+
|
|
|
+ wxPayUnifiedOrderRequest.setProductId(projectRecode.getProId().toString());//否是 trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。
|
|
|
+
|
|
|
+ //wxPayUnifiedOrderRequest.setLimitPay(null);//否 指定支付方式 如:no_credit--指定不能使用信用卡支付
|
|
|
+ //wxPayUnifiedOrderRequest.setSceneInfo(null);//否 该字段用于上报场景信息,目前支持上报实际门店信息。该字段为JSON对象数据,对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }}
|
|
|
+
|
|
|
+ return wxPayUnifiedOrderRequest;
|
|
|
+ }
|
|
|
+
|
|
|
+ //通过xml 返回给给微信消息
|
|
|
+ public String setXml(String return_code, String return_msg) {
|
|
|
+ return "<xml><return_code><![CDATA[" + return_code + "]]>" +
|
|
|
+ "</return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
|
|
|
+ }
|
|
|
+
|
|
|
+ private ProjectRecode createProjectRecode(String jsonStr) throws Exception {
|
|
|
+ ProjectRecode projectRecode= JSONObject.parseObject(jsonStr,ProjectRecode.class);
|
|
|
+ projectRecode.setTime(new Date());
|
|
|
+ ProjectRecode newProjectRecode = projectRecodeService.join(projectRecode);
|
|
|
+ return newProjectRecode;
|
|
|
+ }
|
|
|
+}
|