微信支付--JS--傻瓜式学习

5 篇文章 0 订阅
3 篇文章 0 订阅

微信支付分为网页内(JS)支付和原生支付(Native),这里主要说的是JS页面支付

步骤描述如下:

1、组合参数,调用JS微信支付。

2、支付成功后,处理订单(修改订单状态)并给微信平台发送一个success通知。

3、发货处理时,需要给微信后台发送发货提醒。

4、如果到期不发货,则微信会给服务号发送一个警告通知,成功收到告警通知后,还要给微信发送一个success通知。

5、微信用户购买商品后,如果未收到获取或质量有问题等一系列问题,可以在微信端发起维权。

6、微信用户维权之后,后台收到微信发送过来的XML,解析XML转化为Java类保存到数据库。

7、维权结果处理。

8、订单退款处理。

9、对账单下载。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一、参数组装

1、页面涉及到六个参数:appId(公众号 id)、timeStamp(时间戳)、nonceStr(随机字符串)、package(订单详情扩展
      字符串)、signType(签名方式)、paySign(签名)。

2、支付后,返回值:err_msg;get_brand_wcpay_request:ok 支付成功

                                                           get_brand_wcpay_request:cancel 支付过程中用户取消

                                                          get_brand_wcpay_request:fail 支付失败

3、后台生成参数(PayCallbackBean类)---SHA1Util类和RequestHandler类demo例子中有;

       (1)获取appId:自己公共号的appId;

       (2)获取timeStamp :timestamp = SHA1Util.getTimeStamp();

       (3)获取nonceStr:noncestr = SHA1Util.getNonceStr();

       (4)获取signType:signType=SHA1;

       (5)获取package:

                      RequestUtil.getClientIP()的方法为:

           public static String getClientIP() {
           ExternalContext ec = FacesContext.getCurrentInstance()
				.getExternalContext();
		HttpServletRequest request = (HttpServletRequest) ec.getRequest();

   		if (request == null)
			return "";

 		String ip = request.getHeader("X-Forwarded-For");
		 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
 			ip = request.getHeader("Proxy-Client-IP");
 		}
		 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
 			ip = request.getHeader("WL-Proxy-Client-IP");
		 }
		 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
 			ip = request.getHeader("HTTP_CLIENT_IP");
 		}
		 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
 		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		 }

		 return ip;
 	}

        

        SortedMap<String, String> map = new TreeMap<String, String>();

        map.put("bank_type", "WX");
        map.put("body", "商品名称");
        map.put("partner", "财付通商户身份的标识。前三项审核通过后,在财付通发送的邮件中查看");
        map.put("out_trade_no", "订单Id");
        map.put("total_fee", "订单总价");
        map.put("fee_type", "1");
        map.put("notify_url", "公众号申请支付的时候需要填写的一个链接,微信后台通过此链接来通知支付结果的返回");
        map.put("spbill_create_ip", RequestUtil.getClientIP());
        map.put("input_charset", "UTF-8");

        RequestHandler queryReq = new RequestHandler(null, null);
        queryReq.init("公众号 id", "自己公众号的appkey", "公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份",
               "财付通商户权限密钥 Key");

        String packageValue = queryReq.genPackage(map);
       (6)获取paySign:
                      SortedMap<String, String> map = new TreeMap<String, String>();
                                            map.put("appid", "appId");
                                            map.put("timestamp", "timeStamp");
                                            map.put("noncestr", "nonceStr");
                                            map.put("package","package");
                                            map.put("appkey", "自己公众号的appkey");
                                            String paySign = SHA1Util.createSHA1Sign(map);

  

               后台组装参数成功之后,返回给页面json格式的信息:appId、timeStamp、nonceStr、packageValue、signType、paySign前文已经获取

        JSONObject jsonObject = new JSONObject();
        jsonObject.accumulate("appId",appId);
        jsonObject.accumulate("timeStamp", timeStamp);
        jsonObject.accumulate("nonceStr", nonceStr);
        jsonObject.accumulate("packageValue", packageValue);
        jsonObject.accumulate("signType", signType);
        jsonObject.accumulate("paySign", paySign);
        jsonObject.accumulate("result", "110000");
        System.out.println(jsonObject.toString());

        //把json格式发送回页面
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext.setResponseContentType("application/json");
        externalContext.setResponseCharacterEncoding("UTF-8");
        // 写入josn格式数据
        try {
            externalContext.getResponseOutputWriter().write(jsonObject.toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        facesContext.responseComplete();

 

4、页面js代码:

<script>
			function callpay() {
				var oId = "#{ProductDetailBean.order.orderId}";
				var u = "pacakageValue.jsf?oId=" + oId;
				//alert(u);
				jQuery
						.ajax({
							async : true,
							cache : true,
							contentType : "application/json",
							type : "post",
							url : u,
							data : {
								oId : oId
							},
							dataType : "json",
							success : function callback(data) {
								var result001 = data.result;
								//alert("afda=" + result001);
								if (result001 == "110000") {
									//100000 成功调用方法
									var appId = data.appId;
									var timeStamp = data.timeStamp;
									var nonceStr = data.nonceStr;
									var packageValue = data.packageValue;
									var signType = data.signType;
									var paySign = data.paySign;
									WeixinJSBridge
											.invoke(
													'getBrandWCPayRequest',
													{
														"appId" : appId,
														"timeStamp" : timeStamp,
														"nonceStr" : nonceStr,
														"package" : packageValue,
														"signType" : signType,
														"paySign" : paySign
													},
													function(res) {
														WeixinJSBridge
																.log(res.err_msg);
														var msg = res.err_msg;
														if ("get_brand_wcpay_request:ok" == msg) {
															window.location.href = "#{request.contextPath}/wx/profile/home.jsf";
														} else {
															orderFail(oId);
															alert("支付异常,稍后再试");
															window.location.href = "#{request.contextPath}/wx/profile/home.jsf";
														}
													});
								} else if (result001 == "110001") {
									//110001 商品下架
									alert("商品下架");
								} else if (result001 == "110002") {
									// 110002 没有库存了
									alert("没有库存了");
								} else if (result001 == "110003") {
									//110003 该店铺不存在了
									alert("该店铺不存在了");
								} else {
									//其他情况
									alert("出错了,稍后再试");
								}
							}
						});
			}

			function orderFail(orderId) {
				var url = "orderPayFail.jsf?oId=" + orderId;
				jQuery
				.ajax({
					contentType : "application/json",
					type : "post",
					url : url,
					data : {
						oId : orderId
					},
					dataType : "json"});
			}
		</script>

二、支付后订单处理

        微信用户支付成功后,微信后台会通过notify_url返回给商户,商户解析返回来的XML然后做订单处理,并返回给微信后台success通知。

   (1)解析微信返回来的XML

             解析XML的封装方法为:

      public static Map<String, String> parseXml(HttpServletRequest request) {
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		// 从request中取得输入流
		InputStream inputStream;
		try {
			inputStream = request.getInputStream();
			SAXReader reader = new SAXReader();
			Document document = reader.read(inputStream);
			// 得到xml根元素
			Element root = document.getRootElement();
			// 得到根元素的所有子节点
			List<Element> elementList = root.elements();

			// 遍历所有子节点
			for (Element e : elementList)
				map.put(e.getName(), e.getText());

			// 释放资源
			inputStream.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (DocumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		inputStream = null;

		return map;
	}
              调用解析方法,把XML解析为Map对象
       ExternalContext ec = FacesContext.getCurrentInstance()
				.getExternalContext();
		HttpServletRequest request = (HttpServletRequest) ec.getRequest();
		// 解析微信返回xml文件
		Map<String, String> requestMap = MessageUtil.parseXml(request);
              把Map里的值赋给java的一个对象(PayConfiguration类)

         PayConfiguration pay= new PayConfiguration();
          Set es = requestMap .entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			System.out.println(k + "===" + v);
			if (k == "OpenId")
				pay.setOpenId(v);
			if (k == "AppId")
				pay.setAppId(v);
			if (k == "IsSubscribe")
				pay.setIsSubscribe(v);
			if (k == "TimeStamp")
				pay.setTimeStamp(v);
			if (k == "NonceStr")
				pay.setNonceStr(v);
			if (k == "AppSignature")
				pay.setAppSignature(v);
			if (k == "SignMethod")
				pay.setSignMethod(v);
         

        String signType = RequestUtil.getRequestParam("sign_type");
        pay.setSignType(signType);
        String inputCharset = RequestUtil.getRequestParam("input_charset");
        pay.setInputCharset(inputCharset);
        String sign = RequestUtil.getRequestParam("sign");
        pay.setPaySign(sign);
        String tradeMode = RequestUtil.getRequestParam("trade_mode");
        pay.setTradeMode(tradeMode);
        String tradeState = RequestUtil.getRequestParam("trade_state");
        pay.setTradeState(tradeState);
        String partner = RequestUtil.getRequestParam("partner");
        pay.setPartnerId(partner);
        String bankType = RequestUtil.getRequestParam("bank_type");
        pay.setBankType(bankType);
        String bankBillno = RequestUtil.getRequestParam("bank_billno");
        pay.setBankBillno(bankBillno);
        String totalFee = RequestUtil.getRequestParam("total_fee");
        pay.setTotalFee(totalFee);
        String feeType = RequestUtil.getRequestParam("fee_type");
        pay.setFeeType(feeType);
        String notifyId = RequestUtil.getRequestParam("notify_id");
        pay.setNotifyId(notifyId);
        String transactionId = RequestUtil.getRequestParam("transaction_id");
        pay.setTransactionId(transactionId);
        String outTradeNo = RequestUtil.getRequestParam("out_trade_no");
        pay.setProductId(outTradeNo);
        String attach = RequestUtil.getRequestParam("attach");
        pay.setAttach(attach);
        String timeEnd = RequestUtil.getRequestParam("time_end");
        pay.setTimeEnd(timeEnd);
        String transportFee = RequestUtil.getRequestParam("transport_fee");
        pay.setTransportFee(transportFee);
        String productFee = RequestUtil.getRequestParam("product_fee");
        pay.setProductFee(productFee);
        String discount = RequestUtil.getRequestParam("discount");
        pay.setDiscount(discount);
        String content = "signType=" + signType + ",inputCharset="
                + inputCharset + ",sign=" + sign + ",tradeMode=" + tradeMode
                + ",tradeState=" + tradeState + ",partner=" + partner
                + ",bankType=" + bankType + ",bankBillno=" + bankBillno
                + ",totalFee=" + totalFee + ",feeType=" + feeType
                + ",notifyId=" + notifyId + ",transactionId=" + transactionId
                + ",outTradeNo=" + outTradeNo + ",attach=" + attach
                + ",timeEnd=" + timeEnd + ",transportFee=" + transportFee
                + ",productFee=" + productFee + ",discount=" + discount;
        //验证微信回调支付成功的签名
        SortedMap<String, String> map = new TreeMap<String, String>();
        map.put("appid", pay.getAppId());
        map.put("appkey", pay.getPaySignKey());
        map.put("timestamp", pay.getTimeStamp());
        map.put("noncestr", pay.getNonceStr());
        map.put("openid", pay.getOpenId());
        map.put("issubscribe", pay.getIsSubscribe());
        String paySign = SHA1Util.createSHA1Sign(map);
        boolean falt=false;
        if (paySign == pay.getAppSignature() || paySign.equals(pay.getAppSignature())) {           
              falt=true;
        } else {  
          falt=true;
        } 

       //如果签名正确(即falt=true)
       则进一步处理自己的业务逻辑,保存该此支付信息。
       .........

       //如果如果签名正确(即falt=true),并且从微信获取的字段tradeState==0或者tradeState.equals("0"),
       //则修改数据库订单状态、支付时间等,并且返回给微信一个success通知。
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext.setResponseCharacterEncoding("UTF-8");
        // 写入xml格式数据
        try {
            externalContext.getResponseOutputWriter().write();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        facesContext.responseComplete();
       

三、发货处理

。。。。。。待更新






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值