Переглянути джерело

微信扫码支付模式一Demo

小柒2012 7 роки тому
батько
коміт
1ee3d14c96

+ 0 - 2
.gitignore

@@ -7,6 +7,4 @@
 *.ear
 /target/
 /.settings/
-zfbinfo.properties
-wxinfo.properties
 *apiclient_cert.p12

+ 6 - 3
README.md

@@ -56,9 +56,10 @@ heartbeat_duration = 900
 
 ##微信
 
-- 扫码支付:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1
-- 公众号支付:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
 - H5支付:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1
+- 公众号支付:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
+- 扫码支付模式一:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
+- 扫码支付模式二:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
 - 微信退款说明:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3
 - 参数wxinfo.properties
 
@@ -97,13 +98,15 @@ CERT_PATH = apiclient_cert.p12
 - 支付宝手机端H5支付Demo已经测试完成
 - 支付宝电脑支付Demo已经测试完成
 
-- 微信二维码支付Demo测试完成
+- 微信二维码支付模式二Demo测试完成
 - 微信公众号支付(需要添加认证网址)
 - 微信H5支付(审核中)
 
 - 银联支付电脑支付Demo测试完成
 - 银联支付H5支付Demo测试完成
 
+- 微信二维码支付模式一Demo测试完成
+
 
 作者: 小柒2012
 

+ 100 - 0
src/main/java/com/itstyle/modules/weixinpay/controller/WeixinPayController.java

@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -23,6 +24,7 @@ import com.itstyle.common.constants.Constants;
 import com.itstyle.common.model.Product;
 import com.itstyle.modules.weixinpay.service.IWeixinPayService;
 import com.itstyle.modules.weixinpay.util.ConfigUtil;
+import com.itstyle.modules.weixinpay.util.HttpUtil;
 import com.itstyle.modules.weixinpay.util.PayCommonUtil;
 import com.itstyle.modules.weixinpay.util.XMLUtil;
 
