700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」

微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」

时间:2022-11-05 12:40:12

相关推荐

微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」

前言

微信支付-微信H5外部浏览器支付本文

微信H5内部浏览器支付待写

PC端扫码支付待写

一直计划着写一写微信支付相关的文章,希望能加深一下自己的印象,拖了一天又一天…

最近终于空出时间来填坑了,我将文章分为微信H5外部浏览器支付微信H5内部浏览器支付PC端扫码支付三篇来写。

本篇是微信H5外部浏览器支付:支付时会唤起微信APP进行支付。

扫盲补充:关于微信H5支付,分为内部浏览器支付+外部浏览器支付,两者还是稍微有点点区别的,内部浏览器即在微信内打开网页,进行支付,支付调用由前端发起「JSSDK」;而外部浏览器「比如QQ浏览器等」则通过后台返回的mweb_url交由前端唤起微信APP发起支付操作,微信官方提供了个测试网页 /mch/pay/h5.v2.php,可以在手机浏览器打开体验一番。

本文开发环境: Java + SpringBoot + IDEA + WxJava(开源SDK)

再多啰嗦几句,最开始并没有选择WxJava开源SDK,因为没有仔细阅读官方文档,反正各种报错,比如:支付验证签名失败等等~,最后妥协不重复造轮子了,如下为正文。

1、 引入依赖包

pom.xml文件中引入WxJava依赖「本文使用的是3.3.0版本

<dependency>

<groupId>com.github.binarywang</groupId>

<artifactId>weixin-java-pay</artifactId>

<version>3.3.0</version>

</dependency>

2、基础配置

WxJava提供了微信支付的Demo,可以参考 /binarywang/weixin-java-pay-demo

2.1、增加支付配置信息

下面提供application.ymlapplication.properties两种格式,具体如下:

wx.pay.appId=#微信公众号或者小程序等的appid

wx.pay.mchId=#微信支付商户号

wx.pay.mchKey=#微信支付商户密钥

wx.pay.notifyUrl=#支付成功回调URL

wx.pay.keyPath=#p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)

#-----------------------------------------

wx:

pay:

appId:#微信公众号或者小程序等的appid

mchId:#微信支付商户号

mchKey:#微信支付商户密钥

notifyUrl:#支付成功回调URL

keyPath:#p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)

补充:keyPath 用来指定证书路径,关于证书的用途:发红包/企业付款/退款等操作,本文不涉及,留空。

2.2、代码中的配置

一个是用来读取配置信息的实体类,一个是用来初始化支付SDKConfiguration

读取配置类:WxProperties.java

@Data

@Configuration

@ConfigurationProperties(prefix="wx.pay")

publicclassWxProperties{

/**

*设置微信公众号或者小程序等的appid

*/

privateStringappId;

/**

*微信支付商户号

*/

privateStringmchId;

/**

*微信支付商户密钥

*/

privateStringmchKey;

/**

*apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定

*/

privateStringkeyPath;

/**

*微信回调接口地址

*/

privateStringnotifyUrl;

}

初始化支付SDK类:WxConfig.java

@Configuration

publicclassWxConfig{

@Autowired

privateWxPropertiesproperties;

@Bean

@ConditionalOnMissingBean

publicWxPayServicewxService(){

WxPayConfigpayConfig=newWxPayConfig();

payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));

payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));

payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));

payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));

payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));

//可以指定是否使用沙箱环境

payConfig.setUseSandboxEnv(false);

WxPayServicewxPayService=newWxPayServiceImpl();

wxPayService.setConfig(payConfig);

returnwxPayService;

}

}

2.3、微信支付接口

微信非内部浏览器支付,比如在手机QQ浏览器中发起支付,会唤起微信APP进行支付操作,此时调用微信接口返回的是一个URL,返回结果如下:

weixin://wxpay/bizpayurl?pr=IzX8nS

下方是获取支付URL的后端接口方法:

@RequestMapping(value="createOrder",method={RequestMethod.POST})

publicResult<Object>createQRCode(UserModeluser,HttpServletResponseresponse,@RequestBodyWechatOrderRequestobj){

Ordersorders=null;

if(StringUtils.isNotBlank(obj.getOrderId())){

orders=ordersService.searchOrder(user,obj.getOrderId());

}else{

orders=ordersService.createOrder(user,obj);

}

WechatOrderResponsewechatOrderResponse=newWechatOrderResponse();

wechatOrderResponse.setCodeUrl(wechatService.createOrderInfo(orders,user.getPayType()));

wechatOrderResponse.setOrderId(orders.getOrderId());

returnResultUtil.success(wechatOrderResponse);

}

该方法仅供参考,上方方法中对订单id进行了一个判空操作,因为我这边有可能是用户未支付订单,继续支付的操作,代码主要是wechatService.createOrderInfo方法,实现如下:

