目录

前言

一、服务层

二、控制层

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 支付宝 “(单笔转账接口)转账到支付宝账号”相关推荐

  1. ECSHOP 支付宝发货确认接口,记录支付宝返回的交易号

    1,在order_info 数据表尾添加trade_no 字段 数据表尾怎么添加trade_no 字段 ECSHOP为了支付宝发货确认接口,需要记录支付宝返回的交易号 1,在order_info 数据 ...

  2. 支付宝单笔查询接口需要人工开通【坑爹】

    查询: <alipay><is_success>F</is_success><error>ILLEGAL_PARTNER_EXTERFACE</e ...

  3. java支付宝当面付接口_【图文】支付宝当面付配置教程

    能看到这个文档的,支付宝支付应该都有资格使用了吧!支付宝具备当面付没有资格的请申请支付宝当面付,也可找询问博主这只菜鸡咨询!可以代开哦! 支付宝当面付配置详细教程如下 新版支付宝接口改用了RSA2的密 ...

  4. 对接支付宝单笔转账接口

    对接支付宝单笔转账接口 功能介绍 接入准备 调用支付宝api需要以下参数: 项目引入 操作流程 创建小程序 配置小程序 集成配置 SDK 助手 详细操作流程 获取appId 获取证书 获取AES密钥 ...

  5. php 个人账户转账,支付宝单笔转账到支付宝个人账户接口 ( PHP 版 )

    alipay.fund.trans.toaccount.transfer(单笔转账到支付宝账户接口) 单笔转账到支付宝账户接口是基于支付宝的资金处理能力,为了满足支付宝商家向其他支付宝账户转账的需求, ...

  6. 如何签约支付宝单笔转账接口!

    最近支付宝正在升级单笔转账到支付宝账户的接口,暂停了签约.

  7. 使用TP5接入支付宝单笔转账接口(AlipayFundTransUniTransferRequest)

    使用该接口前需申请如下三个证书 1:alipayCertPublicKey_RSA2.crt 2:alipayRootCert.crt 3:appCertPublicKey_20210*******. ...

  8. java 对接支付宝单笔转账接口

    证书模式及非证书模式转账 查询证书路径 public String queryPath() throws FileNotFoundException, ServerException {String ...

  9. 支付宝单笔转账到支付宝账户(用于分成或者退款)

    超快速接入 支付宝官方文档 直接上代码 SDK AlipayUtils 支付宝官方文档 转账到支付宝用户快速接入 单笔转账到支付宝账户接入助手 直接上代码 SDK <!-- https://mv ...

最新文章

  1. MySQL数据库中的内置函数
  2. 运维开发必会技能之一——虚拟机管理
  3. OpenGL 绘图移动
  4. 预见未来 | 数据智能的现在与未来
  5. opengl 大作业_「陪玩时光」糕妈:说说年糕的小学生活,先从陪作业和家长群聊起...
  6. 温州大学瓯江学院 计算机院赛,温州大学
  7. python大学什么专业学校_好学校的差专业和一般大学的好专业,该怎么选?我来说真话……...
  8. vim 删除多行_Vim 可视化模式入门
  9. 奇怪的象棋游戏及升级版
  10. mongoDB学习--建库、删库、插入、更新
  11. 使用SAX读取XML文件
  12. 实时渲染学习(十一)渲染加速算法总结
  13. 如何写SCI论文的摘要
  14. 关系代数笛卡尔积和自然连接的例子
  15. 云开发【云函数的使用】
  16. linux 鼠标卡顿,树莓派鼠标延迟以及其它问题汇总
  17. 计算机毕业设计(附源码)python游泳馆管理系统
  18. linux新下载的源码或者官方提供的内核查看具体的内核版本
  19. 2021.2.23课程摘要(逻辑教育-王劲胜)
  20. 按字节编址,求地址间的存储容量方法

热门文章

  1. 吐血整理 这200道阿里P6必备Java面试题,我简直太爱了
  2. 原创 | GIS国产化除了软件还有什么
  3. js之Reflect
  4. IPhone基于OAtuth的 twitter客户端开发
  5. Java——继承、方法覆盖
  6. 大型网站架构改进历程
  7. vue3父组件调用子组件的方法
  8. JAVA--正则表达式
  9. 手机sim卡插到电脑上网_淘汰的手机别扔掉,这样设置变身4G上网卡
  10. 学物生地对以后学计算机有影响吗,江苏高考改革后的第一届学生选考物生地,有什么问题吗?...