Ver código fonte

第三方线上支付

plf 4 anos atrás
pai
commit
bc1c679f08

+ 5 - 0
pom.xml

@@ -25,6 +25,11 @@
             <artifactId>lombok</artifactId>
             <optional>true</optional>
         </dependency>
+        <dependency>
+            <groupId>com.caimei.module</groupId>
+            <artifactId>pay</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>com.caimei.module</groupId>
             <artifactId>caimei-search</artifactId>

+ 3 - 0
src/main/java/com/caimei/StartApplication.java

@@ -6,11 +6,14 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication(scanBasePackages = {
         "com.caimei.module.search.service",
+        "com.caimei.module.pay.service",
+        "com.caimei.utils",
         "com.caimei.controller.**",
         "com.caimei.service.**"
 })
 @MapperScan(basePackages = {
         "com.caimei.module.search.dao",
+        "com.caimei.module.pay.dao",
         "com.caimei.mapper.**"})
 public class StartApplication {
 

+ 165 - 0
src/main/java/com/caimei/controller/order/PayOrderController.java

@@ -0,0 +1,165 @@
+package com.caimei.controller.order;
+
+import com.caimei.module.base.entity.bo.JsonModel;
+import com.caimei.module.base.entity.bo.Payment;
+import com.caimei.module.base.entity.vo.OrderPayLinkVo;
+import com.caimei.module.pay.service.PayService;
+import com.caimei.utils.WxConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2020/5/6
+ */
+@Slf4j
+@RestController
+@RequestMapping("/PayOrder")
+public class PayOrderController {
+    private PayService payService;
+
+    @Autowired
+    public void setPayService(PayService payService) {
+        this.payService = payService;
+    }
+
+    @Value("${miniprogram.notifyUrl}")
+    private String notifyUrl;
+
+    @Value("${miniprogram.redirectLink}")
+    private String redirectLink;
+
+    @Value("${miniprogram.linkPage}")
+    private String linkPage;
+
+    /**
+     * 收银台数据显示
+     */
+    @GetMapping("/checkoutCounter")
+    public JsonModel checkoutCounter(Integer orderId) {
+        return payService.checkoutCounter(orderId);
+    }
+
+    /**
+     * 微信线上支付
+     */
+    @PostMapping("/miniWxPay")
+    public JsonModel miniWxPay(Payment payment, HttpServletRequest request) {
+        JsonModel model = JsonModel.newInstance();
+        if (!"WEIXIN".equals(payment.getPayWay()) || payment.getPayAmount() == null || payment.getPayAmount() < 2) {
+            return model.error("参数异常");
+        }
+        Map<String, Object> map = null;
+        if (null == payment.getState()) {
+            //小程序微信快捷支付
+            payment.setPayType("MINIAPP_WEIXIN");
+            JsonModel wxJscode = WxConfig.getWxJscode(payment.getCode(), request);
+            if (wxJscode.getCode() == -1) {
+                return model.error(wxJscode.getMsg());
+            }
+            map = (Map<String, Object>) wxJscode.getData();
+        } else {
+            //pc微信扫码支付,微信公众号支付
+            payment.setPayType("JSAPI_WEIXIN");
+            try {
+                map = WxConfig.getAccessTokenMap(payment.getCode(), "crm");
+            } catch (Exception e) {
+                e.printStackTrace();
+                return model.error("wx公众号获取openid失败");
+            }
+        }
+        String openid = (String) map.get("openid");
+        if (openid == null) {
+            return model.error("wx获取openid失败");
+        }
+        payment.setOpenid(openid);
+        payment.setNotifyUrl(notifyUrl);
+        log.info("wx支付openid>>>>>" + openid);
+        return payService.pay(payment, request);
+    }
+
+    /**
+     * 支付异步通知回调
+     */
+    @GetMapping("/paymentCallback")
+    public String paymentCallback(HttpServletRequest request) throws Exception {
+        log.info("异步回调通知>>>>>>>start");
+        String data = request.getParameter("data");
+        if (StringUtils.isBlank(data)) {
+            return "回调参数失败";
+        }
+        return payService.paymentCallback(data);
+    }
+
+    /**
+     * 小程序生成网银支付链接
+     */
+    @PostMapping("/payLink")
+    public JsonModel payLink(OrderPayLinkVo orderPayLink) {
+        orderPayLink.setRedirectLink(redirectLink);
+        return payService.payLink(orderPayLink);
+    }
+
+    /**
+     * 支付链接重定向到页面
+     */
+    @GetMapping("/jumpPage")
+    public void jumpPage(String linkLogo, HttpServletResponse response) throws IOException {
+        payService.jumpPage(linkLogo, linkPage, response);
+    }
+
+    /**
+     * pc端支付,银联,支付宝
+     */
+    @PostMapping("/pcMallPay")
+    public JsonModel pcMallPay(Payment payment, HttpServletRequest request) {
+        JsonModel model = JsonModel.newInstance();
+        if (null == payment || StringUtils.isBlank(payment.getPayWay()) || StringUtils.isBlank(payment.getReturnUrl()) || payment.getPayAmount() == null) {
+            return model.error("参数异常");
+        }
+        if ("UNIONPAY".equals(payment.getPayWay())) {
+            //银联支付
+            payment.setPayType("GATEWAY_UNIONPAY");
+        } else if ("ALIPAY".equals(payment.getPayWay())) {
+            //支付宝支付
+            payment.setPayType("ALIPAY_H5");
+        }
+        payment.setNotifyUrl(notifyUrl);
+        return payService.pay(payment, request);
+    }
+
+    /**
+     * 判断此次支付是否完成
+     */
+    @GetMapping("/payWhetherSuccess")
+    public JsonModel payWhetherSuccess(Integer orderId, Integer paySuccessCounter) {
+        if (null == orderId || null == paySuccessCounter) {
+            return JsonModel.newInstance().error("参数异常");
+        }
+        return payService.payWhetherSuccess(orderId, paySuccessCounter);
+    }
+
+    /**
+     * 查询本次支付订单是否完成
+     */
+    @GetMapping("/findOrderStatus")
+    public JsonModel findOrderStatus(String mbOrderId) {
+        if (null == mbOrderId) {
+            return JsonModel.newInstance().error("参数异常");
+        }
+        return payService.findOrderStatus(mbOrderId);
+    }
+}

+ 130 - 0
src/main/java/com/caimei/utils/WxConfig.java

@@ -0,0 +1,130 @@
+package com.caimei.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.caimei.module.base.entity.bo.JsonModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 微信工具类
+ *
+ * @author LG
+ * @create 2017-09-21
+ **/
+@Component
+public class WxConfig {
+    protected static final Logger logger = LoggerFactory.getLogger(WxConfig.class);
+
+    public static String MiniAppId;
+
+    @Value("${miniprogram.AppId1}")
+    public void setMiniAppId(String miniAppId) {
+        MiniAppId = miniAppId;
+    }
+
+    public static String MiniAppSecret;
+
+    @Value("${miniprogram.AppSecret1}")
+    public void setMiniAppSecret(String miniAppSecret) {
+        MiniAppSecret = miniAppSecret;
+    }
+
+    public static String CrmAppId;
+
+    @Value("${miniprogram.crm_AppId}")
+    public void setCrmAppId(String crmAppId) {
+        CrmAppId = crmAppId;
+    }
+
+    public static String CrmAppSecret;
+
+    @Value("${miniprogram.crm_AppSecret}")
+    public void setCrmAppSecret(String crmAppSecret) {
+        CrmAppSecret = crmAppSecret;
+    }
+
+
+    /**
+     * 网页授权登录,通过code获取access_token
+     *
+     * @param code wxcode
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, Object> getAccessTokenMap(String code, String source) throws Exception {
+        String link = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+        //微信公众号
+        link = link.replace("APPID", CrmAppId);
+        link = link.replace("SECRET", CrmAppSecret);
+        //填写第一步获取的code参数
+        link = link.replace("CODE", code);
+        String result = HttpRequest.sendGet(link);
+        logger.info(result);
+        Map<String, Object> map = JSONObject.parseObject(result, Map.class);
+        return map;
+    }
+
+
+    /**
+     * 小程序微信授权登录,获取openid
+     *
+     * @param code 微信凭证
+     */
+    public static JsonModel getWxJscode(String code, HttpServletRequest request) {
+        JsonModel res = JsonModel.newInstance();
+        logger.info("Start get SessionKey");
+        Map<String, Object> map = new HashMap<>();
+        //获取当前微信小程序的环境
+        String referer = request.getHeader("Referer");
+        logger.info("referer-is----:" + referer);
+        map.put("referer", referer);
+        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
+        Map<String, String> requestUrlParam = new HashMap<String, String>();
+        //小程序appId
+        requestUrlParam.put("appid", MiniAppId);
+        logger.info("appid: ---" + MiniAppId);
+        //小程序appsecret
+        requestUrlParam.put("secret", MiniAppSecret);
+        //小程序端返回的code
+        requestUrlParam.put("js_code", code);
+        //默认参数
+        requestUrlParam.put("grant_type", "authorization_code");
+        //发送post请求读取调用微信接口获取openid用户唯一标识
+        String infos;
+        try {
+            infos = HttpRequest.sendPost(requestUrl, requestUrlParam);
+        } catch (Exception e) {
+            res.setData(map);
+            return res.error("服务器内部异常");
+        }
+        //解析相应内容(转换成json对象)
+        JSONObject jsonObject = JSON.parseObject(infos);
+        String openid = jsonObject.getString("openid");
+        logger.info("openid----->" + openid);
+        String unionid = jsonObject.getString("unionid");
+        logger.info("unionid------>" + unionid);
+        map.put("openid", openid);
+        map.put("unionid", unionid);
+        String session_key = jsonObject.getString("session_key");
+        map.put("session_key", session_key);
+        String errcode = jsonObject.getString("errcode");
+        String errmsg = jsonObject.getString("errmsg");
+        if (!StringUtils.isEmpty(errcode) &&
+                ("-1".equals(errcode) || "40029".equals(errcode) || "45011".equals(errcode))) {
+            res.setMsg(errmsg);
+            res.setData(map);
+            map.put("sessionKey", session_key);
+            res.setCode(-1);
+            return res;
+        }
+        return res.success(map);
+    }
+}

+ 10 - 1
src/main/resources/dev/application-dev.yml

@@ -26,6 +26,7 @@ mybatis:
   mapper-locations:
     - classpath:mapper/*.xml
     - classpath:caimei-search-mapper/*Mapper.xml
+    - classpath:com-caimei-module-pay/*Mapper.xml
   #pojo别名扫描包
   type-aliases-package: com.caimei.entity
 
@@ -52,4 +53,12 @@ miniprogram:
   #采美组织
   AppId2: wxf3cd4ae0cdd11c36
   AppSecret2: 9bdb37d28c5e74ad3694c09c205e9bd2
-
+  #crm公众号信息
+  crm_AppId: wxea43a0f9ebce9e66
+  crm_AppSecret: 1c3cd60908e72dd280840bee9e15f7f6
+  #支付异步回调地址
+  notifyUrl: http://localhost:8107/PayOrder/paymentCallback
+  #支付链接重定向地址
+  redirectLink: http://localhost:8107/PayOrder/jumpPage
+  #链接页面
+  linkPage: http://192.168.1.20:8107/web/order/view/pay/caimei-starspay.jsp

+ 9 - 0
src/main/resources/prod/application-prod.yml

@@ -54,3 +54,12 @@ miniprogram:
   #采美组织
   AppId2: wxf3cd4ae0cdd11c36
   AppSecret2: 9bdb37d28c5e74ad3694c09c205e9bd2
+  #crm公众号信息
+  crm_AppId: wxea43a0f9ebce9e66
+  crm_AppSecret: 1c3cd60908e72dd280840bee9e15f7f6
+  #支付异步回调地址
+  notifyUrl: https://mall.caimei365.com/PayOrder/paymentCallback
+  #支付链接重定向地址
+  redirectLink: https://mall.caimei365.com/PayOrder/jumpPage
+  #链接页面
+  linkPage: https://www-b.caimei365.com/web/order/view/pay/caimei-starspay.jsp

+ 9 - 0
src/main/resources/test/application-test.yml

@@ -53,3 +53,12 @@ miniprogram:
   #采美组织
   AppId2: wxf3cd4ae0cdd11c36
   AppSecret2: 9bdb37d28c5e74ad3694c09c205e9bd2
+  #crm公众号信息
+  crm_AppId: wxea43a0f9ebce9e66
+  crm_AppSecret: 1c3cd60908e72dd280840bee9e15f7f6
+  #支付异步回调地址
+  notifyUrl: https://mall-b.caimei365.com/PayOrder/paymentCallback
+  #支付链接重定向地址
+  redirectLink: https://mall-b.caimei365.com/PayOrder/jumpPage
+  #链接页面
+  linkPage: https://www-b.caimei365.com/web/order/view/pay/caimei-starspay.jsp