微信支付宝一码付

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/luo4105/article/details/80514731

路由

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

微信和支付宝支持扫描一个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。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券