<返回更多

Java整合微信支付、支付宝支付

2020-05-22    
加入收藏

申请微信支付能力

* 要想使用微信支付能力,不管是App支付、公众号支付、h5支付等支付方式都需要先在微信商户平台申请开通支付能力。

* 申请开通支付能力的资料有公司营业执照、负责人身份证正反面等图片,相关所需的所有资料在微信官方商户平台上有说明。

* 申请完开通支付能力后,我们会得到商户号以及appId,然后设置32位官方密钥。

准备工作

* 如果你是h5支付,还需要去微信商户平台设置支付URL的IP或者域名,一般最多可以设置5个IP或者域名,建议同时将正式环境和测试环境的IP或者域名设置好。

* 如果你是公众号支付,同上,你也需要设置你的支付IP或者域名,注意,异步通知的URL也要在你设置的IP或者域名下。

业务流程

  1. 用户在商户APP中选择商品,提交订单,选择微信支付。(app端向服务端发起请求)
  2. 商户后台收到用户支付单,调用微信支付统一下单接口。(服务端向微信请求)。
  3. 通过微信支付返回的数据调起微信支付。
  4. 用户在微信端支付成功。
  5. 支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意 一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。
  6. 商户APP调起微信支付。(app端利用服务端回传的参数调起微信支付)
  7. 商户后台接收支付通知。(微信将支付结果异步通知服务端)
  8. 商户后台查询支付结果。(微信将支付结果同步通知app端)
Java整合微信支付、支付宝支付

时序图

注意事项

  1. 订单金额total_fee使用的单位是分,支付宝使用的单位是元。

开始集成

*** APP支付**

支付集成流程如下(微信和支付宝流程上基本一致,具体参考代码):

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。(app端向服务端发起请求)

步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。(服务端向微信请求)

步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay(将微信回传的prepayid与其他参数组合返回给app端)

步骤4:商户APP调起微信支付。(app端利用服务端回传的参数调起微信支付)

步骤5:商户后台接收支付通知。(微信将支付结果异步通知服务端)

步骤6:商户后台查询支付结果。(微信将支付结果同步通知app端)

微信支付代码

微信统一下单接口和回调

@Override
public String getWxPayOrderStr(String orderNo, HttpServletRequest request) {
    //最终返回加签之后的,app需要传给支付宝app的订单信息字符串    String orderString = "";
    System.out.println("==================微信下单,商户订单号为:" + orderNo);

    String appId = PayConfigUtil.APP_ID;//appId    String mchId = PayConfigUtil.MCH_ID;//商户id    String key = PayConfigUtil.API_KEY;
    String currTime = PayCommonUtil.getCurrTime();
    String strTime = currTime.substring(8, currTime.length());
    String strRandom = PayCommonUtil.buildRandom(4) + "";
    String nonce_str = strTime + strRandom;


    order_price = order_price.substring(0, order_price.indexOf("."));
    String body = teaNames;

    String spbill_create_ip = PayConfigUtil.CREATE_IP;
    String notify_url = PayConfigUtil.NOTIFY_URL;
    String trade_type = "APP";

    SortedMap<Object, Object> map = new TreeMap<>();
    map.put("appid", appId);
    map.put("mch_id", mchId);
    map.put("nonce_str", nonce_str);
    map.put("body", body);
    map.put("out_trade_no", orderNo);
    map.put("total_fee", order_price);
    map.put("spbill_create_ip", spbill_create_ip);
    map.put("notify_url", notify_url);
    map.put("trade_type", trade_type);

    //签名数据,MD5加密    String sign = PayCommonUtil.createSign("UTF-8", map, key);
    map.put("sign", sign);
    //请求微信支付,进行下单    String requestXML = PayCommonUtil.getRequestXml(map);
    String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);
    System.out.println("微信返回值:" + resXml);
    Map<String, String> data = null;
    try {
        data = XMLUtil.doXMLParse(resXml);

        if (data.get("return_code").equals("SUCCESS")) {
            //返回给APP端的参数,APP端再调起支付接口            SortedMap<Object, Object> repData = new TreeMap<>();
            repData.put("appid", appId);
            repData.put("noncetr", nonce_str);
            repData.put("partnerid", mchId);
            repData.put("prepayid", data.get("prepay_id"));
            repData.put("package", "Sign=WXPay");
            repData.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
            String sign1 = PayCommonUtil.createSign("UTF-8", repData, key);

            JSONObject json = new JSONObject();
            json.put("appid", appId);
            json.put("partnerid", mchId);
            json.put("package", "Sign=WXPay");
            json.put("noncestr", nonce_str);
            json.put("prepayid", data.get("prepay_id"));
            json.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
            json.put("sign", "1232");
            return json.toString();
        } else {
            return "";
        }
    } catch (JDOMException | IOException e) {
        e.printStackTrace();
        return "";
    }
}
@PostMapping("/wxPayAppCallback")
public void wxPayCallback(HttpServletRequest request, HttpServletResponse response) throws JDOMException, Exception {

        System.out.println("微信支付回调");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> map = XMLUtil.doXMLParse(resultxml);
        outSteam.close();
        inStream.close();
        System.out.println("微信返回值:" + map);
        String resultCode = map.get("result_code");
        //订单号        String out_trade_no = map.get("out_trade_no");
        if (StringUtils.equals(resultCode, "SUCCESS")) {
						//业务代码
            System.out.println("微信回调成功");
            //返回微信处理成功            response.setContentType("text/xml");
            response.getWriter().println("success");
        } else {
            response.setContentType("text/xml");
            response.getWriter().println("fail");
        }
    }

