uni-app+springmvc calls JSAPI to complete H5 WeChat official account payment.

1. The application process and background development configuration of wechat service account merchants are brief. Follow the prompts to do OK, and the focus is on the development process

2. Development process

flow chart:

Sequence diagram:

Development and use framework: the H5 end is implemented by uni app framework, and the background is implemented by java language and spring MVC framework

 

 

 

 

The general development steps are as follows:

Step one: start payment request from the official account page, send it to the merchant backstage system in ajax mode, and pass the necessary parameters.

Step 2: the merchant background system prepares the parameters, accesses the wechat API by http post, and calls the unified order interface. The most important step in this step is to retrieve the prepayment id and complete other parameters

The third step: back to the official account page, call jssdk and corresponding methods to complete the payment.

Step 4: callback function after payment, jump, ajax request merchant background system, verify the payment results

2.1 prepare parameters in the background and then reset the WeChat unified order interface.

For ease of reading, first mark the input and output

2.2.1 input and output of background part

Parameters passed from H5 to the background include:

1. Payment amount (fee)

2. IP address of mobile phone (ipaddr)

Parameters returned to H5 after successfully calling wechat unified order interface in the background include:

1. appId of the official account

2. Time stamp

3. Random string nonce_str

Note: this random string is not the random string generated by our own method before calling up the payment interface, but the random string returned to us by wechat interface!

4. Package STR, according to the rules of official documents

5.paySgin, signature

Note: this paySign signature is also a thunder. At the beginning of the exploration stage, it has been unable to pass the verification, because I don't know that it needs to be re signed. A painful lesson!

6.out_trade_no: order number paid

2.2.2 steps to obtain openid:

Wechat official API document address: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

Step 1: users agree to authorize and obtain code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

be careful:

1. redirect_uri parameter: the callback link address redirected after authorization. Please use urlEncode to process the link

2. scope: using snsapi_base

Step 2: exchange the web page authorization access through code_ In fact, there is no need to obtain access for wechat payment_ Token. We only need the openid, not the user information. The result of this step already contains the openid we need.)

After getting the code, request the following link for access_token:   https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_ type=authorization_ code

With the code in the previous step, the parameters of this link are easy. But how to deal with it on the page is a problem. I am pay.jsp After the page loading is completed, the code obtained will be sent asynchronously to the background as a parameter. In the background, the get request is sent by http related classes (you can find it online by yourself). The returned JSON result is:

{ "access_token":"ACCESS_TOKEN",

"expires_in":7200,

"refresh_token":"REFRESH_TOKEN",

"openid":"OPENID",

"scope":"SCOPE"

}

For the JSON returned above, we only need to get the openid

2.2.3 prepare other parameters:

After we get openid, we can start to prepare other parameters in the controller class

Then, the required parameters for calling the prepayment interface are as follows:

1.appId official account appId (already)

2.mch_id is the merchant ID (can be found from the merchant platform)

3.nonce_str random string

4.sign signature

5. The name paid by the body (from H5 end to the background, or the background custom name)

6.out_trade_no payment order No

7.total_fee payment amount (from H5 terminal to background)

8.spbill_create_ip address of IP device, generally refers to the IP address of the mobile phone initiating the address (from H5 terminal to background)

9.notify_url callback address (this is the address that you jump to after successful payment, just configure it from the background)

10.trade_type payment type (here we write: JSAPI)

11.openid payer's unique identification in WeChat official account (which is available in 2.2.1).

11 parameters, who is the difference? out_trade_no,nonce_str, sign, these three

First out_trade_no is the order number of payment. We can achieve this by our own logic, but we must ensure the uniqueness and the official document requires no more than 32 bits. Here, I use the order number generated according to the time accuracy to millisecond level plus four random numbers

nonce_str is a randomly generated string, which also requires less than 32 bits. Here we attach the generated nonce_ JAVA code of STR:

private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();

/**
* Generate random string for wechat payment
* @return
*/
public static String generateNonceStr() {
    char[] nonceChars = new char[32];
    for (int index = 0; index < nonceChars.length; ++index) {
        nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
    }
    return new String(nonceChars);
}

