微信支付接入,就差这一步

首先测试号是无法接入微信支付功能的。必需有公众号并开通支付功能,不会的可以让公司的商务帮你开通。

1. 公众号后台  找到“接口权限”选项,然后找到“网页授权获取用户基本信息”,点“修改”


2.打开界面点“设置”



3.添加网页授权域名,注意去掉“http://”

将下载下来的MP_verify_qHZ4JkZ2soVXMEYX.txt文件放到Tomcatroot。放好后先试试能不能访问,启动tomcat,用chenyuan.tunnel.2bdata.com/MP_verify_qHZ4JkZ2soVXMEYX.txt看能不能正常显示,最好点击确认会提示到成功的。


4.添加授权目录




按图找到授权目录添加地址。添加授权必需精确到支付页面的父目录,而且如果父目录有子目录,子目录下也是不可以发起支付的,切记,切记。


5.看支付流程图:



太多,太晕,简而言之,除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。

前台先通知后台向微信服务器发起“生成预支付交易单”请求,后台正确获取数据再组织报文将数据返回给前端,前台再组织数据调用JSAPI接口把预支付交易单上的数据携带给微信服务器,后面就不用我们管了,微信服务器验证正确后会自动通知微信弹出输入密码框,微信服务器输入成功后会给前端返回成功还是失败值,同时把交易数据以post方式传给商户后台系统,链接是发预支付交易单请求时传的notifyUrl值,微信服务器不能保证向前端和后端返回的数据有先后顺序,一般情况下不用管。

先上代码,java后台收到前端要支付的请求,先发起预支付交易单请求:


@ApiOperation(value = "预付请求", notes = "预付请求")
	@ApiImplicitParams({ @ApiImplicitParam(name = "ordCd", value = "订单号", required = true, dataType = "String") })
	@RequestMapping(value = "ordPrePay", method = RequestMethod.GET)
	@ResponseBody
	public Object ordPrePay(@RequestParam(value = "ordCd", required = true) String ordCd, HttpServletRequest request) {
		try {
			UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo");
			if (null == userInfo) {
				ExpUtil.handle("未网页授权获得用户基本信息,请从微信首页进入!!", logger);
			}
			OrdDtox ordDtox = ordMgrx.getOrdByOrdCd(ordCd);

			if (null == ordDtox) {
				ExpUtil.handle("订单号【" + ordCd + "】查询失败,请确认!", logger);
			}
//weixin-java-mp.jar提供的API
			Map<String, String> payInfo = this.wxMpPayService.getPayInfo(WxPayUnifiedOrderRequest.builder()
					.body(ordDtox.getOrdVo().getWacNm() + "-" + ordDtox.getOrdVo().getNm())
					.totalFee(ordDtox.getOrdVo().getOrdAmt().multiply(new BigDecimal(100)).intValue())
					.spbillCreateIp(request.getRemoteAddr()).outTradeNo(ordDtox.getOrdVo().getCd())
					.openid((String) request.getSession().getAttribute("openId")).build());
			System.out.println(payInfo.toString());
			return payInfo;
		} catch (Throwable t) {
			return buildFailure(ExpUtil.capture(BaseSvcMsgCode.insertFailure, "下单失败", t, logger));
		}
	}

其中有些参数你以为没传吗,其实我在外部已经配了。



将配置的参数存放到WxMpConfigStorage里,再将WxMpConfigStorage注入到WxMpService里,那就不会每次都添加appid等参数了。

其中:notifyURL的作用是:当前端调用WeixinJSBridge.getBrandWCPayRequest方法发请支付请求并支付成功后,微信服务器将参数通知的该地址,数据以POST携带。我们在些链接上做支付成功的后台逻辑操作,比如记录消费记录,修改订单详情等。

 

在预支付交易单里appid,macId,key不用设置,后台会WxMpConfigStorage里得到配置参数从配置文件里补充,nonceStr,sign可由java自动生成,如下


看看unifiedOrder的方法。



当关键参数没有时,会从config里取,注意对着api看哪些参数可以不用传,当然也可参照我上面写的例子。

如果返回:

<xml><return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[appid and openid not match]]></return_msg>
</xml>

则说明,传的openId不是指定公众号下的用户,出现这种情况有可能开发时测试公众号与开发公众号混合开发了。

 

正确返回数据如下:

prePay返回给前端数据:

{appId=wxf81943674XXX, timeStamp=1494902640, signType=MD5, package=prepay_id=wx20170516104359f71cd93cc00819XXXX, nonceStr=1494902640216, paySign=0DFFC6C2A9319E718B5XXXXX}

成功返回给前端后,前端使用JSAPI里的WeixinJSBridge.getBrandWCPayRequest方法发请支付请求。

注意:WeixinJSBridge内置对象在其他浏览器中无效

前端支付请求代码如下:

