h5对接jssdk支付分并调用开启支付分页面

1、ws.config签名   调用ticket等获取ws.config的签名,下面会调用方法再调用方法时需要再次按照调用方法的签名

wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});

jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

1、获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appID&secret=appsecret

2、用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,api 调用次数非常有限,频繁刷新api_ticket 会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
1
2
3
4
5
6


https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=27_1JoR00pdKD26t0IbR_kPzC5FbCChBLVmoRTkJPQ6b3SbHO2D-IfeaCe1-iBI-kFCjZ58QCSffv9IEVhv0PfmfCsT4ZAEDNcwfO8zYEtB05SOM-mY8pspfKJsz_V8LJnqhMWJO-R9ymZhBj00UWRdACAIKF&type=jsapi


获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=9af198bddb8db015e9113ed7379cbcdf

 

微信 JS 接口签名校验工具:

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

 

微信支付接口签名校验工具

https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_

 

 

h5对接jssdk支付分并调用开启支付分页面_第1张图片

h5对接jssdk支付分并调用开启支付分页面_第2张图片




    
    Title
    
    
    
    


后端接口

@ResponseBody
    @RequestMapping("/test")
    @Login(required = false)
    public String test(String signUrl) {
        System.out.println("signUrl:"+signUrl);
        //String res = HttpGetMethod.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=acb8ad2a46765766c7881ea37237c1c7", "utf8", null);
        String jsapi_ticket = "HoagFKDcsGMVCIY2vOjf9kjcHCRqLoF8k77O2dyyZiMTaOwxLTQ9nHU3fa4jfiEj2XW4NsvQG53gZZgVMkQdJA";
        //String url = "http://localhost/h5/weixinexer.html";
        Map ret = com.jd.mrd.m.nc.web.utils.Sign.sign(jsapi_ticket, signUrl);
        ret.put("appid","wx954f1899ef15d2ea");
        for (Map.Entry entry : ret.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
        return JSON.toJSONString(ret);
    }

    /**
     * 获取签名
     * @param timestamp
     * @param nonce_str
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/generateSignature")
    @Login(required = false)
    public String generateSignature(String timestamp,String nonce_str) throws Exception {
        HashMap stringStringHashMap = new HashMap();
        stringStringHashMap.put("mch_id","1518750531");
        stringStringHashMap.put("service_id","00004000000000704283351234894845");
        stringStringHashMap.put("out_request_no","1234323JKHDFE1243259");
        stringStringHashMap.put("timestamp",timestamp);
        stringStringHashMap.put("nonce_str",nonce_str);
        stringStringHashMap.put("sign_type","HMAC-SHA256");
        String signature = WeChatUtils.generateSignature(stringStringHashMap, "acb8ad2a46765766c7881ea37237c1c7", WeChatConstant.SignType.HMACSHA256);
        return signature;
    }


    @RequestMapping(value = "generateImage")
    @ResponseBody
    @Login(required = false)
    public String generateImage(HttpServletRequest request, String base64) throws IOException {

        //String base64=request.getParameter("base64");;
        File directory = new File("");//设定为当前文件夹
        URL resource = IndexController.class.getResource("/");
        String clasFilePath = resource.getPath();
        System.out.println(clasFilePath);//获取标准的路径
        File file = new File(clasFilePath);
        String strParentDirectory = file.getParent();
        System.out.println(strParentDirectory);
        file = new File(strParentDirectory);
        strParentDirectory = file.getParent();
        System.out.println(strParentDirectory);
        strParentDirectory = strParentDirectory + "/h5/img";
        System.out.println(strParentDirectory);

        String fileName = CommonUtils.generateUUID() + ".jpg";
        String fileUrl = strParentDirectory + "/" + fileName;
        String imgStr = base64.split(",")[1];
        Base64Utils.GenerateImage(imgStr, fileUrl);
        System.out.println(fileUrl);
        System.out.println(request.getServerName() + "/h5/img/" + fileName);
        return request.getServerName() + "/h5/img/" + fileName;

//        JSONObject json =new JSONObject();
//        json.put("result",fileUrl);
//        response.setCharacterEncoding("utf-8");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter out = null;
//        out = response.getWriter();
//        out.write(json.toString());
//        return json.toJSONString();
    }


    @RequestMapping(value = "testPost")
    @ResponseBody
    @Login(required = false)
    public String testPost(HttpServletRequest request, String base64) {



        return "";

    }
package com.jd.lestore.payment.common.utils;

import com.jd.lestore.payment.common.constant.WeChatConstant;
import com.jd.lestore.payment.common.constant.WeChatConstant.SignType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class WeChatUtils {

    /**
     * 生成新的请求序列号
     *
     * @return
     */
    public static Integer getNewRequestSerial() {
        String timestamp = String.valueOf( System.currentTimeMillis()/1000 );
        return Integer.valueOf(timestamp).intValue();
    }

    public static String generateSignature(final Map data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }

    public static String generateHMACSHA256Signature(final Map data, String key) throws Exception {
        return generateSignature(data, key, SignType.HMACSHA256);
    }


    /**
     * 生成签名
     *
     * @param data
     * @param key
     * @return
     * @throws Exception 规则
     *                   第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
     *                   

* 特别注意以下重要规则: *

* ◆ 参数名ASCII码从小到大排序(字典序); * ◆ 如果参数的值为空不参与签名; * ◆ 参数名区分大小写; * ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。 * ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段 *

* 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。 */ public static String generateSignature(final Map data, String key, SignType signType) throws Exception { Set keySet = data.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (k.equals(WeChatConstant.FIELD_SIGN)) { continue; } if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名 sb.append(k).append("=").append(data.get(k).trim()).append("&"); } sb.append("key=").append(key); if (SignType.MD5.equals(signType)) { return MD5(sb.toString()).toUpperCase(); } else if (SignType.HMACSHA256.equals(signType)) { System.out.println("HMACSHA256 original text: " + sb.toString()); return HMACSHA256(sb.toString(), key); } else { throw new Exception(String.format("Invalid sign_type: %s", signType)); } } /** * 生成 MD5 * * @param data 待处理数据 * @return MD5结果 */ public static String MD5(String data) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] array = md.digest(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } /** * 生成 HMACSHA256 * * @param data 待处理数据 * @param key 密钥 * @return 加密结果 * @throws Exception */ public static String HMACSHA256(String data, String key) throws Exception { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); sha256_HMAC.init(secret_key); byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } /** * 获取当前时间戳,单位秒 * * @return */ public static long getCurrentTimestamp() { return System.currentTimeMillis() / 1000; } /** * 获取当前时间戳,单位毫秒 * * @return */ public static long getCurrentTimestampMs() { return System.currentTimeMillis(); } /** * XML格式字符串转换为Map * * @param strXML XML字符串 * @return XML数据转换后的Map * @throws Exception */ public static Map xmlToMap(String strXML) throws Exception { InputStream stream = null; try { Map data = new HashMap(); DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); org.w3c.dom.Document doc = documentBuilder.parse(stream); doc.getDocumentElement().normalize(); NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int idx = 0; idx < nodeList.getLength(); ++idx) { Node node = nodeList.item(idx); if (node.getNodeType() == Node.ELEMENT_NODE) { org.w3c.dom.Element element = (org.w3c.dom.Element) node; data.put(element.getNodeName(), element.getTextContent()); } } return data; } finally { try { stream.close(); } catch (Exception ex) { ex.printStackTrace(); } } } private static DocumentBuilderFactory setWechatPaySafeCode( ) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 禁 用 DOCTYPE try{ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //该 feature 的作用是配置是否包含外部的参数,包括外部 DTD 子集,设置false 禁用参数实体 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //该 feature 的功能指是否包含外部生成的实体,设置 false 禁用外部实体 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); dbf.setXIncludeAware(false); dbf.setExpandEntityReferences(false); }catch ( Exception e ){ e.printStackTrace(); } return dbf; } /** * XML格式字符串转换为Map * * @param strXML XML字符串 * @return XML数据转换后的Map * @throws Exception */ public static Map xmlClildToMap(String strXML) throws Exception { InputStream stream = null; try { Map data = new HashMap(); DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); org.w3c.dom.Document doc = documentBuilder.parse(stream); doc.getDocumentElement().normalize(); NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int idx = 0; idx < nodeList.getLength(); ++idx) { Node node = nodeList.item(idx); if (node.getNodeType() == Node.ELEMENT_NODE) { org.w3c.dom.Element element = (org.w3c.dom.Element) node; if(element.hasChildNodes()){//对于三级子项处理 for(int i = 0 ; i < element.getChildNodes().getLength();i++){ Node nodeChild = element.getChildNodes().item(i); data.put(nodeChild.getNodeName(),nodeChild.getTextContent()); } }else { data.put(element.getNodeName(), element.getTextContent()); } } } return data; } finally { try { stream.close(); } catch (Exception ex) { ex.printStackTrace(); } } } /** * 将Map转换为XML格式的字符串 * * @param data Map类型数据 * @return XML格式的字符串 * @throws Exception */ public static String mapToXml(Map data) throws Exception { DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); org.w3c.dom.Document document = documentBuilder.newDocument(); org.w3c.dom.Element root = document.createElement("xml"); document.appendChild(root); for (String key : data.keySet()) { String value = data.get(key); if (value == null) { value = ""; } value = value.trim(); org.w3c.dom.Element filed = document.createElement(key); filed.appendChild(document.createTextNode(value)); root.appendChild(filed); } TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); transformer.transform(source, result); String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", ""); try { writer.close(); } catch (Exception ex) { ex.printStackTrace(); } return output; } /** * 将Map转换为XML格式的字符串 * * @param data Map类型数据 * @return XML格式的字符串 * @throws Exception */ public static String mapToXmlROOT(Map data,String xmlRoot) throws Exception { DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); org.w3c.dom.Document document = documentBuilder.newDocument(); document.setXmlStandalone(true); org.w3c.dom.Element root = document.createElement(xmlRoot); document.appendChild(root); for (String key : data.keySet()) { String value = data.get(key); if (value == null) { value = ""; } value = value.trim(); org.w3c.dom.Element filed = document.createElement(key); filed.appendChild(document.createTextNode(value)); root.appendChild(filed); } TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); transformer.transform(source, result); String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", ""); try { writer.close(); } catch (Exception ex) { ex.printStackTrace(); } return output; } }

 

你可能感兴趣的:(h5对接jssdk支付分并调用开启支付分页面)