微信app支付详细教程

时间:2023-02-27 13:28:53

微信支付作为三大支付之一,越来越多的客户要求产品中添加微信支付   但是网上能找到可用的demo很少

所以写一篇自己写微信支付的过程,希望能给有需要的开发者一点帮助。

下面让我们来进入正题

1准备工作

首先得去微信开放平台申请app支付权限   当申请成功后会收到一封邮件   这里面有个商店号 MCH_ID 和PARTNER_ID 注意这俩 其实是一样的,都是商店号,但是

微信app支付详细教程

微信app支付详细教程

通过上图我们可以看到   不同接口 对应的字段并不一样   (有意思吗  就不能统一一下)但其实都是一个商店号

然后我们还需要拿到一些key值  下面代码有介绍  就不一一说来源了

拿到这些值之后我们就可以进行下一步了

2写支付逻辑

我写的代码如下  关键点都加上了注解

@Api(tags = {"支付接口"})
@RestController
@RequestMapping(value = "weixinMobile")
public class WeixinMobilePayController {
private static final Logger logger = LoggerFactory.getLogger(WeixinMobilePayController.class);

@RequestMapping(value="dop",method=RequestMethod.POST)
public JsonBack dopay(HttpServletRequest request, JsonBack jsonBack,HttpServletResponse response,String membertoken,int num,String id) throws Exception {

Member mem= MemberServiceImp.loginMemberMap.get("token");
if(mem.getMemberToken().equals(membertoken)){
MemberLevel level = memberLevelService.getMemberLevelById(id);
int x = Integer.parseInt(level.getLevelMoney());
int cc=x * num*100;//微信以分为单位,如果数据库里面的价格没扩大100的话这里要乘以100
String total_fee =cc+"";
String body=ConstantUtil.BODY;
String mch_id=ConstantUtil.MCH_ID;
String currTime = PayCommonUtil.getCurrTime();
String strTime = currTime.substring(8, currTime.length());
String strRandom = PayCommonUtil.buildRandom(4) + "";
String nonce_str = strTime + strRandom;
String notify_url=ConstantUtil.NOTIFY_URL;//回调地址  必须能直接访问  不是二级域名也可以
String out_trade_no=String.valueOf(UUID.next()); // 订单号
String timestamp=WXUtil.getTimeStamp();
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid",ConstantUtil.APP_ID);
packageParams.put("mch_id",mch_id);
packageParams.put("nonce_str",nonce_str);
packageParams.put("body",body);// 商品描述
packageParams.put("out_trade_no", out_trade_no);// 商户订单号
packageParams.put("total_fee", total_fee);// 总金额
String addr = AddressUtils.getIpAddr(request);
packageParams.put("spbill_create_ip", addr);// 发起人IP地址
packageParams.put("notify_url", notify_url);// 回调地址
packageParams.put("trade_type", "APP");// 交易类型
packageParams.put("time_start",timestamp);
String sign = PayCommonUtil.createSign("UTF-8", packageParams,ConstantUtil.APP_KEY);
packageParams.put("sign", sign);// 签名
String requestXML = PayCommonUtil.getRequestXml(packageParams);
String resXml = HttpUtil.postData(ConstantUtil.NOTIFY_URL, requestXML);
Map map = XMLUtil.doXMLParse(resXml);
String returnCode = (String) map.get("return_code");
String returnMsg = (String) map.get("return_msg");
logger.info("result:"+returnMsg);
if("SUCCESS".equals(returnCode)){
String resultCode = (String) map.get("result_code");
String prepay_id = (String) map.get("prepay_id");
String noncestr=(String) map.get("nonce_str");
if("SUCCESS".equals(resultCode)){
System.out.println("获取prepay_id成功"+prepay_id);//必须获取到这个prepay_id才算微信认可了你的第一次签名
//这里写预下单业务逻辑
SortedMap<Object, Object> packageParam = new TreeMap<Object, Object>();
// ConfigUtil.commonParams(packageParams);
packageParam.put("appid",ConstantUtil.APP_ID);
packageParam.put("partnerid",mch_id);
packageParam.put("noncestr",noncestr);
packageParam.put("prepayid",prepay_id);// 商品描述
packageParam.put("package", "Sign=WXPay");// 商户订单号
packageParam.put("timestamp",timestamp);
String sign1 = PayCommonUtil.createSign("UTF-8", packageParam,ConstantUtil.APP_KEY);//这里是二次签名  前台要拿到去调起微信支付,如果这个错了的话会在前台报签名错误
map.put("partnerid", mch_id);
map.put("timestamp", timestamp);
map.put("package","Sign=WXPay");
map.put("retcode", "0");
map.put("sign", sign1);
jsonBack = new JsonBack(true, "success", map);
}}
}else{
jsonBack = new JsonBack(false, "token不一致", null);
}
return jsonBack;
}

3 写回调逻辑

微信会根据你的回调地址去请求回调的action  并且地址必须是网络地址  能直接访问  而且不能携带参数

代码如下

@RequestMapping(value="WXP",method=RequestMethod.POST)
public void WXPayBack(HttpServletRequest request, HttpServletResponse response){
String resXml = "";
Member mem= MemberServiceImp.loginMemberMap.get("token");

try {
//解析XML
Map<String, String> map = MobileUtil.parseXml(request);
String return_code = map.get("return_code");//状态
String out_trade_no = map.get("out_trade_no");//订单号
if (return_code.equals("SUCCESS")) {
if (out_trade_no != null) {
//处理订单逻辑

这里面可以根据订单号来查询到付款买的什么

然后在预订单里加一个是否付款的状态来限制只能执行一次业务逻辑

否则就需要返回给微信一个success            

resXml = "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
} catch (Exception e1) {
// TODO Auto-generated catch block
logger.warn("新增服务失败");
}

}
else{
logger.warn("该用户已经买过金卡");
}
}else{
logger.info("已经购买会员完成");
}

}else{
//logger.warn("[payPage]根据id查询等级没有查询到记录,levelId="+levelId);
}
}else{
logger.info("callback fail:{}",out_trade_no);
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
} catch (Exception e) {
logger.error("callback fail",e);
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
}

