最近在写支付 , 遇到了一些支付宝的坑,这里也记录分享一下
首先必须在蚂蚁金服上面有一个应用 , 并且把商户私钥 , 支付宝公钥等都设置好
然后下载支付宝php的SDK , 链接如下
https://docs.open.alipay.com/270/106291/
我用的是TP5框架
这里把SDK下好解压之后放到TP的extend目录下
首先我们需要在自己的数据库中保存以下内容 :
1.subject //订单标题 2.total_amount //需付款金额 3.body //商品描述, 可空 4.out_trade_no //订单号, 需自己生成 5.user_id //这个不用传给支付宝
这里附上我的生成订单号代码
//生成订单号
$osn = date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
以上都完成之后 , 就可以使用SDK了
这里我遇到了第一个问题 , 第三方类的引用. 由于支付宝SDK无法使用composer下载 , 导致了整个包里面的
类都没有命名空间 .
引用的时候总是报错文件不存在或类不存在
查阅了许多资料之后 , 终于找到了解决方法 :
使用Loader加载
Loader::import('alipay.pagepay.service.AlipayTradeService');
Loader::import('alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder');
这样的话即使第三方类库没有命名空间 , 也能完美引用
我把SDK之中的pagepay.php 写到了我的class之中
//以下是简化过后的代码
public function payment ()
{
$data = $this->request->param();
$user_id = $this->userInfo['id'];
//生成唯一订单号
$osn = date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
//保存订单
$res = Db::name('order')->insert([
'title' => $data['subject'], //订单标题
'type' => $data['type'], //订单类型
'number' => $osn, //订单编号
'money' => $data['total_amount'],
'user_id'=> $user_id,
'create_time'=>time(),
]);
if($res){
//订单信息保存成功
Loader::import('alipay.pagepay.service.AlipayTradeService');
Loader::import('alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder');
$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
$payRequestBuilder->setBody($data['body']);
$payRequestBuilder->setSubject($data['subject']);
$payRequestBuilder->setTotalAmount($data['total_amount']);
$payRequestBuilder->setOutTradeNo($osn);
$aop = new \AlipayTradeService(config('alipay'));
/**
* pagePay 电脑网站支付请求
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @param $return_url 同步跳转地址,公网可以访问
* @param $notify_url 异步通知地址,公网可以访问
* @return $response 支付宝返回的信息
*/
$response = $aop->pagePay($payRequestBuilder,config('alipay')['return_url'],config('alipay')['notify_url']);
}
echo $osn; //2018070499495653
}
这里的config函数是我提前就在application目录下的config.php文件中部署好的
//在你application目录下的config文件之后加上支付宝的一些配置信息
// 之后就可以直接使用config('alipay')调用此数组
//一定要确保这些数据没有任何问题
'alipay'=>[
//应用ID,您的APPID。
'app_id' => "",
//商户私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "",
//同步跳转
'return_url' => "",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥
'alipay_public_key' => "",
],
至此 , 调用了pagepay之后 , 就会出现付款界面了
付款成功 , 接下来是支付宝的支付结果异步通知
此通知是支付宝单方面访问你的接口 , 你需要在此接口之中处理商户的业务逻辑
成功之后返回 “success” 即可
注意 ! 请不要把支付宝的异步请求的接口放在继承了登陆等判断的class之中 , 因为如果加了这些判断 ,
则支付宝无法正常请求我们的接口
此接口必须放在服务器上 ,如果在本地则支付宝服务器无法请求
/**
* 支付宝异步回调接口
*/
public function notify_url ()
{
Loader::import('alipay.pagepay.service.AlipayTradeService');
$arr=$_POST;
$alipaySevice = new \AlipayTradeService(config('alipay'));
$alipaySevice->writeLog(var_export($_POST,true));
$result = $alipaySevice->check($arr); //这一步验签
if($result) {//验证成功
//商户订单号
$out_trade_no = $_POST['out_trade_no'];
//订单金额
$total_amount = $_POST['total_amount'];
//支付宝交易号
$trade_no = $_POST['trade_no'];
//交易状态
$trade_status = $_POST['trade_status'];
if($_POST['trade_status'] == 'TRADE_FINISHED') {
//--交易结束执行的业务逻辑--
}else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
//--交易支付成功执行的业务逻辑--
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
echo "success"; //请不要修改或删除
}else {
//验证失败
echo "fail";
}
}
到这里使用支付宝SDK就结束了
这里还说一下 , 你的服务器必须开启openssl拓展 , 调用check验签 , 必需开启openssl