@@ -38,6 +40,9 @@ public class WeixinPayController {
 	@Autowired
 	private IWeixinPayService weixinPayService;
 	
+	@Value("${wexinpay.notify.url}")
+	private String notify_url;
+	
 	@RequestMapping("/index")
     public String   index() {
         return "weixinpay/index";
@@ -132,4 +137,99 @@ public class WeixinPayController {
 		}
 
 	}
+	/**
+	 * 模式一支付回调URL(生成二维码见 qrCodeUtil)
+	 * 商户支付回调URL设置指引:进入公众平台-->微信支付-->开发配置-->扫码支付-->修改
+	 * @Author  科帮网
+	 * @param request
+	 * @param response
+	 * @throws Exception  void
+	 * @Date	2017年8月3日
+	 * 更新日志
+	 * 2017年8月3日  科帮网 首次创建
+	 *
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes"})
+	@RequestMapping(value = "bizpayurl")
+	public void bizpayurl(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		logger.info("模式一支付回调URL");
+		//读取参数
+		InputStream inputStream = request.getInputStream();
+		StringBuffer sb = new StringBuffer();
+		String s;
+		BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+		while ((s = in.readLine()) != null) {
+			sb.append(s);
+		}
+		in.close();
+		inputStream.close();
+		
+		//解析xml成map
+		Map<String, String> map = XMLUtil.doXMLParse(sb.toString());
+		//过滤空 设置 TreeMap
+		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
+		Iterator it = map.keySet().iterator();
+		while (it.hasNext()) {
+			String parameter = (String) it.next();
+			String parameterValue = map.get(parameter);
+
+			String v = "";
+			if (null != parameterValue) {
+				v = parameterValue.trim();
+			}
+			packageParams.put(parameter, v);
+		}
+        //判断签名是否正确
+        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, ConfigUtil.API_KEY)) {
+        	//统一下单
+            SortedMap<Object, Object> params = new TreeMap<Object, Object>();
+    		ConfigUtil.commonParams(params);
+    		//随即生成一个 入库 走业务逻辑
+    		String out_trade_no=Long.toString(System.currentTimeMillis());
+    		params.put("body", "模式一扫码支付");// 商品描述
+    		params.put("out_trade_no", out_trade_no);// 商户订单号
+    		params.put("total_fee", "100");// 总金额
+    		params.put("spbill_create_ip", "192.168.1.66");// 发起人IP地址
+    		params.put("notify_url", notify_url);// 回调地址
+    		params.put("trade_type", "NATIVE");// 交易类型
+    		
+    		String paramsSign = PayCommonUtil.createSign("UTF-8", params, ConfigUtil.API_KEY);
+    		params.put("sign", paramsSign);// 签名
+    		String requestXML = PayCommonUtil.getRequestXml(params);
+
+    		String resXml = HttpUtil.postData(ConfigUtil.UNIFIED_ORDER_URL, requestXML);
+    		Map<String, String>  payResult = XMLUtil.doXMLParse(resXml);
+    		String returnCode = (String) payResult.get("return_code");
+    		if("SUCCESS".equals(returnCode)){
+    			String resultCode = (String) payResult.get("result_code");
+    			if("SUCCESS".equals(resultCode)){
+    				logger.info("(订单号:{}生成微信支付码成功)",out_trade_no);
+    				
+                    String prepay_id = payResult.get("prepay_id");
+                    SortedMap<Object, Object> prepayParams = new TreeMap<Object, Object>();
+                    ConfigUtil.commonParams(params);
+                    prepayParams.put("prepay_id", prepay_id);
+                    prepayParams.put("return_code", "SUCCESS");
+                    prepayParams.put("result_code", "SUCCESS");
+                    String prepaySign =  PayCommonUtil.createSign("UTF-8", prepayParams, ConfigUtil.API_KEY);
+                    prepayParams.put("sign", prepaySign);
+                    String prepayXml = PayCommonUtil.getRequestXml(prepayParams);
+                    
+                    //通知微信 预下单成功
+                    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
+        			out.write(prepayXml.getBytes());
+        			out.flush();
+        			out.close();
+    			}else{
+    				String errCodeDes = (String) map.get("err_code_des");
+    				logger.info("(订单号:{}生成微信支付码(系统)失败[{}])",out_trade_no,errCodeDes);
+    			}
+    		}else{
+    			String returnMsg = (String) map.get("return_msg");
+    			logger.info("(订单号:{} 生成微信支付码(通信)失败[{}])",out_trade_no,returnMsg);
+    		}
+        }else{
+        	logger.info("签名错误");
+        }
+	}
 }

+ 11 - 5
src/main/java/com/itstyle/modules/weixinpay/util/qrCodeUtil.java

@@ -1,27 +1,33 @@
 package com.itstyle.modules.weixinpay.util;
 import java.util.SortedMap;
 import java.util.TreeMap;
+
 import com.alipay.demo.trade.utils.ZxingUtils;
 /**
  * 二维码生成器(扫码支付模式一)
- * 创建者 科帮网
+ * 创建者  小柒2012 https://blog.52itstyle.com/
  * 创建时间	2017年8月2日
  */
 public class qrCodeUtil {
+	//商户支付回调URL设置指引:进入公众平台-->微信支付-->开发配置-->扫码支付-->修改 加入回调URL
     public static void main(String[] args) {
 		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
+		//封装通用参数
 		ConfigUtil.commonParams(packageParams);
 		packageParams.put("product_id", "20170731");//真实商品ID
 		packageParams.put("time_stamp", PayCommonUtil.getCurrTime());
+		//生成签名
 		String sign = PayCommonUtil.createSign("UTF-8", packageParams, ConfigUtil.API_KEY);
+		//组装二维码信息(注意全角和半角:的区别 狗日的腾讯)
     	StringBuffer qrCode = new StringBuffer();
-    	qrCode.append("weixin://pay.52itstyle.com//bizpayurl?");//生产回调地址
-    	qrCode.append("appid"+ConfigUtil.APP_ID);
+    	qrCode.append("weixin://wxpay/bizpayurl?");
+    	qrCode.append("appid="+ConfigUtil.APP_ID);
     	qrCode.append("&mch_id="+ConfigUtil.MCH_ID);
     	qrCode.append("&nonce_str="+packageParams.get("nonce_str"));
-    	qrCode.append("&product_id=1");
+    	qrCode.append("&product_id=20170731");
     	qrCode.append("&time_stamp="+packageParams.get("time_stamp"));
     	qrCode.append("&sign="+sign);
+    	//生成二维码
         ZxingUtils.getQRCodeImge(qrCode.toString(), 256, "D:\\weixn.png");
 	}
-}
+}

