微信云支付的扫码支付

前言

之前研究微信云支付的扫码支付,我将认为重要的内容在本文中分享给大家。

微信云支付相关介绍

微信云支付的相关特点文档中已经介绍的很清楚了,这里就不在介绍了。
微信云支付文档

何为扫码支付

1.“商户主动下单,为每个订单生成一个二维码,顾客打开扫一扫进行扫码后,完成支付”
2.“每个订单一个单独的二维码”
3.“收银机具需要有给顾客展示二维码的屏幕,顾客扫码支付”
4.“希望用户可以在收银机上自助点餐的商户,如肯德基等”

注意:扫码支付的二维码是微信和支付各生成一个,并不是共用同一个二维码

本文介绍扫码支付的支付和退款后台接口的编写,其余功能可根据这两个功能中参数的拼接方法,基本都可以实现

扫码支付

1.准备工作
注册微信支付和支付宝支付的相关服务商账号以及微信云支付的账号,并配置好门店信息,如device_infos和staff_infos(这些信息在请求门店信息中要返回给客户端,可以见微信云支付的请求门店信息的API:请求门店信息)等,具体可以见微信支付、支付宝支付以及微信云支付的相关文档。
2.计算认证码
微信云支付官方文档中提供的是C++版的示例代码,计算认证码的算法是HMAC-SHA256。如果使用C++开发,请查看C++示例代码

请求必须传认证或签名信息。其中退款请求,传签名和签名算法,其他请求传认证码和认证算法。

