php版新浪支付接口之回调接口笔记
所谓的新浪回调接口,就是当资金充值成功之后,新浪会通知本网站一个信息来告知已经充值成功,并返回一组成功的数组,我们根据这些数据再进行一个本地数据库的同步操作,比如更新本地数据库是否充值成功的状态,由未支付改为已支付,然后再网站上面进行显示,还有资金也会进行同步 update,好了,下面夏日博客把日志分享下来,接着上一篇新浪支付新建接口,一个简单的新浪支付回调接口,这个异步回调的信息是通过日志生成到ftp下面的,根据日志进行本地的更新。
一,先查看日志文件
说明:数据提交到新浪之后会生成新浪日志文件,如下:
{"ctl":"collocation","act":"response_sina","call":"registercreditor","notify_time":"20160317112508","sign_type":"RSA","notify_type":"trade_status_sync","gmt_payment":"20160317111255","trade_status":"PAY_FINISHED","version":"1.0","sign":"ULbWNFkn1DhF1z9M5daaJHKcvlyTCHS1SmH3o7AMwAQnYylMQATfpNXzdloFh5R43cm3MTaTuaAxEddSRckMBzemZ+XlqEcERsu8x6HA0OnIZW5YVOgQhPfnz4lbH3MC4yjxPzq9dQgE\/fVLJ+pWnaeVtXJMiyRygohCdX+mT28=","gmt_create":"20160317111254","_input_charset":"utf-8","outer_trade_no":"7L3No20160317111143","trade_amount":"100.00","inner_trade_no":"101145818437424877398","notify_id":"82170f9981b84c40b50a634ed37a2afd"}
二,打开 /app/lib/module/collocationModule.class.php,查找 response_sina 方法,方法如下:
public function response_sina()
{
$content= $_REQUEST;
error_log( date ( "[YmdHis]" ) ."\t" . json_encode($content) . "\r\n", 3, '../'. date ( "Y-m-d" ) . '.log1' );
$class_name = getCollName();
require_once APP_ROOT_PATH."system/collocation/".$class_name."_collocation.php";
$collocation_class = $class_name."_collocation";
$collocation_object = new $collocation_class();
$collocation_code = $collocation_object->SinaNotify($_POST,$_REQUEST);
}
三,打开 system/collocation/Sina_collocation.php 文件,查找 SinaNotify 方法,如下:
function SinaNotify($map,$data){
// $weibopay->write_log("获取到refund_status_sync结果通知:单号:".json_encode($map).json_encode($data));
ksort ($map);
$weibopay = new Weibopay ();
error_log( date ( "[YmdHis]" ) ."\t" . json_encode($map). json_encode($data). "\r\n", 3, '../'. date ( "Y-m-d" ) . '.log10' );
if ($weibopay->checkSignMsg ($map,@$map ["sign_type"] )) {
switch ($map["notify_type"])
{
//交易结果通知
case "trade_status_sync":
//投标代收
if($data['call']=='registercreditor'){
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
registercreditor_status_sync($map);
}
if($data['call']=='dotrtrade'){
error_log( date ( "[YmdHis]" ) ."\t" . json_encode($map). "\r\n",4, '../'. date ( "Y-m-d" ) . '.log4' );
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
dotrtrade_status_sync($map);
}
if($data['call']=='dohktrade'){
error_log( date ( "[YmdHis]" ) ."\t" . json_encode($map). "\r\n", 5, '../'. date ( "Y-m-d" ) . '.log41' );
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
dohktrade_status_sync($map);
}
//按照自己的业务需求获取对应参数进行保存
// $weibopay->write_log("获取到trade_status_sync结果通知:时间:".date("YmdHis"));
// $weibopay->write_log("获取到trade_status_sync结果通知:单号:".json_encode($_REQUEST));
break;
//交易退款结果通知
case "refund_status_sync":
//按照自己的业务需求获取对应参数进行保存
$weibopay->write_log("获取到refund_status_sync结果通知:时间:".date("YmdHis"));
$weibopay->write_log("获取到refund_status_sync结果通知:单号:".json_encode($_REQUEST));
break;
//充值结果通知
case "deposit_status_sync":
//done
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
deposit_status_sync($map);
break;
//提现结果通知
case "withdraw_status_sync":
$weibopay->write_log("获取到batch_trade_status_sync结果通知:时间:".date("YmdHis"));
$weibopay->write_log("获取到batch_trade_status_sync结果通知:单号:".json_encode($_REQUEST));
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
withdraw_status_sync($map);
break;
//批量代付结果通知
case "batch_trade_status_sync":
//按照自己的业务需求获取对应参数进行保存
$weibopay->write_log("获取到batch_trade_status_sync结果通知:时间:".date("YmdHis"));
$weibopay->write_log("获取到batch_trade_status_sync结果通知:单号:".json_encode($_REQUEST));
break;
//审核结果通知
case "audit_status_sync":
require_once(APP_ROOT_PATH.'system/collocation/sina/SinaNotify.php');
audit_status_sync($map);
//按照自己的业务需求获取对应参数进行保存
$weibopay->write_log("获取到audit_status_sync结果通知:时间:".date("YmdHis"));
$weibopay->write_log("获取到audit_status_sync结果通知:单号:".json_encode($_REQUEST));
break;
default:
$weibopay->write_log("获取到未知结果通知:时间:".date("YmdHis"));
$weibopay->write_log("获取到未知结果通知:单号:".json_encode($_REQUEST));
echo "通知类型错误!";
}
// 如果回调成功,需要输出SUCCESS告知新浪回调服务器,已经收到异步通知。
echo 'success';
} else {
$msg="签名错误 or 非法请求";
$weibopay->write_log($msg);
die ( "sign error" );
}
}
//资质提价
四,打开 system/collocation/sina/SinaNotify.php 文件,充值回调。
if($map['trade_status']=='PAY_FINISHED'){
$pErrCode = 'MG00000F';
$data['pErrCode'] ='MG00000F';
$data['pErrMsg'] = 'MG00000F';;
}
五,成功之后进行下面的操作。
在使用新浪支付接口的时候,需要进行一个接口的创建,刚刚由夏日博客新建的一个新浪接口,整合的是方维P2P网贷系统,下面这个接口还是比较简单的,只是一个解绑认证信息的接口,也就是解绑我们在新浪上面的身份证等信息,操作步骤如下,仅供夏日参考学习使用。
1,后台复制一个按钮链接
2,/admin/Tpl/default/Common/js/user.js 添加一个跳转,注意名字
3, php添加一个类,路径-->app/lib/module/collocationModule.class.php,代码如下:
public function AdminUnbindUser(){
$user_id=(int)$_GET['user_id'] ;
$class_name = getCollName();
require_once APP_ROOT_PATH."system/collocation/".$class_name."_collocation.php";
$collocation_class = $class_name."_collocation";
$collocation_object = new $collocation_class();
$collocation_code = $collocation_object->AdminUnbindUser($user_id);
}
4,在 /system/collocation/Sina_collocation.php 文件中添加如下代码:
function AdminUnbindUser($uid){
require_once(APP_ROOT_PATH.'system/collocation/sina/AdminUnbindUser.php');
return AdminUnbindUser($uid);
}
5,到 system/collocation/sina/ 中新建一个 AdminUnbindUser,下面的代码从
/a/zjtg_php_demo/controller/controller_sina.php 中查找服务名称,把类中的文件全复拷贝出来放到 AdminUbindUser($uid) 中,内容如下:
<?php
function AdminUnbindUser($uid){
$weibopay = new Weibopay();
/**************获取解绑认证信息参数****************/
$service='unbinding_verify';//服务名称
$version=sinapay_version;//接口版本
$request_time=date("YmdHis");//请求时间
$partner_id=sinapay_partner_id;//合作者身份ID
$_input_charset=sinapay_input_charset;//参数编码字符集
$sign_type=sinapay_sign_type;//签名类型
/****************业务参数***********************/
$identity_id=sinapay_identity_id.$uid;//用户标识信息---原来的 $identity_id=$data['identity_id'];//用户标识信息
$identity_type=sinapay_identity_type;//用户标识类型
$verify_type='MOBILE';//认证类型
$param=array();
$param['service']=$service;
$param['version']=$version;
$param['request_time']=$request_time;
$param['partner_id']=$partner_id;
$param['_input_charset']=$_input_charset;
$param['sign_type']=$sign_type;
$param['identity_id']=$identity_id;
$param['identity_type']=$identity_type;
$param['verify_type']=$verify_type;
ksort($param);//对签名参数据排序
//对请求sina报文进行签名
$sign=$weibopay->getSignMsg($param,$sign_type);
//将签名结果存入请求sina的数组
$param['sign']=$sign;
$weibopay->write_log("解绑认证信息请求参数".json_encode($param));
$data = $weibopay->createcurl_data($param); // 调用createcurl_data创建模拟表单需要的数据
$result = $weibopay->curlPost(sinapay_mgs_url,$data ); // 使用模拟表单提交进行数据提交
$result = urldecode ($result);
$splitdata = json_decode($result,true);
$sign_type = $splitdata ['sign_type'];//签名方式
ksort($splitdata); // 对签名参数据排序
print_r($param);print_r($splitdata);die();
if ($weibopay->checkSignMsg ($splitdata,$sign_type)) {
if ($splitdata["response_code"] == 'APPLY_SUCCESS') { // 成功
return $splitdata;
exit();
}else
{
//业务处理失败
return $splitdata;
exit();
}
} else {
die ( "sing error!" );
}
}
其中 /a/zjtg_php_demo/controller/controller_sina.php 中的文件是新浪提供的接口实例,只需传递一个UID即可,其它不用变动。
PHP发红包基本流程:当输入完红包数量和总金额后,PHP会根据这两个值进行随机分配每个金额,保证每个人都能领取到一个红包,且每个红包金额不等。也就是每个人领取的红包金额要不同,并且所有红包金额总额等于总金额。如图:
php发红包实现原理:
设定总金额为10元,有N个人随机领取:
N=1 第一个
则红包金额=X元;
N=2 第二个
为保证第二个红包可以正常发出,第一个红包金额=0.01至9.99之间的某个随机数
第二个红包=10-第一个红包金额;
N=3 第三个
红包1=0.01至9.99之间的某个随机数
红包2=0.01至(10-红包1-0.01)的某个随机数
红包3=10-红包1-红包2
……
于是我们得到一个规律,在分配当前红包金额时,先预留剩余红白所需最少金额,然后在0.01至总金额-预留金额间取随机数,得到的随机数就是当前红包分配的金额。
实际应用中,程序先将红包金额分配好,即发红包时,红包个数以及每个红包的金额都分配好了,那么用户来抢红包时,我们随机给用户返回一个红包即可。
jQuery代码:
$(function() {
$("button").click(function() {
$.ajax({
type: 'POST',
url: 'bao.php',
dataType: 'json',
beforeSend: function() {
$("#result").html('正在分配红包');
},
success: function(json) {
if (json.msg == 1) {
var str = '';
var res = json.res;
$.each(res,
function(index, array) {
str += '<p>第<span>' + array['i'] + '</span>个红包,
金额<span>' + array['money'] + '</span>元,余额<span>' +
array['total'] + '元</span></p>';
});
$("#result").html(str);
} else {
$("#result").html('数据出错!');
}
}
});
});
});
PHP代码:bao.php
$total=20;//红包总金额
$num=10;// 分成10个红包,支持10人随机领取
$min=0.01;//每个人最少能收到0.01元
for ($i=1;$i<$num;$i++)
{
$safe_total=($total-($num-$i)*$min)/($num-$i);//随机安全上限
$money=mt_rand($min*100,$safe_total*100)/100;
$total=$total-$money;
echo '第'.$i.'个红包:'.$money.' 元,余额:'.$total.' 元 ';
}
echo '第'.$num.'个红包:'.$total.' 元,余额:0 元';
验证码图片html代码:
<img src="1.php" onclick="this.src = '1.php?t=' + Math.random()" title="点击刷新" />
第一个图像验证码类,其他6种验证码类请下载查看:
class captcha{
/**
+----------------------------------------------------------
* 生成验证码
+----------------------------------------------------------
* @static
* @access public
+----------------------------------------------------------
* @param int $len 验证码字符数
* @param int $font_size 验证码字体大小
* @param string $name session名称
* @param int $width 图片长度
* @param int $height 图片高度
+----------------------------------------------------------
* @return void
+----------------------------------------------------------
*/
static function generate($len=4,$font_size=48,$name='captcha',$width='',$height=''){
if($width=='') $width=($font_size+5)*($len+1);
if($height=='') $height=($font_size)*2;
$chars='bcdefhkmnrstuvwxyABCDEFGHKMNPRSTUVWXY345689';
$str='';
for($i=0;$i<$len;$i++){
$str .= substr($chars,mt_rand(0,strlen($chars)-1),1);
}
$_SESSION[$name]=$str;//写入session
for($num=0;$num<10;$num++){
ob_start();
$image=imagecreatetruecolor($width,$height);//创建图片
$bg_color=imagecolorallocate($image,255,255,255);//设置背景颜色
$border_color=imagecolorallocate($image,100,100,100);//设置边框颜色
$text_color=imagecolorallocate($image,0,0,0);//设置验证码颜色
imagefilledrectangle($image,0,0,$width-1,$height-1,$bg_color);//填充图片背景色
imagerectangle($image,0,0,$width-1,$height-1,$border_color);//填充图片边框颜色
for($i=0;$i<5;$i++){
$line_color=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));//干扰线颜色
imageline($image,rand(0,$width),0,$width,$height,$line_color);//画一条线段
}
for($i=0;$i<500;$i++){
$dot_color=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));//干扰点颜色
imagesetpixel($image,rand()%$width,rand()%$height,$dot_color);//画一个像素点
}
for($i=0;$i<$len;$i++){
imagettftext($image,$font_size,rand(-3,3),$font_size/2+($font_size+5)*$i,$height/1.25-rand(2,3),$text_color,'Groupsex.ttf',$str[$i]);//用规定字体向图像写入文本
}
imagegif($image);
imagedestroy($image);
$imagedata[] = ob_get_contents();
ob_clean();
}
require('GIFEncoder.class.php');
$gif = new GIFEncoder($imagedata);
ob_clean();//防止出现'图像因其本身有错无法显示'的问题
header('Content-type:image/gif');
echo $gif->GetAnimation();
}
}
//调用示例
session_start();
captcha::generate(6,48);
背景
PHP校验邮箱地址的方法很多, 比较常用的就是自己写正则了, 不过正则多麻烦, 我PHP自带了方法做校验。
filter_var
filter_var是PHP内置的一个变量过滤的方法, 提供了很多实用的过滤器, 可以用来校验整数、浮点数、邮箱、URL、MAC地址等。
具体的过滤器参考: filters.validate
filter_var如果返回false, 说明变量无法通过过滤器, 也就是不合法了。
$email = "lastchiliarch@163.com";
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
$email = "asb";
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
$email = "1@a.com";
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
输出:
string(21) "lastchiliarch@163.com"
bool(false)
string(7) "1@a.com"
对于asb这种非法邮箱格式返回了false, 但对于1@a.com则通过了,还是略有瑕疵啊。
不过一般的正则也通过会认为1@a.com是一个合法的邮箱, 那有啥办法可以更精准的验证呢?
checkdnsrr
checkdnsrr其实是用来查询指定的主机的DNS记录的,我们可以借用它来验证邮箱是否存在。
对于1@a.com肯定是MX记录不存在的。
$email = "lastchiliarch@163.com";
var_dump(checkdnsrr(array_pop(explode("@",$email)),"MX"));
$email = "1@a.com";
var_dump(checkdnsrr(array_pop(explode("@",$email)),"MX"));
输出:
bool(true)
bool(false)
可以看到, 很完美, 唯一的缺点就是太慢了, 毕竟是要做一次网络请求。 所以不适合同步对大量的邮箱采用这种做法去校验。
filter_var+checkdnsrr
我们可以接合filter_var 和checkdnsrr做校验, 对于绝大多数的非法邮箱肯定会在filter_var的时候就挂掉了, 剩下的再用
checkdnsrr进一步判断。
$email_arr = array("lastchiliarch@163.com", "1@a.com");
foreach($email_arr as $email) {
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
echo "invalid email: $email \n";
continue;
}
if(checkdnsrr(array_pop(explode("@",$email)),"MX") === false) {
echo "invalid email: $email \n";
continue;
}
}
输出: invalid email: 1@a.com
但要注意的是, 由于只是检查MX记录, 所以只能判断163.com是存在的, 但不能说明lastchiliarch这个用户是存在的。
想要更精确的判断邮箱存在, 那只能连接到smtp服务器去验证了。
相关文章
- 这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
- 这篇文章主要介绍了vue接口请求加密实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-12
- 这篇文章主要介绍了Nodejs回调加超时限制两种实现方法的相关资料,需要的朋友可以参考下...2017-06-15
- 这篇文章主要介绍了C#简单了解接口(Interface)使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-08
- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
- 我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
- 1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
- 这篇文章主要介绍了C# Rx的主要接口深入理解的相关资料,需要的朋友可以参考下...2020-06-25
- 这篇文章主要给大家介绍了关于JS异步的执行原理和回调的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-08
- 这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
- 这篇文章主要介绍了详解C#中委托,事件与回调函数讲解,小编觉得挺不错的,现在就分享给大家,也给大家做个参考。...2020-06-25
- 这篇文章主要介绍了vue设置全局访问接口API地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-14
- 在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12
- php怎么写api接口?本文介绍了php写api接口的实例代码,有兴趣的同学可以参考一下。 http://localhost/openUser.php?act=get_user_list&type=json在这里openUser.php...2017-07-06
- 这篇文章主要介绍了vue配置多代理服务接口地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-08
- 当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
- 下面通过四步给大家介绍了c#处理和对接http接口请求的方法,分步骤介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看下吧...2020-06-25
- 这篇文章主要介绍了Java接口DAO模式代码原理及应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-03
- 这篇文章主要介绍了C#实现两接口中同名方法,涉及C#接口与方法的相关操作技巧,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#接口使用的实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-17