The last parameter: sign, more troublesome, if you go to the official documents, you may be dizzy, I am also Baidu, a lot of experience of the predecessors, finally to break through the barrier successfully

First, look at the parameters of the signature generation method in the java sdk provided by wechat (finally, I will attach the sdk tool class code file WxAPIUtils.java):

String sign = "";
try {
    sign = WxAPIUtils.generateSignature(map, Commons.paySecret, WxAPIUtils.SignType.MD5);
} catch (Exception e1) {
    e1.printStackTrace();
}

One Commons.paySecret It refers to the payment key of a merchant. It is not the appSecret of your official account. This can be found from the background of the merchant platform.

Two WxAPIUtils.SignType.MD5 Signtype is an enumeration type, so we can use MD5

3.map, this map is quite painful. First, we put all other parameters in this map, and then pass this map to the signature generation method, and finally get the signature sign... Here is the code:

//The necessary parameters of single interface will be unified and the Map will be assembled
final Map<String, String> map = new HashMap<String, String>();
map.put("appid", appId);
map.put("attach", "paytest");
map.put("body", body);
map.put("mch_id", mchId);
map.put("nonce_str", nonce_str);
map.put("notify_url", notify_url);
map.put("openid", openId);
map.put("out_trade_no", out_trade_no);
map.put("spbill_create_ip", spbill_create_ip);
map.put("total_fee", total_fee + "");
map.put("trade_type", trade_type);

In the above code, there is an additional attach. I'm not sure it's useful. Anyway, in the previous test, I didn't add an attach. The test failed. You can customize the value of the attach

2.2.4 call up wechat pre payment interface

OK, now we have the sign. According to the interface specification, we can assemble an xml and then adjust the pre payment interface:

String apiXml = "<xml>";
apiXml += "<appid>" + appId + "</appid>";
apiXml += "<attach>paytest</attach>";
apiXml += "<body>" + body + "</body>";
apiXml += "<mch_id>" + mchId + "</mch_id>";
apiXml += "<nonce_str>" + nonce_str + "</nonce_str>";
apiXml += "<notify_url>" + notify_url + "</notify_url>";
apiXml += "<openid>" + openId + "</openid>";
apiXml += "<out_trade_no>" + out_trade_no +"</out_trade_no>";
apiXml += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";
apiXml += "<total_fee>" + total_fee + "</total_fee>";
apiXml += "<trade_type>" + trade_type + "</trade_type>";
apiXml += "<sign>" + sign + "</sign>";
apiXml += "</xml>";
String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder "; / / address of prepayment interface
String xmlStr = HttpUtils.sendPost(unifiedorder_url, apiXml);//The sendPost method will also be attached later

 

If you see an xml return like this, Congratulations, and the payment call is successful

The xmlStr here is what the wechat prepayment interface returns to you. We need to convert it into xml and interpret it

Map wxBackMap = XmlConvertMapUtil.Dom2Map(xmlStr); / / convert the xml returned by wechat interface to map

( XmlConvertMapUtil.java Finally, I will also attach the document)

2.2.5 prepare parameters, assemble JSON to H5 end

1.nonceStr random string. Again, this is a random string returned from wechat interface, not the one we generated before

String nonce_str_back = wxBackMap.get("nonce_str").toString(); / / random string

2.packageStr

String packageStr = "prepay_id=" + wxBackMap.get("prepay_id").toString(); / / always add pay before_ Id=

3.signType

String signType = "MD5"; //signType, default value is MD5

4. Secondary signature paySign

final Map<String, String> mapAgain = new HashMap<String, String>();
mapAgain.put("appId", appId);
mapAgain.put("timeStamp", timestampStr);
mapAgain.put("nonceStr", nonce_str_back);
mapAgain.put("package", packageStr);
mapAgain.put("signType", signType);
String signResultBack = "";
try {
    signResultBack = WxAPIUtils.generateSignature(mapAgain, Commons.paySecret, WxAPIUtils.SignType.MD5);
} catch (Exception e1) {
    e1.printStackTrace();
}

