开启百度智能云CDN后,如何获取用户真实IP,避免微信支付接入报错invalid spbill_create_ip

2020-03-18 09:20:52

开启百度智能云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控制台,找到要配置的域名,点击管理:

百度智能云CDN控制台,域名管理面板

第二步:点击访问控制,下拉到页面底部:

百度智能云CDN控制台,单个域名的访问控制选项

第三步:类型选择,可选Client IP 或 X-Real-IP。

百度智能云CDN控制台,获取真实用户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,微信支付也不会报错了。