本人琢磨微信支付好几天了,终于完成了,下面是开发微信支付的流程:
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<Object, Object> parameters = new TreeMap<Object, Object>();
-
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<String, Object> 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<String, Object> 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<String, String> sign(String url, String chatSet) {
-
Map<String, String> ret = new HashMap<String, String>();
-
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<Object, Object> 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<Object, Object> 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);
-
} catch (NoSuchAlgorithmException e) {
-
e.printStackTrace();
-
return null;
-
}
-
}
-
public static String getRemortIP(HttpServletRequest request) {
-
if (request.getHeader("x-forwarded-for") == null) {
-
return request.getRemoteAddr();
-
}