OK, ready, you can start to assemble JSON

WxPrePayVo wxPrePayVo = new WxPrePayVo();
wxPrePayVo.setAppId(appId);
wxPrePayVo.setTimeStamp(timestampStr);
wxPrePayVo.setNonceStr(nonce_str_back);
wxPrePayVo.setPackageStr(packageStr);
wxPrePayVo.setSignType(signType);
wxPrePayVo.setPaySign(signResultBack);
wxPrePayVo.setOutTradeNo(out_trade_no);
jsonContent = JSONObject.fromObject(wxPrePayVo).toString();
return jsonContent;

At this point, the background call and pre payment interface code is completed, and jsonContent is returned to H5

2.3 front desk H5 end code (uni APP)

2.3.1 reference wechat jssdk and other js tools

It includes: wechat jssdk, sohu tool to obtain ip address, and js file of wechat configuration method and invoke method

My jweixin-1.0.0.js version is relatively old, and it is no problem to introduce a new one

stay App.vue Add code:

var wxSdk = document.createElement('script');
wxSdk.type = 'text/javascript';
wxSdk.src = 'https://res.wx.qq.com/open/js/jweixin-1.0.0.js';
head.appendChild(wxSdk);

var ipadrTool = document.createElement('script');
ipadrTool.type = 'text/javascript';
ipadrTool.src = 'http://pv.sohu.com/cityjson?ie=utf-8';
head.appendChild(ipadrTool);

var mysdk = document.createElement('script');
mysdk.type = 'text/javascript';
mysdk.src = 'http://xxxx.com/js/myJssdk.js';
head.appendChild(mysdk);

H5 end calls the background pre payment interface and the operation code after receiving the return value:

methods: {
    prepay() {
	this.ipaddr = returnCitySN.cip
	this.$http({
	url : 'http://xxxx.com/xxxx/interface/wxPrepay',
 	method: 'POST',
 	expressData: {
  	    userId: this.userId,
	    fee: this.money,
	    ipaddr: this.ipaddr,
	    payType: this.payType
	}
    }).then(res =>{
 	// console.log(res)
	this.appId = res.appId
	this.timeStamp = res.timeStamp
	this.nonceStr = res.nonceStr
	this.packageStr = res.packageStr
	this.paySign = res.paySign
	this.outTradeNo = res.outTradeNo
					
	uni.setStorage({
		key:'payInfo',
		data:{
			userId: this.userId,
			payType: this.payType,
			outTradeNo: this.outTradeNo
		},
	})
	    pay(this.timeStamp, this.nonceStr, this.packageStr, this.paySign)
            //Here's the pay method myJssdk.js Is the core method of calling wechat payment
	})
    }
},

The pay method above calls wechat jssdk to perform payment. See the code attachment for this

Reference link:

1.https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

2.https://blog.csdn.net/javaYouCome/article/details/79473743###

Appendix:

1.myJssdk.js:

function wxconfig(rs) {
	wx.config({
		debug: false,
		appId: '{Your official account. appId}',
		timestamp: rs.timestamp,
		nonceStr: rs.nonceStr,
		signature: rs.signature,
		jsApiList: [
			'onMenuShareTimeline',
			'onMenuShareAppMessage',
			'onMenuShareQQ',
			'onMenuShareWeibo',
			'onMenuShareQZone',
			'chooseWXPay'
		]
	});
}

