当前位置: 首页 > news >正文

PHP 单笔转账到支付宝账户,支付宝公钥证书实现版本

支付宝某些业务只能使用公钥证书方式来验签

如:即使转账

     红包等

笔者就要实现这样一个功能,【单笔转账到支付宝账户】,采用支付宝公钥证书签名来实现。

话不多说,流程先走起

第一步:下载支付宝秘钥生成器

由于我们使用的是php鱼油,点击pkcs1(非java适用)

按照上面图中的 三个步骤操作,操作完成后,点击【打开文件位置】,可以看到下面这些文件

会有

  1. 一个csr文件
  2. 一个公钥
  3. 一个私钥

我们将csr文件上传到支付宝 接口加签方式 里面,然后讲下图里面的三个整数下载下来

 

分别是:

  • alipayCertPublicKey_RSA2.crt
  • alipayRootCert.crt
  • appCertPublicKey_202100000023232.crt

第二步,配置PHP配置

我们将 上面生成的三个文件复制到证书目录,如图:

配置代码如下:

<?php
return ['app_id' => '', // 支付宝应用的appid'alipay_root_cert_sn' => BASE_PATH . '/cert/alipayRootCert.crt', // 支付宝根证书在自己服务器的绝对路径'app_cert_sn' => BASE_PATH . '/cert/appCertPublicKey_2021000199651454.crt', // 应用公钥证书在自己服务器绝对路径'rsa_private_key' => '' // 这个是RSA签名,特别要注意的是,是我们第一步中的对应自己域名的那个私钥哦
];

 

编写AlipayTransServer

class AlipayTransfers
{protected $appId;//私钥值protected $rsaPrivateKey;/*** @var string*/private $charset;public function __construct($appid, $saPrivateKey){$this->appId = $appid;$this->charset = 'utf8';$this->rsaPrivateKey = $saPrivateKey;}/*** 转帐* @param float $totalFee 转账金额,单位:元。* @param string $outTradeNo 商户转账唯一订单号* @param string $remark 转帐备注* @return array*/public function doPay($totalFee, $outTradeNo, $account, $realName, $remark = ''){//请求参数$requestConfigs = array('out_biz_no' => $outTradeNo,'payee_type' => 'ALIPAY_LOGONID','payee_account' => $account,'payee_real_name' => $realName,  //收款方真实姓名'amount' => $totalFee, //转账金额,单位:元。'remark' => $remark,  //转账备注(选填));$commonConfigs = array(//公共参数'app_id' => $this->appId,'method' => 'alipay.fund.trans.toaccount.transfer',             //接口名称'format' => 'JSON','charset' => $this->charset,'sign_type' => 'RSA2','timestamp' => date('Y-m-d H:i:s'),'alipay_root_cert_sn' => $this->getRootCertSN(BASE_PATH . '/cert/alipayRootCert.crt'),//支付宝根证书SN(alipay_root_cert_sn)'app_cert_sn' => $this->getCertSN(BASE_PATH . '/cert/appCertPublicKey_2021000199651454.crt'), //应用公钥证书SN(app_cert_sn)'version' => '1.0','biz_content' => json_encode($requestConfigs),);$commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']);$result = $this->curlPost('https://openapi.alipay.com/gateway.do', $commonConfigs);$resultArr = json_decode($result, true);if (empty($resultArr)) {$result = iconv('GBK', 'UTF-8//IGNORE', $result);return json_decode($result, true);}return $resultArr;}public function generateSign($params, $signType = "RSA"){return $this->sign($this->getSignContent($params), $signType);}protected function sign($data, $signType = "RSA"){$priKey = $this->rsaPrivateKey;$res = "-----BEGIN RSA PRIVATE KEY-----\n" .wordwrap($priKey, 64, "\n", true) ."\n-----END RSA PRIVATE KEY-----";($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');if ("RSA2" == $signType) {openssl_sign($data, $sign, $res, version_compare(PHP_VERSION, '5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持} 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, $this->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 = $this->charset;if (strcasecmp($fileType, $targetCharset) != 0) {$data = mb_convert_encoding($data, $targetCharset, $fileType);}}return $data;}public function curlPost($url = '', $postData = '', $options = array()){if (is_array($postData)) {$url = $url . '?' . http_build_query($postData);cli_log($url);}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数if (!empty($options)) {curl_setopt_array($ch, $options);}//https请求 不验证证书和hostcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);$data = curl_exec($ch);curl_close($ch);return $data;}/*** 从证书中提取**** @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);$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]['serialNumber']);}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*/protected 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);}
}

