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

CefSharp.WinForms 112.2.70最新版体验

一、准备 下载最新包及依赖包(对应.NET4.5.2,后续版本可能4.6.2+)到packages中,本地升级更快 NuGet Gallery | CefSharp.WinForms 112.2.70 NuGet Gallery | CefSharp.Common 112.2.70 NuGet Gallery | cef.redist.x64 112.2.7 NuGet Gallery | cef.redist.x86 112.2.…...

leetcode每日一题:数组篇(1/2)

&#x1f61a;一个不甘平凡的普通人&#xff0c;日更算法学习和打卡&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;每日算法学习 &#x1f4ac;个人…...

每个企业经营者都应该了解的几个网络安全趋势

每个企业主都应了解的一些网络安全趋势&#xff1a; 1. 对实时数据可见性的需求增加 根据 IBM 发布的调查数据&#xff0c;企业发现并遏制漏洞的平均时间为 277 天。这种漏洞得不到解决的时间越长&#xff0c;泄露的数据就越多。这反过来会对您的业务产生更大的影响。企业需要…...

IDEA操作MongoDB快速上手开发

写在前面&#xff1a;最近在公司实习&#xff0c;需要完成一个实习任务。这个任务用的是SSH框架&#xff0c;数据库需要使用mongoDB完成。由于刚接触MongoDB,所以不是很熟练&#xff0c;在网上查找了大量的资料&#xff0c;许多都是抄来抄去的&#xff0c;运行一堆错误。如今&a…...

从FPGA说起的深度学习(六)-任务并行性

这是新的系列教程&#xff0c;在本教程中&#xff0c;我们将介绍使用 FPGA 实现深度学习的技术&#xff0c;深度学习是近年来人工智能领域的热门话题。在本教程中&#xff0c;旨在加深对深度学习和 FPGA 的理解。用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为硬…...

5.39 综合案例2.0 - STM32蓝牙遥控小车4(体感控制)

综合案例2.0 - 蓝牙遥控小车4- 体感控制成品展示案例说明器件说明小车连线小车源码遥控手柄遥控器连线遥控器代码1.摇杆PS2模块说明2.六轴MPU-6050说明成品展示 案例说明 用STM32单片机做了一辆蓝牙控制的麦轮小车&#xff0c;分享一下小车的原理和制作过程。 控制部分分为手机…...

Scala之面向对象

目录 Scala包&#xff1a; 基础语法&#xff1a; Scala包的三大作用&#xff1a; 包名的命名规范&#xff1a; 写包的好处&#xff1a; 包对象&#xff1a; 导包说明&#xff1a; 类和对象&#xff1a; 定义类&#xff1a; 封装&#xff1a; 构造器&#xff1a; 主从…...

深度学习目标检测项目实战(四)—基于Tensorflow object detection API的骨折目标检测及其界面运行

深度学习目标检测项目实战(四)—基于Tensorflow object detection API的骨折目标检测及其界面运行 使用tensorflow object detection进行训练检测 参考原始代码&#xff1a;https://github.com/tensorflow/models/tree/master/research 我用的是1.x的版本 所以环境必须有gpu版…...

嵌入式工程师如何快速的阅读datasheet的方法

目录 ▎从项目角度来看datasheet ▎各取所需 ▎最后 Datasheet&#xff08;数据手册&#xff09;的快速阅读能力&#xff0c;是每个工程师都应该具备的基本素养。 无论是项目开始阶段的选型还是后续的软硬件设计&#xff0c;到后期的项目调试&#xff0c;经常有工程师对着英…...

(三)合约广告

1. 广告位&#xff08;CPT&#xff09;合约 系统&#xff1a;广告排期系统 网站把某一个广告位卖给广告商&#xff0c;这段时间归广告商所有&#xff0c;到点了下线 &#xff08;1&#xff09;流量选择的维度&#xff1a;时间段、地域等 &#xff08;2&#xff09;典型场景…...