当前位置:   article > 正文

微信小程序接入微信支付(四):接收支付结果通知与沙箱测试_微信小程序沙箱支付

微信小程序沙箱支付

代码主体写完后,还有不可或缺的部分需要补充完整,即接收支付结果通知,官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8

目录:

微信小程序接入微信支付(一):大概流程与准备需知
微信小程序接入微信支付(二):后台调用统一下单接口
微信小程序接入微信支付(三):小程序端调用支付接口
微信小程序接入微信支付(四):接收支付结果通知与沙箱测试

支付结果通知:

微信支付官方会调用我们“notify_url” 提供地接口来进行异步地通知每笔订单的支付结果。如果我们提供的接口出现问题,则会按照一定的频率多次通知过来。此外当我们接收到通知后,需要根据通知内容进行处理,并及时把结果回调给微信支付官方。

简单提供下我的代码:

	/**
	 * 暂定为 获取支付结果通知接口 ,根据接收到的通知,处理支付结果
	 * 
	 * @return
	 * @throws Exception 
	 */
	@PostMapping("/getresult")
    @ResponseBody	
	public String getResult(@RequestBody String res) throws Exception {
		String errMsg = "Unknown error";
		String xmlMsg = "<xml>"+
						"<return_code>"+"FAIL"+"</return_code>"+
						"<return_msg>"+errMsg+"</return_msg>"+
						"</xml>";
		
		//接收到的xml格式字符串转map
		Map<String, String> resultMap = xmlToMap(res);
		String return_code;
        if (resultMap.containsKey("return_code")) {
            return_code = resultMap.get("return_code");
        }
        else {
        	errMsg = "No 'return_code' in XML";
            throw new Exception(String.format("GETRESULT No `return_code` in XML: %s", res));
        }
        
        if (return_code.equals("FAIL")) {
        	errMsg = "return_code is FAIL";
        	throw new Exception("GETRESULT return_code : fail from wx_pay :" + res);
        }
        else if (return_code.equals("SUCCESS")) {
        	LOG.info("----getresult success order_no: " + resultMap.get("out_trade_no"));
    		//TODO 签名验证支付结果通知
    		//查询本地该订单
    		Order order =orderservice.selectOrdersByExample(Long.parseLong(resultMap.get("out_trade_no")), null, null, null).get(0);
    		
    		if(order.getOrder_state() != 0 && resultMap.get("time_end") != null) {
    			//订单状态--已支付, 微信通知支付结果--支付成功 返回成功
    			xmlMsg ="<xml>"+
						"<return_code>"+"SUCCESS"+"</return_code>"+
						"<return_msg>"+"OK"+"</return_msg>"+
						"</xml>";
    			return xmlMsg;
    		}else if(order.getOrder_state() != 0 && resultMap.get("time_end") == null) {
    			//订单状态--已支付, 微信通知支付结果--支付未成功 不做操作返回成功
    			xmlMsg ="<xml>"+
						"<return_code>"+"SUCCESS"+"</return_code>"+
						"<return_msg>"+"OK"+"</return_msg>"+
						"</xml>";
    			return xmlMsg;
    		}else if(order.getOrder_state() == 0 && resultMap.get("time_end") != null){
    			//订单状态--待付款, 微信通知支付结果--支付成功 更改订单状态为1--待发货 返回成功
    			orderservice.updateOrder(Long.parseLong(resultMap.get("out_trade_no")), null, 1);
    			xmlMsg ="<xml>"+
						"<return_code>"+"SUCCESS"+"</return_code>"+
						"<return_msg>"+"OK"+"</return_msg>"+
						"</xml>";
    			return xmlMsg;
    		}else {
    			//其余情况,先按已处理解决,返回成功
    			xmlMsg ="<xml>"+
						"<return_code>"+"SUCCESS"+"</return_code>"+
						"<return_msg>"+"OK"+"</return_msg>"+
						"</xml>";
    			return xmlMsg;
    		}
    		//TODO 处理数据时建议使用数据锁进行并发控制
        }   
        
		return xmlMsg;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

相关外部方法可在前面章节中查看:微信小程序接入微信支付(二):后台调用统一下单接口
建议对接受的通知进行签名认证,处理数据时使用数据锁进行并发控制。

沙箱测试:

当我们代码写完后需要进行测试,微信支付官方提供专门的沙箱环境用于测试,不会产生金额交易。
官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=23_1&index=2

我们只需要在调用接口的URL地址中加入/sandboxnew,
例如统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder
可改为https://api.mch.weixin.qq.com/sanboxnew/pay/unifiedorder 就能访问到沙箱环境,但是使用沙箱环境时,我们不能使用商户自己的key,而是通过后台调用-获取验签秘钥API接口来获取沙箱环境专用的key。

		//沙箱环境下需先请求获取key
		Map<String, String> testMap = new HashMap<>();
		testMap.put("mch_id", mchId);
		testMap.put("nonce_str",getRandomString());
		//生成符合规格的签名串
		String stringTestSignTemp = getParamStr(testMap,realKey);
		//进行MD5运算,并转为大写,获得sign参数的值
		String signTestValue = MD5(stringTestSignTemp.toString()).toUpperCase();
		//把sign放入map中
		testMap.put("sign",signTestValue);
		//map转义为xml格式
		String requestTestParam = mapToXml(testMap);
		LOG.info("request sandbox API key - [parameters]:" +requestTestParam);
		System.out.println("request sandbox API key - [parameters]:" +requestTestParam);
		//发送请求
		String testResult = sendPostParam(sandBoxUrl, requestTestParam);
		System.out.println("request sandbox API key - [results]:" +testResult);
		LOG.info("request sandbox API key - [results]:" +testResult);
		//将返回的结果从xml字符串转义为map
		Map<String, String> testResultMap = xmlToMap(testResult);
		if(testResultMap.get("return_code") != null && testResultMap.get("return_code") == "SUCCESS") {
			sandKey = testResultMap.get("sandbox_signkey");
			System.out.println("----sandbox key: " + sandKey);
			LOG.info("---sandbox key:" + sandKey);
		}else {
			return null;
		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

!注意:

我们可以根据沙箱环境的反馈来修改我们的代码以及参数,但是当我们发现自己明明没有什么错误时,沙箱环境依旧报错,那么我们可以转到正式环境去测试了。。。。。。就像有些网友说的,这个沙箱环境一步一个坑,bug满天飞。当转到正式环境时,你就会发现原来自己没错。。。。。。说多了都是泪

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/186240
推荐阅读
相关标签
  

闽ICP备14008679号