开启百度智能云CDN后,如何获取用户真实IP,避免微信支付接入报错:invalid spbill_create_ip,分享解决问题的两种方法(附PHP参考代码)。
根据微信支付官方文档:
spbill_create_ip 指的是终端ip,在APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
注意:任何ipv6地址,多个地址串联都会导致invalid spbill_create_ip报错。
如果您的网站或应用开启了CDN,那么这里获取的ip可能不是或者不仅仅是终端IP。
第一种方法:手动新增 True-Client-Ip 或 X-Real-IP 的HTTP头。
第一步:进入百度智能云CDN控制台,找到要配置的域名,点击管理:
第二步:点击访问控制,下拉到页面底部:
第三步:类型选择,可选Client IP 或 X-Real-IP。
Client IP:源站可以获取到访问源的客户端IP地址,携带True-Client-Ip;
Real IP:源站可以获取到访问源的真实IP地址,携带X-Real-IP。
然后,我们在服务端接受 HTTP_HEADER中 的 True-Client-Ip 或 X-Real-IP 即可。
第二种,一般CDN的类似 透明代理,会将客户端IP,放在前面,节点IP放到后面,用逗号分隔。
这里直接拿Shopxo的Devil大大的PHP代码举例:
function GetClientIP($long = false)
{
$onlineip = '';
if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown'))
{
$onlineip = getenv('HTTP_CLIENT_IP');
} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
{
$onlineip = getenv('HTTP_X_FORWARDED_FOR');
} elseif(getenv('REMOTE_ADDR' ) && strcasecmp(getenv('REMOTE_ADDR'),'unknown'))
{
$onlineip = getenv('REMOTE_ADDR');
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],'unknown'))
{
$onlineip = $_SERVER['REMOTE_ADDR'];
}
if($long)
{
$onlineip = sprintf("%u", ip2long($realip));
}
$ips = explode(',', $onlineip); // 只返回第一个IP
return reset($ips);
}
这样就可以返回正确的客户端IP,微信支付也不会报错了。