function pay(timeStamp, nonceStr, packageStr, paySign) {
    if (typeof WeixinJSBridge == "undefined"){
        if( document.addEventListener ){
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        }else if (document.attachEvent){
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    }else{
        onBridgeReady(timeStamp, nonceStr, packageStr, paySign);
    }
}

function onBridgeReady(timeStamp, nonceStr, packageStr, paySign) {
	WeixinJSBridge.invoke( 'getBrandWCPayRequest', {
		"appId": '{Your official account. appId}',            //The name of the official account is imported from merchants.     
	    "timeStamp": timeStamp,    //Time stamp, seconds since 1970     
	    "nonceStr": nonceStr,      //Random string     
	    "package": packageStr,     
	    "signType": 'MD5',         //Wechat signature method:     
	    "paySign": paySign         //Wechat signature
		},function(res){      
      	
			if(res.err_msg == "get_brand_wcpay_request:ok" ) {
            
				console.log('Payment successful');
				window.location.href = "http://xxxx.com/pages/pay/payback/"
			}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
          	
				console.log('Cancellation of payment');
 
			}else if(res.err_msg == "get_brand_wcpay_request:fail"){
          	
				console.log('Payment failed');
	
			WeixinJSBridge.call('closeWindow');
        
		} 
	});
	//Using the above methods to judge the front-end return, wechat team solemnly prompts: res.err_msg will return ok after the user pays successfully, but it is not guaranteed to be absolutely reliable.
}

2. Code of controller class:

package com.xmtk.lawyerHelp.frontInterface;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xmtk.lawyerHelp.payRecord.entity.WxPrePayVo;
import com.xmtk.lawyerHelp.utils.Commons;
import com.xmtk.lawyerHelp.utils.HttpUtils;
import com.xmtk.lawyerHelp.utils.StrUtils;
import com.xmtk.lawyerHelp.utils.WxAPIUtils;
import com.xmtk.lawyerHelp.utils.XmlConvertMapUtil;

import net.sf.json.JSONObject;

