微信公众号支付是我接触微信支付最复杂的一个了,当时总共弄了五天才弄好,很惭愧.
1,首先咋们还是先看看图,图看懂了一切都好说
2,整个流程大概弄清楚了,需要做准备工作了
code -------------- 用户点击 充值 需要访问微信服务器 获取 code,然后服务器接收Code,此处特别注意,这个code用来获取openId的重要参数
/**
* 用户点击充值 获取Code
* @param request
* @return
*/
@RequestMapping(value = "getCode")
public String getCode(HttpServletRequest request) {
String code = request.getParameter("code");
return "redirect:http://localhost:8080/faint-service/static/h5/topup.html?code=" + code;
}
openId --------------此参数是 调用同意下单接口 必要参数
APIKEY --------- 支付秘钥(微信商户平台可查,需要自己设置)
appid ----- 商户ID(微信商户平台可查)
body------- 商品名称
mch_id ----- 支付商户号(微信商户平台可查)
nonce_str ---------- 随机字符串
/**
* 获取随机字符串 Nonce Str
*
* @return String 随机字符串
*/
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);
}
out_trade_no------------ 订单号
spbill_create_ip ------------请求IP
/**
* 获取用户实际ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
total_fee------------ //,字符串类型,获取金额,单位分
trade_type -------------------//支付类型,公众号就是 "JSAPI"
notify_url ----------------- //此路径是微信服务器调用支付结果带了一大批参数多次请求
3,废话不多说,上代码吧
/**
* 微信公众号充值金币业务逻辑
* @param request
* @param code 微信返回的"code"
* @param rechargeNumber 充值的用户ID
* @param rechargeId 由 金钱+金币个数构成的字符串
* @return
*/
@RequestMapping(value = "goldOrders", method = RequestMethod.GET)
@ResponseBody
public Map goldOrders(HttpServletRequest request, String code, Integer rechargeNumber, String rechargeId) {
t