您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

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

时间:2020-05-22 16:03:05  来源:  作者:

申请微信支付能力

* 要想使用微信支付能力,不管是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("支付异常");
        }
    }


Tags:微信支付   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
如今,微信支付已经是人们再熟悉不过的日常操作了,人们无论是在网上购物,还是在日常出行买菜,亦或者是外出游玩,都需要涉及到微信支付,而现如今,微信支付已经几乎覆盖了我们很多人的...【详细内容】
2021-09-14  Tags: 微信支付  点击:(50)  评论:(0)  加入收藏
手机支付越来越便捷的今天,大部分人已经极少使用现金支付。 微信支付、支付宝支付 = 钱包。 但是,就算揣自己怀里的钱,都有可能被偷、被抢,更别说放在手机里了。 再加上现在个人...【详细内容】
2021-09-13  Tags: 微信支付  点击:(128)  评论:(0)  加入收藏
自从有了电子移动支付,我们出门基本就不带现金了,移动支付给我们的生活带来很多便利,我们使用的电子支付方式主要有两种,微信支付和支付宝支付,今天我就说说使用微信支付需要注意...【详细内容】
2021-09-01  Tags: 微信支付  点击:(81)  评论:(0)  加入收藏
微信支付对于当下的我们来说,是非常重要的一个手机功能,可以方便我们在出门购物消费时直接支付,而不再需要随身携带现金。在使用微信支付之前,是需要实名认证、绑定我们的身份证...【详细内容】
2021-08-25  Tags: 微信支付  点击:(55)  评论:(0)  加入收藏
近期小编听说有的小伙伴名下绑定了多个微信支付账户却毫不知情,这是非常危险的!下面小编为大家介绍一个小方法可以在手机上快速查询名下微信号,闲置的微信号最好还是解绑了哟需...【详细内容】
2021-08-17  Tags: 微信支付  点击:(253)  评论:(0)  加入收藏
商家想要实现微信支付宝收款码二合一,也就是聚合收款码,做法其实很简单。 一,我们首先来认识聚合收款码 1,聚合收款码是什么?聚合收款二维码,从字面来理解就是一个二维码支持多种...【详细内容】
2021-05-26  Tags: 微信支付  点击:(260)  评论:(0)  加入收藏
5月8日,数字人民币APP更新,钱包运营机构中的“网商银行(支付宝)”已呈现可用状态。同时,工、农、中、建、交、邮储六大国有银行数字人民币钱包下均增加了饿了么、盒马鲜生、天猫...【详细内容】
2021-05-11  Tags: 微信支付  点击:(116)  评论:(0)  加入收藏
手机支付最主要的就是通过支付宝和微信了,很多人也会在微信钱包里放入不少零钱,方便支付使用。我们除了可以给手机添加密码外,还可以在微信支付上添加密码,保障大家的财产安全。...【详细内容】
2021-04-30  Tags: 微信支付  点击:(75)  评论:(0)  加入收藏
现如今,微信支付十分方便,很多中老年人也能轻松上手,节省了很多找零时间,也避免了没带钱包的尴尬。可是,在这种便捷背后,信息安全问题却不容小觑!前段时间有新闻报道称,一女子发现了...【详细内容】
2020-11-09  Tags: 微信支付  点击:(170)  评论:(0)  加入收藏
很多早期注册的微信都没有实名制或者是非本人认证的,这时候就需要注销微信支付重新认证,一起看看怎么操作。微信注销更换实名制教程进入微信,点击我的后点击支付,如下图所示 点...【详细内容】
2020-10-10  Tags: 微信支付  点击:(188)  评论:(0)  加入收藏
▌简易百科推荐
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(11)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(12)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(10)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(10)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(14)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(17)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(21)  评论:(0)  加入收藏
一、概述观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察...【详细内容】
2021-12-13  唯一浩哥    Tags:Java   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条