计算认证码的方法:

    public static String caculateAuthenCode(String key, String data) {
        Mac sha256_HMAC = null;
        String hash = null;
        try {
            sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            hash = DatatypeConverter.printHexBinary(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return hash;
    }

其中参数key是云支付提供的“认证秘钥”里的字符串,data是你要加密的数据,也就是组织好的json格式的参数。
这里写图片描述
3.请求门店信息
因为扫码支付的有些请求参数需要在请求门店信息接口返回的数据中获取,例如调用微信云支付的请求门店信息的接口,来获取门店账号(out_shop_id)、终端设备号(device_id)、店员ID(staff_id)以及终端类型(terminal_type)。
根据查询门店信息接口文档,编写请求参数request_content和authen_info,如下

{
    "request_content": "{\"out_mch_id\":\"云支付分配给服务商的帐号\",\"out_sub_mch_id\":\"云支付分配给子商户的帐号\",\"nonce_str\":\"26f827a651761f7d\",\"page_num\":1,\"page_size\":100}",
    "authen_info": {
        "a": {
            "authen_code": "计算得到的认证码",
            "authen_type": 1
        }
    }
}

请求示例代码

  public String request(String url, String requestContent, AuthenInfo authenInfo) {
        String responseContent = null;
        try {
            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost post = new HttpPost();
            post.setURI(new URI(url));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("request_content", "\"" + requestContent + "\"");//json字符串
            jsonObject.put("authen_info", authenInfo);//json对象
            StringEntity urlEncodedFormEntity = new StringEntity(jsonObject.toString(), "utf-8");//解决中文乱码问题
            urlEncodedFormEntity.setContentEncoding("UTF-8");
            urlEncodedFormEntity.setContentType("application/json");//发送json数据需要设置contentType
            post.setEntity(urlEncodedFormEntity);
            CloseableHttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseContent;
    }

值得注意的是参数request_content的结构是json字符串,参数authen_info是json对象,见上面的代码。
status为0代表请求成功
从返回的内容中获取门店账号(out_shop_id)、终端设备号(device_id)、店员ID(staff_id)以及终端类型(terminal_type)

3.根据微信云支付的扫码支付接口文档,编写请求参数
我们可以根据文档中给的参数的类型,编写javabean 然后组织成json字符串,例如

请求内容:

{
    "pay_mch_key": {
        "pay_platform": 1,
        "out_mch_id": "云支付分配给服务商的帐号,固定20个数字或者字母",
        "out_sub_mch_id": "云支付分配给子商户的帐号,固定20个数字或者字母",
        "out_shop_id": "云支付唯一标识门店的账号"
    },
    "pay_content": {
        "out_trade_no": "云支付订单前缀46f827a751761fff",
        "total_fee": 60,
        "fee_type": "CNY",
        "body": "订单介绍",
        "wxpay_pay_content_ext": {
            "attach": "1",
            "goods_tag": "1234",
            "product_id": "spidSPBH129I902",
            "limit_pay": "no_credit"
        }
    },
    "order_client": {
        "device_id": "终端设备号",
        "staff_id": "店员ID",
        "terminal_type": 终端类型,
        "sdk_version": "SDK",
        "spbill_create_ip": "调用云支付API的机器IP"
    },
    "nonce_str": "16f827a651761f77"
}

认证信息

    {
        "a": {
            "authen_code": "计算得到的认证码",
            "authen_type": 1
        }
    }

完成的请求参数结构

{
    "request_content": "{\"pay_mch_key\":{\"pay_platform\":1,\"out_mch_id\":\"云支付分配给服务商的帐号\",\"out_sub_mch_id\":\"云支付分配给子商户的帐号\",\"out_shop_id\":\"云支付唯一标识门店的账号\"},\"pay_content\":{\"out_trade_no\":\"云支付订单前缀46f827a751761fff\",\"total_fee\":60,\"fee_type\":\"CNY\",\"body\":\"订单介绍\",\"wxpay_pay_content_ext\":{\"attach\":\"1\",\"goods_tag\":\"1234\",\"product_id\":\"spidSPBH129I902\",\"limit_pay\":\"no_credit\"}},\"order_client\":{\"device_id\":\"终端设备号\",\"staff_id\":\"店员ID\",\"terminal_type\":终端类型,\"sdk_version\":\"SDK\",\"spbill_create_ip\":\"调用云支付API的机器IP\"},\"nonce_str\":\"16f827a651761f77\"}",
    "authen_info": {
        "a": {
            "authen_code": "通过计算得到的认证码",
            "authen_type": 1
        }
    }
}

值得注意的是,

为了保护不同商户的订单号不重复,云支付为每个服务商录入的子商户分配了“云支付订单前缀”,在云支付后台的商户详情中可以看到,该商户的订单和退款单必须以云支付子商户号做前缀。

out_trade_no是云支付订单前缀加自定义字符串构成,比如,我的云支付订单前缀是ABCdfFS,则我可以设置订单号为
ABCdfFS46f827a7517,订单前缀跟自定义字符串之前不能有特殊字符“+”或者“-”等

请求示例代码

    public String request(String url, String requestContent, AuthenInfo authenInfo) {
        String responseContent = null;
        try {
            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost post = new HttpPost();
            post.setURI(new URI(url));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("request_content", "\"" + requestContent + "\"");//json字符串
            jsonObject.put("authen_info", authenInfo);//json对象
            StringEntity urlEncodedFormEntity = new StringEntity(jsonObject.toString(), "utf-8");//解决中文乱码问题
            urlEncodedFormEntity.setContentEncoding("UTF-8");
            urlEncodedFormEntity.setContentType("application/json");//发送json数据需要设置contentType
            post.setEntity(urlEncodedFormEntity);
            CloseableHttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseContent;
    }

请求成功,返回数据示例:

这里写图片描述

根据请求得到的code_url,Android或iOS端就可以生成二维码进行展示了

值得注意的是,订单是有过期时间的,可以自己指定过期时间(见文档),也可以不指定,不指定过期时间的话,默认过期时间是1分半钟,也就是说,如果此时没有扫码支付,这个订单就过期了,得重新生成一个订单并请求获取二维码。

下一篇文章:微信云支付的退款

OVER

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
技术选型1,前端微信小程序原生框架cssJavaScript2,管理后台开发Cms内容管理系统web网页3,数据后台小程序开发函数数据库存储 1,小程序端1-1,首页首页有以下几个功能点点餐菜单浏览排号等位拨打电话顶部轮播图搜索菜品这里点餐分两种1,可以设置直接点餐直接点餐:适合小型饭店,或者奶茶类的快餐店。直接就可以下单,不用识别桌号2,也可设置扫码点餐扫码点餐适合中大型饭店,可以区分桌号,方便管理我后面会教大家如何生成桌号二维码,只需要把对应桌号的二维码贴在餐桌上,用户点击 扫码点餐 识别二维码,即可获取到桌号信息。1-2,菜品浏览页菜品浏览分两种1,不带分类适合菜品少的时候2,带分类菜品多的时候,带分类更方便客户选择不带分类 带分类 1-3,搜索功能我们这里搜索有两个触发方式1,直接点击搜索图标2,点击键盘上的搜索键1-4,搜索结果,支持模糊查询如我这里只搜‘鱼’,那么菜品中所有包含鱼的都可以搜索到 1-5,购物车首先菜品列表页可以直接添加商品到购物车购物车弹起后可以做如下操作1,增删单个菜品2,清空购物车3,删除菜品这些操作都和菜品列表是联动的,也就是菜品列表和购物车里增删个数,都是可以同步的。我会在项目预览章节的视频里做具体演示。1-6,下单页下单页就是确认订单后进行下单支付的。有以下功能1,点餐明细2,价格计算3,桌号地址4,就餐人数5,添加备注6,点击下单1-7,支付支付页分两种方式1,模拟支付适合前期学习,毕业设计等演示类的场景。2,真实微信支付适合商用,但是使用微信支付必须要有营业执照,所以前期如果只是学习的话,建议使用模拟支付。 1-8,我的订单页我的订单页分以下几个状态1,新下单待上餐2,已上餐待评价3,订单完成4,订单取消1-9,提交评论页我们可以对店家进行评论。 1-10,评价列表页可以查看所有评价和自己的评价 1-11,排号等位可以看出,我们可以选择就餐人数,排大桌或者小桌。我这里已排小桌为例通过上图可以看出1,当前排号情况2,我的排号3,可以重新排号4,到号时会有到号提示后面我会把订阅消息功能加进来,这样到号后会有订阅消息提示。 1-12,个人中心个人中心分登录和未登录两种状态未登录已登录 1-13,微信授权登录小程序 2,后厨端和排号管理端2-1,后厨端主要供后厨的厨师使用1,可以查看当前新下单2,完成后可以操作菜品完成3,可以监听用户新下单4,有新订单时会有语音提示5,厨师登录页语音提示我会在视频课里具体演示厨师登录页 厨师管理页可以查看待制作订单用户新下单后,会有语音提示 2-2,排号管理页同样也有登录页,和上面厨师登录一样,这里重点看下排号管理页管理员可以查看当前排号情况,可以叫号。3,cms管理后台我们这里的可视化网页后台使用的时开发自带的cms(内容管理)3-1,登录页 3-2,管理后台我们可以在这里 1,添加轮播图,删除轮播图,修改轮播图2,添加菜品,删除菜品,修改菜品,上架下架菜品3,管理订单4,查看评价5,管理后厨和排号管理员6,查看排号数据  比如我查询某个用户的所有订单 查询所有新下单还未上菜的订单 还有更多的功能,我会在视频课里给大家用视频来演示,这样更直观。 4,数据库数据库我们这里用开发自带的数据库餐厅管理员查看趋势图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值