4  工具类

上面用到的工具类如下

package com.zhjt.health.testpay;

public class ConstantUtil {
/**
* 微信开发平台应用ID 下面参数都不完整 需要写入自己的参数
*/
public static final String APP_ID="wx60e8c9b5b7";
/**
* 应用对应的凭证
*/
public static final String APP_SECRET="85cae8f9";
/**
* 应用对应的密钥
*/ public static final String APP_KEY="wffgg";
/**
* 微信支付商户号 1500906271
*/
public static final String MCH_ID="271";
/**
* 商品描述
*/
public static final String BODY="yunyi";
/**
* 商户号对应的密钥
*/
public static final String PARTNER_key="2121."; /**
* 商户id
*/
public static final String PARTNER_ID="1";
/**
* 常量固定值
*/
public static final String GRANT_TYPE="client_credential";
/**
* 获取预支付id的接口url
*/
public static String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* 微信服务器回调通知url
*/
public static String NOTIFY_URL="http://106.14.15.78:8090/weck"; public static String NOTIFY_URL2="http://106.14.15.78:8090/wec";
public static String NOTIFY_URL3="http://106.14.15.78:8090/wei;
}

ConstantUtil

package com.zhjt.health.util.pay;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
/**
* http请求(这里用户获取订单url生成二维码)
* 创建者 科帮网
* 创建时间 2017年7月31日
*
*/
public class HttpUtil {
private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
private final static String DEFAULT_ENCODING = "UTF-8"; public static String postData(String urlStr, String data) {
String postData = postData2(urlStr, data, null);
System.out.println(postData+"测试postDate");
return postData;
} public static String postData(String urlStr, String data, String contentType) { BufferedReader reader = null;
System.out.println("跳进来了");
try {
URL url = new URL(urlStr);
System.out.println(url+"测试URL");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if (contentType != null)
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if (data == null)
data = "";
writer.write(data);
writer.flush();
writer.close(); reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
} public static String postData2(String urlStr, String data, String contentType) {
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(contentType != null)
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null)
data = "";
writer.write(data);
writer.flush();
writer.close(); reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
}
}

HttpUtil

