微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付

微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付_第1张图片

 

关于微信网页支付,分为微信域内浏览器支付 + 外部浏览器支付,两者还是稍微有点点区别的,内部浏览器即在微信内打开网页,进行支付,支付调用是需要开通JSAPI支付方式;而外部浏览器「比如浏览器等」则需要开通 H5支付方式。

准备工作

接入说明

开通H5微信支付-V3,用于移动端H5网页调起微信支付进行付款功能。

微信支付需准备商户号、微信社交载体(公众号/小程序/开放平台)、网站备案域名

公众号平台申请-注册服务号(主体信息与商户平台、网站域名备案主体一致)

微信公众平台

商户平台(需备案,与公众号平台、网站域名备案主体一致)

接入微信支付 - 微信商户平台

API参数获取说明

微信社交载体-AppId

appId是微信社交载体身份的唯一凭证,所以需要申请公众号/小程序/开放平台后,获取对应的appId

微信社交载体-appSecret

appSecret是APPID对应的接口密码,用于获取接口调用凭证-accessToken时使用(微信支付已将获取accessToken部分功能封装,无需自己开发),可登录微信社交载体获取AppSecret。

商户平台-mchId(商户号)

mchId是微信商户平台的身份凭证,且每个mchId只能对应一个结算币种,若要使用多个结算币种,则需要申请相应数量的mchId。注册并登录商户平台后,查看账号信息,以获取对应的mchId

商户平台-APIKey

登录微信商户平台,进入【账户中心 > API安全】目录,设置APIV3密钥。内容为32位字符,包括数字及大小写字母,此时需要输入操作密码及管理员手机验证码。

商户平台-商户证书密钥-privateKey

登录微信商户平台,进入【账户中心 > API安全】目录,申请API证书,在弹出窗口内点击点击“下载证书工具”按钮下载证书工具,该工具为.exe格式,需要在windows环境下运行安装。根据证书工具的提示操作,直至生成证书文件至电脑。

打开生成的证书文件夹,其中apiclient_key.pem便是我们需要的商户证书密钥文件,使用文本编辑器打开,复制内容即可。

商户平台-商户证书序列号-mchSerialNo

同证书密钥-登录微信商户平台,进入【账户中心 > API安全 】目录,申请API证书后,在API证书一栏 会 显示该序列号。

java配置样例:

wx:
  pay:
    appId: #公众号或者小程序appid
    mchId:  #商户id
    apiV3Key:  #V3密钥
    certSerialNo: #证书序列号
    privateKeyPath: #证书key路径
    privateCertPath:  #证书路径

H5支付(域外)

整体流程

官方文档: 开发指引-H5支付 | 微信支付商户平台文档中心

微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付_第2张图片

1、用户在商户侧完成下单,使用微信支付进行支付

2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB

3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url 调起微信支付中间页

4、中间页进行H5权限的校验,安全性检查

5、如支付成功,商户后台会接收到微信侧的异步通知

6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)

7、商户在展示页面,引导用户主动发起支付结果的查询

遇到的问题

  1. java调用V3接口统一下单时,会报 Illegal key size 报错问题,你的代码是没错的,jdk的问题
javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1029)
javax.crypto.Cipher.implInit(Cipher.java:795)
javax.crypto.Cipher.chooseProvider(Cipher.java:854)
javax.crypto.Cipher.init(Cipher.java:1374)
javax.crypto.Cipher.init(Cipher.java:1308)
com.focustech.common.codec.encrypter.AES256Encrypter.cipher(AES256Encrypter.java:37)
    com.focustech.common.codec.encrypter.AES256Encrypter.encrypt(AES256Encrypter.java:45)

原因是:如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. 因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于jdk/jre/lib/security,

解决办法:

替换jdk 与jre下两个jar包:local_policy.jar和 US_export_policy.jar即可。见附件

UnlimitedJCEPolicyJDK8.rar

  1. 你的请求必须是从添加的H5域名相同,否则下单链接可以获取,但是支付不能成功

