当前位置: 首页 > 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;点…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址&#xff0c;您可以使用以下几种方法&#xff1a; 1. 查看所有远程仓库地址 使用 git remote -v 命令&#xff0c;它会显示项目中配置的所有远程仓库及其对应的 URL&#xff1a; git remote -v输出示例&#xff1a; origin https://…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

Gitlab + Jenkins 实现 CICD

CICD 是持续集成&#xff08;Continuous Integration, CI&#xff09;和持续交付/部署&#xff08;Continuous Delivery/Deployment, CD&#xff09;的缩写&#xff0c;是现代软件开发中的一种自动化流程实践。下面介绍 Web 项目如何在代码提交到 Gitlab 后&#xff0c;自动发布…...