package com.zhjt.health.util.pay;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap; public class PayCommonUtil {
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
* @Author 科帮网
* @param characterEncoding
* @param packageParams
* @param API_KEY
* @return boolean
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
@SuppressWarnings({ "rawtypes"})
public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if(!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
//算出摘要
String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();
return tenpaySign.equals(mysign);
}
/**
* @author
* @date 2016-4-22
* @Description:sign签名
* @param characterEncoding
* 编码格式
* @param parameters
* 请求参数
* @return
*/
@SuppressWarnings({ "rawtypes"})
public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
} /**
* 将请求参数转换为xml格式的string
* @Author 科帮网
* @param parameters
* @return String
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
@SuppressWarnings({ "rawtypes"})
public static String getRequestXml(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
} /**
* 取出一个指定长度大小的随机正整数.
* @Author 科帮网
* @param length
* @return int
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
public static int buildRandom(int length) {
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < length; i++) {
num = num * 10;
}
return (int) ((random * num));
} /**
* 获取当前时间 yyyyMMddHHmmss
*
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
}

PayCommonUtil

package com.zhjt.health.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
/**
* XML解析
* 创建者 科帮网
* 创建时间 2017年7月31日
*
*/
public class XMLUtil {
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
*
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); if (null == strxml || "".equals(strxml)) {
return null;
} Map m = new HashMap(); InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if (children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
} m.put(k, v);
} // 关闭流
in.close(); return m;
} /**
* 获取子结点的xml
*
* @param children
* @return String
*/
@SuppressWarnings({ "rawtypes" })
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if (!children.isEmpty()) {
Iterator it = children.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if (!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
} return sb.toString();
} }

XMLUtil

package com.zhjt.health.util.pay;

