官网下载php版本的alipay-php-demo
- 解压后复制文件夹中的aop文件包,粘贴到tp8/extend目录下,并修改目录名为alipay_aop;。
- 修改alipay_aop目录下AopClient.php文件,在第一行加入命名空间:namespace alipay_aop;
<?php
namespace alipay_aop;
require_once 'AopEncrypt.php';
class AopClient {
......
}
- 修改alipay_aop/request/目录下AlipayTradePagePayRequest.php文件,加入命名空间:alipay_aop\request;
<?php
namespace alipay_aop\request;
/**
* ALIPAY API: alipay.trade.page.pay request
*
* @author auto create
* @since 1.0, 2017-04-06 15:55:36
*/
class AlipayTradePagePayRequest
{
/**
* 统一收单下单并支付页面接口
**/
......
}
使用
- tp8/app/model目录下新建AlipayModel.php文件
<?php
namespace app\model;
use alipay_aop\AopClient;
use alipay_aop\request\AlipayTradePagePayRequest;
class AlipayModel {
//应用ID,APPID。
// private $appId = "";
//商户私钥
// private $merchantPrivateKey = "";
//异步通知地址
private $notifyUrl = "https://api.mydomain.com/notify.html";
//同步跳转
private $returnUrl = "https://api.mydomain.com/returns.html";
//编码格式
private $charset = "UTF-8";
//签名方式
private $signType = "RSA2";
//支付宝网关
private $gatewayUrl = "https://openapi.alipay.com/gateway.do";
// 支付宝公钥,
private $alipayPublicKey = "MIIBIjANBgkqhkiG9w0lnUw2TTjDFwj3D1Qk3iSKUAZg9CTcQB129+5DRlLkzEfWyffnUkUtA4VYLS8r6ycvG0iYHd6tN4muXg0b6029iaWzjuR9meJ079KIKAqQkSdfCESBJMSsVp62a7gVbIwXILDn3P6jGaiuA8317yCCd0bhEw9JeKLGmlQOaBUwIDAQAB";
//开启AES加密后密钥
// private $encryptKey = "";
// 电脑网站支付下单
public function webPagePay($data, $channelConfig) {
//商户订单号,商户网站订单系统中唯一订单号,必填
$out_trade_no = trim($data['platform_order_no']);
//订单名称,必填
$subject = trim($data['subject']);
//付款金额,必填
$total_amount = trim($data['amount']);
//商品描述,可空
$body = trim($data['remark']);
/** PHP 语言 普通公钥签名
* $aop = new AopClient;
$aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
$aop->appId = "app_id";
$aop->rsaPrivateKey = '请填写开发者私钥去头去尾去回车,一行字符串';
$aop->format = "json";
$aop->charset = "UTF-8";
$aop->signType = "RSA2";
$aop->alipayrsaPublicKey = '请填写支付宝公钥,一行字符串';
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
$request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
$request->setBizContent("{\"body\":\"我是测试数据\","
. "\"subject\": \"App支付测试\","
. "\"out_trade_no\": \"20170125test01\","
. "\"timeout_express\": \"30m\","
. "\"total_amount\": \"0.01\","
. "\"product_code\":\"QUICK_MSECURITY_PAY\""
. "}");
$request->setNotifyUrl("商户外网可以访问的异步地址");
//这里和普通的接口调用不同,使用的是sdkExecute
$response = $aop->sdkExecute($request);
//htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题
echo htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。
*
*
*/
$aop = new AopClient();
$aop->gatewayUrl = $channelConfig['gateway'];
$aop->appId = $channelConfig['appid'];
$aop->format = "json";
$aop->charset = $this->charset;
$aop->signType = $this->signType;
$aop->encryptKey = $channelConfig['encryptKey'];
$aop->alipayrsaPublicKey = $channelConfig['providerPublicKey'];
$aop->rsaPrivateKey = $channelConfig['merchantPrivateKey'];
$biz_content = json_encode([
'out_trade_no' => $out_trade_no,
'product_code' => 'FAST_INSTANT_TRADE_PAY', // 固定值
'total_amount' => $total_amount,
'subject' => $subject,
'timeout_express' => '120m',
// 'qr_pay_mode' => '0',
]);
// 判断是否需要内容aes加密
$needEncrypt = empty(trim($channelConfig['encryptKey'])) ? false : true;
$payRequest = new AlipayTradePagePayRequest();
$payRequest->setReturnUrl($this->returnUrl);
$payRequest->setNotifyUrl($this->notifyUrl);
$payRequest->setNeedEncrypt($needEncrypt);
// $payRequest->setQrPayMode('0');
$payRequest->setBizContent($biz_content);
$response = $aop->sdkExecute($payRequest);
return $channelConfig['gateway'] . '?' . $response;
// echo('<a href="https://openapi.alipay.com/gateway.do?'.$response.'">');
}
// 查询接口
public function query() {
......
}
/**
* 验签方法
* @param $arr 验签支付宝返回的信息,使用支付宝公钥。
* @return boolean
*/
function checkSign($data) {
/** 异步同步通知数据验签
* $aop = new AopClient ();
//编码格式
$aop->postCharset="UTF-8";
//支付宝公钥赋值
$aop->alipayrsaPublicKey="";
//回调的待验签字符串
$_POST="buyer_id=20880****42&total_amount=0.01&body=煜雨电脑网站测试&trade_no=2019032922001481941025940236¬ify_time=2019-03-29 19:42:04&subject=煜雨测试电脑网站支付&sign_type=RSA2&charset=UTF-8&auth_app_id=201****22¬ify_type=trade_status_sync&invoice_amount=0.01&out_trade_no=20190329ygyg45484544100003&trade_status=TRADE_SUCCESS&gmt_payment=2019-03-29 19:42:03&version=1.0&point_amount=0.00&sign=LDDUIGQmc+1qNtk3oyoAKVeMUKTngdX3ZjVeZOK0EjiPDJ/+Nk+0WSqcE6J7/5xb96Z/vP0yY3pVhZUiFVJ1G45/ys/HAleHh+EERZ1lkCkule1sSyaGFTKQGKx4uHpTyqIgRB1bouf19RPbSx1EkA0VkCarSy9G/OEG5Qmg8UdL2dRulMhlbOHS7tdMJJycDA8vOspOUMeQmk/H6IK9R2Kou5hN2T3KR1GWLYFK+z1jeZhQB3q52lZynO0OFjSzU4aQUBMW5QskQppBYd/ghtY/2YP+2H6YVGNgVmaheZMQ3PVTBALEV+8rZa91salH9DkKN2UCYGvNSNDT1VGCTQ==&gmt_create=2019-03-29 19:42:00&buyer_pay_amount=0.01&receipt_amount=0.01&fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]&seller_id=208850*0**&app_id=20141****2¬ify_id=2019032900222194204081941005192208";
//签名方式
$sign_type="RSA2";
//把字符串通过&符号拆分成数组
$data = explode('&', $_POST);
$params = array();
//遍历数组
foreach ($data as $param) {
$item = explode('=', $param,"2");
$params[$item[0]] = $item[1];
}
//输出拆分后的数据
//print_r($params);
//验签代码
$flag = $aop->rsaCheckV1($params, null, $sign_type);
//输出验签结果
//echo $flag;
if ($flag)
{
echo "success";
}
else
{
echo "fail";
}
*
*
*/
$aop = new AopClient();
$aop->postCharset = $this->charset;
$aop->signType = $this->signType;
$aop->alipayrsaPublicKey = $this->alipayPublicKey;
//验签代码
$flag = $aop->rsaCheckV1($data, null, $this->signType);
// var_dump($flag);
return $flag;
}
}
- 调用
$alipayModel = new AlipayModel();
// 这里是向支付宝提交平台订单号
$data['platform_order_no'] = $orderNo;
// 读取商户通道配置文件
$config = [
'appid' => $hasChannel['appid'],
'gateway' => $hasChannel['gateway'],
'merchantPrivateKey' => $hasChannel['private_key'],
'providerPublicKey' => $hasChannel['provider_public_key'],
'encryptKey' => $hasChannel['encrypt_key'],
];
$returnPayLink = $alipayModel->webPagePay($data, $config);
- 接收支付宝异步通知时验证签名:
<?php
namespace app\controller;
use app\model\AlipayModel;
// 这里一定要加入header设置,否则支付宝收到的返回值可能会在success或fail前加入一个空格,导致支付宝会多次回调
header('Content-Type: text/plain; charset=utf-8');
class Notify{
public function Index(){
$data = $_POST;
// 写入日志
$this->debugModel->writeLog(var_export($_POST, true));
// 验证支付宝接口签名
$alipayModel = new AlipayModel();
$result = $alipayModel->checkSign($data);
if ($result) {
echo "success";
}else{
echo "fail";
}
}
}
一定要加入header设置,否则支付宝收到的返回值可能会在success或fail前加入一个空格,导致支付宝会多次回调