@Controller
@RequestMapping("/interface")
public class interfaceController2 {
	@RequestMapping(value = "/wxPrepay", method = RequestMethod.POST, 
			produces = "application/json;charset=UTF-8")
	public @ResponseBody String wxPrepay(@RequestBody String jsonStr, HttpServletRequest request) {
		String jsonContent = "{\"data\":\"none\"}"; 
		JSONObject jo = JSONObject.fromObject(jsonStr);
		String userId = jo.getString("userId");
		String openId = "";
		if(StrUtils.isNotEmptyStr(userId)) {  //The user's wechat openid has been saved in the user table in advance
			openId = tabUserService.getTabUserById(Integer.parseInt(userId)).getWxOpenId();
		}
		//Unified order: parameter preparation required
		String appId = Commons.appId;  //appId
		String mchId = Commons.mch_id;  //Merchant number
		String nonce_str = WxAPIUtils.generateNonceStr();  //Random string
		
		String body = "lawyerMember";//Product description
		String out_trade_no = WxAPIUtils.getOrderNo();  //Merchant order number
		Integer total_fee = Integer.parseInt(jo.getString("fee"));  //Payment amount (unit: points)
		String spbill_create_ip = jo.getString("ipaddr");  //IP address of the device
		String notify_url = Commons.notify_url;
		String trade_type = "JSAPI";  //Transaction type
		
		//The necessary parameters of single interface will be unified and the Map will be assembled
		final Map<String, String> map = new HashMap<String, String>();
		map.put("appid", appId);
		map.put("attach", "paytest");
		map.put("body", body);
		map.put("mch_id", mchId);
		map.put("nonce_str", nonce_str);
		map.put("notify_url", notify_url);
		map.put("openid", openId);
		map.put("out_trade_no", out_trade_no);
		map.put("spbill_create_ip", spbill_create_ip);
		map.put("total_fee", total_fee + "");
		map.put("trade_type", trade_type);
		
		String sign = "";
		try {
			sign = WxAPIUtils.generateSignature(map, Commons.paySecret, WxAPIUtils.SignType.MD5);
		} catch (Exception e1) {
			e1.printStackTrace();
		}  //autograph
		//put the obtained signature into the map
		map.put("sign", sign);
		
		//Map to XML
		String apiXml = "<xml>";
		apiXml += "<appid>" + appId + "</appid>";
		apiXml += "<attach>paytest</attach>";
		apiXml += "<body>" + body + "</body>";
		apiXml += "<mch_id>" + mchId + "</mch_id>";
		apiXml += "<nonce_str>" + nonce_str + "</nonce_str>";
		apiXml += "<notify_url>" + notify_url + "</notify_url>";
		apiXml += "<openid>" + openId + "</openid>";
		apiXml += "<out_trade_no>" + out_trade_no +"</out_trade_no>";
		apiXml += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";
		apiXml += "<total_fee>" + total_fee + "</total_fee>";
		apiXml += "<trade_type>" + trade_type + "</trade_type>";
		apiXml += "<sign>" + sign + "</sign>";
		apiXml += "</xml>";
		
//		System.out.println("pre call XML:" + apiXml);
		String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		String xmlStr = HttpUtils.sendPost(unifiedorder_url, apiXml);//Send a post request to "unified order interface" and return the prepayment id:prepay_id
		Long tstp = System.currentTimeMillis() / 1000;
		String timestampStr = tstp.toString();  //time stamp
//		System.out.println("unified order return:" + xmlStr);
		Map wxBackMap = XmlConvertMapUtil.Dom2Map(xmlStr);  //Convert xml returned by wechat interface to map
		
		String nonce_str_back = wxBackMap.get("nonce_str").toString();  //Random string
		//Package, the parameter specified in the API is package. Since package is a JAVA keyword, the name change is returned to the front end for further processing
		String packageStr = "prepay_id=" + wxBackMap.get("prepay_id").toString();
		String signType = "MD5";   //signType, MD5 by default
//		String signResultBack = wxBackMap.get("sign").toString();
		
		//Secondary signature
		final Map<String, String> mapAgain = new HashMap<String, String>();
		mapAgain.put("appId", appId);
		mapAgain.put("timeStamp", timestampStr);
		mapAgain.put("nonceStr", nonce_str_back);
		mapAgain.put("package", packageStr);
		mapAgain.put("signType", signType);
		String signResultBack = "";
		try {
			signResultBack = WxAPIUtils.generateSignature(mapAgain, Commons.paySecret, WxAPIUtils.SignType.MD5);
		} catch (Exception e1) {
			e1.printStackTrace();
		} 
		
		//Assign a value to the Vo object to be returned to the foreground, and prepare to assemble json
		WxPrePayVo wxPrePayVo = new WxPrePayVo();
		wxPrePayVo.setAppId(appId);
		wxPrePayVo.setTimeStamp(timestampStr);
		wxPrePayVo.setNonceStr(nonce_str_back);
		wxPrePayVo.setPackageStr(packageStr);
		wxPrePayVo.setSignType(signType);
		wxPrePayVo.setPaySign(signResultBack);
		wxPrePayVo.setOutTradeNo(out_trade_no);
//		wxPrePayVo.setPayType(payType);
		jsonContent = JSONObject.fromObject(wxPrePayVo).toString();
		return jsonContent;
	}
}

3.XmlConvertMapUtil.java

