博主昨天在實現一個需求,因爲用到支付寶接口HTTP方式請求,特意將過程分享記錄下來
還是要吐槽下支付寶的文檔以及技術人員,根本寫的不詳細,最後還是去看了他們的代碼實現過程,最終實現,下面向大家分享,首先我們先封裝一個基礎類,裏面包含了sign加密、請求url以及處理結果,代碼如下:
<?php
/**
* 支付寶公共方法
* Created by PhpStorm.
* User: pc001
* Date: 2019/1/24
* Time: 8:56
*/
/**
* 獲取支付寶HTTP方式請求URL
* @param array $params
* @param string $privatekey
* @param string $url
* @return string
*/
function getTarUrl($params = array(), $privatekey = "", $url = "")
{
#請求數組轉成字符串
$signString = getSignContent($params);
#待請求字符串加密獲取sign
$sign = alonersaSign($signString, $privatekey, "RSA2");
#將sign帶入數組
$params["sign"] = $sign;
#請求鏈接編碼及轉換
$url = getSignContentUrlencode($params);
#獲取最終請求URL
$targetUrl = "https://openapi.alipay.com/gateway.do?" . $url;
#返回
return $targetUrl;
}
/**
* 鏈接拼接
* @param $params
* @return string
*/
function getSignContentUrlencode($params)
{
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 轉換成目標字符集
$v = characet($v, "UTF-8");
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . urlencode($v);
} else {
$stringToBeSigned .= "&" . "$k" . "=" . urlencode($v);
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
/**
* 請求參數加密獲取sign
* @param $data
* @param $privatekey
* @param string $signType
* @param bool $keyfromfile
* @return string
*/
function alonersaSign($data, $privatekey, $signType = "RSA", $keyfromfile = false)
{
if (!$keyfromfile) {
$priKey = $privatekey;
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($priKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
} else {
$priKey = file_get_contents($privatekey);
$res = openssl_get_privatekey($priKey);
}
($res) or die('您使用的私鑰格式錯誤,請檢查RSA私鑰配置');
if ("RSA2" == $signType) {
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
} else {
openssl_sign($data, $sign, $res);
}
if ($keyfromfile) {
openssl_free_key($res);
}
$sign = base64_encode($sign);
return $sign;
}
/**
* 數組轉成字符串
* @param $params
* @return string
*/
function getSignContent($params)
{
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 轉換成目標字符集
$v = characet($v, "UTF-8");
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
/**
* 判斷參數值是否爲空
* @param $value
* @return bool
*/
function checkEmpty($value)
{
if (!isset($value))
return true;
if ($value === null)
return true;
if (trim($value) === "")
return true;
return false;
}
/**
* 轉換成目標字符集
* @param $data
* @param $targetCharset
* @return string
*/
function characet($data, $targetCharset)
{
if (!empty($data)) {
$fileType = "UTF-8";
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset, $fileType);
// $data = iconv($fileType, $targetCharset.'//IGNORE', $data);
}
}
return $data;
}
/**
* Get請求
* @param $url
* @param $apiName
* @return mixed
*/
function curlAliGet($url, $apiName)
{
// 初始化curl
$ch = curl_init();
// 設置超時
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// 運行curl,結果以jason形式返回
$res = curl_exec($ch);
curl_close($ch);
#json轉換
$returnData = json_decode($res);
#獲取結果體
$responseNode = str_replace(".", "_", $apiName) . "_response";
$result = $returnData->$responseNode;
//返回
return $result;
}
封裝完這個方法後,我們便開始在主程序中調用,博主這裏是請求支付寶的發送消息模板接口,代碼如下:
#調用公共方法
require 'aliCom.php';
#獲取參數
$shh_template_id = $_REQUEST["shh_template_id"];
$shh_id = $_REQUEST["shh_id"];
$shh_head_color = $_REQUEST["shh_head_color"];
$shh_url = $_REQUEST["shh_url"];
$shh_action_name = $_REQUEST["shh_action_name"];
$shh_keyword1_value = $_REQUEST["shh_keyword1_value"];
$shh_keyword1_color = $_REQUEST["shh_keyword1_color"];
$shh_keyword2_value = $_REQUEST["shh_keyword2_value"];
$shh_keyword2_color = $_REQUEST["shh_keyword2_color"];
$shh_keyword3_value = $_REQUEST["shh_keyword3_value"];
$shh_keyword3_color = $_REQUEST["shh_keyword3_color"];
$shh_keyword4_value = $_REQUEST["shh_keyword4_value"];
$shh_keyword4_color = $_REQUEST["shh_keyword4_color"];
$shh_remark_value = $_REQUEST["shh_remark_value"];
$shh_remark_color = $_REQUEST["shh_remark_color"];
$shh_first_value = $_REQUEST["shh_first_value"];
$shh_first_color = $_REQUEST["shh_first_color"];
$openId = $_REQUEST["openId"];
#獲取基本配置
$rsaPrivateKey ="你的密鑰";
$alipayrsaPublicKey ="你的公鑰";
#組合內容
$bizCont = "{" .
"\"to_user_id\":\"" . $openId . "\"," .
"\"template\":{" .
"\"template_id\":\"" . $shh_template_id . "\"," .
"\"context\":{" .
"\"head_color\":\"" . $shh_head_color . "\"," .
"\"url\":\"" . $shh_url . "\"," .
"\"action_name\":\"" . $shh_action_name . "\"," .
"\"keyword1\":{" .
"\"color\":\"" . $shh_keyword1_color . "\"," .
"\"value\":\"" . $shh_keyword1_value . "\"" .
" }," .
"\"keyword2\":{" .
"\"color\":\"" . $shh_keyword2_color . "\"," .
"\"value\":\"" . $shh_keyword2_value . "\"" .
" }," .
"\"keyword3\":{" .
"\"color\":\"" . $shh_keyword3_color . "\"," .
"\"value\":\"" . $shh_keyword3_value . "\"" .
" }," .
"\"keyword4\":{" .
"\"color\":\"" . $shh_keyword4_color . "\"," .
"\"value\":\"" . $shh_keyword4_value . "\"" .
" }," .
"\"first\":{" .
"\"color\":\"" . $shh_first_color . "\"," .
"\"value\":\"" . $shh_first_value . "\"" .
" }," .
"\"remark\":{" .
"\"color\":\"" . $shh_remark_color . "\"," .
"\"value\":\"" . $shh_remark_value . "\"" .
" }" .
" }" .
" }" .
" }";
#生成簽名
$params = array(
'app_id' => $shh_id,
'charset' => 'UTF-8',
'method' => 'alipay.open.public.message.single.send',
'sign_type' => 'RSA2',
'timestamp' => date('Y-m-d H:i:s', time()),
'version' => '1.0',
'biz_content' => $bizCont
);
#獲取最終請求URL
$url = getTarUrl($params, $rsaPrivateKey, "https://openapi.alipay.com/gateway.do?");
#請求地址
$data = curlAliGet($url, $params["method"]);
#判斷髮送是否成功
if (isset($data->code) && intval($data->code) === 10000) {
#返回成功
$json = json_encode(array(
'status' => 1,
'msg' => $data->msg
));
echo($json);
exit();
} else {
#返回失敗
$json = json_encode(array(
'status' => -1,
'msg' => $data->sub_msg
));
echo($json);
exit();
}
這樣我們便成功的完成了支付寶HTTP方式請求接口,而不用依賴支付寶的SDK。