博主昨天在实现一个需求,因为用到支付宝接口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。
更多分享请关注微信公众号