准备工作
1:下载支付宝开放平台开发助手,使用助手工具生成应用公钥和应用私钥。
参考文档:
2:给应用配置接口加签方式,此处的目的是将应用appid与应用公钥绑定。
参考文档:
3:查看应用是否开通了电脑网站支付
4:下载官方demo
选择对应开发语音下载即可,此处以php为例
5:代码示例:
我们将php SDK代码放在项目sdk目录下,取名alipagepay,目录结构如下:
其中key文件夹是我们新增的,用于存放第2步操作绑定应用公钥后生成的支付宝公钥
前端html部分:
html 部分代码请自己完成,此处忽略
后端逻辑处理部分:
调起支付宝支付界面代码:
header('Content-type:text/html; Charset=utf-8');
//sdk路径根据自己实际项目需求更改
require_once '/sdk/alipagepay/pagepay/service/AlipayTradeService.php';
require_once '/sdk/alipagepay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
//站内生成订单记录,此处可根据自己实际项目需求更改
$data=array(
'touid' =>$uid,
'uid' =>$uid,
'money' => $money,
'coin' =>$coin,
'coin_give' =>$give,
'trade_no' =>'',
'orderno' =>$orderid,
'status' =>0,
'addtime' =>time(),
'type' =>1,
'ambient' =>1,
);
$res=Db::name("charge_user")->insert($data);
if(!$res){
$this->assign("jumpUrl",'/');
$this->error("订单创建失败,请重新提交");
}
$config=$this->getaliPagePayConfig();
//商户订单号,商户网站订单系统中唯一订单号,必填
$out_trade_no = trim($orderid);
//订单名称,必填
$subject = trim($order_name);
//付款金额,必填
$total_amount = trim($money);
//商品描述,可空
$body = trim($order_name);
//构造参数
$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setOutTradeNo($out_trade_no);
$aop = new \AlipayTradeService($config);
$response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
//输出表单
var_dump($response);
return;
获取支付支付配置信息代码:
/**
* 获取支付宝支付配置信息
* @return array 配置信息
*/
public function getaliPagePayConfig(){
$alipay_public_key_path='/sdk/alipagepay/key/publickey.php';
require $alipay_public_key_path;
$config = array (
//应用ID,您的APPID。
'app_id' => '',
//商户私钥
'merchant_private_key' => '',
//异步通知地址,替换为外网可访问的域名
'notify_url' => "http://****.com/home/Payment/alipay_notify",
//同步跳转,替换为外网可访问的域名
'return_url' => "http://****.com/home/Payment/alipayres",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
//此处的$publickey就是前面sdk中添加的key文件夹下的publickey.php中返回的支付宝公钥
'alipay_public_key' =>$publicKey,
//日志路径,根据自己项目需求更改
'log_path' => '/log/think/home/payment/alipagepay_'.date("Y-m-d").'.txt',
);
return $config;
}
支付宝同步回调代码:
//支付宝支付同步回调地址
function alipayres(){
//sdk路径根据自己实际项目需求更改
require_once '/sdk/alipagepay/pagepay/service/AlipayTradeService.php';
$config=$this->getaliPagePayConfig();
$arr=$_GET;
$this->logali("同步回调信息");
$this->logali(json_encode($arr));
$alipaySevice = new \AlipayTradeService($config);
$result = $alipaySevice->check($arr);
$this->logali("同步回调信息验证结果:".json_encode($result));
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
if($result) {//验证成功
/
//请在这里加上商户的业务逻辑程序代码
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
//商户订单号
$out_trade_no = htmlspecialchars($arr['out_trade_no']);
//支付宝交易号
$trade_no = htmlspecialchars($arr['trade_no']);
//交易金额
$total_amount =htmlspecialchars($arr['total_amount']);
//应用appid
$app_id=htmlspecialchars($arr['app_id']);
//=============查询站内订单状态【根据自己实际项目需求更改】
$orderinfo=Db::name("charge_user")->where(['orderno'=>$out_trade_no,'type'=>1,'ambient'=>1,'money'=>$total_amount])->find();
$this->logali("同步回调订单内容:".json_encode($orderinfo));
if(!$orderinfo){
//订单不存在
$status=-1;
$orderinfo=array();
}else{
//订单已支付
if($orderinfo['status']==0){
$status=0;
$orderinfo=array();
}else{
$status=1;
}
}
//=============
}else {
//======【根据自己实际项目需求更改】========
//验证失败
$status=0;
$orderinfo=array();
//=============
}
//======【根据自己实际项目需求更改】========
$this->assign('status',$status);
$this->assign('orderinfo',$orderinfo);
return $this->fetch();
//=============
}
支付宝异步回调代码:
/**
* 支付宝异步回调地址
* @return string 支付状态 success:成功 fail:失败
*/
function alipay_notify(){
/*************************页面功能说明*************************
* 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
*/
//sdk路径根据实际项目需求更改
require_once '/sdk/alipagepay/pagepay/service/AlipayTradeService.php';
$config=$this->getaliPagePayConfig();
$arr=$_POST;
$this->logali("异步回调信息:".json_encode($arr));
$alipaySevice = new \AlipayTradeService($config);
//$alipaySevice->writeLog(var_export($_POST,true));
$result = $alipaySevice->check($arr);
$this->logali("异步回调信息验证结果:".json_encode($result));
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
if($result) {//验证成功
//请在这里加上商户的业务逻辑程序代
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
//获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
//商户订单号
$out_trade_no = $arr['out_trade_no'];
//支付宝交易号
$trade_no = $arr['trade_no'];
//交易状态
$trade_status = $arr['trade_status'];
//交易金额
$total_amount=$arr['total_amount'];
if($arr['trade_status'] == 'TRADE_FINISHED') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
}else if ($arr['trade_status'] == 'TRADE_SUCCESS') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//付款完成后,支付宝系统发送该交易状态通知
$where['orderno']=$out_trade_no;
$where['money']=$total_amount;
$where['type']=1;
$where['ambient']=1;
$data=[
'trade_no'=>$trade_no
];
//$alipaySevice->writeLog(var_export($where,true));
$this->logali("异步回调,订单查询条件:".json_encode($where));
$res=Db::name->where($where)->update($data);
if($res==0){
$this->logali("异步回调,orderno:".$out_trade_no.' 订单信息不存在');
echo "fail";
return;
}
$this->logali("异步回调,订单支付成功");
echo "success"; //请不要修改或删除
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
//echo "success"; //请不要修改或删除
}else {
//验证失败
$this->logali("异步回调验证失败");
echo "fail";
}
}
/* 打印log */
public function logali($msg){
file_put_contents(CMF_ROOT.'log/think/home/payment/alipagepay_'.date("Y-m-d").'.txt',date('Y-m-d H:i:s').' '.$msg."\r\n",FILE_APPEND);
}