PHP 网页支付支付宝支付接口对接
本文全程使用沙箱测试 真实环境更换配置文件即可
总个小结 : 目前大多数常用接口都比较完善,只要参数传的没毛病,基本对接没啥问题,排排小坑,跑起来就行。下面讲下个人开发步骤
开发前准备
- 去 蚂蚁金服开放平台 注册账号
- 入驻
- (真实环境)
- 进入 应用列表 签约
- 然后获取 APPID 以及 公钥 等配置信息 https://openhome.alipay.com/platform/keyManage.htm
- 下载公钥生成器
- 打开之后有这个东西
- 这个公钥就放在账户中心上面就是你的应用公钥,密钥在生成上面的文件夹里。 然后把它们写进代码就OK了!
- (沙箱测试)
- 去 蚂蚁金服开放平台 注册账号 (有帐号直接登录)
- 进入 我的开放平台
- 添加一个 沙箱应用
- 从里面获取 这些…
- 按步骤获取信息 不知道咋整的先放放 下载sdk 看看里面需要啥 要啥整啥
- 开始下载 正经网址 https://docs.open.alipay.com/270/106291/
- 下载解压之后大概长这样
差不多就开始撸代码!
- 这个文件里的demo基本可以满足我们去支付的逻辑
- 我自己写了个公共函数 所以就复制过来改一改
- 写个配置项的函数
/**
* 支付宝支付配置参数
* @return array
*/
function pay_ali_ini()
{
// 获取网站域名(可写死)
$http_ = Request::instance()->domain();
return array(
//应用ID,您的APPID。
'app_id' => "您的APPID",
//商户私钥
'merchant_private_key' => "你的商户私钥",
//异步通知地址
'notify_url' => $http_ . "/异步通知地址",
//同步跳转
'return_url' => $http_ . "/同步跳转",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//版本
'apiVersion' => '1.0',
//支付宝网关 (沙箱网关 真实环境要更换 https://openapi.alipay.com/gateway.do)
'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "你的支付宝公钥",
'format' => 'json',
);
}
- 然后就写个调用的方法 (参考 pagepay.php)
- 注意传参
//商户订单号,商户网站订单系统中唯一订单号,必填
$out_trade_no = trim($_POST['WIDout_trade_no']);
//订单名称,必填
$subject = trim($_POST['WIDsubject']);
//付款金额,必填
$total_amount = trim($_POST['WIDtotal_amount']);
//商品描述,可空
$body = trim($_POST['WIDbody']);
- 传参详情可阅读文档 https://docs.open.alipay.com/api_1/alipay.trade.page.pay/
- 准备好之后就可以运行了 (瞬间笑了)
- 小坑两个(手动标红)
- 坑1 你会在好多地方发现这个函数
- 所以要给这个 一个 可读写的权限 (chmod -R 777 )
- 坑2 (仅针对 7.2及以上版本的玩家)
- 啊哈 因为 each 函数在7.2被废了 (哈哈哈…)
- 然后就可以为所欲为测试啦~~~
回调地址 (同步?异步?)
- 这个问题困扰了我许久…
- 结论 : 同步地址里面就写个简单的判断 ,仅前端提示展示跳转即可 不可作为实际支付依据进行逻辑处理
- 异步地址用来处理逻辑 可参考这两个文件
- 个人回调处理
// Alipay 同步跳转url
public function alipayReturnUrl()
{
$arr = $_GET;
$config = pay_ali_ini();
require_once $_SERVER['DOCUMENT_ROOT']. '/../api/alipay/pagepay/service/AlipayTradeService.php';
$alipaySevice = new \AlipayTradeService($config);
$result = $alipaySevice->check($arr);
// 获取跳转地址
$url = session('pay_url_back');
session('pay_url_back', null);
if ($result){
$this->success('支付验证成功!', $url);
}else {
//验证失败
$this->error('支付验证失败!', $url);
}
}
// Alipay 异步跳转url
public function alipayNotifyUrl()
{
$arr = $_POST;
$config = pay_ali_ini();
require_once $_SERVER['DOCUMENT_ROOT']. '/../api/alipay/pagepay/service/AlipayTradeService.php';
$alipaySevice = new \AlipayTradeService($config);
$alipaySevice->writeLog(var_export($_POST,true));
$result = $alipaySevice->check($arr);
if($result) {//验证成功
//获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
if($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
//判断该笔订单是否在商户网站中已经做过处理
$is_have = Db::name('order_pay')->field('id')->where('order_no', $arr['out_trade_no'])->find();
if ($is_have){return false;}
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 启动事务
Db::startTrans();
try{
$insert_data = [
'create_time' => time(),
'out_trade_no' => $arr['out_trade_no'],
'gmt_create' => $arr['gmt_create'],
'gmt_payment' => $arr['gmt_payment'],
'subject' => $arr['subject'],
'buyer_id' => $arr['buyer_id'],
'body' => isset($arr['body'])?$arr['body']:'',
'total_amount' => $arr['total_amount'],
'receipt_amount' => $arr['receipt_amount'],
'fund_bill_list' => $arr['fund_bill_list'],
'auth_app_id' => $arr['auth_app_id'],
'point_amount' => $arr['point_amount'],
'buyer_pay_amount' => $arr['buyer_pay_amount'],
'seller_id' => $arr['seller_id'],
'trade_status' => $arr['trade_status'],
];
$insert_id = Db::name('alipay')->insertGetId($insert_data);
Db::name('order_pay')->insert(['db_name'=>'alipay', 'order_no' => $arr['out_trade_no'], 'd_id' => $insert_id, 'pay_type' => 'alipay']);
// 查询是否在 cmf_goods_order 表中
$is_have_order = Db::name('goods_order')->field('order_id')->where('order_no', $arr['out_trade_no'])->find();
if ( $is_have_order ){
// 修改订单状态
$goods_order_data = [
'pay_status' => 2,
'modify_time' => time(),
'pay_time' => strtotime($arr['gmt_payment']),
'order_status' => 3,
];
//添加任务进度状态
$progress_remark = '订单已支付';
$task_progress = [
'order_id' => $is_have_order['order_id'],
'create_time' => time(),
'modify_time' => time(),
'progress_remark' => $progress_remark
];
Db::name('task_progress')->insert($task_progress);
Db::name('goods_order')->where('order_id', $is_have_order['order_id'])->update($goods_order_data);
}
$this->doNotify($arr['out_trade_no']);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return false;
}
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
}
echo "success"; //请不要修改或删除
}else {
//验证失败
echo "fail";
}
}
放个大招
输入 人工客服 (一遍不行多输入几遍 就会出来 联系人工客服…)
有问题找技术 盘他!