PHP 支付宝 “(单笔转账接口)转账到支付宝账号”
目录
前言
一、服务层
二、控制层
1.控制层
2.接口返回参数实例
前言
单笔转账接口 | 网页&移动应用
准备:
1:应用的证书(证书申请和配置可以参考我另一篇分享“支付宝 ‘应用证书配置’ ”)
2:配置证书后注意公共参数中 私钥值 是csr生成后的私钥
3:需要接口能力已开通
一、服务层
<?phpclass AlipayMethod
{// 私钥值const RSAPRIVATEKEY = "配置证书后私钥是在CSR生成中的私钥";// 网关地址const SERVERURL = "https://openapi.alipay.com/gateway.do";// 开放平台上创建的应用的ID const APPID = "app_id";// 字符串编码,推荐:utf-8 const CHARSET = "UTF-8";// 签名算法类型,推荐:RSA2 const SIGNTYPE = "RSA2"; // 报文格式,推荐:json const FORMAT = "json";// 敏感信息对称加密算法密钥 const ENCRYPYKEY = "";// 调用的接口版本,固定为:1.0 const 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('https://openapi.alipay.com/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("https://openapi.alipay.com/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": "2022-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": "2022-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": "...."
}
PHP 支付宝 “(单笔转账接口)转账到支付宝账号”相关推荐
- ECSHOP 支付宝发货确认接口,记录支付宝返回的交易号
1,在order_info 数据表尾添加trade_no 字段 数据表尾怎么添加trade_no 字段 ECSHOP为了支付宝发货确认接口,需要记录支付宝返回的交易号 1,在order_info 数据 ...
- 支付宝单笔查询接口需要人工开通【坑爹】
查询: <alipay><is_success>F</is_success><error>ILLEGAL_PARTNER_EXTERFACE</e ...
- java支付宝当面付接口_【图文】支付宝当面付配置教程
能看到这个文档的,支付宝支付应该都有资格使用了吧!支付宝具备当面付没有资格的请申请支付宝当面付,也可找询问博主这只菜鸡咨询!可以代开哦! 支付宝当面付配置详细教程如下 新版支付宝接口改用了RSA2的密 ...
- 对接支付宝单笔转账接口
对接支付宝单笔转账接口 功能介绍 接入准备 调用支付宝api需要以下参数: 项目引入 操作流程 创建小程序 配置小程序 集成配置 SDK 助手 详细操作流程 获取appId 获取证书 获取AES密钥 ...
- php 个人账户转账,支付宝单笔转账到支付宝个人账户接口 ( PHP 版 )
alipay.fund.trans.toaccount.transfer(单笔转账到支付宝账户接口) 单笔转账到支付宝账户接口是基于支付宝的资金处理能力,为了满足支付宝商家向其他支付宝账户转账的需求, ...
- 如何签约支付宝单笔转账接口!
最近支付宝正在升级单笔转账到支付宝账户的接口,暂停了签约.
- 使用TP5接入支付宝单笔转账接口(AlipayFundTransUniTransferRequest)
使用该接口前需申请如下三个证书 1:alipayCertPublicKey_RSA2.crt 2:alipayRootCert.crt 3:appCertPublicKey_20210*******. ...
- java 对接支付宝单笔转账接口
证书模式及非证书模式转账 查询证书路径 public String queryPath() throws FileNotFoundException, ServerException {String ...
- 支付宝单笔转账到支付宝账户(用于分成或者退款)
超快速接入 支付宝官方文档 直接上代码 SDK AlipayUtils 支付宝官方文档 转账到支付宝用户快速接入 单笔转账到支付宝账户接入助手 直接上代码 SDK <!-- https://mv ...
最新文章
- MySQL数据库中的内置函数
- 运维开发必会技能之一——虚拟机管理
- OpenGL 绘图移动
- 预见未来 | 数据智能的现在与未来
- opengl 大作业_「陪玩时光」糕妈:说说年糕的小学生活,先从陪作业和家长群聊起...
- 温州大学瓯江学院 计算机院赛,温州大学
- python大学什么专业学校_好学校的差专业和一般大学的好专业,该怎么选?我来说真话……...
- vim 删除多行_Vim 可视化模式入门
- 奇怪的象棋游戏及升级版
- mongoDB学习--建库、删库、插入、更新
- 使用SAX读取XML文件
- 实时渲染学习(十一)渲染加速算法总结
- 如何写SCI论文的摘要
- 关系代数笛卡尔积和自然连接的例子
- 云开发【云函数的使用】
- linux 鼠标卡顿,树莓派鼠标延迟以及其它问题汇总
- 计算机毕业设计(附源码)python游泳馆管理系统
- linux新下载的源码或者官方提供的内核查看具体的内核版本
- 2021.2.23课程摘要(逻辑教育-王劲胜)
- 按字节编址,求地址间的存储容量方法