调用微信Js-SDK支付

$(document).ready(function(){
	var url = location.href.split('#')[0];
	$.get(rootPath + "/wechat/member/user/getWechatConfig?url=" + url,"",function(data){
		wx.config({
			debug: false,
			appId: data.appId,
			nonceStr: data.nonceStr,
			signature: data.signature,
			timestamp: parseInt(data.timestamp),
			jsApiList: [
	            'checkJsApi',
	            'onMenuShareTimeline',
	            'onMenuShareAppMessage',
	            'onMenuShareQQ',
	            'onMenuShareWeibo',
	            'hideMenuItems',
	            'showMenuItems',
	            'hideAllNonBaseMenuItem',
	            'showAllNonBaseMenuItem',
	            'translateVoice',
	            'startRecord',
	            'stopRecord',
	            'onRecordEnd',
	            'playVoice',
	            'pauseVoice',
	            'stopVoice',
	            'uploadVoice',
	            'downloadVoice',
	            'chooseImage',
	            'previewImage',
	            'uploadImage',
	            'downloadImage',
	            'getNetworkType',
	            'openLocation',
	            'getLocation',
	            'hideOptionMenu',
	            'showOptionMenu',
	            'closeWindow',
	            'scanQRCode',
	            'chooseWXPay',
	            'openProductSpecificView',
	            'addCard',
	            'chooseCard',
	            'openCard'
	        ]
		});
	});

	document.querySelector('#wxpay').onclick = function () {
		$.get(rootPath + "/wechat/member/user/getWechatPayConfig","",function(data){
			if(data != null){
			    wx.chooseWXPay({
			    	 timestamp: data.timestamp,
			    	 nonceStr: data.nonceStr,
			    	 package: data.pkg,
			    	 signType: 'MD5',
			    	 paySign: data.paySign,
			    	 success: function (res) {
			    		 // 支付成功后的回调函数
			    		 alert(res.err_msg);
			    	 }
			    });
			}else{
				alert("支付异常");
			}
		});
	};

	wx.error(function (res) {
		alert(res.errMsg);
	});
});

  获取页签参考调用微信Js-SDK上传、预览图片,下面是后台获取支付签名等参数:

public static WechatPayConfig getWechatPayConfig(String openId)
            throws Exception {
        WechatPayConfig config = new WechatPayConfig();
        config.setAppId(APPID);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        config.setTimestamp(timestamp);
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
        config.setNonceStr(nonceStr);

        PayInfo payInfo = new PayInfo();
        payInfo.setAppid(APPID);
        payInfo.setMch_id(WEIXIN_MCH_ID);// 商户号
        payInfo.setDevice_info("WEB");// 设备号
        payInfo.setNonce_str(nonceStr);// 随机字符串
        payInfo.setBody("这是商品描述");// 商品描述
        payInfo.setOut_trade_no(nonceStr);// 商户订单号
        payInfo.setTotal_fee("1");// 支付金额
        payInfo.setSpbill_create_ip(InetAddress.getLocalHost().getHostAddress());// 终端IP
        payInfo.setNotify_url(PAY_CALL_BACK);// 接收微信支付异步通知回调地址
        payInfo.setTrade_type("JSAPI");// 交易类型
        payInfo.setOpenid(openId);// 用户标识
        payInfo.setSign(getSign(payInfo));// 签名
        logger.info(JsonMapper.toJsonString(payInfo));
        
        String paramesValue = MessageUtil.payInfoToXML(payInfo)
                .replace("__", "_").replace("<![CDATA[", "").replace("]]>", "");
        Map<String, String> map = httpsRequestToXML(paramesValue);
        if (!map.get("return_code").equals("SUCCESS")) {
            logger.info("调用微信统一下单接口失败:" + map.get("return_msg"));
            return null;
        }
        logger.info("调用微信统一下单接口成功:");
        logger.info(map.toString());
        String pkg = "prepay_id=" + map.get("prepay_id");
        config.setPkg(pkg);

        String str = "appId=" + APPID + "&nonceStr=" + nonceStr + "&package="
                + config.getPkg() + "&signType=MD5" + "&timeStamp=" + timestamp
                + "&key=" + WEIXIN_KEY;
        logger.info("str:" + str);

        String paySign = MD5Util.MD5Encode(str, "UTF-8").toUpperCase();
        logger.info("paySign:" + paySign);
        config.setPaySign(paySign);

        return config;
}
public static String getSign(PayInfo payInfo) throws Exception {
        String signTemp = "appid=" + payInfo.getAppid() + "&body="
                + payInfo.getBody() + "&device_info="
                + payInfo.getDevice_info() + "&mch_id=" + payInfo.getMch_id()
                + "&nonce_str=" + payInfo.getNonce_str() + "&notify_url="
                + payInfo.getNotify_url() + "&openid=" + payInfo.getOpenid()
                + "&out_trade_no=" + payInfo.getOut_trade_no()
                + "&spbill_create_ip=" + payInfo.getSpbill_create_ip()
                + "&total_fee=" + payInfo.getTotal_fee() + "&trade_type="
                + payInfo.getTrade_type()
                + "&key=" + WEIXIN_KEY; // 商户号API安全的API密钥
        String sign = MD5Util.MD5Encode(signTemp, "UTF-8").toUpperCase();
        return sign;
}
public static String payInfoToXML(PayInfo pi) {
        XStream xstream = new XStream();
        xstream.alias("xml", pi.getClass());
        return xstream.toXML(pi);
}
public static Map<String, String> httpsRequestToXML(String outputStr) {
        Map<String, String> result = new HashMap<>();
        try {
            StringBuffer buffer = httpsRequest(WeixinUtil.WEIXIN_UNIFIED_ORDER,
                    "POST", outputStr);
            result = MessageUtil.parseXml(buffer.toString());
        } catch (ConnectException ce) {
            logger.error("连接超时:" + ce.getMessage());
        } catch (Exception e) {
            logger.error("https请求异常:" + e.getMessage());
        }
        return result;
}


