1、前期准备
申请支付宝平台账号(个人号、企业号)根据实际需求申请
申请成功后进入控制台 -》 沙箱
看到相应的信息
2、下载官方提供的sdk和demo 按实际需求下载对应的版本
官方文档地址 https://opendocs.alipay.com/open/203/105910?pathHash=1a2e3a94
3、实现代码
自己封装一个类 Alipay.class 也可用官方提供的demo
相关 开发信息 ,可用证书模式或者公钥模式,根据实际情况选择
点击可以查看,密钥生成需要平台提供的工具生成,官网有可以自己查看
生成的密钥在文件夹中
可以替换对应密钥。
配置文件代码
$config = array ( //应用ID,您的APPID。 'app_id' => "", //商户私钥,您的原始格式RSA私钥 'merchant_private_key' => "", //异步通知地址 'notify_url' => "http://自己的/alipay.trade.wap.pay-PHP-UTF-8/notify_url.php", //同步跳转 'return_url' => "http://自己的/alipay.trade.wap.pay-PHP-UTF-8/return_url.php", //编码格式 'charset' => "UTF-8", //签名方式 'sign_type'=>"RSA2", //支付宝网关 'gatewayUrl' => "自己的", //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 'alipay_public_key' => "", //日志路径 'log_path' => "", );
配置的异步地址和同步地址可以正常访问。
异步通知:支付成功后会访问方法,再通过返回的状态码去更改订单状态。
同步跳转:支付成功后会跳转到这个地址
生成订单
方法一:官方文档 可参考
方法二:
/* * 下单 * */ public function pay($data){ import('alipay.aop.AopClient', EXTEND_PATH); //pc import('alipay.aop.request.AlipayTradePagePayRequest', EXTEND_PATH); //手机 import('alipay.aop.request.AlipayTradeWapPayRequest', EXTEND_PATH); $alipayConfig = Config::get('alipay'); $aop = new \AopClient (); $aop->gatewayUrl = $alipayConfig['gatewayUrl']; $aop->appId = $alipayConfig['app_id']; $aop->rsaPrivateKey = $alipayConfig['merchant_private_key']; $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key']; $aop->apiVersion = '1.0'; $aop->signType =$alipayConfig['sign_type']; $aop->postCharset=$alipayConfig['charset'];; $aop->format='json'; $request = request()->isMobile() ? new \AlipayTradeWapPayRequest() : new \AlipayTradePagePayRequest(); //异步接收地址,仅支持http/https,公网可访问 $request->setNotifyUrl($alipayConfig['notify_url']); //同步跳转地址,仅支持http/https $request->setReturnUrl($alipayConfig['return_url']); /******必传参数******/ $object = new \stdClass(); //商户订单号,商家自定义,保持唯一性 $object->out_trade_no = $data['out_trade_no']; //支付金额,最小值0.01元 $object->total_amount = $data['total_amount']; //订单标题,不可使用特殊符号 $object->subject = $data['subject']; //区分支付场景电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY手机端为QUICK_WAP_WAY $object->product_code = request()->isMobile() ? 'QUICK_WAP_WAY' : 'FAST_INSTANT_TRADE_PAY'; /******可选参数******/ $object->time_expire = date('Y-m-d H:i:s',time()+120); $json = json_encode($object); $request->setBizContent($json); return $aop->pageExecute($request); }
//异步回调地址,用作逻辑处理,更改订单状态。第二种写法 public function notify_url(){ import('alipay.pagepay.service.AlipayTradeService', EXTEND_PATH); $arr=$_POST; $alipaySevice = new \AlipayTradeService(Config::get('alipay')); $alipaySevice->writeLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); if($result) { //验证成功 //请在这里加上商户的业务逻辑程序代 file_put_contents('./log.txt',$_POST['out_trade_no'].','.$_POST['trade_no']); //请在这里加上商户的业务逻辑程序代 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 //商户订单号 $out_trade_no = $arr['out_trade_no']; //支付宝交易号 $trade_no = $arr['trade_no']; //交易状态 $trade_status = $arr['trade_status']; if($trade_status == 'TRADE_FINISHED') { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 } else if ($trade_status == 'TRADE_SUCCESS') { //支付成功后逻辑处理 } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— echo "success"; //请不要修改或删除 }else { //验证失败 echo "fail"; } }
//同步回调,支付成功跳转的地址,get方式获取订单信息 第二种方法 public function return_url(){ import('alipay.pagepay.service.AlipayTradeService', EXTEND_PATH); $arr=$_GET; $alipaySevice = new \AlipayTradeService(Config::get('alipay')); $result = $alipaySevice->check($arr); if($result) {//验证成功 //请在这里加上商户的业务逻辑程序代码 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表 //商户订单号 $out_trade_no = htmlspecialchars($_GET['out_trade_no']); //支付宝交易号 $trade_no = htmlspecialchars($_GET['trade_no']); echo "验证成功<br />支付宝交易号:".$trade_no; //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— echo '<pre>'; print_r($_GET); echo '</pre>'; exit(); }
查询订单相关代码
注意:查询时会报错 Class 'SignData' not found
引入就可以了
//查询支付宝订单结果 public function queryOrder($id){ //$id = input('post.id/d') ? : 1;//查询订单 import('alipay.aop.AopClient', EXTEND_PATH); import('alipay.aop.request.AlipayTradeQueryRequest', EXTEND_PATH); $alipayConfig = Config::get('alipay'); $aop = new \AopClient(); $aop->gatewayUrl = $alipayConfig['gatewayUrl']; $aop->appId = $alipayConfig['app_id']; $aop->rsaPrivateKey = $alipayConfig['merchant_private_key']; $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key']; $aop->apiVersion = '1.0'; $aop->signType =$alipayConfig['sign_type']; $aop->postCharset=$alipayConfig['charset'];; $aop->format='json'; $request = new \AlipayTradeQueryRequest(); $setBizContent = [ //'out_trade_no'=>$o_info['out_trade_no'],//可不传 //'trade_no'=>$o_info['trade_no'], 'out_trade_no'=>$id,//可不传 ]; $request->setBizContent(json_encode($setBizContent)); $result = $aop->execute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; if(!empty($resultCode)&&$resultCode == 10000){ echo "成功"; //打印订单信息 echo '<pre>'; print_r($result); echo '</pre>'; exit(); } else { echo "失败"; } }
运行结果
退款申请代码
//支付宝退款 public function refund($id){ import('alipay.aop.AopClient', EXTEND_PATH); import('alipay.aop.request.AlipayTradeRefundRequest', EXTEND_PATH); $alipayConfig = Config::get('alipay'); $aop = new \AopClient (); $aop->gatewayUrl = $alipayConfig['gatewayUrl']; $aop->appId = $alipayConfig['app_id']; $aop->rsaPrivateKey = $alipayConfig['merchant_private_key']; $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key']; $aop->apiVersion = '1.0'; $aop->signType =$alipayConfig['sign_type']; $aop->postCharset=$alipayConfig['charset'];; $aop->format='json'; $object = new \stdClass(); $object->trade_no = $id;//订单号(支付宝订单号) $object->refund_amount = 0.01;//订单金额 $json = json_encode($object); $request = new \AlipayTradeRefundRequest(); $request->setBizContent($json); $result = $aop->execute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; if(!empty($resultCode)&&$resultCode == 10000){ echo "成功"; } else { echo "失败"; } }
运行结果
退款查询代码
//支付宝退款查询 public function refund_query($id){ import('alipay.aop.AopClient', EXTEND_PATH); import('alipay.aop.request.AlipayTradeFastpayRefundQueryRequest', EXTEND_PATH); $alipayConfig = Config::get('alipay'); $aop = new \AopClient (); $aop->gatewayUrl = $alipayConfig['gatewayUrl']; $aop->appId = $alipayConfig['app_id']; $aop->rsaPrivateKey = $alipayConfig['merchant_private_key']; $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key']; $aop->apiVersion = '1.0'; $aop->signType =$alipayConfig['sign_type']; $aop->postCharset=$alipayConfig['charset'];; $aop->format='json'; //请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号 $object = new \stdClass(); $object->trade_no = $id;//订单号(支付宝订单号) $object->out_request_no = $id;//退款请求号 $json = json_encode($object); $request = new \AlipayTradeFastpayRefundQueryRequest(); $request->setBizContent($json); $result = $aop->execute($request); var_dump($result);die; $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; if(!empty($resultCode)&&$resultCode == 10000){ echo "成功"; } else { echo "失败"; } }
运行结果
退款总结:
(1)传入参数支付宝交易号,执行退款操作前先查询订单状态是否能退款,订单查询后的“trade_status”为TRADE_SUCCESS才能退款,否则不能进行退款。
(2)退款成功后 trade_status会变成TRADE_CLOSED。
(3)超过12个月订单会变成TRADE_FINISHED就不能进行退款操作了。
详细参考文档
以上是以沙箱账号实现的功能,正式发布需要把配置文件修改一下。
不足之处请大家指教