//用ajax向后台发请预计交易支付请求,当后台成功获取数据返回给前端时,前端组织数据发请真正的扣款支付请求。
function payforNow() {
	var json = {};
	json["ordCd"] = vue.cd;
	jQuery.ajax({
		type: "GET",
		url: "../bss/pay/ordPrePay",
		xhrFields: {
			withCredentials: true
		},
		data: json,
		contentType: "application/x-www-form-urlencoded",
		dataType: "json",
		async: true,
		success: function (data) {
			prePayData = data;
//成功得到预支付交易数据
			doBridgeReady(data);
			console.log("appId:" + data.appId);
		},
		error: function (res) {
			console.log("ajax请求失败,res:" + res.toString());
		}
	});
}

//判断浏览器是否支持JSAPI,只用微信内置浏览器可用。
function doBridgeReady(data){
	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(data);
		} 
}

//真实支付请求
function onBridgeReady(data){
	   WeixinJSBridge.invoke(
	       'getBrandWCPayRequest', {
	    	   "appId" : data.appId, /* 微信支付,坑一 冒号是中文字符 */
	           "appId": data.appId,     //公众号名称,由商户传入     
	           "timeStamp": data.timeStamp,         //时间戳,自1970年以来的秒数     
	           "nonceStr": data.nonceStr, //随机串     
	           "package": data.package,     
	           "signType": data.signType,         //微信签名方式:     
	           "paySign": data.paySign //微信签名 
	       },
	       function(res){  
	           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
	        	   window.location.href="../page/orderWaitTakeCloth.jsp";
	           }else{
	        	   alert("支付失败,提示【" + res.err_msg + "】");
	           }
	       }
	   ); 
}

微信服务器验证参数是否正确,如里正确则让微信客户端弹出输入密码框

之后微信服务器验证成功则支付成功,并通知前端。


返回get_brand_wcpay_request:cancel,get_brand_wcpay_request:fail请检查一下授权目录是否包含当前调用h5支付的目录。注意是精确,即使是子目录也没权限,必需授权。

 

notifyURL指定的接收微信服务器返回支付成功的数据:

@ApiOperation(value = "支付成功后台通知", notes = "支付成功后台通知")
	@RequestMapping(value = "paySuccessCallBack", method = RequestMethod.POST)
	@ControllerTraced(name = "支付成功后台通知")
	public Object paySuccessCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			String xmlData = textRequestStream(request);
//将post里的数据读取出来映射成class对象。后台的操作就是自己服务器的逻辑了。
			WxPayOrderNotifyResult wxPayOrderNotifyResult = this.wxMpPayService.getOrderNotifyResult(xmlData);
			//微信订单号,先判断该笔订单是否处理过,如果处理过,则直接返回
			PayLogDtox payLogDtox = payLogMgrx.getPayLogDtox(wxPayOrderNotifyResult.getTransactionId());
			if(null == payLogDtox){
				payMgrx.wxMpPayForSuccessCBack(wxPayOrderNotifyResult);
			}else{
				return WxPayOrderNotifyResponse.fail("收到重复消息");
			}
		} catch (WxErrorException e) {
			e.printStackTrace();
			return WxPayOrderNotifyResponse.fail(e.getMessage());
		}catch (Throwable t) {
    		// ExpUtil.capture(BaseSvcMsgCode.selectFailure,"保存失败", t, logger);
			logger.error("保存失败");
        }
		return WxPayOrderNotifyResponse.success("成功");
	}


结,第一,添加授权目录,而且要精确到支付页面的父目录

第二,自己后台服务器向微信服务器发请预支付交易请求,并将得到的数据传给前端

第三,前端使用WeixinJSBridge.getBrandWCPayRequest方法组织报文数据向微信服务器发起真正的支付请求,验证成功并扣款成功后,微信服务器会将数据通知到预支付交易里填写的notifyURL上。如果交易失败,请查看是否授权目录填写正确,大部分情况是这里出了问题。

第四,nofityURL接收支付数据并插入到数据库。

 

以上帮助大家了解过程,以及解决些bug,我还是要亲自去微信支付接入文档仔细阅读。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Spring Boot项目中实现微信支付接入可以按照以下步骤进行: 1. 首先,需要在项目中引入相应的依赖,如微信支付的sdk和Spring Boot的相关依赖。 2. 在项目中创建微信支付的配置类,可以在该类中配置微信支付的相关信息,如appid、商户号、商户密钥等。可以参考之前提到的中的配置信息。 3. 创建微信支付的服务类,该类中可以编写具体的支付相关的方法,如生成预支付订单、回调处理等。可以使用微信支付sdk提供的API完成支付功能的具体实现。 4. 在需要使用微信支付的地方,可以注入微信支付服务类,并调用相应的方法来完成支付操作。可以结合具体的业务需求,如生成支付链接、调用支付接口等。 需要注意的是,在实现微信支付接入的过程中,还需要处理支付回调通知,以及支付结果的验签等安全问题,确保支付流程的安全性和可靠性。 这样,在Spring Boot项目中就可以实现微信支付接入。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Spring Boot项目实现微信支付支付](https://blog.csdn.net/orton777/article/details/131538447)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [spring+mybatis接入微信支付支付支付(包含微信公众号支付和H5支付)](https://download.csdn.net/download/yongyuai/10603536)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值