import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.google.gson.Gson;
/**
* 微信H5支付工具类
* 创建者 科帮网
* 创建时间 2017年7月31日
*/
public class MobileUtil {
/**
* 获取用户openID
* @Author 科帮网
* @param code
* @return String
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
public static String getOpenId(String code){
if (code != null) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+ "appid="+ ConfigUtil.APP_ID
+ "&secret="+ ConfigUtil.APP_SECRET + "&code="
+code + "&grant_type=authorization_code";
String returnData = getReturnData(url);
Gson gson = new Gson();
OpenIdClass openIdClass = gson.fromJson(returnData,
OpenIdClass.class);
if (openIdClass.getOpenid() != null) {
return openIdClass.getOpenid();
}
}
return "**************";
}
public static String getReturnData(String urlString) {
String res = "";
try {
URL url = new URL(urlString);
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url
.openConnection();
conn.connect();
java.io.BufferedReader in = new java.io.BufferedReader(
new java.io.InputStreamReader(conn.getInputStream(),
"UTF-8"));
String line;
while ((line = in.readLine()) != null) {
res += line;
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
/**
* 回调request 参数解析为map格式
* @Author 科帮网
* @param request
* @return
* @throws Exception Map<String,String>
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(HttpServletRequest request)
throws Exception {
// 解析结果存储在HashMap
Map<String, String> map = new HashMap<String, String>();
InputStream inputStream = request.getInputStream();
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList)
map.put(e.getName(), e.getText());
// 释放资源
inputStream.close();
inputStream = null;
return map;
}
}

MobileUtil

package com.zhjt.health.entity;

import java.util.Map;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; @ApiModel
public class JsonBack { @ApiModelProperty(value = "是否成功", required = true)
private boolean success; @ApiModelProperty(value = "返回消息", required = true)
private String message; @ApiModelProperty(value = "其他", required = false)
private Map<String, Object> map; public JsonBack() {
super();
} public JsonBack(boolean success, String message, Map<String, Object> map) {
super();
this.success = success;
this.message = message;
this.map = map;
} public boolean isSuccess() {
return success;
} public void setSuccess(boolean success) {
this.success = success;
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} public Map<String, Object> getMap() {
return map;
} public void setMap(Map<String, Object> map) {
this.map = map;
} }

JsonBack

package com.zhjt.health.util.pay;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; /**
* 根据IP地址获取详细的地域信息
* 创建者 科帮网
* 创建时间 2017年7月31日
*
*/
public class AddressUtils {
/**
*
* @param content
* 请求的参数 格式为:name=xxx&pwd=xxx
* @param encoding
* 服务器端请求编码。如GBK,UTF-8等
* @return
* @throws UnsupportedEncodingException
*/
public static String getAddresses(String ip) throws UnsupportedEncodingException {
String urlStr ="http://ip.taobao.com/service/getIpInfo.php";
String returnStr = getResult(urlStr, ip);
if (returnStr != null) {
// 处理返回的省市区信息
String[] temp = returnStr.split(",");
if (temp.length < 3) {
return "0";// 无效IP,局域网测试
}
String region = (temp[5].split(":"))[1].replaceAll("\"", "");
region = decodeUnicode(region);// 省份 String country = "";
String area = "";
// String region = "";
String city = "";
String county = "";
String isp = "";
for (int i = 0; i < temp.length; i++) {
switch (i) {
case 1:
country = (temp[i].split(":"))[2].replaceAll("\"", "");
country = decodeUnicode(country);// 国家
break;
case 3:
area = (temp[i].split(":"))[1].replaceAll("\"", "");
area = decodeUnicode(area);// 地区
break;
case 5:
region = (temp[i].split(":"))[1].replaceAll("\"", "");
region = decodeUnicode(region);// 省份
break;
case 7:
city = (temp[i].split(":"))[1].replaceAll("\"", "");
city = decodeUnicode(city);// 市区
break;
case 9:
county = (temp[i].split(":"))[1].replaceAll("\"", "");
county = decodeUnicode(county);// 地区
break;
case 11:
isp = (temp[i].split(":"))[1].replaceAll("\"", "");
isp = decodeUnicode(isp); // ISP公司
break;
}
}
String address = region+city;
if(StringUtils.isBlank(address)){
address = "地球村";
}
return address;
}
return null;
} /**
* @param urlStr
* 请求的地址
* @param content
* 请求的参数 格式为:name=xxx&pwd=xxx
* @param encoding
* 服务器端请求编码。如GBK,UTF-8等
* @return
*/
private static String getResult(String urlStr, String ip) {
URL url = null;
HttpURLConnection connection = null;
try {
url = new URL(urlStr);
connection = (HttpURLConnection) url.openConnection();// 新建连接实例
/**
* 超时错误 由 2s改为5s
*/
connection.setConnectTimeout(5000);// 设置连接超时时间,单位毫秒
connection.setReadTimeout(5000);// 设置读取数据超时时间,单位毫秒
connection.setDoOutput(true);// 是否打开输出流 true|false
connection.setDoInput(true);// 是否打开输入流true|false
connection.setRequestMethod("POST");// 提交方法POST|GET
connection.setUseCaches(false);// 是否缓存true|false
connection.connect();// 打开连接端口
DataOutputStream out = new DataOutputStream(connection.getOutputStream());// 打开输出流往对端服务器写数据
out.writeBytes("ip="+ip);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
out.flush();// 刷新
out.close();// 关闭输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));// 往对端写完数据对端服务器返回数据
// ,以BufferedReader流来读取
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
reader.close();
return buffer.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();// 关闭连接
}
}
return null;
} /**
* unicode 转换成 中文
* @param theString
* @return
*/
public static String decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len;) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + aChar - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException("Malformed encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar == 't') {
aChar = '\t';
} else if (aChar == 'r') {
aChar = '\r';
} else if (aChar == 'n') {
aChar = '\n';
} else if (aChar == 'f') {
aChar = '\f';
}
outBuffer.append(aChar);
}
} else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}
/**
* 获取IP地址
* @Author 科帮网
* @param request
* @return String
* @Date 2017年7月31日
* 更新日志
* 2017年7月31日 科帮网 首次创建
*
*/
public static String getIpAddr(HttpServletRequest request)
{
String ip = request.getHeader("X-Real-IP");
if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip))
return ip;
ip = request.getHeader("X-Forwarded-For");
if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip))
{
int index = ip.indexOf(',');
if(index != -1)
return ip.substring(0, index);
else
return ip;
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("Proxy-Client-IP");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("WL-Proxy-Client-IP");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("HTTP_CLIENT_IP");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getRemoteAddr();
if(ip==null||ip!=null&&ip.indexOf("0:0:0:0:0:0:0")!=-1){
return "127.0.0.1";
}
return ip;
}
}

