微信支付接口IP获取与调用之统一下单

获取用户真实的IP地址

没有代理的情况

在商户的前端接入层没有做代理的情况下获取ip的方式比较简单,直接获取'REMOTE_ADDR '即可。

function get_client_ip(){
$cip = "unknown";
if($_SERVER['REMOTE_ADDR']){
$cip = $_SERVER['REMOTE_ADDR'];
}elseif(getenv("REMOTE_ADDR")){
$cip = getenv("REMOTE_ADDR");
}
return $cip
}
有代理的情况

在有代理的情况下,因为要代替客户端去访问服务器,所以,当请求包经过反向代理后,在代理服务器这里这个IP数据包的IP包头做了修改,最终后端WEB服务器得到的数据包的头部源IP地址是代理服务器的IP地址。这样一来,后端服务器的程序就无法获取用户的真实ip。

nginx有代理的情况:
server 端默认获取到的ip则是nginx服务器的ip。这并不是我们想要的。这个时候就需要添加如下配置:
在nginx中配置中加入

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;                                     客户端ip
proxy_set_header X-Real-Port $remote_port;                                  客户端或上一级端口
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     包含了客户端和各级代理ip的完整ip链路


Apache有代理的情况:

vi /usr/local/apache/conf/httpd.conf
Include conf/extra/httpd-remoteip.conf
vi /usr/local/apache/conf/extra/httpd-remoteip.conf
LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1

代码 示例

java端servlet获取

/**
* 从request中获取请求方IP
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
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则证明获得客户端并没有采用反向代理直接使用getRemoteAddr()获取客户端的ip地址
ip = request.getRemoteAddr();
}
// 多个路由时,取第一个非unknown的ip
final String[] arr = ip.split(",");
for (final String str : arr) {
if (!"unknown".equalsIgnoreCase(str)) {
ip = str;
break;
}
}
return ip;
}

网络处理工具类

/**
* http请求客户端
*
* @author Administrator
*
*/
public class HttpClient {
private String url;
private Map<String, String> param;
private int statusCode;
private String content;
private String xmlParam;
private boolean isHttps;

public boolean isHttps() {
return isHttps;
}

public void setHttps(boolean isHttps) {
this.isHttps = isHttps;
}

public String getXmlParam() {
return xmlParam;
}

public void setXmlParam(String xmlParam) {
this.xmlParam = xmlParam;
}

public HttpClient(String url, Map<String, String> param) {
this.url = url;
this.param = param;
}

public HttpClient(String url) {
this.url = url;
}

public void setParameter(Map<String, String> map) {
param = map;
}

public void addParameter(String key, String value) {
if (param == null)
param = new HashMap<String, String>();
param.put(key, value);
}

public void post() throws ClientProtocolException, IOException {
HttpPost http = new HttpPost(url);
setEntity(http);
execute(http);
}

public void put() throws ClientProtocolException, IOException {
HttpPut http = new HttpPut(url);
setEntity(http);
execute(http);
}

public void get() throws ClientProtocolException, IOException {
if (param != null) {
StringBuilder url = new StringBuilder(this.url);
boolean isFirst = true;
for (String key : param.keySet()) {
if (isFirst)
url.append("?");
else
url.append("&");
url.append(key).append("=").append(param.get(key));
}
this.url = url.toString();
}
HttpGet http = new HttpGet(url);
execute(http);
}

/**
* set http post,put param
*/
private void setEntity(HttpEntityEnclosingRequestBase http) {
if (param != null) {
List<NameValuePair> nvps = new LinkedList<NameValuePair>();
for (String key : param.keySet())
nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
}
if (xmlParam != null) {
http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
}
}

private void execute(HttpUriRequest http) throws ClientProtocolException,
IOException {
CloseableHttpClient httpClient = null;
try {
if (isHttps) {
SSLContext sslContext = new org.apache.http.ssl.SSLContextBuilder()
.loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} else {
httpClient = HttpClients.createDefault();
}
CloseableHttpResponse response = httpClient.execute(http);
try {
if (response != null) {
if (response.getStatusLine() != null)
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
// 响应内容
content = EntityUtils.toString(entity, Consts.UTF_8);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.close();
}
}

public int getStatusCode() {
return statusCode;
}

public String getContent() throws ParseException, IOException {
return content;
}

/**
* 获取用户实际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;

}

}

接口统一下单的方法:

/**
* 调用统一下单,并获取支付跳转链接
* @param total_fee 支付金额
* @param out_trade_no 商户订单号
* @param ip 客户ip
* @return
*/
public Map<String,String> payH5(String total_fee, String out_trade_no, String ip){
// 封装需要的信息
Map<String, String> payMap = new HashMap<String, String>();
try {
// 1. 拼接下单地址参数
Map<String,String> param = new HashMap<String,String>();
param.put("appid", PayConfig.APP_ID); // 公总号ID
param.put("mch_id", PayConfig.MCH_ID); // 商户号ID
param.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
param.put("body", "我是H5支付测试商品") ;// 商品描述
param.put("out_trade_no", out_trade_no); // 商户订单号
param.put("total_fee", total_fee);//金额(分)
param.put("spbill_create_ip", ip); // 商户终端ip
param.put("notify_url", PayConfig.NOTIFY_URL_H5); // H5微信异步通知回调地址
param.put("trade_type", "MWEB"); // H5支付类型
String scene_info = "{"h5_info":{"type":"Wap","wap_url":"+PayConfig.WAP_URL+","wap_name": "APP名字,我没想好"}}";
param.put("scene_info", scene_info); // 需要支付的场景信息;有几种方式,参考文档
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, PayConfig.API_KEY);
param.put("sign", sign);

// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);

// 2. 发送请求
//String xmlStr = HttpRequest.sendPost(unifiedorder_url, xml);//发送post请求"统一下单接口"
HttpClient httpClient = new HttpClient(PayConfig.UFDODER_URL);
httpClient.setHttps(true);// https协议
httpClient.setXmlParam(xmlParam);
httpClient.post();

// 获取结果
String xmlResult = httpClient.getContent();
//以下内容是返回前端页面的json数据
String mweb_url = "";//跳转链接
if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下发接口,都会包含SUCCESS的
Map<String, String> map = WXPayUtil.xmlToMap(xmlResult);
//mweb_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,mweb_url的有效期为5分钟。
mweb_url = (String) map.get("mweb_url");

//支付完返回浏览器跳转的地址,如跳到查看订单页面
String redirect_url = "http://www.zzw777.com/";
String redirect_urlEncode = URLEncoder.encode(redirect_url,"utf-8");//对上面地址urlencode
mweb_url = mweb_url + "&redirect_url=" + redirect_urlEncode;//拼接返回地址
} else {
System.out.println("统一支付接口获取预支付订单出错");
payMap.put("msg", "支付失败");
return payMap;
}

payMap.put("mweb_url", mweb_url);
payMap.put("out_trade_no", out_trade_no);
payMap.put("total_fee", total_fee);
} catch (Exception e) {
e.printStackTrace();
System.out.println("统一支付接口获取预支付订单出错");
payMap.put("msg", "系统支付错误");
return payMap;
}
//添加微信支付记录日志等操作

payMap.put("msg", "success");
return payMap;
}

原文地址:https://www.cnblogs.com/schyzhkj/p/12495472.html