public static StringBuffer httpsRequest(String requestUrl,
            String requestMethod, String output) throws Exception {
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url
                    .openConnection();
            connection.setConnectTimeout(30000); // 设置连接主机超时(单位:毫秒)
            connection.setReadTimeout(30000); // 设置从主机读取数据超时(单位:毫秒)
            connection.setDoOutput(true); // post请求参数要放在http正文内,顾设置成true,默认是false
            connection.setDoInput(true); // 设置是否从httpUrlConnection读入,默认情况下是true
            connection.setUseCaches(false); // Post 请求不能使用缓存
            // 设定传送的内容类型是可序列化的java对象(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
            connection.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            connection.setRequestMethod(requestMethod);// 设定请求的方法为"POST",默认是GET
            connection.setRequestProperty("Content-Length", requestUrl.length()
                    + "");
            String encode = "utf-8";
            if (null != output) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes("UTF-8"));
                outputStream.flush();
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(
                    inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(
                    inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            connection.disconnect();
        } catch (Exception e) {
            logger.info("post请求调用统一下单接口异常" + e);
        }
        return buffer;
}

public static Map<String, String> parseXml(String xml) throws Exception {
         Map<String, String> map = new HashMap<String, String>();
         Document document = DocumentHelper.parseText(xml);
         Element root = document.getRootElement();
         List<Element> elementList = root.elements();
         for (Element e : elementList)
         map.put(e.getName(), e.getText());
         return map;
}
import java.security.MessageDigest;

public class MD5Util {

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

}

步骤:

1.获取页签,只有成功获取了页签,才能调微信Js-SDK下的API

2.调统一支付也叫统一下单接口,出入都是一个xml,成功会返回:

{
  result_code=SUCCESS,
  sign=3E5062C1CCBBF020628280A9E6CDE9E9,
  mch_id=10022311,
  prepay_id=wx201511170958368f617c0d5f0988190603,
  return_msg=OK,
  appid=wx3d407f02f5d3dd63,
  nonce_str=Fl2ViAVbdwQdZSQz,
  return_code=SUCCESS,
  device_info=WEB,
  trade_type=JSAPI
}

其中prepay_id=wx201511181358442e0bc083190380094951就是package的值

3.最后用appId、nonceStr、package、signType、timeStamp、key 6个参数得到paySign的值

 

你可能感兴趣的:(调用微信Js-SDK支付)