1. 程式人生 > >PHP服務端整合支付寶APP支付以及回撥

PHP服務端整合支付寶APP支付以及回撥

說到支付寶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支付