实现业务部分:

      

      /*** 转账提现* @param $realName 收款人真实姓名* @param $account  收款人账号* @param $amount  付款金额* @param string $remark 付款备注* @return array|void*/public function transfer($realName, $account, $amount, $remark = '提现'){$aliConfig = config('alipay');$aliTransfers = new Transfers($aliConfig['app_id'], $aliConfig['rsa_private_key']);$outTradeNo = date('Ymd') . time() . rand_string(6, true);return $aliTransfers->doPay($amount, $outTradeNo, $account, $realName, $remark);}

相关文章:

PHP 单笔转账到支付宝账户,支付宝公钥证书实现版本

支付宝某些业务只能使用公钥证书方式来验签 如&#xff1a;即使转账 红包等 笔者就要实现这样一个功能&#xff0c;【单笔转账到支付宝账户】&#xff0c;采用支付宝公钥证书签名来实现。 话不多说&#xff0c;流程先走起 第一步&#xff1a;下载支付宝秘钥生成器 由于我们使…...

第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组 E 题

颜色平衡树问题描述格式输入格式输出样例输入样例输出评测用例规模与约定解析参考程序问题描述 格式输入 输入的第一行包含一个整数 n &#xff0c;表示树的结点数。 接下来 n 行&#xff0c;每行包含两个整数 Ci , Fi&#xff0c;用一个空格分隔&#xff0c;表示第 i 个结点 …...

Python 小型项目大全 21~25

二十一、DNA 可视化 原文&#xff1a;http://inventwithpython.com/bigbookpython/project21.html 脱氧核糖核酸是一种微小的分子&#xff0c;存在于我们身体的每个细胞中&#xff0c;包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构&#xff1a;鸟嘌呤、…...

MinIO从信息泄漏到RCE

文章目录信息泄露漏洞利用漏洞分析漏洞修复RCE漏洞分析参考文章信息泄露 漏洞利用 如果MinIO以集群方式部署&#xff0c;存在信息泄露漏洞&#xff0c;攻击者可以通过HTTP请求获取目标进程的所有环境变量&#xff0c;包括MINIO_SECRET_KEY和MINIO_ROOT_PASSWORD. vulhub有环…...

202.Spark(九):SparkStreaming案例实操

目录 一、启动zookeeper,kafka基础环境 二、项目导好jar包,并且创建源数据,并在kafka中测试能否消费到数据...

GlusterFS(GFS)分布式文件系统

目录 一.文件系统简介 1.文件系统的组成 2.文件系统的作用 3.文件系统的挂载使用 二.GlusterFS概述 1.GlusterFS是什么&#xff1f; 2.GlusterFS的特点 3.GlusterFS术语介绍 3.1 Brick&#xff08;存储块&#xff09; 3.2 Volume&#xff08;逻辑卷&#xff09; 3.3…...

ChatGPT文本框再次升级,打造出新型操作系统

在ChatGPT到来之前&#xff0c;没有谁能够预见。但是&#xff0c;它最终还是来了&#xff0c;并引起了不小的轰动&#xff0c;甚至有可能颠覆整个行业。 从某种程度上说&#xff0c;ChatGPT可能是历史上增长最快的应用程序&#xff0c;仅在两个多月就拥有了1亿多活跃用户&…...

DPU02国产USB转UART控制芯片替代CP2102

目录DPU02简介DPU02芯片特性应用DPU02简介 DPU02是高度集成的USB转UART的桥接控制芯片&#xff0c;该芯片为RS-232设计更新为USB设计&#xff0c;并简化PCB组件空间提供了一个简单的解决方案。       DPU02包括了一个USB 2.0全速功能控制器、USB收发器、振荡器、EEPROM和带…...

Softing新版HART多路复用器软件支持西门子控制器