微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付_第3张图片

  1. 链接不能通过浏览器直接打开,会报下面的错误。你必须在app或者H5里面使用代码打开。

微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付_第4张图片

当前调用H5支付的referer为空导致,你需要在app或者H5里面使用代码打开,或者发起支付是,手动设置referer。 如果是webview中,手动设置referer., referer必须是申请H5提交时的授权域名。

JSAPI支付(域内)

整体流程

微信内部浏览器支付,支付时会直接调起微信支付,不同于外部浏览器支付,内部浏览器支付首先需要获得当前支付用户对该公众号的唯一标识 openId,拿到 openId 后,结合后端其他参数调用微信预支付接口,获得预支付id,然后交由前端发起微信支付,支付成功后回调后端接口。

官方文档:开发指引-JSAPI支付 | 微信支付商户平台文档中心

  1. 【服务端】JSAPI下单

重要入参说明

package:JSAPI下单接口返回的prepay_id参数值,提交格式如:prepay_id=***

signType:该接口V3版本仅支持RSA

paySign:签名

paySign生成规则、响应详情及错误码请参见 JSAPI调起支付接口文档

  1. 【客户端】JSAPI调起支付
  2. 【服务端】接收支付结果通知
  3. 【服务端】查询订单

遇到的问题

  1. 配置token , 报token失败?

微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付_第5张图片

需要公网下,接受微信的验证消息,并且返回正确值, java代码示例

@GetMapping(value = "/mp/portal",produces = "text/plain;charset=utf-8")
    public String authGet(
                          @RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {

        LOGGER.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature,
                timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        if (wxMpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

  1. JSAPI微信支付必须要openid,怎么获取openid?

官方文档: 网页授权 | 微信开放文档

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

code 是用来取得 openid 的钥匙,先访问微信指定的api取得 code,再拿 code 去换取 openid 是第一步要做的事情。

获取 code 只需按照微信给出的固定访问方式,拼接参数,请求指定接口,如无错误即可获得,详见下

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

第二步,AppID + AppSecret + code 获取 openid

首先,通过公众号的 微信公众平台 开发 基本配置 开发者ID 开发者密码(AppSecret) IP白名单 ,获取 AppID 和 AppSecret 两个关键信息(APPID第一步已经获得),需要注意的是,虽然微信的官方Wiki教程中并没有提到设置IP白名单,但在设置 AppSecret 时是被提示需要一并设置的。

按开发文档要求拼接参数,请求以下链接获取access_token, 同时可以获取到openid

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

  1. 前端如何唤起支付?
function onBridgeReady() {
  WeixinJSBridge.invoke('getBrandWCPayRequest', {
    "appId": "wx2421b1c4370ec43b",     //公众号ID,由商户传入     
    "timeStamp": "1395712654",     //时间戳,自1970年以来的秒数     
    "nonceStr": "e61463f8efa94090b1f366cccfbbb444",      //随机串     
    "package": "prepay_id=up_wx21201855730335ac86f8c43d1889123400",
    "signType": "RSA",     //微信签名方式:     
    "paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==" //微信签名 
  },
                        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();
}

支付回调

官方指引文档: 微信支付-开发者文档

由于微信支付回调的参数数据都是加密的,需要解密后,再处理逻辑。

验签

验签的目的是为了确定回调请求来自于微信官方,而非其他第三方。

解密

解密是解密出微信官方回调后resource字段里的 ciphertext 字段。从而实现本身业务

问题

  1. 通知返回给微信,微信重试机制?

接收成功:HTTP应答状态码需返回200或204,无需返回应答报文。

接收失败:HTTP应答状态码需返回5XX或4XX,同时需返回应答报文,格式如下:

如果微信手动商户的应答不是成功或者超时时,微信会认为通知失败,微信会通过一定的策略(如:30分钟共8次)定期重新发起通知,尽可能提高成功的通过率,但是微信不保证通知最终能成功

你可能感兴趣的:(后端开发,微信,java,微信小程序,小程序)