publicStringcreateOrderInfo(Ordersorders,StringpayType){

WxPayMwebOrderResultresult=null;

try{

WxPayUnifiedOrderRequestorderRequest=newWxPayUnifiedOrderRequest();

orderRequest.setOutTradeNo(orders.getOrderId());

orderRequest.setBody("我是商品描述");

orderRequest.setTotalFee(orders.getAmount().multiply(newBigDecimal("100")).intValue());//金额需要扩大100倍:1代表支付时是0.01

orderRequest.setSpbillCreateIp(DispatchParams.getInstance().getWechatSpbillCreateIp());

orderRequest.setProductId(orders.getOrderId());

orderRequest.setTradeType(WxPayConstants.TradeType.MWEB);//h5网页支付

result=wxPayService.createOrder(orderRequest);

returnresult.getMwebUrl();

}catch(WxPayExceptione){

logger.error("[微信支付异常]异常",e);

//抛出一个自定义全局异常「自己定义」

thrownewCommonException(微信支付异常提示信息,状态码);

}

}

具体参数就不啰嗦了,详细请看官方支付文档。

综上,当前端调用createOrder方法,将 weixin://wxpay/bizpayurl?pr=IzX8nS 返回给前端,那么前端怎么调用呢?

下面是我的一个测试例子,其中res.codeUrl为后端返回的URL

window.open(res.codeUrl,'_blank’);

是的,就是这么简单,新窗口打开就可以了,看一下运行调起微信的截图「我手机装了两个微信」:

支付成功后会回调后端接口,具体由后端参数配置的return_url控制。

2.4、微信回调接口

当支付完成后,微信会自动回调该接口,我们可以根据返回的信息修改订单状态,看一下方法,代码仅供参考:

@RequestMapping(value="/notify")

@ResponseBody

publicStringnotify(Stringbody)throwsException{

WxPayOrderNotifyResultresult=null;

try{

result=wxPayService.parseOrderNotifyResult(body);

}catch(WxPayExceptione){

logger.error("[微信解析回调请求]异常",e);

returnWxPayNotifyResponse.fail(e.getMessage());

}

logger.info("处理微信支付平台的订单支付");

logger.info(JSONObject.toJSONString(result));

Stringappid=result.getAppid();//应用ID

Stringattach=result.getAttach();//商家数据包

Stringbank_type=result.getBankType();//付款银行

Integercash_fee=result.getCashFee();//现金支付金额

Stringfee_type=result.getFeeType();//货币种类

Stringis_subscribe=result.getIsSubscribe();//是否关注公众账号

Stringmch_id=result.getMchId();//商户号

Stringnonce_str=result.getNonceStr();//随机字符串

Stringopenid=result.getOpenid();//用户标识

Stringout_trade_no=result.getOutTradeNo();//获取商户订单号

Stringresult_code=result.getResultCode();//业务结果

Stringreturn_code=result.getReturnCode();//SUCCESS/FAIL

Stringsign=result.getSign();//获取签名

Stringtime_end=result.getTimeEnd();//支付完成时间

Integertotal_fee=result.getTotalFee();//获取订单金额

Stringtrade_type=result.getTradeType();//交易类型

Stringtransaction_id=result.getTransactionId();//微信支付订单号

//如果成功写入数据库

if("SUCCESS".equals(return_code)){//如果微信返回的结果是success,则修改订单状态

Ordersorders=ordersDao.selectByOrderId(out_trade_no);

//验证签名

if(orders!=null){

if(!"1".equals(orders.getOrderStatus())){//判断是否订单已经完成了

//判断金额是否跟数据库订单金额一致,放置人为修改

if(orders.getAmount().multiply(newBigDecimal("100")).compareTo(newBigDecimal(total_fee))==0){

//更新订单状态

业务逻辑处理部分...

returnWxPayNotifyResponse.success("订单已经处理成功!");

}else{

logger.error("微信:金额不一致!");

returnWxPayNotifyResponse.fail("订单金额不一致");

}

}else{

returnWxPayNotifyResponse.success("订单已经处理成功!");

}

}else{

returnWxPayNotifyResponse.fail("商户订单号不匹配");

}

}

System.out.println("回调成功");

System.out.println("----返回给微信的xml:"+result);

returnWxPayNotifyResponse.success("支付成功!");

}

如上代码,微信返回的是XML,经过wxPayService.parseOrderNotifyResult()方法转换后得到WxPayOrderNotifyResult实体,具体参数我上边罗列出来了「尽管没用到」,然后就是修改数据库订单状态等操作。

最后

博客地址:/niceyoo

如果觉得这篇文章有丶东西,不放关注一下我,关注是对我最大的鼓励~

专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。