package com.xmtk.lawyerHelp.utils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class XmlConvertMapUtil {
	public static Map<String,String> Dom2Map(String xml) {
		Map<String,String> map = new HashMap<String, String>();
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(xml);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		if(doc ==null)
			return map;
		Element root = doc.getRootElement();
	  for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
		 Element e = (Element) iterator.next();
		 map.put(e.getName(), e.getText());
	  }
	  return map;
	}
	
	public static byte[] callMapToXML(Map map) {
//		System.out.println("convert Map to Xml, Map:"+ map.toString());
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
//		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xml>");
		mapToXMLTest2(map, sb);
		sb.append("</xml>");
//		System.out.println (convert Map to Xml, Xml:+ sb.toString());
		try {
			return sb.toString().getBytes("UTF-8");
		} catch (Exception e) {
			System.out.println(e);
		}
		return null;
	}
	
	private static void mapToXMLTest2(Map map, StringBuffer sb) {
		Set set = map.keySet();
		for (Iterator it = set.iterator(); it.hasNext();) {
			String key = (String) it.next();
			Object value = map.get(key);
			if (null == value)
				value = "";
			if (value.getClass().getName().equals("java.util.ArrayList")) {
				ArrayList list = (ArrayList) map.get(key);
				sb.append("<" + key + ">");
				for (int i = 0; i < list.size(); i++) {
					HashMap hm = (HashMap) list.get(i);
					mapToXMLTest2(hm, sb);
				}
				sb.append("</" + key + ">");
			} else {
				if (value instanceof HashMap) {
					sb.append("<" + key + ">");
					mapToXMLTest2((HashMap) value, sb);
					sb.append("</" + key + ">");
				} else {
					sb.append("<" + key + ">" + value + "</" + key + ">");
				}
			}
		}
	}
	
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("key1", "value1");
		map.put("key2", "value2");
		map.put("key3", "value3");
		try {
			String c = new String(callMapToXML(map), "UTF-8");
			System.out.println(c);
			Map mapback = Dom2Map(c);
			System.out.println(mapback.get("key1"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
	}
}

4.WxAPIUtils.java

package com.xmtk.lawyerHelp.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class WxAPIUtils {
	
	public enum SignType {
        MD5, HMACSHA256
    }
	
	private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final Random RANDOM = new SecureRandom();
	/**
	 * Generate random string for wechat payment
	 * @return
	 */
	public static String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }
	
	/**
	 * Generate merchant's order number (21 digit length, wechat document stipulates that order number shall not exceed 32 digits)
	 * @return
	 */
	public static String getOrderNo(){
	    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
	    Date date = new Date();
	    return sdf.format(date) + getRandomStringByLength(4);
	}
	
	public static String getRandomStringByLength(int length) {
	    String base = "0123456789";
	    Random random = new Random();
	    StringBuffer sb = new StringBuffer();
	    for (int i = 0; i < length; i++) {
	        int number = random.nextInt(base.length());
	        sb.append(base.charAt(number));
	    }
	    return sb.toString();
	}
	
	/**
     * Generate a signature. Note that if there is a sign_type field, which must be consistent with the signType parameter.
     *
     * @param data Data to be signed
     * @param key API secret key
     * @param signType Signature method
     * @return autograph
     */
    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> 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("sign")) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // If the parameter value is empty, signature is not involved
                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)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }
    
    public static String MD5(String s) {
    	char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    	try {
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			mdInst.update(s.getBytes("UTF-8"));
			byte[] rawBit = mdInst.digest();
			String outputMD5 = " ";
			for(int i = 0; i<16; i++){
				outputMD5 = outputMD5 + hexArray[rawBit[i]>>>4& 0x0f];
				outputMD5 = outputMD5 + hexArray[rawBit[i]& 0x0f];
			}
			return outputMD5.trim();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
    	return null;
    }
	
    /**
     * Generate MD5
     *
     * @param data Data to be processed
     * @return MD5 result
     */
    public static String MD5_bak(String data) throws Exception {
        java.security.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();
    }
    
    /**
     * Generating HMACSHA256
     * @param data Data to be processed
     * @param key secret key
     * @return Encryption results
     * @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();
    }
    
	public static void main(String args[]) {
//		String orderNo = getOrderNo();
//		System.out.println(orderNo);
	}
}

5.sendPost method:

/**
             * Send a request for the POST method to the specified URL
     * 
     * @param url
             *   URL to send the request
     * @param param
             *   Request parameters, which should be in the form of name1 = value1 & Name2 = Value2.
     * @return The response result of the remote resource represented
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // Open connection to URL
            URLConnection conn = realUrl.openConnection();
            // Set common request properties
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                    
            // To send a POST request, the following two lines must be set
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // Gets the output stream corresponding to the URLConnection object
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));	
            // Send request parameters
            out.print(param);
            // Buffer of flush output stream
            out.flush();
            // Define BufferedReader input stream to read response of URL
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("send out POST Request exception!"+e);
            e.printStackTrace();
        }
        //Use the finally block to close the output stream and input stream
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Tags: Java xml JSON Javascript

Posted on Mon, 29 Jun 2020 05:28:39 -0400 by tefuzz