PHP服務端整合支付寶APP支付以及回撥
阿新 • • 發佈:2019-01-08
說到支付寶APP支付,相對於微信APP支付要簡單一點,下篇會具體說微信APP支付的具體接入;
流程:客戶端提供資料 -> 服務端處理生成支付引數返回給客戶端調起支付 -> 支付成功 -> 支付寶回撥結果 -> 接受回撥修改訂單狀態
首先,去下載服務端SDK(PHP版本),命名為appAliSDk;
新建一個支付類,命名為appAliPay_class.php,然後引入支付需要的依賴檔案
ini_set('date.timezone','Asia/Shanghai'); header("Content-type: text/html; charset=utf-8"); require_once $_SERVER['DOCUMENT_ROOT'].'/appAliSDK/aop/AopClient.php'; require_once $_SERVER['DOCUMENT_ROOT'].'/appAliSDK/aop/request/AlipayTradeAppPayRequest.php';
在支付類中定義幾個支付需要的引數常量,
//支付寶公鑰
const alipay_public_key = "";
//商戶私鑰
const merchant_private_key = "";
//支付寶閘道器
const gatewayUrl = "https://openapi.alipay.com/gateway.do";
//應用ID
const app_id = "";
//非同步通知地址,只有掃碼支付預下單可用
const notify_url = "";
接下來是發起支付方法需要的引數傳入
//客戶端提供引數
下面是支付寶非同步回撥給我們支付結果接受的方法public function appPay($body="商品購買",$subject="商品購買",$out_trade_no,$total_amount){ $aop = new AopClient; $aop->gatewayUrl = self::gatewayUrl; $aop->appId = self::app_id; $aop->rsaPrivateKey = self::merchant_private_key; $aop->format = "json"; $aop->charset = "UTF-8"; $aop->signType = "RSA2"; $aop->alipayrsaPublicKey = self::alipay_public_key; //例項化具體API對應的request類,類名稱和介面名稱對應,當前呼叫介面名稱:alipay.trade.app.pay $request = new AlipayTradeAppPayRequest(); //SDK已經封裝掉了公共引數,這裡只需要傳入業務引數 $bizcontent = "{\"body\":\"$body\"," . "\"subject\": \"$subject\"," . "\"out_trade_no\": \"$out_trade_no\"," . "\"timeout_express\": \"30m\"," . "\"total_amount\": \"$total_amount\"," . "\"product_code\":\"QUICK_MSECURITY_PAY\"" . "}"; $request->setNotifyUrl(self::notify_url); $request->setBizContent($bizcontent); //這裡和普通的介面呼叫不同,使用的是sdkExecute $response = $aop->sdkExecute($request); //htmlspecialchars是為了輸出到頁面時防止被瀏覽器將關鍵引數html轉義,實際列印到日誌以及http傳輸不會有這個問題 // return htmlspecialchars($response);//就是orderString 可以直接給客戶端請求,無需再做處理。 return $response; }
//回撥
public function notify(){
$data = $_POST;
$aop = new AopClient;
$aop->alipayrsaPublicKey = self::alipay_public_key;
$flag = $aop->rsaCheckV1($data, NULL, "RSA2");
$data['flag'] = $flag;
return $data;
}
下面提供兩個方法,是為支付日誌做準備的,陣列與xml格式互轉的方法
至此,支付類就完成了,下面是呼叫//陣列轉XML public function arrayToXml($arr){ $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml.="</xml>"; return $xml; } //將XML轉為array public function xmlToArray($xml){ //禁止引用外部xml實體 libxml_disable_entity_loader(true); $values = json_decode(json_encode(simplexml_load_string($xml,'SimpleXMLElement', LIBXML_NOCDATA)), true); return $values; }
//客戶端傳入引數,獲取發起APP支付的引數,這裡說下order_id是我們系統的訂單id,這裡傳入,回撥時會一併傳給我們
$aliPayString = appAlipay_class::appPay("商品購買","商品購買",$order_id,$goodsResult['final_sum']);
//返回給客戶端的支付寶支付引數,帶有一大群用&符號拼接的引數,不需要處理,直接返回給客戶端就行
$this->aliPayString = $aliPayString;
支付寶回撥支付狀態,接受並修改對應訂單狀態
//支付寶app回撥
function appAliPayStatu(){
$data = appAlipay_class::notify();
//追加日誌
$postXml = appAlipay_class::arrayToXml($data);
file_put_contents(dirname(__file__)."/log/aliPay.log",$postXml.PHP_EOL,FILE_APPEND);//確認是支付寶回撥的
if ($data["flag"]) {
//商戶訂單號
$order_id = $data['out_trade_no'];
//交易狀態
$trade_status = $data['trade_status'];
$total_amount = $data['total_amount'];
//檢視是否存在該未支付訂單,下面可以根據自己業務邏輯編寫
$orderGoodsDB = new IModel('order_goods');
$result = $orderGoodsDB->query("pay_status = 0 and order_id = ".$order_id);
//存在該訂單並支付成功,進行修改
if ($result && $trade_status=="TRADE_SUCCESS") {
$sqlData = array(
"pay_status" => 1,
"pay_time" => ITime::getDateTime(),
"pay_type" => 3,
);
$orderGoodsDB->setData($sqlData);
$res = $orderGoodsDB->update('order_id = '.$order_id);
//修改成功
if ($res) {
//新增交易記錄
$model = new IModel("niuScore_trans");
$arr=array(
"user_id" => $orderArr["user_id"],
"reduce" => $total_amount,
"detail" => "支付寶支付",
"remain" => 0,
"type" => "3",
"trans_time" => ITime::getDateTime()
);
$model->setData($arr);
$model->add();
echo "success"; //返回給支付寶系統,請不要修改或刪除
}
}else{
echo "fail";
}
}
}
到這裡,就結束了,下篇會更新微信APP支付