700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > PHP 支付宝 “(单笔转账接口)转账到支付宝账号”

PHP 支付宝 “(单笔转账接口)转账到支付宝账号”

时间:2021-03-25 05:05:07

相关推荐

PHP 支付宝 “(单笔转账接口)转账到支付宝账号”

目录

前言

一、服务层

二、控制层

1.控制层

2.接口返回参数实例

前言

单笔转账接口 | 网页&移动应用

准备:

1:应用的证书(证书申请和配置可以参考我另一篇分享“支付宝 ‘应用证书配置’ ”)

2:配置证书后注意公共参数中 私钥值 是csr生成后的私钥

3:需要接口能力已开通

一、服务层

<?phpclass AlipayMethod{// 私钥值const RSAPRIVATEKEY = "配置证书后私钥是在CSR生成中的私钥";// 网关地址const SERVERURL= "/gateway.do";// 开放平台上创建的应用的ID const APPID= "app_id";// 字符串编码,推荐:utf-8const CHARSET = "UTF-8";// 签名算法类型,推荐:RSA2 const SIGNTYPE = "RSA2"; // 报文格式,推荐:json const FORMAT = "json";// 敏感信息对称加密算法密钥 const ENCRYPYKEY= "";// 调用的接口版本,固定为:1.0const VERSION = "1.0"; // 接口方法const METHOD_TRANSFER = "alipay.fund.trans.uni.transfer"; // 转账到支付宝账号const METHOD_OAUTH_TOKEN = "alipay.system.oauth.token"; // 换取授权访问令牌const TOKE_NGRANT_TYPE = "authorization_code"; // 访问令牌授权方式// 证书const ALIPAY_ROOT_CERT = "你的路径"; // 支付宝根证书路径const ALIPAY_CERT_PUBLIC_KEY = "你的路径"; // 应用公钥证书路径/*** (单笔转账接口)转账到支付宝账号* @param sOid 订单号* @param ALIPAY_USER_ID 支付宝用户UID* @param nMoney 转款金额* @return array*/public function onPaymentByAlipay($alipayUserId, $nMoney){// 转账金额:保留两位小数$transAmount = number_format($nMoney, 2);// $transAmount = number_format("1", 2);// 请求参数$biz_content = [// 商家侧唯一订单号,由商家自定义"out_biz_no" => "测试订单号".time(), // 订单总金额,单位为元,不支持千位分隔符,精确到小数点后两位 "trans_amount" => $transAmount,// 固定为 TRANS_ACCOUNT_NO_PWD"product_code" => "TRANS_ACCOUNT_NO_PWD",// 固定为 DIRECT_TRANSFER"biz_scene" => "DIRECT_TRANSFER",// 转账业务的标题:收款方会收到"order_title" => "测试支付",// 收款方信息 "payee_info" => [ // 参与方的标识 ID:ALIPAY_USER_ID(UID) ALIPAY_LOGON_ID(支付宝登录号)"identity"=> $alipayUserId,"identity_type" => "ALIPAY_USER_ID", // "name"=> "真实姓名",// identity_type = ALIPAY_LOGON_ID name必填]];// 请求参数 $params = ["app_id" => self::APPID,"method" => self::METHOD_TRANSFER,"format" => self::FORMAT,"charset" => self::CHARSET,"sign_type" => self::SIGNTYPE,"timestamp" => date('Y-m-d H:i:s'),"version" => self::VERSION,"biz_content" => json_encode($biz_content, 256),"alipay_root_cert_sn" => $this->getRootCertSN(dirname(__FILE__) . self::ALIPAY_ROOT_CERT),// 支付宝根证书路径"app_cert_sn" => $this->getCertSN(dirname(__FILE__) . self::ALIPAY_CERT_PUBLIC_KEY), // 应用公钥证书路径];// 签名 $params["sign"] = $this->generateSign($params, $params['sign_type']);// 发起请求$result = $this->curlPost('/gateway.do', $params);// 结果数组化$result = json_decode($result, true);return $result;}/*** 换取授权访问令牌* @param authCode 授权code * @return array*/public function getAccessToken($authCode){//公共参数$params = array("app_id" => self::APPID,"method" => self::METHOD_OAUTH_TOKEN,"format" => self::FORMAT,"charset" => self::CHARSET,"sign_type" => self::SIGNTYPE,"timestamp" => date("Y-m-d H:i:s"),"version" => self::VERSION,"grant_type"=> self::TOKE_NGRANT_TYPE,"code"=> $authCode,"alipay_root_cert_sn" => $this->getRootCertSN(dirname(__FILE__) . self::ALIPAY_ROOT_CERT),// 支付宝根证书路径"app_cert_sn" => $this->getCertSN(dirname(__FILE__) . self::ALIPAY_CERT_PUBLIC_KEY), // 应用公钥证书路径);// 签名 $params["sign"] = $this->generateSign($params, $params['sign_type']);// 发起请求$result = $this->curlPost("/gateway.do?charset=" . self::CHARSET, $params);// 结果数组化$result = json_decode($result, true);return $result;}/**-------------------------------我是分割线---------------------------------- *//*** 加签* @param $params* @param string $signType* @return mixed*/public function generateSign($params, $signType){return $this->sign($this->getSignContent($params), $signType);}protected function sign($data, $signType){$priKey = self::RSAPRIVATEKEY;$res = "-----BEGIN RSA PRIVATE KEY-----\n" .wordwrap($priKey, 64, "\n", true) ."\n-----END RSA PRIVATE KEY-----";($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');if ($signType == "RSA2") {openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);// OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持// openssl_sign($data, $sign, $res, version_compare(PHP_VERSION, '5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256);} else {openssl_sign($data, $sign, $res);}$sign = base64_encode($sign);return $sign;}/*** 校验$value是否非空* if not set ,return true;* if is null , return true;**/protected function checkEmpty($value){if (!isset($value))return true;if ($value === null)return true;if (trim($value) === "")return true;return false;}public function getSignContent($params){ksort($params);$stringToBeSigned = "";$i = 0;foreach ($params as $k => $v) {if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {// 转换成目标字符集$v = $this->characet($v, self::CHARSET);if ($i == 0) {$stringToBeSigned .= "$k" . "=" . "$v";} else {$stringToBeSigned .= "&" . "$k" . "=" . "$v";}$i++;}}unset($k, $v);return $stringToBeSigned;}/*** 转换字符集编码* @param $data* @param $targetCharset* @return string*/function characet($data, $targetCharset){if (!empty($data)) {$fileType = self::CHARSET;if (strcasecmp($fileType, $targetCharset) != 0) {$data = mb_convert_encoding($data, $targetCharset, $fileType);}}return $data;}/*** 发送curl请求* @param $url* @param null $postFields* @return bool|string* @throws Exception*/protected function curlPost($url, $postFields = null){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_FAILONERROR, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);$postBodyString = "";$encodeArray = array();$postMultipart = false;if (is_array($postFields) && 0 < count($postFields)) {foreach ($postFields as $k => $v) {if ("@" != substr($v, 0, 1)) //判断是不是文件上传{$postBodyString .= "$k=" . urlencode($this->characet($v, self::CHARSET)) . "&";$encodeArray[$k] = $this->characet($v, self::CHARSET);} else //文件上传用multipart/form-data,否则用www-form-urlencoded{$postMultipart = true;$encodeArray[$k] = new \CURLFile(substr($v, 1));}}unset($k, $v);curl_setopt($ch, CURLOPT_POST, true);if ($postMultipart) {curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray);} else {curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));}}if (!$postMultipart) {$headers = array('content-type: application/x-www-form-urlencoded;charset=' . self::CHARSET);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);}$reponse = curl_exec($ch);if (curl_errno($ch)) {throw new \Exception(curl_error($ch), 0);} else {$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);if (200 !== $httpStatusCode) {throw new \Exception($reponse, $httpStatusCode);}}curl_close($ch);return $reponse;}/*** 从证书中提取序列号* @param $cert* @return string*/public function getCertSN($certPath){$cert = file_get_contents($certPath);$ssl = openssl_x509_parse($cert);$SN = md5($this->array2string(array_reverse($ssl['issuer'])) . $ssl['serialNumber']);return $SN;}/*** 提取根证书序列号* @param $cert 根证书* @return string|null*/public function getRootCertSN($certPath){$cert = file_get_contents($certPath);$this->alipayRootCertContent = $cert;$array = explode("-----END CERTIFICATE-----", $cert);$SN = null;for ($i = 0; $i < count($array) - 1; $i++) {$ssl[$i] = openssl_x509_parse($array[$i] . "-----END CERTIFICATE-----");if (strpos($ssl[$i]['serialNumber'], '0x') === 0) {$ssl[$i]['serialNumber'] = $this->hex2dec($ssl[$i]['serialNumberHex']);}if ($ssl[$i]['signatureTypeLN'] == "sha1WithRSAEncryption" || $ssl[$i]['signatureTypeLN'] == "sha256WithRSAEncryption") {if ($SN == null) {$SN = md5($this->array2string(array_reverse($ssl[$i]['issuer'])) . $ssl[$i]['serialNumber']);} else {$SN = $SN . "_" . md5($this->array2string(array_reverse($ssl[$i]['issuer'])) . $ssl[$i]['serialNumber']);}}}return $SN;}/*** 0x转高精度数字* @param $hex* @return int|string*/function hex2dec($hex){$dec = 0;$len = strlen($hex);for ($i = 1; $i <= $len; $i++) {$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));}return $dec;}protected function array2string($array){$string = [];if ($array && is_array($array)) {foreach ($array as $key => $value) {$string[] = $key . '=' . $value;}}return implode(',', $string);}}

二、控制层

1.控制层

/*** 换取授权访问令牌* @param authCode 授权code * @return array*/public function getAccessToken($authCode,$nMoney){$cAlipayMethod = new AlipayMethod();// 换取授权访问令牌(获取返回中code对应的user_id)$result = $cAlipayMethod->getAccessToken($authCode);if (!isset($result["alipay_system_oauth_token_response"])) {// 换取授权访问令牌失败return json(["code" => 0, "data" => $result]);} else {// 获取用户唯一标识$alipayUserId = $result["alipay_system_oauth_token_response"]["user_id"];// 请求转账$result = $cAlipayMethod->onPaymentByAlipay($alipayUserId, $nMoney);if ($result["alipay_fund_trans_uni_transfer_response"]["code"] == "10000") {dump("转账成功")// 业务逻辑} else {dump("转账失败")// 业务逻辑}}}

2.接口返回参数实例

alipay.system.oauth.token(换取授权访问令牌):成功:{"alipay_system_oauth_token_response": {"access_token": "....","alipay_user_id": "....","auth_start": "-11-19 11:05:18","expires_in": ....,"re_expires_in": ....,"refresh_token": "....","user_id": "...." // 用户标识:是我们需要的},"alipay_cert_sn": "....","sign": "...."}错误:{"error_response": {"code": "40002","msg": "Invalid Arguments","sub_code": "isv.code-invalid","sub_msg": "授权码code无效"},"alipay_cert_sn": "....","sign": "...."}alipay.fund.trans.uni.transfer(单笔转账接口)转账到支付宝账号:成功:{"alipay_fund_trans_uni_transfer_response": {"code": "10000","msg": "Success","order_id": "....","out_biz_no": "....","pay_fund_order_id": "....","status": "SUCCESS","trans_date": "-11-18 13:45:02"},"alipay_cert_sn": "....","sign": "...."}异常:{"alipay_fund_trans_uni_transfer_response": {"code": "40004","msg": "Business Failed","sub_code": "INVALID_PARAMETER","sub_msg": "参数有误参数payee_info.identity格式非法"},"alipay_cert_sn": "....","sign": "...."}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。