1. 程式人生 > >支付寶APP支付介面-PHP

支付寶APP支付介面-PHP

       最近做了一個基於微信,alipay的支付功能,主要包括alipay的wap(喚醒支付寶APP),pc,APP支付,前兩者基於MD5簽名,後者基於RSA簽名;
微信的內部瀏覽器支付,APP支付,至於wap,需要申請,達到一定的條件才能審批通過,目前只有京東,1號店及一些企業公司有喚醒微信APP.
這裡主要說下:alipay的APP介面與微信APP的支付介面。

前期準備工作就不說了,比如要建立APP應用(會有應用私鑰與公鑰),相關的支付寶key,secret等資訊根據官方文件引導即可。

一.Alipay的APP介面支付(mobile.securitypay.pay)
1.構造支付寶支付資訊
$param = array(
    'partner' => $this->_payBaseConfig['partner'],
    'seller_id' => $this->_payBaseConfig['partner'],
    'out_trade_no' => time().$param['tradeNo'],//唯一訂單號
    'subject' => 'demo',//標題
    'body' => 'demo',//描述
    'total_fee' => '1',//金額
    'notify_url' => 'http://www.xxx.org/notify.php'//回撥地址
    'service' => 'mobile.securitypay.pay',//alipay的服務介面
    'payment_type' => '1',//支付型別
    '_input_charset' => 'utf-8',//編碼
    'it_b_pay' => '30m',//超時時間
    'show_url' => 'm.xxx.com',//商品展示網址
    "sign_type" => 'RSA',//簽名方式
    'extra_common_param' => $userId . "_" . $userName . "_" . $classId . "_" . $orderId . "_" . $relOrderId,//附加引數
);
注:引數的詳解見官方文件:點選開啟連結
2.將$param生成給支付寶的引數陣列,
a.首先去掉空值和簽名的引數,以key="value"方式,並用&拼接引數,
b.過濾後的引數,進行簽名,

c.在將生成的簽名與簽名方式追加到a步驟後面

各個步驟分別詳見SDK中的
paraFilter($param);//過濾引數
buildRequestMysign(param);簽名

前兩部OK,就是上面所說的追加引數,上面c步驟

注意:
1.給APP提供介面,APP支付RSA是utf-8的,所以這裡一定要注意:進行buildRequestMysign(param)簽名的時候,一定要將待簽名的資料轉換成utf-8與APP的私鑰進行簽名,之後簽名後,追加到未轉碼的待簽名資料後面,返給APP端。否則APP端最後拿到引數請求支付寶會報"建立交易異常,請重新建立交易再支付"。

2.如果你用的的RSA金鑰為pem格式檔案,必須嚴格遵守pem格式,否則在執行openssl_get_privatekey($preKey)這個函式會一直返回false.為了避免格式錯誤,你可以寫段程式碼處理下合格的金鑰檔案,程式碼如下:

private function rsaSign($data, $privateKeyPath) {
    $privateKey = file_get_contents($privateKeyPath);
    $privateKey=str_replace("-----BEGIN RSA PRIVATE KEY-----","",$privateKey);
    $privateKey=str_replace("-----END RSA PRIVATE KEY-----","",$privateKey);
    $privateKey=str_replace("\n","",$privateKey);
    $privateKey="-----BEGIN RSA PRIVATE KEY-----".PHP_EOL .wordwrap($privateKey, 64, "\n", true). PHP_EOL."-----END RSA PRIVATE KEY-----";
    $res=openssl_get_privatekey($privateKey);

    if($res)
    {
        openssl_sign($data, $sign,$res);
    }
    else {
        exit('The format of your private_key is incorrect!');
    }
    openssl_free_key($res);
    $sign = base64_encode($sign);
    return $sign;
}

最終APP需要拿到這樣的引數,才可以正常支付,如下:

partner="2088001547690275"&seller_id="200001547690275"&out_trade_no="Q2F4ZPP68CKKW9T"&subject="1"&body="我是測試資料"&total_fee="0.02"¬ify_url="http://www.xxx.com"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&show_url="m.alipay.com"&sign="kPaDQ9iDseaQOymN4sOJKDCr6PF5S%2FFzsyeBwMVzJZBXXasuH3OF2n8AN%2B8F%2FhM6oBr3tSF6PAyXxl6925gSBq6tBzRGPRbc40y85O5O%2FTDLcYYR0Ggmph4G5Wo%2BCtEaMeCBI%2Fdywd2eZGGQfqkWeAiffvtpRUwzukMs%2BMqB7SE%3D"&sign_type="RSA",

Aliapy支付回撥問題,是否被惡意篡改,是否是來自於支付寶發起的(引數中返回的notify_id),驗籤問題,驗證完畢,進行相關業務處理。支付寶回撥返回的陣列,如下:
$ret = array (
	'discount' => '0.00',//折扣
	'extra_common_param' => '1_2_1_101083_848081256280252416',//附加引數
	'payment_type' => '1',//支付型別 1商品 2購買
	'subject' => '我是測試',
	'trade_no' => '2017040121001004720227329601',支付寶交易號
	'buyer_email' => '15503333339',//買家支付寶賬號
	'gmt_create' => '2017-04-01 15:55:12',
	'notify_type' => 'trade_status_sync',
	'quantity' => '1',//購買數量
	'out_trade_no' => '201704011010831491033308',
	'seller_id' => '2000001547690275',
	'notify_time' => '2017-04-01 15:55:13',
	'body' => '我是測試',
	'trade_status' => 'TRADE_SUCCESS',
	'is_total_fee_adjust' => 'N',
	'total_fee' => '0.01',
	'gmt_payment' => '2017-04-01 15:55:13',
	'seller_email' => '[email protected]',
	'price' => '0.01',
	'buyer_id' => '2000001547690275',
	'notify_id' => '3f7414c9ab17a53e48003a20fea9319lp2',//判斷成功之後使用getResponse方法判斷是否是支付寶發來的非同步通知。
	'use_coupon' => 'N',
	'sign_type' => 'RSA',
	'sign' => 'hiOXQN4VopsSZ3ST4RFhbjNz2/cwcE7nplV8o+AkdJhoeauQaWXUe40gYy5lSVYLmCYeVkc7g+L22gHfCvdLZMJg05/iefLsujolXWgBICBUydpdPduc0ad0UFc3yfcFWBBEFf4RTViGQfgI
	FfP9XbiytAv9nqGLdUO/uzbM1Ts=',
)

注意:驗籤時候是支付寶的公鑰,登入了平臺後,有很多應用檢視支付寶公鑰,以為就是這個。那你就會卡在openssl_verify這步,一直返回false.請登入登入b.alipay.com,檢視支付寶公鑰.官方貌似沒有明確指明到底用哪個支付寶公鑰,可能是我粗心沒看到。我問了技術,技術看了下公鑰,正確啊。之後利用我提供的報文模擬了驗籤,模擬了大約1個多小時,告訴我公鑰沒有問題,就用這個,還指出支付時候的附加引數不能加,這樣導致了驗籤不過。真是呵呵了。