1、https://openhome.alipay.com/ 支付寶開放平台並創建應用,審核通過后並簽約app支付拿到pid


2、按照官方文檔用 【RSA簽名驗簽工具.bat】生成應用公鑰和私鑰


3、下載支付寶官方demo(https://docs.open.alipay.com/54/106370/根據自己的開發語言下載)包整合到項目中(說實話這個php的demo着實有些坑)

整合好開始寫支付寶支付類代碼如下:
<?php
namespace data\extend;
use data\extend\alipay_app\aop\AopClient;
use data\extend\alipay_app\aop\request\AlipayTradeAppPayRequest as AlipayTradeAppPayRequest;
/**
* 功能說明:自定義支付寶支付接入類
*/
class AliPayApp {
protected $aop;
/**
* 初始化
*/
public function __construct()
{
$this->aop = new AopClient();
$this->aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
$this->aop->appId = "步驟一中拿到的應用appid";
$this->aop->rsaPrivateKey = "*******";//私有密鑰(步驟二中生成的商戶私有秘鑰)
$this->aop->format = "JSON";
$this->aop->charset = "utf-8";
$this->aop->signType = "RSA2";
$this->aop->alipayrsaPublicKey = "****";//商戶公鑰(步驟二中生成的商戶公鑰)
$this->aop->alipayPublicKey = "*****";//支付寶公鑰
}
/**
* 創建APP支付訂單
*
* @param string $body 對一筆交易的具體描述信息。
* @param string $subject 商品的標題/交易標題/訂單標題/訂單關鍵字等。
* @param string $order_sn 商戶網站唯一訂單號
* @return array 返回訂單信息
*/
public function createAppPay($order_sn,$body, $subject, $total_amount)
{
//實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
$request = new AlipayTradeAppPayRequest();
//SDK已經封裝掉了公共參數,這里只需要傳入業務參數
$bizcontent = [
'body' => $body,
'subject' => $subject,
'out_trade_no' => $order_sn,
'timeout_express' => '1d',//失效時間為 1天
'total_amount' => $total_amount,//價格
'product_code' => 'QUICK_MSECURITY_PAY',
];
//商戶外網可以訪問的異步地址 (異步回掉地址,根據自己需求寫)
$request->setNotifyUrl("http://".$_SERVER['HTTP_HOST']."/此處為回調通知地址");
$request->setBizContent(json_encode($bizcontent));
//這里和普通的接口調用不同,使用的是sdkExecute
$response = $this->aop->sdkExecute($request);
return $response;
//htmlspecialchars是為了輸出到頁面時防止被瀏覽器將關鍵參數html轉義,實際打印到日志以及http傳輸不會有這個問題
}
/**
* 異步通知驗簽
*
* @param string $params 參數
* @param string $signType 簽名類型:默認RSA
* @return bool 是否通過
*/
public function rsaCheck($params, $signType)
{
return $this->aop->rsaCheckV1($params, NULL, $signType);
}
}
上面代碼注意在調用 data\extend\alipay_app\aop\AopClient 這個類需要注意回調驗簽的過程調用 $this->aop->rsaCheckV1()這個類進行通知的sign和post回來的參數(此處需要主要驗簽過程按照官方要求去掉sign和sign_type后)重新組裝+支付寶公鑰($this->aop->alipayPublicKey切記不是應用公鑰)代碼稍作調整如下
/** rsaCheckV1 & rsaCheckV2
* 驗證簽名
* 在使用本方法前,必須初始化AopClient且傳入公鑰參數。
* 公鑰是否是讀取字符串還是讀取文件,是根據初始化傳入的值判斷的。
**/
public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') {
$sign = $params['sign'];
$params['sign_type'] = null;
$params['sign'] = null;
return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType);
}
function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') {
if($this->checkEmpty($this->alipayPublicKey)){
$pubKey= $this->alipayrsaPublicKey;
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($pubKey, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
//logWrite("商戶RSA公鑰".$res);
}else {
//讀取公鑰文件(注釋部分為原來)
//$pubKey = file_get_contents($rsaPublicKeyFilePath);
//轉換為openssl格式密鑰
//$res = openssl_get_publickey($pubKey);
//此處更改為支付寶公鑰驗簽
$pubKey= $this->alipayPublicKey;
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($pubKey, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
// logWrite("支付寶RSA公鑰".$res);
}
($res) or die('支付寶RSA公鑰錯誤。請檢查公鑰文件格式是否正確');
//調用openssl內置方法驗簽,返回bool值
//logWrite("簽名:".$sign);
if ("RSA2" == $signType) {
$result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256);
} else {
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
}
if(!$this->checkEmpty($this->alipayPublicKey) && is_file($this->alipayPublicKey)) {
//釋放資源
openssl_free_key($res);
}
//logWrite("驗簽結果:".var_export($result,true));
return $result;
}
至此基本大功告成,最后一步是APP端的調用代碼如下:
public function aliPayApp()
{
$out_trade_no = $this->GetReqArgc('out_trade_no');
if (empty($out_trade_no)) {
$this->error("沒有獲取到支付信息");
}
$data = $this->getPayInfo($out_trade_no);
if($data < 0)
{
return $data;
}
$ali_pay = new AliPayApp();
$retval = $ali_pay->createAppPay($out_trade_no, $data['pay_body'], $data['pay_detail'], $data['pay_money']);
if($res){
$this->ExitMessage(SUCCESS,"",array("out_trade_no"=>$out_trade_no,"retData"=>$res));
}else{
$this->ExitMessage(ERROR_CODE,"支付寶參數錯誤",0);
}
}
以上接口返回給APP端后喚起快捷SDK創建訂單並支付的參數后即可調起支付寶APP進行支付操作,最后就是通知處理支付結果的業務邏輯如下代碼:
public function payCallback(){
$request = input('post.');
$pay = new AliPayApp();
$verify = $pay->rsaCheck($params,$signType);
if ($verify_result) { // 驗證成功
$out_trade_no = $request['out_trade_no'];
// 支付寶交易號
$trade_no = $request['trade_no'];
// 交易狀態
$trade_status = $request['trade_status'];
//logWrite("支付成功了");
if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') {
//此處支付成功后的業務邏輯處理根據自己需求
echo "success"; // 請不要修改或刪除
}
} else {
// 驗證失敗
echo "fail";
}
}
ok大功告成!說實話支付寶支付還是比微信支付要好許多雖然也有坑,但微信支付的坑是比較多的!
