| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 |
- package com.uas.service.donate.controller;
- import com.alibaba.fastjson.JSONObject;
- import com.github.binarywang.utils.qrcode.QrcodeUtils;
- 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.dfs.service.FileClient;
- 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.core.support.SystemSession;
- import com.uas.service.donate.model.Project;
- import com.uas.service.donate.model.ProjectRecode;
- import com.uas.service.donate.model.User;
- import com.uas.service.donate.model.WechatOrder;
- import com.uas.service.donate.service.ProjectRecodeService;
- import com.uas.service.donate.service.ProjectService;
- import com.uas.service.donate.service.UserService;
- import com.uas.service.donate.service.WechatOrderService;
- import com.uas.service.donate.util.IpUtils;
- import com.uas.service.donate.util.StringUtils;
- import com.uas.service.donate.util.WechatConnector;
- 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;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * Created by 黄诚天 on 2017-10-27.
- */
- @Controller
- @RequestMapping("/wxpay")
- public class WxpayController {
- @Autowired
- private FileClient fileClient;
- @Autowired
- protected WxPayApi wxPayApi;
- @Autowired
- protected WechatOrderService wechatOrderService;
- @Autowired
- private ProjectRecodeService projectRecodeService;
- @Autowired
- private ProjectService projectService;
- @Autowired
- private UserService userService;
- private Logger logger = LoggerFactory.getLogger(WxpayController.class);
- private static String redirectUrl = "http://lj.ubtob.com/wxpay/redirectUrl";
- //private String orderNumber = NumberGenerator.generateId();
- /**
- * 扫码支付 @RequestParam ProjectRecode projectRecode
- * 使用模式一 模式一,先扫码,再生成订单。模式二,先生成订单,再扫码。
- * @param request
- * @param response
- * @throws Exception
- */
- @ResponseBody
- @RequestMapping(value = "/pcPay", method = RequestMethod.POST)
- public ModelMap pcPay(@RequestParam("jsonStr") String jsonStr, HttpServletRequest request, HttpServletResponse response) throws Exception {
- ModelMap modelMap = new ModelMap();
- ProjectRecode projectRecode= null;
- try {
- projectRecode = this.createProjectRecode(jsonStr);
- } catch (Exception e) {
- logger.error("生成商户订单错误,原因:{}", e.getMessage());
- modelMap.put("error", "参数错误");
- return modelMap;
- }
- WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.NATIVE);
- Map map = unifiedOrder(wxPayUnifiedOrderRequest);
- if ("FAIL".equals(map.get("status"))) {
- modelMap.put("error", map.get("message"));
- } else {
- modelMap.put("qrcodeUrl", map.get("qrcodeUrl"));
- modelMap.put("outTradeNo", projectRecode.getId());
- }
- return modelMap;
- }
- /**
- * 公众号支付 网页支付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 webPay(@RequestParam("jsonStr") String jsonStr, HttpServletRequest request, HttpServletResponse response) throws Exception {
- ModelMap modelMap = new ModelMap();
- ProjectRecode projectRecode= null;
- try {
- projectRecode = this.createProjectRecode(jsonStr);
- } catch (Exception e) {
- logger.error("生成商户订单错误,原因:{}", e.getMessage());
- modelMap.put("error", "参数错误");
- return modelMap;
- }
- WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.JSAPI);
- String openId = null;
- Object openIdObj = request.getSession().getAttribute("openId");
- /*User user =SystemSession.getUser();
- if (user != null && user.getWxOpenId() != null) {
- logger.info("当前用户信息:" + user.toString());
- openId = user.getWxOpenId();
- } else {
- logger.info("公众号支付缺少openId:--需要用户授权");
- String url = WechatConnector.createAuthorizeUrl(WxConfig.oauthUserScope, wxPayApi.getConfig().getAppId(), URLEncoder.encode("http://lj.ubtob.com", "UTF-8"));
- response.sendRedirect(url);
- }*/
- if (openIdObj != null) {
- openId = (String) openIdObj;
- logger.info("当前微信用户信息:" + openId);
- } else {
- logger.info("公众号支付缺少openId:--需要用户授权");
- String url = WechatConnector.createAuthorizeUrl(WxConfig.oauthUserScope, wxPayApi.getConfig().getAppId(), URLEncoder.encode("http://lj.ubtob.com", "UTF-8"));
- response.sendRedirect(url);
- return null;
- }
- logger.info("公众号支付处理:openId=" + openId);
- 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。
- }
- Map map = unifiedOrder(wxPayUnifiedOrderRequest);
- if ("FAIL".equals(map.get("status"))) {
- modelMap.put("error", map.get("message"));
- } else {
- //modelMap.put("outTradeNo", projectRecode.getId());
- //将prepayId返回给js
- String nonceStr = String.valueOf(System.currentTimeMillis());
- String timeStamp = String.valueOf(Long.parseLong(nonceStr) / 1000);
- String appId = wxPayApi.getConfig().getAppId();
- String packagePrepayId = "prepay_id=" + map.get("prepayId");
- modelMap.put("appId", appId);
- modelMap.put("timeStamp", timeStamp);
- modelMap.put("nonceStr", nonceStr);
- modelMap.put("package", packagePrepayId);
- modelMap.put("signType", "MD5");
- logger.info("参数--" + appId + "," + timeStamp + "," + nonceStr + "," + packagePrepayId);
- Map<String, String> signMap = new HashMap<>();
- signMap.put("appId", appId);
- signMap.put("timeStamp", timeStamp);
- signMap.put("nonceStr", nonceStr);
- signMap.put("package", packagePrepayId);
- signMap.put("signType", "MD5");
- //预付订单再次签名
- String packageSign = SignUtils.createSign(signMap, "MD5", wxPayApi.getConfig().getMchKey(), false);
- logger.info("预付订单再次签名验签--" + SignUtils.checkSign(signMap, "MD5", wxPayApi.getConfig().getMchKey()));
- modelMap.put("paySign", packageSign);
- }
- return modelMap;
- }
- /**
- * 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 modelMap = new ModelMap();
- ProjectRecode projectRecode= null;
- try {
- projectRecode = this.createProjectRecode(jsonStr);
- } catch (Exception e) {
- logger.error("生成商户订单错误,原因:{}", e.getMessage());
- modelMap.put("error", "参数错误");
- return modelMap;
- }
- WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = createWxPayUnifiedOrderRequest(request, projectRecode, WxPayConstants.TradeType.MWEB);
- Map map = unifiedOrder(wxPayUnifiedOrderRequest);
- if ("FAIL".equals(map.get("status"))) {
- modelMap.put("error", map.get("message"));
- } else {
- modelMap.put("mwebUrl", map.get("mwebUrl"));
- }
- return modelMap;
- }
- //通过统一下单接口发起请求,获得prepay_id(预支付交易会话标识),这个标示是微信提交支付的关键数据
- public Map unifiedOrder(WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest) throws Exception {
- Map map = new HashMap();
- WxPayUnifiedOrderResult wxPayUnifiedOrderResult = null;
- try {
- wxPayUnifiedOrderResult = wxPayApi.unifiedOrder(wxPayUnifiedOrderRequest);
- //map.put("status", "SUCCESS");
- 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");
- map.put("mwebUrl", mwebUrl);
- } else if (WxPayConstants.TradeType.NATIVE.equals(wxPayUnifiedOrderRequest.getTradeType())) {
- //扫码支付
- //QrcodeUtils.encode(wxPayUnifiedOrderResult.getCodeURL(),response.getOutputStream());
- byte[] bytes = QrcodeUtils.createQrcode(wxPayUnifiedOrderResult.getCodeURL(), 400, null);
- String qrcodeUrl = fileClient.upload(bytes, bytes.length,"jpg",null);
- //保存图片地址
- String outTradeNo = wxPayUnifiedOrderRequest.getOutTradeNo();
- ProjectRecode projectRecode = projectRecodeService.findOne(Long.parseLong(outTradeNo));
- projectRecode.setQrcodeUrl(qrcodeUrl);
- projectRecodeService.update(projectRecode);
- map.put("qrcodeUrl", qrcodeUrl);
- } else if (WxPayConstants.TradeType.JSAPI.equals(wxPayUnifiedOrderRequest.getTradeType())) {
- //公众号支付
- String prepayId = wxPayUnifiedOrderResult.getPrepayId();
- map.put("prepayId", prepayId);
- }
- //byte[] arr = wxPayApi.createScanPayQrcodeMode2(wxPayUnifiedOrderResult.getCodeURL(),null,null);
- } catch (WxPayException e) {
- logger.error("微信支付失败!订单号:{},原因:{}", wxPayUnifiedOrderRequest.getOutTradeNo(), e.getMessage());
- e.printStackTrace();
- map.put("status", e.getReturnCode());
- map.put("message", e.getReturnMsg());
- }
- return map;
- }
- /**
- * 查询订单支付状态 参数二选一
- * @param transactionId
- * @param outTradeNo
- */
- @ResponseBody
- @RequestMapping(value = "/queryTradeState", method = RequestMethod.POST)
- public String queryTradeState(@RequestParam(required = false) String transactionId, @RequestParam(required = false) String outTradeNo){
- try {
- WxPayOrderQueryResult wxPayOrderQueryResult =wxPayApi.queryOrder(transactionId, outTradeNo);
- return wxPayOrderQueryResult.getTradeState();
- } catch (WxPayException e) {
- return "ERROR";
- }
- }
- /**
- * 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,
- * 如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,
- * 要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
- * 特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,
- * 防止数据泄漏导致出现“假通知”,造成资金损失。
- * @param request
- * @param response
- * @return
- */
- @ResponseBody
- @RequestMapping("/notifyUrl")
- public synchronized void payNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
- ModelMap map = new ModelMap();
- String returnResult = null;
- try {
- String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
- WxPayOrderNotifyResult result = wxPayApi.parseOrderNotifyResult(xmlResult);
- //商户系统订单默认支付状态
- short projectRecodePayStatus = 1;
- if ("SUCCESS".equals(result.getReturnCode())) {
- if ("SUCCESS".equals(result.getResultCode())) {
- returnResult = setXml("SUCCESS", "OK");
- WechatOrder wechatOrder = wechatOrderService.getByTransactionId(result.getTransactionId());
- WxPayOrderQueryResult OrderQueryResult = null;
- if (wechatOrder != null) {
- OrderQueryResult = wxPayApi.queryOrder(result.getTransactionId(),null);//二选一填
- }
- ProjectRecode projectRecode = projectRecodeService.findOne(Long.parseLong(result.getOutTradeNo()));
- //微信在数据库中订单存在且状态已处理
- if (wechatOrder != null && wechatOrder.getStatus() == 1 && projectRecode != null && projectRecode.getStatus() != 1 && wechatOrder.getTradeState().equals(OrderQueryResult.getTradeState())) {
- logger.info("系统已对该笔交易进行处理,交易订单号" + wechatOrder.getOutTradeNo() + "微信交易号" + wechatOrder.getTransactionId());
- returnResult = setXml("SUCCESS", "OK");
- } else {
- // 自己处理订单的业务逻辑
- //校验返回的订单金额是否与商户侧的订单金额一致
- if (!(projectRecode != null && ((int) (projectRecode.getAmount()*100)) == result.getTotalFee().intValue())) {
- logger.warn("防止数据泄漏导致出现“假通知”,以免造成资金损失");
- map.put("warning", "防止数据泄漏导致出现“假通知”,以免造成资金损失");
- returnResult = setXml("FAIL", "商户侧的订单金额与返回的订单金额不一致");
- projectRecodePayStatus = 3;
- projectRecode.setStatus(projectRecodePayStatus);
- projectRecode.setExceptionMsg("{'AmountMsg' : '支付宝返回金额(单位分)与订单金额不相等', 'notifyTotalFee' : " + result.getTotalFee().intValue() + "}");
- } else {
- WxPayOrderQueryResult wxPayOrderQueryResult = wxPayApi.queryOrder(result.getTransactionId(),null);//二选一填
- if (wxPayOrderQueryResult != null) {
- map.put("tradeState", wxPayOrderQueryResult.getTradeState());//微信订单状态
- map.put("tradeStateDesc", wxPayOrderQueryResult.getTradeStateDesc());//微信订单状态详情
- }
- if ("SUCCESS".equals(wxPayOrderQueryResult.getTradeState())) {
- logger.info("异步通知支付成功处理开始:商户订单状态:" + projectRecode.getStatus());
- projectRecodePayStatus = 2;
- if (projectRecode.getStatus() == 1) {
- //如果当前数据库中商户订单还是待支付状态 更新项目参数人数和金额
- Project project = projectService.findOne(projectRecode.getProId());
- logger.info("查看项目,查看项目id为" + project.getId() + ",项目名称为"
- + project.getName() + ",当前参与人数为" + project.getJoinAmount() + ",当前已筹集的金额" + project.getTotalAmount());
- project.setJoinAmount(project.getJoinAmount() + 1);
- project.setTotalAmount(project.getTotalAmount() + projectRecode.getAmount());
- logger.info("此次用户捐款金额为" + projectRecode.getAmount() + "元");
- projectService.save(project);
- logger.info("更新项目,更新了项目id为" + project.getId() + ",项目名称为"
- + project.getName()+ "的参数人数和金额" + ",当前参与人数为" + project.getJoinAmount() + ",当前已筹集的金额" + project.getTotalAmount());
- }
- projectRecode.setStatus(projectRecodePayStatus);
- logger.info("异步通知支付成功处理结束:商户订单状态:" + projectRecode.getStatus());
- }
- wechatOrderService.save(WechatOrder.WxPayOrderNotifyResultToConvert(result, (short) 1, wxPayOrderQueryResult));
- returnResult = setXml("SUCCESS", "OK");
- }
- //更新订单状态
- projectRecodeService.update(projectRecode);
- }
- //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
- response.getWriter().write(returnResult);
- }
- }
- @ResponseBody
- @RequestMapping("/redirectUrl")
- public String redirectUrl(HttpServletRequest request) {
- /*由于设置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 基础支持token 一日上限2000次 与用户网页授权无关 与支付无关
- * @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;
- }
- @ResponseBody
- @RequestMapping(value = "/userAdvanced", method = RequestMethod.GET)
- public void userAdvanced(HttpServletRequest request, HttpServletResponse response) throws Exception {
- //配置网页授权url
- String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wxPayApi.getConfig().getAppId() + "&redirect_uri=" + URLEncoder.encode("http://lj.ubtob.com/wxpay/getOpenId", "UTF-8") + "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
- response.sendRedirect(url);
- }
- /**
- * 获取用户基本信息 静默获取 无需用户同意 只有公众号模式需要
- * https://mp.weixin.qq.com/advanced/advanced?action=table&token=719542712&lang=zh_CN
- * 网页授权添加url 需icp备案
- * @param request
- * @return
- */
- @ResponseBody
- @RequestMapping(value = "/getOpenId", method = RequestMethod.GET)
- public void getOpenId(HttpServletRequest request) throws IOException {
- try {
- //TODO 授权方式 是否需要电话号码 名字等信息
- //TODO 获取code
- String code = request.getParameter("code");
- String state = request.getParameter("state");
- logger.info("公众号获取:authCode=" + code + ",state=" + state);
- //String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
- String openId = wxPayApi.authcode2Openid(code);
- } catch (WxPayException e) {
- e.printStackTrace();
- }
- }
- /**
- * 验证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) {
- //核心逻辑
- }
- }
- //
- 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("一元捐-" + projectService.findOne(projectRecode.getProId()).getName());
- } else if (WxPayConstants.TradeType.JSAPI.equals(tradeType)) {
- if (StringUtils.isEmpty(wxPayApi.getConfig().getSubAppId())) {
- wxPayUnifiedOrderRequest.setOpenid(null);//TODO 否是 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("优软科技-" + projectService.findOne(projectRecode.getProId()).getName());
- } else if (WxPayConstants.TradeType.NATIVE.equals(tradeType)) {
- //PC网站——传入浏览器打开的网站主页title名-实际商品名称,例如:腾讯充值中心-QQ会员充值;
- wxPayUnifiedOrderRequest.setBody("一元捐-" + projectService.findOne(projectRecode.getProId()).getName());
- }
- //wxPayUnifiedOrderRequest.setDetail("");//否 商品详细描述,对于使用单品优惠的商户,改字段必须按照规范上传,详见“单品优惠参数说明”
- wxPayUnifiedOrderRequest.setAttach("这是附加数据");//否 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
- wxPayUnifiedOrderRequest.setOutTradeNo(projectRecode.getId().toString());//是 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
- //wxPayUnifiedOrderRequest.setFeeType("CNY");//否 符合ISO 4217标准的三位字母代码,默认人民币:CNY
- wxPayUnifiedOrderRequest.setTotalFee((int)(projectRecode.getAmount() * 100));//是 订单总金额,只能为整数
- String spbillCreateIp = IpUtils.getIpFromRequest(request);
- if ("0:0:0:0:0:0:0:1".equals(spbillCreateIp)) {
- spbillCreateIp = "127.0.0.1";
- }
- wxPayUnifiedOrderRequest.setSpbillCreateIp(spbillCreateIp);//是 APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
- //wxPayUnifiedOrderRequest.setSpbillCreateIp(getIp(request));
- //wxPayUnifiedOrderRequest.setSpbillCreateIp("10.10.100.200");
- //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 {
- JSONObject jsonObject = JSONObject.parseObject(jsonStr);
- String imid = jsonObject.getString("imid");
- logger.info("移动端imid=" + imid);
- Long uuid = null;
- User user = SystemSession.getUser();
- if (user != null) {
- uuid = user.getUserUU();
- }
- if (!StringUtils.isEmpty(imid)) {
- jsonObject.remove("imid");
- //TODO 通过imid获取uuid
- Object uuidObj = userService.getUserByImId(Long.parseLong(imid));
- if (uuidObj !=null) {
- uuid = (Long)uuidObj;
- logger.info("移动端imid转为uuid,uuid=" + uuid);
- }
- }
- ProjectRecode projectRecode= JSONObject.parseObject(jsonObject.toJSONString(),ProjectRecode.class);
- if (uuid != null) {
- projectRecode.setUuid(uuid);
- }
- projectRecode.setTime(new Date());
- ProjectRecode newProjectRecode = projectRecodeService.join(projectRecode);
- return newProjectRecode;
- }
- public String getIp(HttpServletRequest request) {
- String ip = request.getHeader("X-Forwarded-For");
- if(ip!=null && !"unKnown".equalsIgnoreCase(ip)){
- int index = ip.indexOf(",");
- if(index != -1){
- return ip.substring(0,index);
- }else{
- return ip;
- }
- }
- ip = request.getHeader("X-Real-IP");
- if(ip!=null && !"unKnown".equalsIgnoreCase(ip)){
- return ip;
- }
- return request.getRemoteAddr();
- }
- }
|