精华内容
下载资源
问答
  • 主要介绍了APP微信支付(java后台_统一下单和回调),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 微信支付回调工具类

    2018-11-30 16:26:50
    对接微信支付统一下单接口时,下单支付成功后的回调工具类,相关的回调工具类使用,大家可以关注我的博客进入查看,有关键代码解析,配套使用更佳
  • 在用户支付完过后微信会调用我们给它的异步通知地址返回支付的结果,需要注意的是我们给的通知地址是可以进行外网访问的 我使用的一些工具类方法大多是从官方给的demo,下面是下载地址 ...好了上代码 ...

    在用户支付完过后微信会调用我们给它的异步通知地址返回支付的结果,需要注意的是我们给的通知地址是可以进行外网访问的

    我使用的一些工具类方法大多是从官方给的demo,下面是下载地址
    https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

    好了上代码

      @RequestMapping("/wechatpayment")
       @Transactional
        public void wechatpayment(HttpServletRequest req, HttpServletResponse resp){
            //读取参数
            InputStream inputStream;
            StringBuffer sb=new StringBuffer();
            try {
                inputStream=req.getInputStream();
                String s ;
                BufferedReader br=new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
                while ((s=br.readLine())!=null) {
                    sb.append(s);
                }
                br.close();
                inputStream.close();
                boolean verdict;
                Map<String, String> map;
                //将参数转换成map
                map= WXPayUtil.xmlToMap(sb.toString());
                //根据订单id查询订单信息
                Order order = orderService.selectOrderId(map.get("out_trade_no"));
                //判断是否处理过该订单信息
                //已经处理过直接返回成功的消息给微信
                String xml=null;
                if (order.getStatus().equals("2")){
                    xml="<xml>" +
                            "  <return_code><![CDATA[SUCCESS]]></return_code>" +
                            "  <return_msg><![CDATA[OK]]></return_msg>" +
                            "</xml>";
                }else{
    	            //校验签名是否正确(使用HMACSHA256签名算法)
    	            verdict=WXPayUtil.isSignatureValid(map, WeixinPayConfig.key,WXPayConstants.SignType.HMACSHA256);
    	            Map<String,String> result=new HashMap<>();
    	             //判断微信返回的结果是否是交易成功
    	            if("SUCCESS".equals(map.get("return_code"))){
    	            	//判断签名是否校验成功
    	                if (verdict) {
    	                    BigDecimal total_fee=new BigDecimal(map.get("total_fee"));
    	                    BigDecimal price = order.getPrice();
    	                    System.out.println(total_fee.compareTo(price));
    	                    //判断与订单价格是否一致
    	                    if (total_fee.compareTo(price)==0){
    	                        //交易成功
    	                   		 /**
    	                   		 *修改订单状态
                                 * 进行成功后的业务逻辑
                                 */
    	                        xml="<xml>" +
    	                                "  <return_code><![CDATA[SUCCESS]]></return_code>" +
    	                                "  <return_msg><![CDATA[OK]]></return_msg>" +
    	                                "</xml>";
    	                    }else {
    	                        xml="<xml>" +
    	                                "  <return_code><![CDATA[FAIL]]></return_code>" +
    	                                "  <return_msg><![CDATA[预订单金额不一致]]></return_msg>" +
    	                                "</xml>";
    	                    }
    	                }else {
    	                    xml="<xml>" +
    	                            "  <return_code><![CDATA[FAIL]]></return_code>" +
    	                            "  <return_msg><![CDATA[签名失败]]></return_msg>" +
    	                            "</xml>";
    	                }
    	            }else {//未收到微信成功状态码
    	                xml="<xml>" +
    	                            "  <return_code><![CDATA[FAIL]]></return_code>" +
    	                            "  <return_msg><![CDATA[未收到微信成功状态码]]></return_msg>" +
    	                            "</xml>";
    	            }
                }
                PrintWriter out = resp.getWriter();
                out.print(xml);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    微信的回调就这些了

    微信统一下单 https://blog.csdn.net/weixin_45589505/article/details/105270203

    展开全文
  • 微信支付统一下单与支付成功回调

    千次阅读 2020-06-01 17:10:58
    3、等待微信后台回调我们自己的回调接口 微信后台 接口文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 统一下单工具类 /** * @param appKey 商户平台设置的密钥key * @param appid ...

    微信下单流程

    1、统一下单生成预支付订单,获取对应参数
    2、使用对应参数进行二次签名,返回给小程序进行发起支付
    3、等待微信后台回调我们自己的回调接口

    微信后台 接口文档
    https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1

    统一下单工具类

    /**
         * @param appKey         商户平台设置的密钥key
         * @param appid            应用id
         * @param openid           微信openid
         * @param mch_id           商户号id
         * @param body             商品描述
         * @param out_trade_no     商户订单号
         * @param total_fee        金额,单位:分
         * @param spbill_create_ip 终端ip
         * @param notify_url       通知地址
         * @param trade_type       交易类型,小程序:JSAPI
         * @return
         * @throws Exception
         */
          
      public static UnifiedOrderResponse unifiedorder(String appKey, String appid, String openid, String mch_id, String body, String out_trade_no, Integer total_fee, String spbill_create_ip, String notify_url, String trade_type) throws Exception {
            SortedMap<String, String> ps = new TreeMap();
            ps.put("appid", appid);
            ps.put("openid", openid);
            ps.put("mch_id", mch_id);
            ps.put("nonce_str", EncryptionUtils.getMD5String(System.currentTimeMillis() + out_trade_no)); //随机字符串 
            ps.put("body", body);
            ps.put("out_trade_no", out_trade_no);
            ps.put("total_fee", String.valueOf(total_fee));
            ps.put("spbill_create_ip", spbill_create_ip);
            ps.put("notify_url", notify_url);
            ps.put("trade_type", trade_type);
            String sign = sign(ps, wxApiKey);
            ps.put("sign", sign);
            String xml = XmlUtil.mapToXml(ps);
            log.debug("unifiedorder xml:" + xml);
            try {
                RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"), xml);
                Response execute = OkHttpUtil.getInstance().post("https://api.mch.weixin.qq.com/pay/unifiedorder";, (Map)null, requestBody);
                int code = execute.code();
                if (code == 200) {
                    String result = execute.body().string();
                    log.debug("unifiedorder result:" + result);
                    UnifiedOrderResponse response = (UnifiedOrderResponse)XmlUtil.xmlToBeanByJAXB(UnifiedOrderResponse.class, result);
                    if (response == null) {
                        throw new Exception("wx统一下单结果未知,返回数据解析错误,返回数据为:" + result);
                    } else if (response.getReturn_code().equals("SUCCESS")) {
                        return response;
                    } else {
                        throw new Exception("wx统一下单通信失败,原因如下:" + result);
                    }
                } else {
                    throw new Exception("wx统一下单失败,http 访问结果不是 200,返回结果为:" + execute.body().string());
                }
            } catch (IOException var18) {
                throw new Exception("wx统一下单失败,http 访问错误:" + var18.getMessage());
            }
        }try {
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"), xml);
            Response execute = OkHttpUtil.getInstance().post("https://api.mch.weixin.qq.com/pay/unifiedorder";, (Map)null, requestBody);
            int code = execute.code();
            if (code == 200) {
                String result = execute.body().string();
                log.debug("unifiedorder result:" + result);
                UnifiedOrderResponse response = (UnifiedOrderResponse)XmlUtil.xmlToBeanByJAXB(UnifiedOrderResponse.class, result);
                if (response == null) {
                    throw new Exception("wx统一下单结果未知,返回数据解析错误,返回数据为:" + result);
                } else if (response.getReturn_code().equals("SUCCESS")) {
                    return response;
                } else {
                    throw new Exception("wx统一下单通信失败,原因如下:" + result);
                }
            } else {
                throw new Exception("wx统一下单失败,http 访问结果不是 200,返回结果为:" + execute.body().string());
            }
        } catch (IOException var18) {
            throw new Exception("wx统一下单失败,http 访问错误:" + var18.getMessage());
        }
    }
    

    获取用户ip

    获取ip
    import javax.servlet.http.HttpServletRequest;
    public class IpAddress {
        /**
         * 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
         * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值
         *
         * @return ip
         */
        public static String getIpAddress(HttpServletRequest request) {
            String ip = request.getHeader("x-forwarded-for");
            if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
                if (ip.indexOf(",") != -1) {
                    ip = ip.split(",")[0];
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            return ip;
        }
    }
    

    UnifiedOrderResponse

    // 具体参数对照微信 api 
    @Data
    public class UnifiedOrderResponse {
        private String return_code;
        private String return_msg;
        private String result_code;
        private String err_code;
        private String err_code_des;
        private String appid;
        private String mch_id;
        private String device_info;
        private String nonce_str;
        private String sign;
        private String trade_type;
        private String prepay_id;
        private String code_url;
      }
    

    请求成功后 需要进行二次签名

    /**
         * 设置统一下单返回给前端的参数 二次签名
         *
         * @param unifiedorder
         * @return
         */
        public WxparamVO getWxparamVO(UnifiedOrderResponse unifiedorder, Orders order, Integer realPaymentPrice) {
            String body = order.getProductFullName().split(";")[0];
            WxparamVO wxparamVO = new WxparamVO();
            wxparamVO.setPrepayId(unifiedorder.getPrepay_id());// 获取预支付交易id
            wxparamVO.setBody(body); // 显示支付内容
            wxparamVO.setNonce_str(unifiedorder.getNonce_str()); // 随机字符串
            Long timeStamp = System.currentTimeMillis() / 1000;
            SortedMap<String, String> ps = new TreeMap();
            ps.put("appId", unifiedorder.getAppid());
            ps.put("nonceStr", unifiedorder.getNonce_str());
            ps.put("package", "prepay_id=" + unifiedorder.getPrepay_id());
            ps.put("signType", "MD5");
            ps.put("timeStamp", String.valueOf(timeStamp));
            wxparamVO.setSign(sign(ps, WX_API_KEY)); // 签名
            wxparamVO.setOut_trade_no(order.getOrderId());//订单id
            wxparamVO.setTotal_fee(realPaymentPrice);//支付价格
            wxparamVO.setTimeStamp(String.valueOf(timeStamp));
            log.info("正在请求支付,支付信息:order_id" + order.getOrderId() + " 支付金额:" + order.getRealPaymentPrice());
            return wxparamVO;
        }
    

    WxparamVO

    
    @Data
    public class WxparamVO {
        @ApiModelProperty(value = "预支付交易会话id")
        private String prepayId;
    
    
        /*随机字符串,长度要求在32位以内*/
        @ApiModelProperty(value = "随机字符串")`在这里插入代码片`
        private String nonce_str;
    
        /*签名*/
        @ApiModelProperty(value = "签名")
        private String sign;
    
        /*商品描述*/
        @ApiModelProperty(value = "商品描述")
        private String body;
    
        /*商户订单号*/
        @ApiModelProperty(value = "商户订单号 也就是 订单id orderId")
        @JsonSerialize(using = ToStringSerializer.class)
        private Long out_trade_no;
    
        /*标价金额 默认分*/
        @ApiModelProperty(value = "标价金额 默认分")
        private Integer total_fee;
    
        /*标价金额 默认分*/
        @ApiModelProperty(value = "时间戳")
        private String timeStamp;
    
    }
    

    微信回调通知

    回调通知需要进行校验签名!!!

    //controller 类
    @ApiOperation(value = "微信支付成功回调", notes = "微信支付成功异步回调,修改订单信息")
        @PostMapping("/xxx-notify")
        public String orderNotify() throws Exception {
            return OrderService.orderNotify();
        }
    
    // 实现类
      // 实现类
        public String orderNotify() {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            //校验 订单
            String xml = request2String(request);
            boolean flag = validateSign(xml, WxDataManager.WX_API_KEY);
            if(flag){
                // TODO 业务
              return  success();
            }
            return false();
    }
    
       String fail() {
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
        }
    
        String success() {
            return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        }
    

    request 转换为字符串

    /**
         * 微信回调参数 转化为String的 xml
         *
         * @param request
         * @return
         */
        public static String request2String(HttpServletRequest request) {
            String notifyData = "";
            try {
                InputStream is = request.getInputStream();
                try {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    notifyData = sb.toString();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    is.close();
                }
            } catch (Exception e) {
                log.error("获取回调数据异常:" + e.getMessage());
            }
            return notifyData;
        }
    

    校验sign签名 工具类

    /**
         * 验证 签名sign
         *
         * @param xml
         * @param APPKEY 商户的app key
         * @return
         */
        public static boolean validateSign(String xml, String APPKEY) {
            SortedMap<String, String> stringStringMap = xmlToMap(xml);// 微信返回来的xml 参数是 已经按照字典序排序了
            String sign = stringStringMap.get("sign");
            if (StringUtils.isEmpty(sign)) {//签名为空
                return false;
            }
            String validSign = sign(stringStringMap, APPKEY);
            if (sign.equals(validSign)) {
                return true;
            }
            log.error("微信支付 签名错误");
            return false;
        }
    
    展开全文
  • Payment:支付回调统一处理

    万次阅读 2017-05-01 21:26:45
    则是进行回调相关的处理,它返回的值,是需要返回给第三方支付机构的,第三方机构通过返回值来识别商户是否正确处理了回调通知,并且以此来处理是否需要重发。 这里的重点就是 $callback ,注意看上面的代码 $...

    有20天没有更新了,主要原因有二:其一这期间对自己的职业规划做了一些调整;其二生了一场小病。所以大家一定要保重身体,平时得多锻炼锻炼了。

    根据大家反馈,大家对 Payment 还是很认同,这让我很开心。五一花了两天时间把招商一网通集成进来了。希望能够帮助到更多的人。


    Payment使用文档https://helei112g.github.io/categories/payment-3/

    项目GitHub地址https://github.com/helei112g/payment

    言归正传,这篇拖了很久了,借着五一假期的最后一天,搞定它!先上一个支付的一般流程图。

    image
    图片来源:支付宝

    异步与同步

    在我们完成支付后,要确认用户是否真的支付了这笔钱,以及这笔钱支付的金额是否符合预期。怎么知道这些事情呢?

    用户告诉我们?我们肯定不能确认是否真假。比较恰当的方式是,第三方(支付宝、微信、招商一网通等)收到用户付款后,他来告诉我们。所以这里就引出了通知这个概念。

    通知的方式又有两种:同步通知,异步通知。同步通知的概念存在于网站支付或者H5支付中,因为只有在浏览器中才可以通过url进行跳转。那么我们应该使用同步通知作为支付成功的依据还是使用异步通知呢?

    我的答案是:同步通知不做服务端的更新,可用于客户端的显示,异步收到通知时才做相关的更新处理。原因有三:

    1. 并不是所有的支付模块都有同步通知这个概念;
    2. 同步通知的参数在url中,就算采用https协议,也存在更大被篡改的风险;
    3. 异步通知提供完整的失败重发机制,更值得信耐。

    异步通知处理

    所以在 Payment 中只针对异步通知到达的数据进行了签名相关处理。下面我们来看看代码。

    不管你是支付宝的异步通知,还是微信的异步通知或者招商一网通的异步通知,Payment 都提供了统一的异步处理接口,并且调用者完全不必去关心如何验证签名,如何核实数据,只需要专注自己的业务逻辑即可。

    回调使用了一个开发的小技巧:依赖注入,我先上代码,后面稍微解释下。

    $callback = new TestNotify();
    
    $type = 'ali_charge';// ali_charge wx_charge  cmb_charge
    
    try {
        // 获取第三方的原始数据,未进行签名检查,根据自己需要决定是否需要该步骤
        //$retData = Notify::getNotifyData($type, $config);
    
        $ret = Notify::run($type, $config, $callback);// 处理回调,内部进行了签名检查
    } catch (PayException $e) {
        echo $e->errorMessage();
        exit;
    }
    
    return $ret;

    回调 的代码就这么简单,其中 Notify::getNotifyData($type, $config); 可以获取到第三方的回调数据,sdk仅仅是解析成数组返回,没有做签名检查,不能直接用来进行回调处理。

    Notify::run($type, $config, $callback); 则是进行回调相关的处理,它返回的值,是需要返回给第三方支付机构的,第三方机构通过返回值来识别商户是否正确处理了回调通知,并且以此来处理是否需要重发。

    这里的重点就是 $callback,注意看上面的代码 $callback = new TestNotify();

    大家的重点就是创建这个 TestNotify 这个类,我们就叫它:商户回调业务处理类,名字大家随便取,根据自己的需要。看一下我示例中 TestNotify.php 的内容

    use Payment\Notify\PayNotifyInterface;
    use Payment\Config;
    
    /**
     * 客户端需要继承该接口,并实现这个方法,在其中实现对应的业务逻辑
     * Class TestNotify
     * anthor helei
     */
    class TestNotify implements PayNotifyInterface
    {
        public function notifyProcess(array $data)
        {
            $channel = $data['channel'];
            if ($channel === Config::ALI_CHARGE) {// 支付宝支付
    
            } elseif ($channel === Config::WX_CHARGE) {// 微信支付
    
            } elseif ($channel === Config::CMB_CHARGE) {// 招商支付
    
            } elseif ($channel === Config::CMB_BIND) {// 招商签约
    
            } else {
                // 其它类型的通知
            }
    
            // 执行业务逻辑,成功后返回true
            return true;
        }
    }

    这里的核心就是,客户端创建的 商户回调业务处理类 一定要实现 PayNotifyInterface 这个接口,并且实现 notifyProcess 这个方法,在这个方法中完成自己的商户逻辑。然后根据处理结果返回布尔值。

    这里要重点说明的是 TestNotify::notifyProcess(array $data) 这个方法的参数 $data,它是通过sdk内部传过来的,它返回的信息与配置文件 return_raw的设置有关系。

    如果 return_raw = false 返回的是我映射的结果,这里需要小心,如果你的php报错级别设置的太高,可能会出现报错,因为内部有很多 Undefined index 错误,因为我并未进行检查,当前可能暂时也不打算修复这个问题。
    如果 return_raw = true 则返回的是第三方支付机构的原始数据。

    不管是设置成什么,该参数里边都有一个 channel 参数,大家可以根据这个参数区分回调属于那一个类别。像上面的示例一样。

    PayNotifyInterface 接口

    最近有很多人在微信中问我,干嘛一定要实现这个接口?我这里举个例子:
    你出去旅行,到了突然发现ios的手机充电线没带,怎么办?找个便利店买一根好了(因为附近没有苹果店),那么怎么买的充电线确保你手机可以用呢?这个很简单,因为苹果把自己充电线的接口标准公布了,凡事想造苹果手机充电线的按照这个标准造出来的,你都可以用。

    所以接口的作用就是制定一个标准;你们都实现我规定的接口,然后返回布尔值给我,我就可以处理了。至于内部你们想怎么做,是你们的事情。

    通过这个接口完全将签名与商户业务逻辑进行了分离,以后你的调整只围绕这一个类即可。当然这里涉及到的思想有 ioc/di ,这又是另外一个话题,空的时候我们聊聊。

    联系我

    我的微信公众号,欢迎订阅 icanfo

    现在这个公众号名字不太好,想名字真头痛。有谁可以给推荐一个?

    image

    展开全文
  • 1、服务器端使用TP3.2处理(随便写在一个Controller里面) /* 小程序报名,生成订单 */ public function make_order(){ if(IS_POST){ $data['openid'] = I('POST.openid'); $data_total = I('POST.data_total');...
  • 【微信支付】H5支付开发文档 b. Java 后端微信支付demo 引入jar包 <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> ...

    首先,参考文档:

    【微信支付】H5支付开发文档
    Java 后端微信支付demo

    1. 引入jar包
    		<dependency>
                <groupId>com.github.wxpay</groupId>
                <artifactId>wxpay-sdk</artifactId>
                <version>0.0.3</version>
            </dependency>
    
    1. 配置申请好的AppId,MchId, Key

    这里只需要统一下单、支付回调以及查询订单,所以不需要加载证书

    import com.github.wxpay.sdk.WXPayConfig;
    
    import java.io.InputStream;
    
    /** 配置我们自己的信息  */
    
    public class WxPayConfig implements WXPayConfig {
    
    //    /** 加载证书  这里证书需要到微信商户平台进行下载*/
    //    private byte [] certData;
    //
    //    public WxPayConfig() throws  Exception{
    //        InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("../cert/pay/apiclient_cert.p12");
    //        this.certData = IOUtils.toByteArray(certStream);
    //        certStream.close();
    //    }
    
        /** 设置我们自己的appid
         * 商户号
         * 秘钥
         * */
    
        @Override
        public String getAppID() {
            return "###AppId";
        }
    
        @Override
        public String getMchID() {
            return "###MchId";	
        }
    
        @Override
        public String getKey() {
            return "###Key";
        }
    
        @Override
        public InputStream getCertStream() {
            return null;
        }
    
        @Override
        public int getHttpConnectTimeoutMs() {
            return 0;
        }
    
        @Override
        public int getHttpReadTimeoutMs() {
            return 0;
        }
    }
    
    1. 统一下单接口示例:
     	// 微信支付下单
        @PreAuthorize("@el.check('anonymous')") // 匿名访问
        @PostMapping("/prePay")
        public ResponseEntity placeOrder(HttpServletRequest request, @RequestBody Map params) throws Exception {
    
            // 保存订单并返回订单号 shopOrderDTO.getId()
    
            // 处理请求参数
            WxPayConfig wxPayConfig = new WxPayConfig();
            WXPay wxPay = new WXPay(wxPayConfig);
            String url = "###公网地址";
            String notifyUrl = url + "/payReturn";	// 微信支付回调地址,详情参考微信官方文档要求
    
            Map<String,String> data = new HashMap<>();
            data.put("out_trade_no", shopOrderDTO.getId()+"");   //订单编号
            data.put("total_fee",params.get("total_free").toString());   //金额(单位为分) int
            data.put("attach", new JSONObject().toJSONString(attach));  //附加数据:{nums:1, device_id:"0x234143", store_id:10000000}
    
            data.put("appid",wxPayConfig.getAppID());
            data.put("mch_id",wxPayConfig.getMchID());
            data.put("trade_type","MWEB");	// h5支付固定写法
            data.put("device_info","WEB"); // h5支付固定写法
            data.put("notify_url",notifyUrl);
            data.put("spbill_create_ip", IPUtil.getIPAddress(request));
            data.put("fee_type","CNY");
            data.put("body","###支付信息描述");
            data.put("nonce_str", WXPayUtil.generateNonceStr()); 
            data.put("scene_info", "###参考官方文档");
            // 生成签名
            String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
            data.put("sign",s);
    
            // 发起下单请求
            Map<String, String> respData = wxPay.unifiedOrder(data);
    
            // 处理下单结果
            if (respData.get("return_code").equals("SUCCESS")){
                if (respData.get("result_code").equals("SUCCESS")) {
                    respData.put("out_trade_no", shopOrderDTO.getId()+"");
                    return new ResponseEntity<>(respData, HttpStatus.OK);
                } else {
                    // 下单失败的处理 如保存日志
                    throw new Exception(respData.get("err_code_des"));
                }
            } else {
            	// 下单失败的处理 如保存日志
                throw new Exception(respData.get("return_msg"));
            }
    
        }
    
    1. 支付回调接口
        // 微信支付回调
        @PreAuthorize("@el.check('anonymous')")
        @RequestMapping("/payReturn")
        public String payReturn(HttpServletRequest request, HttpServletResponse response) throws Exception {
            // logger.info("微信支付回调:");
    
            WxPayConfig wxPayConfig = new WxPayConfig();
            WXPay wxPay = new WXPay(wxPayConfig);
    
            // 接收请求参数
            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 xml = new String(outSteam.toByteArray(), "utf-8");
            // 转为Map
            Map<String, String> params = WXPayUtil.xmlToMap(xml);
            outSteam.close();
            inStream.close();
    
            // 验证签名
            if (wxPay.isResponseSignatureValid(params)) { 
    
                if (params.get("return_code").equals("FAIL")) {
    
                    shopLogService.anonymousCreate(shopLogService.getShopLog(null, null, "支付发起失败",params.get("return_msg") + "" ));
    
                } else if (params.get("return_code").equals("SUCCESS")){
    
                    if (params.get("result_code").equals("FAIL")) {
    
                        // 支付失败
    
                    } else if (params.get("result_code").equals("SUCCESS")) {
    
                        // 查询订单,将支付返回结果与订单保存信息对比
                        ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(params.get("out_trade_no")));	
    
    					// 判断金额、订单支付状态、支付结果
                        if (orderDTO.getAmount() == Integer.valueOf(params.get("total_fee")) && orderDTO.getState() == 1
                                && !StringUtils.isBlank(params.get("transaction_id"))) {
    
                            // 修改订单状态为已支付 省略
                            
                            return "<xml>\n" +
                                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                                    "</xml>";
    
                        } else if (StringUtils.isBlank(params.get("transaction_id"))){
                            // 支付ID为空
                        } else if (orderDTO.getState() == 0){
                            // 订单状态为已支付
                        } else if (orderDTO.getAmount() != Integer.valueOf(params.get("total_fee"))){
                            // 支付金额与订单金额不相等
                        }
                    }
                }
            }
            return "";
        }
    
    
    1. 查询订单接口
        // 微信支付查询 参数是订单id
        @PreAuthorize("@el.check('anonymous')")
        @RequestMapping("/paySearch")
        public Map paySearch(String id) throws Exception {
    		
    		// 查询订单
            ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(id));
    
    		// 如果订单已支付且支付id不为空,可以直接返回结果
            if (orderDTO.getState() == 0 && !StringUtils.isBlank(orderDTO.getPayId())) {
                Map<String, String> result = new HashMap<>();
                result.put("return_code", "SUCCESS");
                result.put("result_code", "SUCCESS");
                result.put("trade_state", "SUCCESS");
                return result;
            } else {
            	// 处理参数
                WxPayConfig wxPayConfig = new WxPayConfig();
                WXPay wxPay = new WXPay(wxPayConfig);
                Map<String,String> data = new HashMap<>();
                data.put("out_trade_no", id);   //订单编号
                data.put("appid",wxPayConfig.getAppID());
                data.put("mch_id",wxPayConfig.getMchID());
                data.put("nonce_str", WXPayUtil.generateNonceStr()); 
                // 签名
                String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
                data.put("sign",s);
                // 发起查询
                Map<String, String> result = wxPay.orderQuery(data);
    			
    			// 如果用户已支付
                if (result.get("return_code").equals("SUCCESS") && result.get("result_code").equals("SUCCESS") && result.get("trade_state").equals("SUCCESS")) {
                    // 修改订单支付状态和支付id
                }
                return result;
            }
        }
    
    展开全文
  • 第三方支付平台支付接口及回调接口开发 作为开放式的B/S架构程序,无论所属电商,金融,机械制造,企业OA,ERP,CRM,CMS等等行业或系统中,第三方支付以及银联支付的业务一定是客户关心所在,也是...
  • 前段时间在工作中又一次接触到了公司关于支付相关的业务领域,于是又一次重新回顾了工作中使用的支付框架。之前写过的很多篇文章都是先介绍整体背景,再深入到每一点去做分析,今天打算换种方式,尝试...
  • 注意:进行异步回调时一定要确认消息是否来自支付宝 public void payCompent(String out_trade_no, String trade_status, HttpServletRequest request, HttpServletResponse response) { ...
  • 这里我是把微信里的回调dome 拿出来重写了一下, 在配置回调地址的时候,要确定你的回调链接地址一定要能够访问,  里面注释的比较多- -是我自己测试用的 也可以拿来作为参考,  配合上面一篇我写的统一下单...
  • 3.支付回调统一处理

    千次阅读 2016-07-29 23:23:13
    在支付宝、微信支付sdk接入的过程中,处理支付回调、退款回调等操作一直让人头痛。Payment通过依赖注入的方式将业务与支付回调行为进行分离。切底让客户端专注业务。简单方便的跳用。
  • 踩坑: 微信小程序支付流程(统一下单, 支付回调)

    万次阅读 多人点赞 2018-07-30 16:15:55
    众所周知,微信小程序目前只能使用微信支付,而且微信小程序支付相对于app支付,h5支付都要简单一些,但是该支付文档对java这语言是非常不友好的,居然没有demo,网上虽说有很多博客,但是找了好多都是跑不通,乱七八糟的很...
  • 回调地址链接是通过【统一下单API】中提交的参数notify_url设置, 如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。 示例:notify_url:...
  • 微信支付回调通知实现

    千次阅读 2021-01-13 20:05:47
    } } 二 支付回调 1 回调方法 该链接是通过【统一下单API】中提交的参数notify_url设置,如果链接无法访问,商户将无法接收到微信通知。 参考文档:...
  • PHP 支付宝小程序 支付以及回调处理

    千次阅读 2019-07-26 09:31:13
    PHP 支付宝小程序 支付以及回调处理一、去支付宝官网下载对应的PHP SDK二、 在服务端调用 alipay.trade.create (统一收单交易创建接口),获得支付宝交易号 tradeNO首先加载支付宝的系统参数,以及基础的配置第二步...
  • 需求: 安卓,ios端集成微信支付,PHPer(我)要提供一个接口给微信调用,(支付完成后调用),如果成功,就返回success,如果失败就返回fail, 环境说明:thinkphp 框架开发, 微信的接口说明文档:...
  • Java微信支付-支付成功异步回调验签

    千次阅读 2019-10-12 12:08:00
    接上一篇Java微信支付-统一下单API,本篇在上篇文章的基础上讲述统一下单支付成功之后微信异步回调通知 在调用微信支付-统一下单API时,会传递notify_url这个参数给微信,这个参数是用户成功支付之后微信端会向此...
  • APP微信支付(java后台_统一下单和回调

    万次阅读 多人点赞 2018-03-24 22:23:04
    方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", ...
  • 微信和支付宝移动端调起客户端支付回调刷新页面的问题
  • 微信支付方式有很多,在公众号开发中比较常用的就是用JSAPI进行支付处理,方便快捷,官网提供的有sdk,接入方面比较简单,不做说明,或有时间了再整理吧,着重总结下在处理支付结果通知的方面遇到的恶心问题。...
  • 框架本身的支付接口没有做完全,用户在PC端用微信二维码支付后因为没有回调函数,无法判断是否成功。 这样就带来了一系列问题,比如我要设置赠送优惠券,因为这个无法判断是否支付成功了,所以优惠券不能自动赠送...
  • 03支付回调逻辑处理

    2020-03-10 22:40:49
    3.支付回调逻辑处理 3.1 需求分析 在完成支付后,修改订单状态为已支付,并记录订单日志。 3.2 实现思路 (1)接受微信支付平台的回调信息(xml) <xml><appid><![CDATA[wx8397f8696b538317]]><...
  • 1、微信公众号、微信小程序开发过程中,第三方服务器与微信服务器数据交互,需要进行数据转换,必须用到这两个函数: 分别是xml_to_array、array_to_xml ; (此图片来源于网络,如有侵权,请联系删除!...
  • 微信支付接口--支付成功的回调--超详细Demo

    万次阅读 多人点赞 2018-07-30 16:56:52
    写微信支付成功回调的代码,尤其要注意官方文档的一句话: 如果不注意这里,支付成功后微信会一直对这个地址进行调用,更新订单的对数据库进行操作,也会一直存在更新:...
  • java 微信支付异步回调接口

    千次阅读 2019-07-08 10:51:22
    1.微信支付异步回调接口 @SuppressWarnings("static-access") @RequestMapping("callback") @ResponseBody public Object callback(HttpServletRequest request,HttpServletResponse response) throws Exception...
  • public function returnpay(){ // 获取微信回调的数据  $notifiedData = file_get_contents('php://input');  //XML格式转换  $xmlObj = simplexml_load_string($notifiedData, 'SimpleXMLElement', LIBXM...
  • ... 遇到的问题: 1.支付成功后,微信没有请求(没有进到)配置的回调接口; 2.请求接口后,接口里未获取到...问题1详细描述:在统一生成订单接口中配置的回调地址(notify_url),外网可直接访问且能访问成功,服...
  • 一、引言 上篇文章中,讲解并且实现微信支付,既然微信下单成功了,那我们怎么知道用户有没有付款呢?...那么这里微信首先会:异步回调通知商户系统 —— 商户系统调用SDK中异步回调处理的方法 —— 商户系统拿到S...
  • 微信支付所需的条件配置已经完成,接下来就开始实现(以下仅供参考) 一,实现准备 ①,阅读官方支付文档,主要是业务流程这一点https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4 ②,官方demo下载...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,908
精华内容 6,363
关键字:

统一支付回调