+ 14 - 0
src/main/resources/wxinfo.properties

@@ -0,0 +1,14 @@
+#\u670d\u52a1\u53f7\u7684\u5e94\u7528ID \u6b22\u8fce\u5173\u6ce8https://blog.52itstyle.com/
+APP_ID = XXXXXXXXXXXXXXXX
+#\u670d\u52a1\u53f7\u7684\u5e94\u7528\u5bc6\u94a5
+APP_SECRET = XXXXXXXXXXXXXXXX
+#\u670d\u52a1\u53f7\u7684\u914d\u7f6etoken
+TOKEN = XXXXXXXXXXXXXXXX
+#\u5546\u6237\u53f7
+MCH_ID = XXXXXXXXXXXXXXXX
+#API\u5bc6\u94a5
+API_KEY = XXXXXXXXXXXXXXXX
+#\u7b7e\u540d\u52a0\u5bc6\u65b9\u5f0f
+SIGN_TYPE = MD5
+#/\u5fae\u4fe1\u652f\u4ed8\u8bc1\u4e66\u540d\u79f0
+CERT_PATH = apiclient_cert.p12

+ 26 - 0
src/main/resources/zfbinfo.properties

@@ -0,0 +1,26 @@
+# \u652f\u4ed8\u5b9d\u7f51\u5173\u540d\u3001partnerId\u548cappId \u6b22\u8fce\u5173\u6ce8https://blog.52itstyle.com/
+open_api_domain = https://openapi.alipay.com/gateway.do
+mcloud_api_domain = http://mcloudmonitor.com/gateway.do
+#\u6b64\u5904\u8bf7\u586b\u5199\u4f60\u7684PID
+pid =XXXXXXXXXXXXXXXX
+#\u6b64\u5904\u8bf7\u586b\u5199\u4f60\u5f53\u9762\u4ed8\u7684APPID 
+appid =XXXXXXXXXXXXXXXX
+
+# RSA\u79c1\u94a5\u3001\u516c\u94a5\u548c\u652f\u4ed8\u5b9d\u516c\u94a5
+private_key = XXXXXXXXXXXXXXXX
+public_key = XXXXXXXXXXXXXXXX
+alipay_public_key = XXXXXXXXXXXXXXXX
+
+# \u5f53\u9762\u4ed8\u6700\u5927\u67e5\u8be2\u6b21\u6570\u548c\u67e5\u8be2\u95f4\u9694\uff08\u6beb\u79d2\uff09
+max_query_retry = 5
+query_duration = 5000
+
+# \u5f53\u9762\u4ed8\u6700\u5927\u64a4\u9500\u6b21\u6570\u548c\u64a4\u9500\u95f4\u9694\uff08\u6beb\u79d2\uff09
+max_cancel_retry = 3
+cancel_duration = 2000
+
+# \u4ea4\u6613\u4fdd\u969c\u7ebf\u7a0b\u7b2c\u4e00\u6b21\u8c03\u5ea6\u5ef6\u8fdf\u548c\u8c03\u5ea6\u95f4\u9694\uff08\u79d2\uff09
+heartbeat_delay = 5
+heartbeat_duration = 900
+
+