支付宝支付代码

支付宝支付和回调

/** * 获取支付宝加签后台的订单信息字符串 */
@Override
public String getAliPayOrderStr(String orderNo) {
    String teaNames = "";//商品名称
    //最终返回加签之后的,app需要传给支付宝app的订单信息字符串    String orderString = "";
    System.out.println("==================支付宝下单,商户订单号为:" + orderNo);
    try {
        //实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID,
                AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET,
                AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay        AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();

        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

        //业务参数传入,可以传很多,参考API        //model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用参数(附加数据)        
     		model.setBody("购买商品");//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。        
        model.setSubject(teaNames);//商品名称        
        model.setOutTradeNo(orderNo);//商户订单号(自动生成)        
        model.setTimeoutExpress("15m");//交易超时时间        
        model.setTotalAmount(String.valueOf(orderTea.getOrderTotal()));//支付金额        
        model.setProductCode("QUICK_MSECURITY_PAY");//销售产品码(固定值)        
        ali_request.setBizModel(model);

        ali_request.setNotifyUrl(AlipayConfig.notify_url);//异步回调地址(后台)        
      	ali_request.setReturnUrl(AlipayConfig.return_url);//同步回调地址(APP)        
      	// 这里和普通的接口调用不同,使用的是sdkExecute        
      	AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request); //返回支付宝订单信息(预处理)        
      	orderString = alipayTradeAppPayResponse.getBody();//就是orderString 可以直接给APP请求,无需再做处理。    
    } catch (AlipayApiException e) {
        e.printStackTrace();
    }
    return orderString;
}
@PostMapping("/appCallback")
public void appCallback(HttpServletRequest request, HttpServletResponse response) {
	try {
            // 获取支付宝POST过来反馈信息            Map<String, String> params = new HashMap<>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }

            // 调用SDK验证签名            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE);
            //先不做回调验证            //if (signVerified) {            System.out.println("回调验签");
            // 商户订单号(后台生成)            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 支付宝交易号            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 交易状态            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("trade_no:" + trade_no);
            // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//            if (StringUtils.equals("TRADE_SUCCESS", trade_status)) {

                //ZK表示用户购买了赚客商品开通了赚客                if (out_trade_no.contains("d") || out_trade_no.contains("ZK")) {

                    String[] orderNoArr = new String[1024];
                    int a = 0;
                    //根据订单号修改订单状态                    MallOrder mallOrder = new MallOrder();
                    mallOrder.setOrderStatus(Byte.valueOf("1"));
                    mallOrder.setOutTradeNo(trade_no);//支付宝交易号                    mallOrder.setPayChannel(Byte.valueOf("2"));//支付方式                    mallOrder.setPayTime(new Date());
                    mallOrder.setCreated(true);
                    if (out_trade_no.contains(",")) {
                        orderNoArr = out_trade_no.split(",");
                        for (String orderNo : orderNoArr) {
                            MallOrderExample mallOrderExample = new MallOrderExample();
                            mallOrderExample.createCriteria().andOrderNoEqualTo(orderNo);
                            saveRecord(orderNo);
                            a += orderService.updateByExampleSelective(mallOrder, mallOrderExample);
                        }
                    } else {
                        saveRecord(out_trade_no);
                        MallOrderExample mallOrderExample = new MallOrderExample();
                        mallOrderExample.createCriteria().andOrderNoEqualTo(out_trade_no);
                        a = orderService.updateByExampleSelective(mallOrder, mallOrderExample);
                    }
                    if (a > 1) {
                        System.out.println("修改成功");
                    }
                    System.out.println("订单提交成功");
                } else {
                    //根据订单号修改订单状态,生成取货码                    machineOrderTea orderTea = machineService.findMachineOrder(out_trade_no);
                    String prefix = RandomStringUtils.random(4, "1234567890").toUpperCase();
                    long l = System.currentTimeMillis();
                    String newSuffix=String.valueOf(l).substring(String.valueOf(l).length()-5,String.valueOf(l).length());
                    String suffix = String.valueOf(l / 500000000);
//                    String verificationCode = prefix + suffix;                    String verificationCode = prefix + newSuffix;
                    orderTea.setVerificationCode(verificationCode);
                    orderTea.setTradeNo(trade_no);
                    orderTea.setOrderNo(out_trade_no);
                    orderTea.setPayMethod("Alipay");
                    orderTea.setOrderStatus("1");

                    //如果使用了优惠券则将优惠券设置为已使用                    Integer couponLinkId = orderTea.getCouponId();
                    if (null != couponLinkId) {
                        MemberCouponsLink link = couponsLinkMapper.selectByPrimaryKey(couponLinkId);
                        //设置优惠为已使用//                        link.setIsUse(true);                        /*临时方案↓*/                        //如果优惠券码不为"888888"或者"666666",则设置优惠券为"已使用"                        if(!(link.getCouponCode().equals("888888")||link.getCouponCode().equals("666666"))){
                            link.setIsUse(true);
                        }
                        /*临时方案↑*/                        couponsLinkMapper.updateByPrimaryKeySelective(link);
                    }

                    machineService.updateMachineOrder(orderTea);
                    System.out.println("订单提交成功");
                }

                String result = "success";
//                if(signVerified){//验签成功//                    result="success";//                }else{//                    result="fail";//                }                //,不然业务代码不会执行                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(result.getBytes());
                out.flush();
                out.close();

            }
//            } else {//                System.out.println("回调验签失败");//            }        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("支付异常");
        }
    }
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>