yb鸭脖体育网

  • <tr id='k5bfe4'><strong id='qro0'></strong> <small id='ws0k'></small><button id='bp5pn'></button><li id='yn57i1'> <noscript id='8e9je'><big id='8dr0a'></big><dt id='tukv'></dt></noscript></li></tr> <ol id='mqc1'><option id='hdzg'><table id='0mnkj'><blockquote id='m8pvw'> <tbody id='5265op'></tbody></blockquote></table></option></ol><u id='hoe7xu'></u><kbd id='vvagh'> <kbd id='8enb'></kbd></kbd>

    <code id='0p4xeo'><strong id='kzqm9'></strong></code>

    <fieldset id='tady'></fieldset>
          <span id='6sy2'></span>

              <ins id='0yft4c'></ins>
              <acronym id='pxcb'><em id='b3ty'></em><td id='f404'><div id='f2rr'></div></td></acronym><address id='qfppon'><big id='fkxz'><big id='f4a6g'></big><legend id='1mpmx'></legend></big></address>

              <i id='0y7ys'><div id='5ygurn'><ins id='h8t3'></ins></div></i>
              <i id='5m6lr'></i>
            1. <dl id='xhsxbt'></dl>
              1. <blockquote id='d1it'><q id='jo22p'><noscript id='cp8et'></noscript><dt id='p89ja'></dt></q></blockquote><noframes id='vvdp'><i id='18y58d'></i>

                yb鸭脖体育网 官网:/

                API调用

                调用API 之前呢,我们需要获取到自己 appidappsecret

                获取 方式 如图 商家登录 后 点击 支付渠道管理 再点击 我的支付渠道

                我们 获取到我们的 appidappsecret 后 就可以 模拟Http 请求,调用api 了

                官方 API 解释:/

                不想看人家网站,直接看我提取内容就够了

                客户端请求时 参数含义:

                # 参数名 含义 类型 说明
                1 version API 版本号 string(24) 必填。目前为1.1
                2 appid APP ID string(32) 必填。支付渠道ID
                3 trade_order_id 商户订单号 string(32) 必填。请确保在当前网站内是唯一订单号
                4 total_fee 订单金额(元) decimal(18,2) 必填。单位为人民币,精确到分
                5 title 订单标题 string(128) 必填。商户订单标题
                6 time 当前时间戳 int(11) 必填。PHP示例:time()
                7 notify_url 通知回调网址 string(128) 必填。用户支付成功后,我们服务器会主动发送一个post消息到这个网址(注意:当前接口内,SESSION内容无效)
                8 return_url 跳转网址 string(128) 可选。用户支付成功后,我们会让用户浏览器自动跳转到这个网址
                9 callback_url 商品网址 string(128) 可选。用户取消支付后,我们可能引导用户跳转到这个网址上重新进行支付
                10 plugins 备注 string(128) 可选。备注字段,可以传入一些备注数据,回调时原样返回
                11 nonce_str 随机值 string(32) 必填。作用:1.避免服务器页面缓存,2.防止安全密钥被猜测出来
                12 hash 签名 string(32) 必填。
                13 redirect=Y get请求 string(32) GET请求必填

                服务端响应 参数含义:

                # 参数名 含义 类型 说明
                1 oderid 订单id int 订单id
                2 url_qrcode 二维码地址 string(156) 可将该参数生成二维码展示出来进行扫码支付
                3 url 请求url string(155)
                4 errcode 错误码 int
                5 errmsg 错误信息 string(8) 错误信息具体值
                6 hash 签名 string(32) 数据签名,参考下面签名算法

                正式开始

                我们 从官方获取到 API 请求的地址

                https://api.xunhupay.com/payment/do.html

                拿到地址 我们 就可以模拟请求了,我们采用 Postman 的方式进行测试。如果不了解 Postman 可以访问 XXX,(这里 Postman 教程 没写,写了会补全)

                先看下 成功PostMan 案例。这里泄露我 appid 各位老铁,不要干坏事。

                好了 上图 各个参数 都能 只有 time 和 hash 需要我们额外生成,别急,下面有 JAVA 代码。

                原理

                讲代码之前:我们 先说说 客户端 与 服务端 运行的原理

                客户端 与 服务端 之间 相互鉴别 通过一个叫 hash 的签名。如果 hash签名一致,就认定请求成功!

                hash ,这里不叫哈希了,他叫签名。他的生成原理是:将请求中的所有参数(除本身外),进行 键的Ascll 从小到大进行排序,之后使用 “&” 进行关联。最后直接拼接上 appsecret (注意,appsecret 前 不需要 “&” 关联)。得到一串字符串后,进行MD5 加密。就达到了 hash 值

                将来服务端 验证的时候,根据我们请求参数,重复一遍 生成我们客户端生成的Hash 过程。(注意,我们请求参数里面,没有传 appsecret 。服务端是 自己从自己服务器 根据我们传递 appid 取出 appsecret) 进行比对,信息是否正确。

                原理说完,我们说一下代码实现

                真实代码实现

                说明,我使用了Hutool 中的 加密工具,就需要我们在 Maven 添加

                <!-- Hutool工具 -->
                        <dependency>
                            <groupId>cn.hutool</groupId>
                            <artifactId>hutool-all</artifactId>
                            <version>5.5.7</version>
                        </dependency>

                首先 我们模拟postman 发送请求的时候,唯一缺少的就是 hash 签名 和 秒的时间戳 了。我们就去生成一下。

                在模拟 hash签名之前,我们需要去写一个方法 去获取 秒的时间戳

                /**
                     * 获取精确到秒的时间戳   原理 获取毫秒时间戳,因为 1秒 = 100毫秒 去除后三位 就是秒的时间戳
                     * @return
                     */
                    public static int getSecondTimestamp(Date date){
                        if (null == date) {
                            return 0;
                        }
                        String timestamp = String.valueOf(date.getTime());
                        int length = timestamp.length();
                        if (length > 3) {
                            return Integer.valueOf(timestamp.substring(0,length-3));
                        } else {
                            return 0;
                        }
                    }

                有了秒的时间戳了,就可以去生成 hash签名了 下面是伪代码

                String appid = "你的APPID";  
                      Map<String,Object> options = new HashMap<>();
                        // 设置版本号
                        options.put("version","1.1");
                        // 设置 appid
                        options.put("appid",appid);
                
                        // 密钥不需要参数
                        //options.put("appsecret",appsecret);
                
                        // 订单号 具体内容自己控制 长度 32位
                        options.put("trade_order_id","1");
                
                        // 价格价格 精确到分
                        options.put("total_fee","0.01");
                
                        // 标题
                        options.put("title","测试使用的title");
                
                        // 当前时间戳 调用 刚写的方法 getSecondTimestamp
                        options.put("time", getSecondTimestamp(new Date()));
                
                        // notify_url 回调地址
                        options.put("notify_url","49.72.184.28");
                
                        // nonce_str  随机值 32位内  作用: 1.避免服务器页面缓存,2.防止安全密钥被猜测出来(md5 密钥越复杂,就越难解密出来)
                        options.put("nonce_str","740969606");
                
                        // 定义 sb 为了获取 MD5 加密前的字符串
                        StringBuilder sb = new StringBuilder();
                
                        // 将HashMap 进行 键 的 Ascll 从小到大排序 并 将每个 hashmap元素 以 & 拼接起来
                        options.entrySet().stream().sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey())).forEach(a ->{
                            sb.append(a).append("&");});
                
                        // 去除 最后一位的 &
                        sb.deleteCharAt(sb.length()-1);
                
                        // 拼接上密钥
                        sb.append(appsecret);
                
                        // 调用 Hutool 的 加密工具 进行 MD5 加密
                        String s = SecureUtil.md5(sb.toString());
                        
                        // 输出hash结果 postman 要用
                        System.out.println("我们生成的Hash 是:"+s);
                        // 输出time结果 postman 要用
                        System.out.println("我们生成的time 是:"+options.get("time"));

                上面 代码 自己创建一下 run 一下 控制台会输出 hash 和 time,有了这些数据,我们就可以postman 模拟了 ,看到 Hashmap集合填写的参数,放到 postman unlencoded 格式中

                最终,会看到结果 Success

                当然,第一次测试,大部分都不会成功,如图

                一定要确保 参数正确。就可以了。

                简单的 postman 测试成功了,我们 就准备 制作我们的 支付 – 跳转 功能了。

                待更新!!!

                好了 完成 Java 调用的测试了,上代码。

                Java 代码

                package com.zlk;
                
                import cn.hutool.crypto.SecureUtil;
                import cn.hutool.http.HttpUtil;
                import com.alibaba.fastjson.JSON;
                import org.junit.Test;
                
                import java.util.Date;
                import java.util.HashMap;
                import java.util.Map;
                
                /**
                 * @author : zanglikun
                 * @date : 2021/2/20 13:48
                 * @Version: 1.0
                 * @Desc : 费劲,没啥好说的
                 */
                public class pay {
                
                    // 请求参数的含义 与 值范围,请访问呢: /doc/api/pay.html
                    @Test
                    public void pay(){
                        // appid
                        String appid = "201906134645";
                        // appsecret
                        String appsecret = "你的密钥";
                        // 请求路径
                        String url = "https://api.xunhupay.com/payment/do.html";
                
                        // 设置 传递参数的集合,方便 传递数据。
                        Map<String,Object> options = new HashMap<>();
                        // 必填 设置版本号
                        options.put("version","1.1");
                        // 必填 设置 appid
                        options.put("appid",appid);
                
                        // 密钥不需要直接传递
                        //options.put("appsecret",appsecret);
                
                        // 必填 订单号 具体内容自己控制 长度 32位 官网说 请确保在当前网站内是唯一订单号,具体含义 我测试了 在描述 此备注
                        options.put("trade_order_id","1");
                
                        // 必填 价格 精确到RMB分
                        options.put("total_fee","0.01");
                
                        // 必填 标题
                        options.put("title","测试使用的title");
                
                        // 必填 当前时间戳 调用 刚写的方法 getSecondTimestamp
                        options.put("time", getSecondTimestamp(new Date()));
                
                        // 必填 通知回调地址 url 什么含义 我们后台需要知道 用户支付了。
                        options.put("notify_url","https://zanglikun.cn1.utools.club/paycallback"); // 只有这个有用
                
                        // 非必填 使用 响应字段中 url 就直接跳到百度了,如果访问,url_qrcode ,不会直接跳转,只有当支付完成后,再次刷新 url_qrcode中的连接,才会跳转。
                        options.put("return_url","https://www.");
                
                        // 非必填 用户取消支付,跳转的页面   经过测试,没有触发机制,建议不传递
                        options.put("callback_url","https://www.sina.com.cn/");
                
                        //plugins 非必填 备注信息
                        options.put("plugins","我是备注信息");
                
                        // nonce_str  必填 随机值 32位内  作用: 1.避免服务器页面缓存,2.防止安全密钥被猜测出来(md5 密钥越复杂,就越难解密出来)
                        options.put("nonce_str","740969606");
                
                        // 定义 sb 为了获取 MD5 加密前的字符串
                        StringBuilder sb = new StringBuilder();
                
                        // 将HashMap 进行 键 的 Ascll 从小到大排序 并 将每个 hashmap元素 以 & 拼接起来
                        options.entrySet().stream().sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey())).forEach(a ->{
                            sb.append(a).append("&");});
                
                        // 去除 最后一位的 &
                        sb.deleteCharAt(sb.length()-1);
                        // 拼接上密钥
                        sb.append(appsecret);
                
                        // 调用 Hutool 的 加密工具 进行 MD5 加密
                        String s = SecureUtil.md5(sb.toString());
                
                        // 输出hash结果 postman 要用
                        System.out.println("我们生成的Hash 是:"+s);
                        // 输出time结果 postman 要用
                        System.out.println("我们生成的time 是: "+options.get("time"));
                
                        System.out.println();
                        // 必填 hash 签名
                        options.put("hash", s);
                
                
                        System.out.println("我们传递的参数有:"+options.toString());
                        System.out.println("开始调 yb鸭脖体育网支付 接口...");
                
                        // 调用 Hutool 的HttpUtil 发送 post 请求
                        String post = HttpUtil.post(url, options);
                
                        System.out.println("结束调 yb鸭脖体育网支付 接口...\n");
                        System.out.println("yb鸭脖体育网支付 接口 响应的结果是:"+post+"\n");
                
                        // 说明:这里 因为yb鸭脖体育网支付 响应结果 不统一,正确是Json;不正确 就是一行String 。没办法 判断是否请求是否有效。所以 只能通过 是由能够解析成json 有无异常判断 是否调用成功
                        try{
                            Map map = (Map)JSON.parse(post);
                            map.keySet().stream().forEach(k -> {
                                if (k == "url") {
                                    System.out.println("url二维码链接是: "+map.get(k));
                                }
                            });
                        }catch (Exception e){
                            e.printStackTrace();
                            System.out.println("调 yb鸭脖体育网支付 时 出现了问题");
                        }
                
                
                    }
                
                    /**
                     * 获取精确到秒的时间戳   原理 获取毫秒时间戳,因为 1秒 = 100毫秒 去除后三位 就是秒的时间戳
                     * @return
                     */
                    public static int getSecondTimestamp(Date date){
                        if (null == date) {
                            return 0;
                        }
                        String timestamp = String.valueOf(date.getTime());
                        int length = timestamp.length();
                        if (length > 3) {
                            return Integer.valueOf(timestamp.substring(0,length-3));
                        } else {
                            return 0;
                        }
                    }
                
                }

                测试的结果 截图:

                再次 强调一下:请求支付成功,返回的数据中,有 url 和 url_qrcode ,建议去使用 url 的链接 支付,因为 它可以直接 跳转 请求成功的页面。当支付成功时,再次访问 这两个url 都会自动跳转 你指定的页面。

                上述 代码中 蓝色 标注的代码是 回调地址。会spring框架的兄弟 都能看懂。

                import org.springframework.stereotype.Controller;
                import org.springframework.web.bind.annotation.RequestMapping;
                import org.springframework.web.bind.annotation.ResponseBody;
                
                import javax.servlet.http.HttpServletRequest;
                import java.util.Map;
                
                /**
                 * @author : zanglikun
                 * @date : 2021/2/22 12:04
                 * @Version: 1.0
                 * @Desc : 费劲,没啥好说的
                 */
                @Controller
                public class PayCallback {
                
                    @RequestMapping("/paycallback")
                    @ResponseBody
                    public String abc(HttpServletRequest request){
                        // 记得 map 第二个泛型是数组 要取 第一个元素 即[0]
                        Map<String, String[]> parameterMap = request.getParameterMap();
                        System.out.println("展示 回调的所有结果:");
                        // 处理 回调 结果
                        parameterMap.keySet().stream().forEach((k) ->{
                            System.out.println(k+":"+parameterMap.get(k)[0]);
                        });
                
                        System.out.println("展示 回调的所有结果完成");
                        System.out.print("\n最终结果是:");
                        
                        if("OD".equals(parameterMap.get("status")[0])){
                            System.out.println("用户支付成功了");
                        }else {
                            System.out.println("用户支付不成功");
                        }
                        return "ok";
                    }
                
                }

                控制台输出 结果展示:

                展示 回调的所有结果:
                trade_order_id:1
                total_fee:0.01
                transaction_id:2021022222001486491437925203
                open_order_id:20207745197
                order_title:测试使用的title
                status:OD
                plugins:我是备注信息
                nonce_str:9375163117
                time:1613975317
                appid:201906134645
                hash:621a90afe443c278f22927a1220f0ee5
                展示 回调的所有结果完成
                
                最终结果是:[Ljava.lang.String;@790a1d8e
                用户支付成功了

                • yb鸭脖体育网支付宝V2.0与V1.0的区别?如何选择?
                • yb鸭脖体育网关于最新政策微信、支付宝个人收款码不能用于经营收款的说明
                • 小程序:微信支付商家助手实用功能展示yb鸭脖体育网个人支付
                • 支付宝个人电脑+手机网站支付接口开放申请
                • 关于停止接入通讯行业的通知
                J9九游体育网站