用于访问配置和诊断数据的HART多路复用器软件——Softing smartLink SW-HT&#xff0c;现在支持西门子的ET200远程IO和FDT/DTM接口。 smartLink SW-HT是一个基于Docker容器的软件应用。通过该软件&#xff0c;用户可以快速地访问以太网远程IO的HART设备&#xff0c;并且无需额外…...

〖Python网络爬虫实战⑫〗- XPATH语法介绍

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付费…...

实例方法、类方法、静态方法、实例属性、类属性

背景&#xff1a;今天在复习类相关知识的时候&#xff0c;突然想到这几种类型的方法的区别和用法&#xff0c;感觉有点模棱两可&#xff0c;于是总结一下&#xff0c;加深记忆。 定义&#xff1a;想要区别和理解几种方法&#xff0c;首先要定义一个类&#xff0c;要在类中加深…...

数据结构---二叉树

专栏&#xff1a;数据结构 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;这里是HaiFan.的数据结构专栏&#xff0c;今天的内容是二叉树。 二叉树树的概念及结构二叉树概念及结构二叉树的概念二叉树的存储结构二叉树的顺序结构及实现大根堆和小根堆堆的实现及其各个接口堆的…...

CMake——从入门到百公里加速6.7s

目录 一、前言 二、HelloWorld 三、CMAKE 界面 3.1 gui正则表达式 3.2 GUI构建 四 关键字 4.1 add_library 4.2 add_subdirectory 4.3 add_executable 4.4 aux_source_directory 4.5 SET设置变量 4.6 INSTALL安装 4.7 ADD_LIBRARY 4.8 SET_TARGET_PROPERTIES 4.9…...

无公网IP,在外公网远程访问RabbitMQ服务「内网穿透」

文章目录前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基础上…...

Node【二】NPM

文章目录&#x1f31f;前言&#x1f31f;NPM使用&#x1f31f;NPM使用场景&#x1f31f;NPM的常用命令&#x1f31f;NPM命令使用介绍&#x1f31f; 使用NPM安装模块&#x1f31f; 下载三方包&#x1f31f; 全局安装VS本地安装&#x1f31f; 本地安装&#x1f31f; 全局安装&…...

【2023最新】超详细图文保姆级教程:App开发新手入门(2)

上章节我们已经成功的创建了一个 App 项目&#xff0c;接下来我们讲述一下&#xff0c;如何导入项目、编辑代码和提交项目代码。 Let’s Go! 4. 项目导入 当用户创建一个新的应用时&#xff0c;YonStudio 开发工具会自动导入模板项目的默认代码&#xff0c;不需要手动进行代…...

sftp使用

Client端使用Server端的账户username&#xff0c;sftp登录Server&#xff0c;除了IP地址&#xff0c;也可以使用/etc/hosts定义的域名&#xff0c;注意&#xff0c;Client的默认路径&#xff1a;Shell中的当前路径&#xff0c;Server的默认路径&#xff1a;server账户家目录 ​…...

FastGithub---------不再为访问github苦恼

声明&#xff1a;只解决github加速神器&#xff0c;解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。 github为什么打不开&#xff1f; 其实不用加速的情况下&#xff0c;使用5G是可以打开的&#xff0c;只是资源加载…...

Spring Boot AOP @Pointcut拦截注解的表达式与运算符

项目场景&#xff1a; 这里主要说下Spring Boot AOP中Pointcut拦截类上面的注解与方法上面的注解&#xff0c;怎么写表达式怎么&#xff0c;还有Pointcut中使用运算符。 PointCut 表达式 拦截注解的表达式有3种&#xff1a;annotation、within、target 1、annotation 匹配有…...

2023年第十四届蓝桥杯javaB组省赛真题

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;练习时长两年半的java博主 &#x1f4d6;个人主页&#xff1a;君临๑ &#x1f39e;️文章介绍&#xff1a;2023年第十四届蓝桥杯javaB组省赛真题 &#x1f389;所属专栏&#xff1a;算法专栏 &#x1f381; ps&#xff1a;点…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解&#xff1a;从决策树开始理解三、解法一&#xff1a;二叉决策树 DFS四、解法二&#xff1a;组合式回溯写法&#xff08;推荐&#xff09;五、解法对比 递归算法是编程中一种非常强大且常见的思想&#xff0c;它能够优雅地解决很多复杂的…...