本人琢磨微信支付好几天了,终于完成了,下面是开发微信支付的流程:
1.先要有认证后的微信服务号,然后申请开通微信支付功能,通过之后,腾讯会跟你发一封邮件,如下图:
2.配置好微信支付的支付授权目录(配置错误,支付时微信会返回:http://ki.hdh.com/kjjk/jh未注册错误)
3.我们要参照微信传的参数,如下图:
4.生成prepay_id(在WeiXinUtils工具类里)
String getPrepayId = WeiXinUtils.getPayOrderByWeiXin(openid,String.valueOf(sumPrice*100),userIp,url,body,num+timeStamp);
public static String getPayOrderByWeiXin(String opentId, String total_fee, String userIp, String notifyUrl, String body, String orderNumber) {
SortedMap parameters = new TreeMap();
parameters.put("appid", APP_ID);
System.out.println("appid:"+APP_ID);
parameters.put("mch_id", MCH_ID);
System.out.println("mch_id:"+MCH_ID);
parameters.put("nonce_str", nonceStr);
System.out.println("nonce_str:"+"HZNAONAOCOM");
parameters.put("body", body);
System.out.println("body:"+body);
parameters.put("out_trade_no", orderNumber);
System.out.println("out_trade_no:"+orderNumber);
parameters.put("total_fee", total_fee.substring(0, total_fee.indexOf(".")));
System.out.println("total_fee="+total_fee.substring(0, total_fee.indexOf(".")));
parameters.put("spbill_create_ip", userIp);
System.out.println("spbill_create_ip="+userIp);
parameters.put("notify_url",notifyUrl );
System.out.println("notify_url="+notifyUrl);
parameters.put("trade_type", "JSAPI");
System.out.println("trade_type=JSAPI");
parameters.put("openid", opentId);
System.out.println("openid="+opentId);
String sign = Sign.createSign("UTF-8", parameters);
System.out.println("sign="+sign);
parameters.put("sign", sign);
String requestXML = Utils.getRequestXml(parameters);
System.out.println("requestXML="+requestXML);
String result = PostRequest.httpsRequest(unifiedOrder, "POST", requestXML);
System.out.println("prepay_id="+result);
return getPrepayId(result);
}
5.工具类
package com.naonao.cmall.utils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import org.springframework.cache.annotation.Cacheable;
import com.naonao.cmall.utils.http.HttpClient;
public class Sign {
@Cacheable(value="baseCache")
public static String getToken() {
String s = HttpClient.sendGet(
"https://api.weixin.qq.com/cgi-bin/token",
"grant_type=client_credential&appid=" + WeiXinUtils.APP_ID
+ "&secret=" + WeiXinUtils.APP_SECRET);
HashMap json = JsonUtil.stringToTObj(s, HashMap.class);
String token = json.get("access_token").toString();
return token;
}
@Cacheable(value="baseCache")
public static String getTicket() {
String token = Sign.getToken();
String s1 = HttpClient.sendGet(
"https://api.weixin.qq.com/cgi-bin/ticket/getticket",
"access_token=" + token + "&type=jsapi");
HashMap json1 = JsonUtil
.stringToTObj(s1, HashMap.class);
return json1.get("ticket").toString();
}
public static String getNonceStr() {
return create_timestamp();
}
//chatSet SHA-1 or MD5
public static Map sign(String url, String chatSet) {
Map ret = new HashMap();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
String jsapi_ticket = getTicket();
// 注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
+ "×tamp=" + timestamp + "&url=" + url;
// System.out.println(string1);
try {
MessageDigest crypt = MessageDigest.getInstance(chatSet);
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return ret;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
public static String createSign(String characterEncoding, SortedMap parameters) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)
&& !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + WeiXinUtils.APP_KEY);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
public static String paySign(String characterEncoding, SortedMap parameters) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)
&& !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
//sb.replace(sb.length()-1, sb.length(), "?");
sb.append("key=" + WeiXinUtils.APP_KEY);
//sb.append("params=value");
System.out.println(sb);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
}package com.naonao.cmall.utils;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import javax.servlet.http.HttpServletRequest;
public class Utils {
// MD5加密
public static String getMd5(String plainText) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
// 32
return buf.toString();
// 16
// return buf.toString().substring(8, 24);
}