AddressUtils

微信app支付详细教程的更多相关文章

  1. 微信app支付android客户端以及&period;net服务端实现

    由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...

  2. 微信app支付 ci框架做的

    /**     * 组合微信app支付  获得prepayid     * @param int $order_num     */    private function _wxpay_reques ...

  3. &period;net 微信APP支付接口的开发流程以及坑

    流程 申请APP的微信支付 申请成功之后得到APPID 商户号 以及自己设置商户号的支付密码 这时就可以开发接口了 微信APP支付API:https://pay.weixin.qq.com/wiki/ ...

  4. php开发微信APP支付接口

    之前在开发APP中用到了微信支付,因为是第一次用,所以中途也遇到了好多问题,通过查看文档和搜集资料,终于完成了该功能的实现.在这里简单分享一下后台php接口的开发实例. 原文地址:代码汇个人博客 ht ...

  5. H5使用codovar插件实现微信支付(微信APP支付模式,前端)

    H5打包的app实现微信支付及支付宝支付,本章主要详解微信支付,支付宝支付请查看另一篇“H5使用codovar插件实现支付宝支付(支付宝APP支付模式,前端)” ps:本文只试用H5开发的,微信 AP ...

  6. nodejs&plus;koa2微信app支付,小程序支付

    企业付款到零钱文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 1,搞微信支付,先看流程图 https: ...

  7. asp&period;net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4

    微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...

  8. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  9. Android版-微信APP支付

    首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...

随机推荐

  1. java&period;util&period;concurrent&period;CopyOnWriteArrayList

    import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; impo ...

  2. cocos2d-x中的Box2D物理引擎

    在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...

  3. Ubuntu常用命令整理

    最近开始用Ubuntu系统了,各种命令很不熟练,想收集一下,以便以后查阅,用这个时常更新的随笔 1.Ubuntu设置与修改用户密码 设置ROOT密码方法:sudo passwd root ,然后输入密 ...

  4. CSS3的radial-gradient&lpar;径向渐变&rpar;

    所谓径向渐变,如图下,类似光晕 语法: radial-gradient(  [    [渐变大小]?    [ at 渐变圆心坐标]?  ,]?  颜色[ 开始位置]  [,颜色[ 开始位置]]+); ...

  5. Spark 基本概念

    Application:用户编写的 Spark 应用程序,包含驱动程序(Driver),和分布在集群中多个节点上运行的 Executor 代码,在执行过程中由一个或多个作业组成 Driver(驱动程序 ...

  6. Could not resolve view with name &&num;39&semi;&ast;&ast;&ast;&&num;39&semi; in servlet with name &&num;39&semi;dispatcher&&num;39&semi;

    今天在开发中遇到了一个问题,控制层使用的是SpringMVC框架. @RequestMapping("historyDetail") private String History( ...

  7. Android中的Socket

    1. UDP (1)访问网络必须添加权限,访问网络必须添加权限,访问网络必须添加权限,重要的事情说三遍. (2)简述 UDP协议是面向报文的,简单地说,利用UDP访问网络的步骤就是"寄快递& ...

  8. 洛谷 P1146 【硬币翻转】题解

    很久很久之前做过的一道题 翻n-1枚硬币,就是有一枚不翻,也可以理解为翻一枚 直接上程序,看程序说话 #include<iostream> using namespace std; ; b ...

  9. &lpar;后端&rpar;SQL SERVER 字符串按数字排序

    应用于B1-1,B1-2,B10-1,B11-1 sqlserver肯定不能按照字符串进行排序,需要进行处理一番: select CONVERT(varchar, LEFT(code,1)),conv ...

  10. &lbrack; 9&period;28 &rsqb;CF每日一题系列—— 940A规律构造

    Description: 输入a,b,x,给你a个0,b个1,你要给出一个组合,让这个组合里存在x位,使得这x为和其x+1位不相等 Solution: 因为肯定有一个正确的答案,所以钻了一下空子,贪心 ...