微信支付_微信支付流程 - CSDN
微信支付 订阅
微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程。微信支付以绑定银行卡的快捷支付为基础,向用户提供安全、快捷、高效的支付服务。 [1]  自2017年11月23日起,微信支付服务功能在中国铁路客户服务中心12306网站上线运行。 [2]  2018年4月1日,消费者在使用微信钱包扫描静态条码支付时,单日使用零钱包支付的上限不超过500元,同时微信关联的所有银行卡还可以再独立获得500元的支付上限。 [3]  2018年3月,车牌=付款码,微信直接推出“高速e行”。 [4]  2018年6月29日,微信支付与米其林指南在广州宣布达成战略合作。 [5]  2020年2月,微信支付取得了尼泊尔央行的运营牌照。 [6] 展开全文
微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程。微信支付以绑定银行卡的快捷支付为基础,向用户提供安全、快捷、高效的支付服务。 [1]  自2017年11月23日起,微信支付服务功能在中国铁路客户服务中心12306网站上线运行。 [2]  2018年4月1日,消费者在使用微信钱包扫描静态条码支付时,单日使用零钱包支付的上限不超过500元,同时微信关联的所有银行卡还可以再独立获得500元的支付上限。 [3]  2018年3月,车牌=付款码,微信直接推出“高速e行”。 [4]  2018年6月29日,微信支付与米其林指南在广州宣布达成战略合作。 [5]  2020年2月,微信支付取得了尼泊尔央行的运营牌照。 [6]
信息
发布时间
2013年8月5日
所属企业
腾讯
平    台
微信第三方平台
所属用户
微信app使用者
中文名
微信支付
注册用户
8亿(2017年12月) [7]
支持系统
IOS,安卓
外文名
WeChat Pay
微信支付发展历程
2013年8月5日,财付通与微信合作推出微信支付。 [8]  微信支付正式上线。 [9]  2014年1月4日,滴滴打车接入微信支付,3天突破10万单。 [10]  2014年1月27日,微信正式推出微信红包,并迅速流行开来。 [8]  2014年08月28日,智慧生活全行业解决方案正式公布。 [11]  2015年02月18日,开创春晚红包,10.1亿次收发创新了春节全民红包互动的新高潮。 [12]  2015年05月,零钱用户突破3亿。 [12]  2016年01月,微信支付接入线下门店超30万家。 [13]  2016年08月8日,提出“无现金生活”理念,打造全球首个移动支付节日“无现金日”,倡导低碳、高效的生活方式。 [14]  2018年6月29日,微信支付与米其林指南在广州宣布达成战略合作。 [5]  2018年10月1日起,微信香港钱包正式为香港用户提供内地移动支付服务。用户于内地商户消费时,微信香港钱包会将所需支付的人民币金额,自动换算为对应的港币金额。服务推广期间,用户使用微信香港钱包在内地商户消费,无需支付手续费。 [15]  2019年10月,微信支付钱包入口上线银行储蓄(仅部分用户可见)服务,点击银行储蓄可跳转至工商银行存款产品。用户同意“工商银行定存相关协议”可免费开通工商银行存款账户,选择存入存款,三年期利率3.85%,随时可取,并且不需要跳转到工商银行就可以操作。 [16]  2019年5月,尼泊尔中央银行出台一项命令:在尼境内使用支付宝支付、微信支付及跨境POS机等国际支付系统(获得尼官方授权的除外)的行为是非法的,有关人员将会根据有关法令受到惩处。2020年2月上旬,微信支付取得了尼泊尔央行的运营牌照。 [6] 
收起全文
精华内容
参与话题
  • 微信支付全部详细流程

    万次阅读 2018-07-09 01:53:45
    微信支付时序图 官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_51、什么是时序图 是一种UML交互图,描述了对象之间传递消息的时间顺序, 用来表示用例中的行为顺序, 是强调消息时间顺序...



    微信支付时序图 官方文档:

    https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

    1、什么是时序图
    是一种UML交互图,描述了对象之间传递消息的时间顺序, 用来表示用例中的行为顺序, 是强调消息时间顺序的交互图;
    通俗解释:就是交互流程图 (把大象装冰箱分几步)
    2、时序图包括四个元素 对象(Object), 生命线(Lifeline), 激活(Activation), 消息(Message);
    对象:时序图中的对象在交互中扮演的角色就是对象,使用矩形将对象名称包含起来, 名称下有下划线
    生命线:生命线是一条垂直的虚线, 这条虚线表示对象的存在, 在时序图中, 每个对象都有生命线
    激活:代表时序图中对象执行一项操作的时期, 表示该对象被占用以完成某个任务,当对象处于激活时期, 生命线可以拓宽为矩形
    消息:对象之间的交互是通过相互发消息来实现的,箭头上面标出消息名,一个对象可以请求(要求)另一个对象做某件事件
    消息从源对象指向目标对象,消息一旦发送便将控制从源对象转移到目标对象,息的阅读顺序是严格自上而下的
    消息交互中的实线:请求消息
    消息交互中的虚线:响应返回消息
    自己调用自己的方法:反身消息

    参考:https://www.cnblogs.com/langtianya/p/3825764.html

    统一下单接口介绍:

    商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。

    2、微信支付订单接口开发之订单增删改查
    简介: 微信扫码支付之统一下单接口开发之订单增删改查

    1、Dao层VideoOrder增删改查开发
    @Insert("")
    @Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id")   //keyProperty java对象的属性;keyColumn表示数据库的字段
    int insert(VideoOrder order);
     
    @Select("SELECT * FROM video_order WHERE id = #{id}")
    VideoOrder findById(int id);


    @Select("SELECT * FROM video_order WHERE id = #{id}")
    VideoOrder findByOutTradeNo(String  outTradeNo);


    @Delete("DELETE FROM video_order WHERE id =#{id}")

     int delete(int  id);

    3、微信统一下单接口开发之CommonUtils和WXpayUtils开发
    简介:封装常用工具类CommonUtils和WXpayUtils


    从微信开发者文档获取部分代码 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1


    1、CommonUtils包含方法 md5,uuid等
    //生成 uuid, 即用来标识一笔单,也用做 nonce_str
    public static String generateUUID() {
    return UUID.randomUUID().toString().replaceAll("-", "")
    .substring(0, 32);
    }


    //MD5工具类
    public static String MD5(String data)  {
    try {
    java.security.MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] array = md.digest(data.getBytes("UTF-8"));
    StringBuilder sb = new StringBuilder();
    for (byte item : array) {
    sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
    }
    return sb.toString().toUpperCase();
    } catch (Exception exception) {
    }
    return null;


    }


    2、WXPayUtil包含方法 xmlToMap,mapToXml,createSign,isCorrectPaySign


    4、微信支付Controller下单API接口开发
    简介:讲解下单接口开发,开发技巧和支付配置文件设置


    1、开发controller,开发期间不加入拦截器登录校验
    2、iputils工具类介绍
    3、加入微信支付配置
    #微信商户平台
    wxpay.mer_id=1503808832
    wxpay.key=xdclasss20182018xdclass2018x018d

    wxpay.callback=16web.tunnel.qydev.com/pub/api/v1/wechat/order/callback1

    5.签名测试结果



    XML源串

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>

    <xml>
    <appid>wxt89583oxy157pv6e</appid>
    <body>SpringBoot+Maven整合Websocket课程</body>
    <mch_id>0747785655</mch_id>
    <nonce_str>bd215711233047ba98089bd7d26e8532</nonce_str>
    <notify_url>http://qcsell.natapp1.cc/api/v1/wechat/order/callback</notify_url>

    <out_trade_no>56c0a8ae122b4b7da8f74628534a6108</out_trade_no>

    ---------------------------------------------------------------------------

    商户Key:k66z0230Vf5K22Qj70Q3U8R5460930F1


    6 调用微信统一下单接口,发送post请求,并获取响应转成map,获取交易会话的二维码链接code_url。


    1、配置统一下单接口
    2、发送请求验证
    微信统一下单响应
    <xml><return_code><![CDATA[SUCCESS]]></return_code>
    <return_msg><![CDATA[OK]]></return_msg>
    <appid><![CDATA[wx5beac15ca207c40c]]></appid>
    <mch_id><![CDATA[1503809911]]></mch_id>
    <nonce_str><![CDATA[Go5gDC2CYL5HvizG]]></nonce_str>
    <sign><![CDATA[BC62592B9A94F5C914FAAD93ADE7662B]]></sign>
    <result_code><![CDATA[SUCCESS]]></result_code>
    <prepay_id><![CDATA[wx262207318328044f75c9ebec2216783076]]></prepay_id>
    <trade_type><![CDATA[NATIVE]]></trade_type>
    <code_url><![CDATA[weixin://wxpay/bizpayurl?pr=hFq9fX6]]></code_url>
    </xml>
    3、获取code_url


    遇到问题,根据错误码解决

    https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1


    7谷歌二维码工具生成扫一扫支付二维码
    简介:使用谷歌二维码工具根据code_url生成扫一扫支付二维码

    1、生成二维码返回页端


    加入依赖
    <!-- google二维码生成包 -->
    <dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>javase</artifactId>
       <version>3.3.0</version>
    </dependency>

    <dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>core</artifactId>
       <version>2.0</version>
    </dependency>

    2、使用微信扫码完成支付
    参考资料:https://blog.csdn.net/shenfuli/article/details/68923393
    https://www.cnblogs.com/lanxiamo/p/6293580.html

    二维码知识:https://coolshell.cn/articles/10590.html

    简介:使用Ngrock本地接收微信回调,并开发回调接口

    文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3


      1 、开发支付回调接口


      //读取回调输入流   
          StringBuffer sb = new StringBuffer();    
          InputStream inputStream = request.getInputStream();    
          String line ;    
          BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));    
          while ((line = in.readLine()) != null){    
              sb.append(line);  
          }  
          in.close();  
          inputStream.close();  
          
          //解析xml成map    
          //{transaction_id=4200000141201805266700247361, nonce_str=cbb67accd8044c9ea48f3318b99d88e4, bank_type=CFT, openid=oiNKG03vVY4PHlGUEwT-ztFo8K8Y, sign=0575804DBE4E9FFF6545046FA062BC4C, fee_type=CNY, mch_id=1503809911, cash_fee=1, out_trade_no=78902e694bab485b8e7745b61e05dbfe, appid=wx5beac15ca207c40c, total_fee=1, trade_type=NATIVE, result_code=SUCCESS, time_end=20180526162759, is_subscribe=Y, return_code=SUCCESS}
          Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());    
            
          //获取有序map    
          SortedMap<String, String> sortedMap = CommonUtil.getSortedMap(callbackMap) ;  




          回调数据:
          <xml><appid><![CDATA[wx5beac15ca207c40c]]></appid><bank_type><![CDATA[CFT]]></bank_type><cash_fee><![CDATA[10]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[1503809911]]></mch_id><nonce_str><![CDATA[de019d5f1e5d40649cd76de33f18b13e]]></nonce_str><openid><![CDATA[oiNKG03vVY4PHlGUEwT-ztFo8K8Y]]></openid><out_trade_no><![CDATA[4d8cea4a916440368583edaf82488624]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[FA799B7DF70C2BAC558E839E01EF341A]]></sign><time_end><![CDATA[20180626230347]]></time_end><total_fee>10</total_fee><trade_type><![CDATA[NATIVE]]></trade_type><transaction_id><![CDATA[4200000142201806264038572903]]></transaction_id></xml>


          转成map:
          {transaction_id=4200000142201806264038572903, nonce_str=de019d5f1e5d40649cd76de33f18b13e, bank_type=CFT, openid=oiNKG03vVY4PHlGUEwT-ztFo8K8Y, sign=FA799B7DF70C2BAC558E839E01EF341A, fee_type=CNY, mch_id=1503809911, cash_fee=10, out_trade_no=4d8cea4a916440368583edaf82488624, appid=wx5beac15ca207c40c, total_fee=10, trade_type=NATIVE, result_code=SUCCESS, time_end=20180626230347, is_subscribe=Y, return_code=SUCCESS}
           
         
       2、注意点:
       
        回调要用post方式,微信文档没有写回调的通知方式
        可以用这个注解 @RequestMapping


        问题:一定要看日志


    14、微信回调处理之更新订单状态和幂等性讲解
    简介:微信支付回调处理之更新订单状态和讲解什么是接口的幂等性
    微信回调通知规则(通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)


    幂等性: 同样的参数和值,不管调用你的接口多少次,响应结果都和调用一次是一样的
     
    1、校验签名是否正确,防止伪造回调

    2、查询订单是否已经更新


    3、若没更新则更新订单状态


    4、回应微信,SUCCESS 或者 FAIL 
           response.setContentType("text/xml");        
           response.getWriter().println("success");




















    15、微信支付之下单事务处理
    简介:讲解下单接口增加事务和常见的事务选择
    1、springboot开启事务,启动类里面增加 @EnableTransactionManagement
    2、需要事务的方法上加 @Transactional(propagation = Propagation.REQUIRED)
    3、aop的管理事务的好处和选择
    增,删,改  开启事务

    XML源串
    展开全文
  • 微信支付接口--支付成功的回调--超详细Demo

    万次阅读 多人点赞 2019-03-20 17:52:52
    微信支付成功回调的代码,尤其要注意官方文档的一句话: 如果不注意这里,支付成功后微信会一直对这个地址进行调用,更新订单的对数据库进行操作,也会一直存在更新:...

    如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人。谢谢大家!❤

    如果解决不了,可以在文末进群交流。

    写微信支付成功回调的代码,尤其要注意官方文档的一句话:

    如果不注意这里,支付成功后微信会一直对这个地址进行调用,更新订单的对数据库进行操作,也会一直存在更新:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7.

    这其实不是坑的主要所在,问题是这个文档,我真的不知道该如何吐槽。一次偶然的意外才看到。这个文档说明。


    好了,其他的没有什么需要特别注意的,直接上代码:

    <?php   
        //获取接口数据,如果$_REQUEST拿不到数据,则使用file_get_contents函数获取
        $post = $_REQUEST;
        if ($post == null) {
            $post = file_get_contents("php://input");
        }
    
        if ($post == null) {
            $post = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
        }
    
        if (empty($post) || $post == null || $post == '') {
            //阻止微信接口反复回调接口  文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
            $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';  
            echo $str;
            exit('Notify 非法回调');
        }
    
        /*****************微信回调返回数据样例*******************
         $post = '<xml>
            <return_code><![CDATA[SUCCESS]]></return_code>
            <return_msg><![CDATA[OK]]></return_msg>
            <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
            <mch_id><![CDATA[10000100]]></mch_id>
            <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
            <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
            <result_code><![CDATA[SUCCESS]]></result_code>
            <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
            <trade_type><![CDATA[APP]]></trade_type>
            </xml>';
         *************************微信回调返回*****************/
    
        libxml_disable_entity_loader(true); //禁止引用外部xml实体
    
        $xml = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组
        
        $post_data = (array)$xml;
        
        /** 解析出来的数组
            *Array
            * (
            * [appid] => wx1c870c0145984d30
            * [bank_type] => CFT
            * [cash_fee] => 100
            * [fee_type] => CNY
            * [is_subscribe] => N
            * [mch_id] => 1297210301
            * [nonce_str] => gkq1x5fxejqo5lz5eua50gg4c4la18vy
            * [openid] => olSGW5BBvfep9UhlU40VFIQlcvZ0
            * [out_trade_no] => fangchan_588796
            * [result_code] => SUCCESS
            * [return_code] => SUCCESS
            * [sign] => F6890323B0A6A3765510D152D9420EAC
            * [time_end] => 20180626170839
            * [total_fee] => 100
            * [trade_type] => JSAPI
            * [transaction_id] => 4200000134201806265483331660
            * )
        **/
        //订单号
        $out_trade_no = isset($post_data['out_trade_no']) && !empty($post_data['out_trade_no']) ? $post_data['out_trade_no'] : 0;
    
        //查询订单信息
        $order_info = DB::fetch_first("SELECT * FROM order WHERE order_no = '" .$out_trade_no."'");
    
    
        if(count($order_info) > 0){
            //查询平台信息
            $platform_info = DB::fetch_first("SELECT * FROM pingtaiInfo WHERE `open_pid`= {$order_info['part1']}");
    
            //平台支付key
            $wxpay_key = $platform_info['zhifu_key'];
    
            //接收到的签名
            $post_sign = $post_data['sign'];
            unset($post_data['sign']);
    
            //重新生成签名
            $newSign = MakeSign($post_data,$wxpay_key);
    
            //签名统一,则更新数据库
            if($post_sign == $newSign){
    
                $updateData = array();  
                $updateData['pay_time'] = TIMESTAMP; //支付时间
                $updateData['order_status'] = 2; //订单状态
    
                //更新order数据库
                //Do what you want...
            }
        }
    
        //阻止微信接口反复回调接口  文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
        $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';  
        echo $str;
    
        function MakeSign($params,$key){
            //签名步骤一:按字典序排序数组参数
            ksort($params);
            $string = ToUrlParams($params);  //参数进行拼接key=value&k=v
            //签名步骤二:在string后加入KEY
            $string = $string . "&key=".$key;
            //签名步骤三:MD5加密
            $string = md5($string);
            //签名步骤四:所有字符转为大写
            $result = strtoupper($string);
            return $result;
        }
    
        function ToUrlParams( $params ){
            $string = '';
            if( !empty($params) ){
                $array = array();
                foreach( $params as $key => $value ){
                    $array[] = $key.'='.$value;
                }
                $string = implode("&",$array);
            }
            return $string;
        }

     

    废话不多说了,直接上代码,不懂地方可留言,或者进微信群内交流。群二维码如果过期,请加我微信:mengyilingjian.

    展开全文
  • 微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程。微信支付以绑定银行卡的快捷支付为基础,向用户提供安全、快捷、高效的支付服务。 公众号支付 APP支付 扫码支付 刷卡支付 H5支付 ...

    微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程。微信支付以绑定银行卡的快捷支付为基础,向用户提供安全、快捷、高效的支付服务。

    • 公众号支付
    • APP支付
    • 扫码支付
    • 刷卡支付
    • H5支付
    • 小程序支付

    (本文档主要介绍公众号支付和扫码支付)

    注:微信公众号目前必须是服务认证号,且开通微信支付功能。公众号对应的商户号也必须开通支付功能。

    一、公众号支付

    公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

    • 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
    • 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付
    • 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

    1.  设置JSSDK接口调用域名

    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。  

    2.  设置授权域名

    开发公众号支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。如下图:

     

    3.  设置支付目录

    请确保实际支付时的请求目录与后台配置的目录一致,否则将无法成功唤起微信支付。

      在微信商户平台(pay.weixin.qq.com)设置您的公众号支付支付目录,设置路径:商户平台-->产品中心-->开发配置,如下图所示。公众号支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

    注意:这三个地方的域名需使用字母、数字及“-”的组合,不支持IP地址、端口号及短链域名,且填写的域名须通过ICP备案的验证。

    4.   设置支付密钥app_key

    点击帐户中心——API安全——设置API密钥(用于支付是的验签)

    5.   获取openid

      由于openid必须为当前用户在当前支付公众号内的身份标识,所以在智慧校园项目中采取实时获取的方式获得。

      步骤一:用户同意授权,获取code

      访问以下链接获得带code参数的Url:

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

      参数说明

    参数

    是否必须

    说明

    appid

    公众号的唯一标识

    redirect_uri

    授权后重定向的回调链接地址,请使用urlencode对链接进行处理

    response_type

    返回类型,请填写code

    scope

    应用授权作用域,snsapi_base(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)

    state

    重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节

    #wechat_redirect

    无论直接打开还是做页面302重定向时候,必须带此参数

    注:回调链接一定要urlencode,不然识别不出

      步骤二:通过code换取网页授权access_token

      首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

      获取code后,请求以下链接获取access_token:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

      参数说明

    参数

    是否必须

    说明

    appid

    公众号的唯一标识

    secret

    公众号的appsecret

    code

    填写第一步获取的code参数

    grant_type

    填写为authorization_code

      返回JSON数据包如下:

    复制代码

    {
       "access_token":"ACCESS_TOKEN",
       "expires_in":7200,
       "refresh_token":"REFRESH_TOKEN",
       "openid":"OPENID",
       "scope":"SCOPE",
       "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" 
    }

    复制代码

      附:关于网页授权access_token和普通access_token的区别

      1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

      2、其他微信接口,如发微信消息接口,需要通过基础支持中的“获取access_token”接口(https://api.weixin.qq.com/cgi-bin/token)来获取到的普通access_token调用。

    -----------------------------上述5个步骤都为支付的准备步骤。-----------------------------

      支付业务流程及步骤如下图:

     

    6.   微信内H5调起支付

      步骤一:后台统一下单获取jsapi支付参数

      请求地址:https://api.mch.weixin.qq.com/pay/unifiedorder

      请求参数:   appid(公众账号ID),

    mch_id(商户号),

    device_info(设备号),

    nonce_str(随机字符串),

    sign(签名),

    sign_type(签名类型),

    body(商品描述) ,

    detail(商品详情),

    attach(附加数据),

    out_trade_no(商户订单号),

    fee_type(标价币种),

    total_fee(标价金额),

    spbill_create_ip(终端IP),

    time_start(交易起始时间),

    time_expire(交易结束时间),

    notify_url(支付回调地址),

    trade_type(交易类型),

    product_id(商品ID),

    opened(用户标识)

       注:参数值用XML转义即可,CDATA标签用于说明数据不被XML解析器解析。

       具体下单过程可参照微信支付Demo:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

      当请求成功,返回的XML中return_code 和result_code都为SUCCESS时会返回如下:

    复制代码

    <xml>
       <return_code><![CDATA[SUCCESS]]></return_code>
       <return_msg><![CDATA[OK]]></return_msg>
       <appid><![CDATA[wx3556f3b4523gf12r]]></appid>
       <mch_id><![CDATA[10000100]]></mch_id>
       <nonce_str><![CDATA[jfjsdh47fin0jdnv]]></nonce_str>
       <openid><![CDATA[oECxywCpJW8G-ktn3lwZ7MR4Cx2Q]]></openid>
       <sign><![CDATA[8SDVCNKDF89W32SDKCSAA0S32JKSDJJL]]></sign>
       <result_code><![CDATA[SUCCESS]]></result_code>
       <prepay_id><![CDATA[wx201801041172356eidnvnd9qk398324745]]></prepay_id>
       <trade_type><![CDATA[JSAPI]]></trade_type>
    </xml>

    复制代码

      步骤二:H5发起微信支付

      在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。

      注意:WeixinJSBridge内置对象在其他浏览器中无效,参数名区分大小,大小写错误签名验证会失败。

    引用js:http://res.wx.qq.com/open/js/jweixin-1.0.0.js

      调用支付js如下:

    复制代码

    function onBridgeReady(){
       WeixinJSBridge.invoke(
           'getBrandWCPayRequest', {
               "appId":"wx2421b1c4370ec43b",     //公众号名称,由商户传入     
               "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
               "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
               "package":"prepay_id=u802345jgfjsdfgsdg888",     
               "signType":"MD5",         //微信签名方式:     
               "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
           },
           function(res){     
               if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
           }
       ); 
    }
    if (typeof WeixinJSBridge == "undefined"){
       if( document.addEventListener ){
           document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
       }else if (document.attachEvent){
           document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
           document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
       }
    }else{
       onBridgeReady();
    }

    复制代码

      支付完成后,微信会将订单参数会以XML方式发送给商户系统回调地址,商户在回调地址接收参数并做相应处理。

      回调的XML格式为:

    复制代码

    <xml>
      <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
      <attach><![CDATA[支付测试]]></attach>
      <bank_type><![CDATA[CFT]]></bank_type>
      <fee_type><![CDATA[CNY]]></fee_type>
      <is_subscribe><![CDATA[Y]]></is_subscribe>
      <mch_id><![CDATA[10000100]]></mch_id>
      <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
      <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
      <out_trade_no><![CDATA[1409811653]]></out_trade_no>
      <result_code><![CDATA[SUCCESS]]></result_code>
      <return_code><![CDATA[SUCCESS]]></return_code>
      <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
      <sub_mch_id><![CDATA[10000100]]></sub_mch_id>
      <time_end><![CDATA[20140903131540]]></time_end>
      <total_fee>1</total_fee>
      <trade_type><![CDATA[JSAPI]]></trade_type>
      <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
    </xml>

    复制代码

    推荐技术文档:

    1.https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

    2.https://wenku.baidu.com/view/cebde8a764ce0508763231126edb6f1aff007185.html?re=view

     

    二、扫码支付

      扫码支付可分为两种模式,商户根据支付场景选择相应模式。

      【模式一】:

      商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。

      商户支付回调URL设置指引:进入商户平台-->产品中心-->开发配置,进行配置和修改,如下图所示。

      【模式二】:

      商户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付,不依赖设置的回调支付URL。

      流程图:

      

      业务流程说明:

    (1)商户后台系统根据用户选购的商品生成订单。

    (2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;

    (3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。

    (4)商户后台系统根据返回的code_url生成二维码。

    (5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。

    (6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。

    (7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。

    (8)微信支付系统根据用户授权完成支付交易。

    (9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。

    (10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。

    (11)未收到支付通知的情况,商户后台系统调用【查询订单API】。

    (12)商户确认订单已支付后给用户发货。

      附:

      前端页面代码:

    //前端页面
    <img src=" MakeQRCode?code_url=@code_url" alt="二维码"/>

       C#生成二维码后台代码:

    复制代码

        //生成二维码方法  
         public FileResult MakeQRCode(string code_url)
            {
                if (string.IsNullOrEmpty(code_url))
                    throw new ArgumentException("code_url");
                //初始化二维码生成工具
                QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
                qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
                qrCodeEncoder.QRCodeVersion = 0;
                qrCodeEncoder.QRCodeScale = 4;
                //将字符串生成二维码图片
                Bitmap image = qrCodeEncoder.Encode(code_url, Encoding.Default);
                //保存为PNG到内存流  
                MemoryStream ms = new MemoryStream();
                image.Save(ms, ImageFormat.Jpeg);
                return File(ms.ToArray(), "image/jpeg");
            }

    复制代码

      推荐技术文档:

    1. https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1
    2. http://www.cnblogs.com/vinsonLu/p/5166214.html
    展开全文
  • JAVA实现微信支付功能

    万次阅读 热门讨论 2019-02-28 09:12:30
    这两天,需要接入微信支付功能。由于我是公众号开发,因此,我选择的微信支付方式是JSAPI支付方式。 二,解决方案 2.1 配置微信平台 ①配置微信公众平台 登录微信公众平台=》公众号设置=》功能设置=》网页授权域名 ...

    一,问题

    这两天,需要接入微信支付功能。由于我是公众号开发,因此,我选择的微信支付方式是JSAPI支付方式。

    二,解决方案

    2.1 配置微信平台

    ①配置微信公众平台

    登录微信公众平台=》公众号设置=》功能设置=》网页授权域名
    

    在这里插入图片描述

    在这里插入图片描述

    ②配置微信商家平台

    产品中心=》开发配置
    

    在这里插入图片描述

    在这里插入图片描述

    2.2 后台代码的实现

    JSAPI官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
    

    ①先去官方下载SDK,并导进项目中

    地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
    

    在这里插入图片描述

    ②准备好11个参数

    appid:商家平台ID。在微信的平台上有
    body:商品描述。
    mch_id:商户ID。在微信的平台上有
    nonce_str:随机字符串,UUID就好了。
    openid:用户标识。因为这边是用户已经登录成功了。所以在session中就能拿到。
    out_trade_no:商户订单号
    spbill_create_ip:终端IP。这个可以从请求头中拿到
    total_fee:支付金额。单位是分。
    trade_type:交易类型。这里我填JSAPI
    notify_url:通知地址。就是用户支付成功之后,微信访问你的哪个接口,跟你传递支付成功的相关信息。
    
    sign:签名。这个签名它是由上面的10个参数计算得出的。
    

    ③源码
    sendPay类:

    import java.io.IOException;
    import java.io.InputStream;
    import java.math.BigDecimal;
    import java.net.URLEncoder;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.http.auth.AUTH;
    import org.hamcrest.core.Is;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.jc.util.wxPay.WXPayUtil;
    import com.sun.xml.internal.fastinfoset.Encoder;
    
    import controller.AuthUtil;
    import net.sf.json.JSONObject;
    
    @Controller
    @RequestMapping("/pay")
    public class sendPay {
     
    	/**
    	 * @Description 微信浏览器内微信支付/公众号支付(JSAPI)
    	 * @param request
    	 * @param code
    	 * @return Map
    	 */
    	@RequestMapping(value = "orders")
    	public @ResponseBody Map<String, String> orders(HttpServletRequest request, HttpServletResponse response) {
    		try {
    			 
    			String openId = "用户的openid";
    
    			// 拼接统一下单地址参数
    			Map<String, String> paraMap = new HashMap<String, String>();
    			// 获取请求ip地址
    			String ip = request.getHeader("x-forwarded-for");
    			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.getRemoteAddr();
    			}
    			if (ip.indexOf(",") != -1) {
    				String[] ips = ip.split(",");
    				ip = ips[0].trim();
    			}
    
    			paraMap.put("appid", AuthUtil.APPID); // 商家平台ID
    			paraMap.put("body", "纯情小店铺-薯条"); // 商家名称-销售商品类目、String(128)
    			paraMap.put("mch_id", AuthUtil.MCHID); // 商户ID
    			paraMap.put("nonce_str", WXPayUtil.generateNonceStr()); // UUID
    			paraMap.put("openid", openId);
    			paraMap.put("out_trade_no", UUID.randomUUID().toString().replaceAll("-", ""));// 订单号,每次都不同
    			paraMap.put("spbill_create_ip", ip);
    			paraMap.put("total_fee", "1"); // 支付金额,单位分
    			paraMap.put("trade_type", "JSAPI"); // 支付类型
    			paraMap.put("notify_url", "用户支付完成后,你想微信调你的哪个接口");// 此路径是微信服务器调用支付结果通知路径随意写
    			String sign = WXPayUtil.generateSignature(paraMap, AuthUtil.PATERNERKEY);
    			paraMap.put("sign", sign);
    			String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式
    
    			// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
    			String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    
    			System.out.println("xml为:" + xml);
    
    			// String xmlStr = HttpRequest.sendPost(unifiedorder_url,
    			// xml);//发送post请求"统一下单接口"返回预支付id:prepay_id
    
    			String xmlStr = HttpRequest.httpsRequest(unifiedorder_url, "POST", xml);
    
    			System.out.println("xmlStr为:" + xmlStr);
    
    			// 以下内容是返回前端页面的json数据
    			String prepay_id = "";// 预支付id
    			if (xmlStr.indexOf("SUCCESS") != -1) {
    				Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
    				prepay_id = (String) map.get("prepay_id");
    			}
    
    			Map<String, String> payMap = new HashMap<String, String>();
    			payMap.put("appId", AuthUtil.APPID);
    			payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
    			payMap.put("nonceStr", WXPayUtil.generateNonceStr());
    			payMap.put("signType", "MD5");
    			payMap.put("package", "prepay_id=" + prepay_id);
    			String paySign = WXPayUtil.generateSignature(payMap, AuthUtil.PATERNERKEY);
    			payMap.put("paySign", paySign);
    			//将这个6个参数传给前端
    			return payMap;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    
    	/**
    	 * @Title: callBack
    	 * @Description: 支付完成的回调函数
    	 * @param:
    	 * @return:
    	 */
    	@RequestMapping("/notify")
    	public String callBack(HttpServletRequest request, HttpServletResponse response) {
    		// System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");
    		InputStream is = null;
    		try {
    
    			is = request.getInputStream();// 获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)
    			String xml = WXPayUtil.InputStream2String(is);
    			Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);// 将微信发的xml转map
    			
    			System.out.println("微信返回给回调函数的信息为:"+xml);
    			
    			if (notifyMap.get("result_code").equals("SUCCESS")) {
    				String ordersSn = notifyMap.get("out_trade_no");// 商户订单号
    				String amountpaid = notifyMap.get("total_fee");// 实际支付的订单金额:单位 分
    				BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);// 将分转换成元-实际支付金额:元
    
    				/*
    				 * 以下是自己的业务处理------仅做参考 更新order对应字段/已支付金额/状态码
    				 */
    				System.out.println("===notify===回调方法已经被调!!!");
    				
    			}
    			
    			// 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可
    			response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (is != null) {
    				try {
    					is.close();
    				} catch (IOException e) { 
    					e.printStackTrace();
    				}
    			}
    		}
    		
    		return null;
    	}
    
    }
    
    

    HttpRequest类:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.List;
    import java.util.Map;
    
    import javax.net.ssl.HttpsURLConnection;
    
    public class HttpRequest {
    	/**
    	 * 向指定URL发送GET方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return URL 所代表远程资源的响应结果
    	 */
    	public static String sendGet(String url, String param) {
    		String result = "";
    		BufferedReader in = null;
    		try {
    			String urlNameString = url + "?" + param;
    			System.out.println(urlNameString);
    			URL realUrl = new URL(urlNameString);
    			// 打开和URL之间的连接
    			URLConnection connection = realUrl.openConnection();
    			// 设置通用的请求属性
    			connection.setRequestProperty("accept", "*/*");
    			connection.setRequestProperty("connection", "Keep-Alive");
    			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    			// 建立实际的连接
    			connection.connect();
    			// 获取所有响应头字段
    			Map<String, List<String>> map = connection.getHeaderFields();
    			// 遍历所有的响应头字段
    			for (String key : map.keySet()) {
    				System.out.println(key + "--->" + map.get(key));
    			}
    			// 定义 BufferedReader输入流来读取URL的响应
    			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    			String line;
    			while ((line = in.readLine()) != null) {
    				result += line;
    			}
    		} catch (Exception e) {
    			System.out.println("发送GET请求出现异常!" + e);
    			e.printStackTrace();
    		}
    		// 使用finally块来关闭输入流
    		finally {
    			try {
    				if (in != null) {
    					in.close();
    				}
    			} catch (Exception e2) {
    				e2.printStackTrace();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 向指定 URL 发送POST方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的 URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return 所代表远程资源的响应结果
    	 */
    	public static String sendPost(String url, String param) {
    		PrintWriter out = null;
    		BufferedReader in = null;
    		String result = "";
    		try {
    			URL realUrl = new URL(url);
    			// 打开和URL之间的连接
    			URLConnection conn = realUrl.openConnection();
    			// 设置通用的请求属性
    			conn.setRequestProperty("accept", "*/*");
    			conn.setRequestProperty("connection", "Keep-Alive");
    			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    			// 发送POST请求必须设置如下两行
    			conn.setDoOutput(true);
    			conn.setDoInput(true);
    			// 获取URLConnection对象对应的输出流
    			out = new PrintWriter(conn.getOutputStream());
    			// 发送请求参数
    			out.print(param);
    			// flush输出流的缓冲
    			out.flush();
    			// 定义BufferedReader输入流来读取URL的响应
    			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
    			String line;
    			while ((line = in.readLine()) != null) {
    				result += line;
    			}
    		} catch (Exception e) {
    			System.out.println("发送 POST 请求出现异常!" + e);
    			e.printStackTrace();
    		}
    		// 使用finally块来关闭输出流、输入流
    		finally {
    			try {
    				if (out != null) {
    					out.close();
    				}
    				if (in != null) {
    					in.close();
    				}
    			} catch (IOException ex) {
    				ex.printStackTrace();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * post请求并得到返回结果
    	 * 
    	 * @param requestUrl
    	 * @param requestMethod
    	 * @param output
    	 * @return
    	 */
    	public static String httpsRequest(String requestUrl, String requestMethod, String output) {
    		try { 
    			URL url = new URL(requestUrl);
    			HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
    			connection.setDoOutput(true);
    			connection.setDoInput(true);
    			connection.setUseCaches(false);
    			connection.setRequestMethod(requestMethod);
    			if (null != output) {
    				OutputStream outputStream = connection.getOutputStream();
    				outputStream.write(output.getBytes("UTF-8"));
    				outputStream.close();
    			}
    			// 从输入流读取返回内容
    			InputStream inputStream = connection.getInputStream();
    			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
    			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    			String str = null;
    			StringBuffer buffer = new StringBuffer();
    			while ((str = bufferedReader.readLine()) != null) {
    				buffer.append(str);
    			}
    			bufferedReader.close();
    			inputStreamReader.close();
    			inputStream.close();
    			inputStream = null;
    			connection.disconnect();
    			return buffer.toString();
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    
    		return "";
    	}
    }
    

    AuthUtil类

    import java.io.IOException;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    
    import net.sf.json.JSONObject;
    public class AuthUtil {
    	public static final String APPID = "平台ID";
    	public static final String APPSECRET = "平台密钥";
    	public static final String MCHID = "商家ID";
    	public static final String PATERNERKEY = "商家密钥";
    	
    	
    	public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
    		JSONObject jsonObject = null;
    		// 首先初始化HttpClient对象
    		DefaultHttpClient client = new DefaultHttpClient();
    		// 通过get方式进行提交
    		HttpGet httpGet = new HttpGet(url);
    		// 通过HTTPclient的execute方法进行发送请求
    		HttpResponse response = client.execute(httpGet);
    		// 从response里面拿自己想要的结果
    		HttpEntity entity = response.getEntity();
    		if (entity != null) {
    			String result = EntityUtils.toString(entity, "UTF-8");
    			jsonObject = jsonObject.fromObject(result);
    		}
    		// 把链接释放掉
    		httpGet.releaseConnection();
    		return jsonObject;
    	}
    }
    

    2.3 前端的实现

    这是只用一个jsp页面来做测试

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="./js/jquery-1.11.0.min.js"></script>
    <title>微信支付JSP</title>
    </head>
    <body> 
    	<input type="button" value="进行微信支付" id="payId">
    
    	<script type="text/javascript">
    	
    		$(function(){
    			var appId,timeStamp,nonceStr,package,signType,paySign; 
    			
    			$("#payId").click(function(){
    				pay();
    			});
    			
    			//去后台拿六个参数
    			function pay(){   
    				var url = "http://localhost:8082/WeChat/pay/orders";
    			  	$.get(url,function(result) {	
    		  				appId = result.appId;
    						timeStamp = result.timeStamp;
    						nonceStr = result.nonceStr;
    						package = result.package;
    						signType = result.signType;
    						paySign = result.paySign;
    						
    						if (typeof WeixinJSBridge == "undefined") {
    							if (document.addEventListener) {
    								document.addEventListener('WeixinJSBridgeReady',
    										onBridgeReady, false);
    							} else if (document.attachEvent) {
    								document.attachEvent('WeixinJSBridgeReady',
    										onBridgeReady);
    								document.attachEvent('onWeixinJSBridgeReady',
    										onBridgeReady);
    							}
    							alert("请在微信上进行支付操作!");
    							onBridgeReady();
    						} else { 
    							onBridgeReady();
    						}
    					});
    				}
    			//去微信那边发起支付请求
    			function onBridgeReady(){
    				
    				 alert("appId:"+appId+" "+"timeStamp:"+timeStamp+" "+"nonceStr:"+nonceStr+" "+"package:"+package+" "+"signType:"+signType+" "+"paySign:"+paySign+" ");
    				
    				  WeixinJSBridge.invoke( 'getBrandWCPayRequest', {
    					  "appId":appId,     //公众号名称,由商户传入     
    			          "timeStamp":timeStamp,         //时间戳,自1970年以来的秒数     
    			          "nonceStr":nonceStr, //随机串     
    			          "package":package,     
    			          "signType":signType,         //微信签名方式:     
    			          "paySign":paySign //微信签名 
    			         }, 
    			         function(res){      
    			      	   if(res.err_msg == "get_brand_wcpay_request:ok" ) {
    			                 //alert('支付成功');
    			                 console.log("支付成功");
    			                 //支付成功后跳转的页面
    			             }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
    			            	 alert('支付取消');
    			             }else if(res.err_msg == "get_brand_wcpay_request:fail"){
    			            	 alert('支付失败');
    			            	 
    			            	 alert(JSON.stringify(res));
    			            	 
    			                 WeixinJSBridge.call('closeWindow');
    			             } //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
    			   });    
    			}
    		})
    </script>
    
    </body>
    </html>
    

    三,总结

    虽然第一次看官方文档很乱,信息量很多,但仔细总结一下,其实就下面这点流程而已。
    

    在这里插入图片描述

    最后,很感谢网上一位大哥分享了他的经验。
    大哥链接:https://blog.csdn.net/javaYouCome/article/details/79473743

    展开全文
  • 微信公众号+vue+微信支付

    万次阅读 热门讨论 2018-07-11 14:25:32
    在上一篇文章中本人讲述了微信公众号的授权以及获取用户信息,在此基础上今天这篇博客跟大家分享一下微信支付的流程及代码,还有自己在开发时的一些坑。1、在进行微信支付时,除了需要一个公众号之外,你还需要一个...
  • loonggg读完需要3分钟速读仅需1分钟事件还得还原到昨天晚上,10 月 29 日晚上 20:09-21:14 之间,微信支付发生故障,全国微信支付交易无法正常进行。然...
  • 微信支付类型介绍

    千次阅读 2019-05-28 16:02:37
    微信支付类型 小程序认证以后,登录微信公众平台申请微信支付微信支付开放能力主要分为两大类。 普通模式 适合用对象:适合用户自己团队开发或者外包服务开发商。 申请内容:发者申请自己的appid和mch_id服务...
  • 微信支付

    2020-10-18 17:59:35
    微信支付微信支付首先需要在微信上申请公众号(商户号) 会得到四个信息 #关联的公众号appid: #商户号 partner: #商户key partnerkey: #回调地址 notifyurl: 首先引入依赖 <dependencies> <dependency&...
  • 央行对移动支付宣布了一个新规定:表明凡是使用微信支付和支付宝支付的第三方支付软件,每笔交易额超过5万的,必须写一份报告说明提交平台,而且这个规定从2019年1月1日就开始实行了。 众多网友表示以后有了大的...
  • 手把手教你--JAVA微信支付(公众号支付JSAPI)

    万次阅读 多人点赞 2019-08-26 17:54:15
    写这篇文章的目的有2个,一是自己的项目刚开发完微信支付功能,趁热回个炉温习一下,二也是帮助像我这样对微信支付不熟悉,反复看了多天文档还是一知半解,原理都没摸清,更不要说实现了。本以为网上的微信开发教程会和...
  • 1、确认公众号的appSecret和商户号的API密钥没有搞混。 2、重置商户API密钥。 3、确认公众号授权的域名和目录是正确的。 4、参数body含有中文字符,改换英文签名成功,那么就转换字符编码试试。...
  • ​​WPS 开启会员模式之后还是非常好用的,老古这些年就一直使用 WPS 会员来办公,不过有些用户不想花钱购买会员了就想...如果你开通 WPS 会员自动续费时所选择的支付方式是微信,那么我们就可以通过手机微信 APP 来取
  • 微信支付服务商分账-添加分账接收方写在前面:服务商官方文档SIGN值校验检查地址调试中可能遇到的问题直接上代码 服务商添加分账接收方与普通商户添加分账接收方的区别。1 写在前面: 服务商官方文档 ...
  • 1-1) 查看微信支付 appid 的方法 微信支付使用的 appid, 是微信服务号的 appid, 需要你登录微信服务号后台, 在 开发-基本配置/开发者ID(AppID) 中查看微信支付 appid 1-2) 获取微信支付 appsecret 的方法 微信...
  • 官方微信支付跟特约商户的区别

    万次阅读 热门讨论 2017-04-07 09:43:13
    这几天在研究微信会员卡开发,做到快速买单的时候,他要求我开通微信支付,此前已经在服务商中开通了微信支付,最后发现他还要求我开通原生的微信支付,打客服电话求证后。发现了一个很坑的东西,发现微信支付其实有...
  • 一个大客户的
  • 小程序如何开通微信支付

    万次阅读 2018-05-14 18:24:54
    目前开通微信小程序支付功能有两种方式,一个是你已经有微信商户号的情况下直接绑定一下商户号就可以了,另一个就是需要新申请一个微信支付的商户号。第一种:绑定已有微信支付商户号如果您开通过微信支付商户,绑定...
  • 手机浏览器唤起微信app支付说明

    万次阅读 多人点赞 2016-07-08 09:58:59
    微信支付官方文档并没有显示h5唤起微信app支付的文档,但是自微信6.0.2版本后已支持该功能,而且官方已经有了开发文档,只是没有显示出来。 微信h5支付文档地址: ...
  • 微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等...
  • 微信支付调起支付控件一闪而过

    万次阅读 2016-06-03 17:25:18
    调起支付控件后一闪而过,一般是支付秘钥或者授权目录的问题。 解决办法: 1.重置支付秘钥(更换服务器地址必须更换) 2.检查授权目录
1 2 3 4 5 ... 20
收藏数 108,548
精华内容 43,419
关键字:

微信支付