玩轉小程序支付之支付結果通知

上一篇講了小程序支付的過程,接下來就是支付結果通知php

官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7java

注意: 小程序

支付通知的url 是經過【統一下單API】中提交的參數notify_url設置,若是連接沒法訪問,商戶將沒法接收到微信通知。api

通知url必須爲直接可訪問的url,不能攜帶參數。示例:notify_url:「https://pay.weixin.qq.com/wxpay/pay.action」服務器

 

在前面的支付的參數中設置了支付結果的URL——baseUrl+"/notify"微信

因此支付通知會發到我本身服務器下的這個路徑下,會接收到相似以下的xml字符串(若是正常的話,即result_code 和return_code都爲SUCCESS)app

解析這個xml,能夠獲得transaction_id,out_trade_no等關鍵信息。ui

爲了保證返回信息是否正確,咱們能夠去驗證其正確性。加密

方法是對參數進行加密獲取的簽名,而後比對返回的簽名和咱們生成的簽名是否一致,若不一致就代表返回的支付通知被修改,不過通常不會出現這種狀況。url

注意:

 多是微信方面以爲一次不必定能通知到,因此支付通知可能會發屢次,因此咱們在收到正確的通知以後,須要給小程序官方返回一段xml,表示收到,以後就不會再收到啦。

 

整個支付通知的處理的代碼以下

/**
	 * 支付完成通知
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/notify",method = RequestMethod.POST)
    public String notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
        	sb.append(line);
        }
        //解析並給微信發回收到通知確認
        Map map =  PayUtils.doXMLParse(sb.toString());
        String returnCode = map.get("return_code").toString();
        if(returnCode.equals("SUCCESS")){
        	String resultCode = map.get("result_code").toString();
        	if(resultCode.equals("SUCCESS")){
        		SortedMap<String, String> packageParams = new TreeMap<String, String>();
        		packageParams.put("appid", map.get("appid").toString());
        		packageParams.put("attach", map.get("attach").toString());
        		packageParams.put("bank_type", map.get("bank_type").toString());
        		packageParams.put("cash_fee", map.get("cash_fee").toString());
        		packageParams.put("fee_type", map.get("fee_type").toString());
        		packageParams.put("is_subscribe", map.get("is_subscribe").toString());
        		packageParams.put("mch_id", map.get("mch_id").toString());
        		packageParams.put("nonce_str", map.get("nonce_str").toString());
        		packageParams.put("openid", map.get("openid").toString());
        		packageParams.put("out_trade_no", map.get("out_trade_no").toString());
        		packageParams.put("result_code", map.get("result_code").toString());
        		packageParams.put("return_code", map.get("return_code").toString()); 
        		packageParams.put("time_end", map.get("time_end").toString());
        		packageParams.put("total_fee", map.get("total_fee").toString());
        		packageParams.put("trade_type", map.get("trade_type").toString());
        		packageParams.put("transaction_id", map.get("transaction_id").toString());
        		String sign = PayUtils.createSign(packageParams,key);
        		String originSign = map.get("sign").toString();
        		if(sign.equals(originSign)){
        			//簽名一致,保存支付流水
        			String xml="<xml>"
                			  +"<return_code>SUCCESS</return_code>"
                			  +"<return_msg>OK</return_msg>"
                			  +"</xml>";
        			ProfPayLog payLog = new ProfPayLog();
        			payLog.setCreatedAt(new Date());
        			payLog.setSource(Source.WeiXin);
        			DecimalFormat df = new DecimalFormat("######0.00"); 
        			payLog.setTotalFee(String.valueOf(df.format((Double.valueOf(map.get("total_fee").toString())/100))));
        			payLog.setTradeNo(map.get("out_trade_no").toString());
        			payLog.setTransactionId(map.get("transaction_id").toString());
        			String attach = map.get("attach").toString();//userId+"#wx#"+activityId
        			payLog.setUserId(attach.split("#wx#")[0]);
        			payLog.setType(ProfPayLog.Type.Pay);
        			WxappUser user = wxappUserService.find(Long.valueOf(attach.split("#wx#")[0]));
        			WxappActivity activity = wxappActivityService.find(Long.valueOf(attach.split("#wx#")[1]));
        			WxappActivityApply activityApply = wxappActivityApplyService.findActivityApplyByUserAndActivity(user, activity);
        			if(activityApply.getPayLogId() != null){
        				System.out.println("=========已經完成了存儲支付流水=========");
        				return xml;
        			}else{
        				System.out.println("=========完成第一次保存支付流水=========");
        				payLog = wxappPayService.save(payLog);
        				//在活動申請表中關聯上支付流水的id
            			activityApply.setPayLogId(String.valueOf(payLog.getId()));
            			wxappActivityApplyService.save(activityApply);
                    	return xml;
        			}
        		}else{
        			String xml="<xml>"
        	      			  +"<return_code>FAIL</return_code>"
        	      			  +"<return_msg>簽名不一致</return_msg>"
        	      			  +"</xml>";
        	      	return xml;
        		}
        	}else{
        		String xml="<xml>"
            			  +"<return_code>FAIL</return_code>"
            			  +"<return_msg>支付通知失敗</return_msg>"
            			  +"</xml>";
            			return xml;
        	}
        } else {
        	String xml="<xml>"
      			  +"<return_code>FAIL</return_code>"
      			  +"<return_msg>支付通知失敗</return_msg>"
      			  +"</xml>";
      			return xml;
        }
    }
相關文章
相關標籤/搜索