微信支付宝一码付

路由

一码付指的是一个二维码同时指出支付宝、微信扫描并支付。

微信和支付宝支持扫描一个url二维码并通过内置的浏览器跳转。

我们可以通过js获得是来自支付宝的还是微信的浏览器,通过user-agent,有MicroMessenger是微信,有AlipayClient是支付宝。

var ua = navigator.userAgent.toLowerCase();
if (/MicroMessenger/.test(window.navigator.userAgent)) {
    //微信
} else if (/AlipayClient/.test(window.navigator.userAgent)) {
    //支付宝
}

接着就是查看支付宝和微信中关于网页支付的教程了。

支付宝:https://docs.open.alipay.com/203/

微信: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

notice

1.网址必须以http://https://开头。

流程时序图

这里写图片描述

支付宝

在一码付中,支付宝属于手机网站支付一类。官方api地址:https://docs.open.alipay.com/203/

测试代码

@Test
public void main() throws AlipayApiException {
    alipayClient = new DefaultAlipayClient(alipayConfig.getAlipayGateway(), alipayConfig.getAppId(),
            alipayConfig.getAppPrivateKey(), "json", DEFAULT_ENCODING, alipayConfig.getAppPublicKey(),
            SIGN_RSA);
    AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
    alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");
    alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");
    alipayRequest.setBizContent("{" +
            "\"out_trade_no\":\"fc00001\"," +
            "\"total_amount\":0.01," +
            "\"product_code\":\"QUICK_WAP_WAY\","+
            "\"subject\":\"测试\"" +
            "}");

    AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest);
    if(response.isSuccess()){
        System.out.println("调用成功");
        System.out.println(response.getBody());
    } else {
        System.out.println("调用失败");
        System.out.println(response.getBody());
    }
}

支付宝API

请求地址

环境 HTTPS请求地址
正式环境 https://openapi.alipay.com/gateway.do

公共请求参数

参数 类型 是否必填 最大长度 描述 示例值
app_id String 32 支付宝分配给开发者的应用ID 2014072300007148
method String 128 接口名称 alipay.trade.wap.pay
format String 40 仅支持JSON JSON
return_url String 256 HTTP/HTTPS开头字符串 https://m.alipay.com/Gk8NF23
charset String 10 请求使用的编码格式,如utf-8,gbk,gb2312等 utf-8
sign_type String 10 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2 RSA2
sign String 256 商户请求参数的签名串,详见签名 详见示例
timestamp String 19 发送请求的时间,格式”yyyy-MM-dd HH:mm:ss” 2014-07-24 03:07:50
version String 3 调用的接口版本,固定为:1.0 1.0
notify_url String 256 支付宝服务器主动通知商户服务器里指定的页面http/https路径。 https://api.xx.com/receive_notify.htm
biz_content String - 业务请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档

请求参数

参数 类型 是否必填 最大长度 描述 示例值
subject String 256 商品的标题/交易标题/订单标题/订单关键字等。 大乐透
out_trade_no String 64 商户网站唯一订单号 70501111111S001111119
total_amount Price 9 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 9.00

支付宝还支持交易具体描述、逾期自动关闭等。

更多api详情查看官方api: https://docs.open.alipay.com/203/107090/

微信

微信,微信使用的是公众号支付,官方api:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1,微信的支付流程如下

  1. 微信网页授权
  2. 授权凭证
  3. 下单接口

下单详细步骤代码和api

1.获得code,等待微信回调,get请求https://open.weixin.qq.com/connect/oauth2/authorize

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重定向时候,必须带此参数

2.获得openid,请求https://api.weixin.qq.com/sns/oauth2/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

返回说明

正确的返回:

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

参数说明

参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。

3.微信预下单,请求https://api.mch.weixin.qq.com/pay/unifiedorder

{
String reqBody = WXPayUtil.mapToXml(params);
byte[] bytes = LockerHttpClient.postTypedBinary("https://api.mch.weixin.qq.com/pay/unifiedorder", reqBody
                    .getBytes(DEFAULT_ENCODING), TEXT_XML);
Map<String, String> resultMap = WXPayUtil.xmlToMap(new String(bytes, DEFAULT_ENCODING));
}

private Map<String, String> populateReq(String orderId, String totalFee, String openId) throws Exception {
    Map<String, String> params = new HashMap<>();
    params.put("appid", wechatConfig.getWechatAppId());
    params.put("mch_id", wechatConfig.getWechatMchId());
    params.put("nonce_str", STRING_GENERATOR.generate(30));
    params.put("sign_type", "MD5");
    params.put("openid", openId);
    params.put("body", wechatConfig.getPayTitle());
    params.put("total_fee", totalFee);
    params.put("spbill_create_ip", DEFAULT_IP);
    params.put("trade_type", "JSAPI");
    //限制用户不能使用信用卡支付
    params.put("limit_pay", "no_credit");
    params.put("out_trade_no", orderId);
    params.put("notify_url", wechatConfig.getWechatPayNotifyUrl());
    params.put("product_id", orderId);
    params.put("sign", WXPayUtil.generateSignature(params, wechatConfig.getWechatApiKey()));
    return params;
}

请求参数

字段名 变量名 必填 类型 示例值 描述
公众账号ID appid String(32) wxd678efh567hg6787 微信支付分配的公众账号ID(企业号corpid即为此appId)
商户号 mch_id String(32) 1230000109 微信支付分配的商户号
设备号 device_info String(32) 013467007045764 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传”WEB”
随机字符串 nonce_str String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,长度要求在32位以内。推荐随机数生成算法
签名 sign String(32) C380BEC2BFD727A4B6845133519F3AD6 通过签名算法计算得出的签名值,详见签名生成算法
签名类型 sign_type String(32) MD5 签名类型,默认为MD5,支持HMAC-SHA256和MD5。
商品描述 body String(128) 腾讯充值中心-QQ会员充值 商品简单描述,该字段请按照规范传递,具体请见参数规定
商户订单号 out_trade_no String(32) 20150806125346 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一。详见商户订单号
标价金额 total_fee Int 88 订单总金额,单位为分,详见支付金额
终端IP spbill_create_ip String(16) 123.12.12.123 APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
通知地址 notify_url String(256) http://www.weixin.qq.com/wxpay/pay.php 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
交易类型 trade_type String(16) JSAPI JSAPI 公众号支付NATIVE 扫码支付APP APP支付说明详见参数规定
商品ID product_id String(32) 12235413214070356458058 trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
指定支付方式 limit_pay String(32) no_credit 上传此参数no_credit–可限制用户不能使用信用卡支付
用户标识 openid String(128) oUpF8uMuAJO_M2pxb1Q9zNjWeS6o trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换

举例如下:

<xml>
   <appid>wx2421b1c4370ec43b</appid>
   <attach>支付测试</attach>
   <body>JSAPI支付测试</body>
   <mch_id>10000100</mch_id>
   <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
   <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
   <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
   <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
   <out_trade_no>1415659990</out_trade_no>
   <spbill_create_ip>14.23.150.211</spbill_create_ip>
   <total_fee>1</total_fee>
   <trade_type>JSAPI</trade_type>
   <sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml> 

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

归纳

优点:一码支持两码,可能方便

缺点:微信支付链路太长,耗时极长,特别是access_token接口,特别是生成access_token,耗时可能会达到5s。

猜你喜欢

转载自blog.csdn.net/luo4105/article/details/80514731