原文地址:个人商城系统开源(配置支付宝支付2) - Pleasure的博客
下面是正文内容:
前言
在上一篇文章中我曾提到过关于网站支付宝支付的方法,接下来我们来介绍第二种。
个人博客地址:个人商城系统开源(配置支付宝支付!) - Pleasure的博客
CSDN地址:个人商城系统开源(配置支付宝支付!)-CSDN博客
正文
前情提要
在上一篇文章中我曾提到过一些注意事项。如果你不想通过正规申请开通电脑网站支付,而且你也没有相应的审核材料,那还是借助上一篇提到的第四方支付平台来进行操作吧。
而且操作涉及到财产,审核要求较高,所以如果不是真有需要大致看看就可以了。
我的开源商城系统是由PHP语言编写的(不是JAVA),语言不同的也可以跳过了。
需要准备的材料:两个支付宝账号,一张(个体工商户的)营业执照,完成网站ICP备案。
项目地址
其实这是一个前人栽树,后人乘凉的项目。在很早之前就存在了。
因为支付功能这个操作在php建站中是可以通过两三个文件独立出来实现的,只需要在回调函数中确认了支付成功这个操作就结束了,和商城系统内置文件并没有直接的关联。
在GitHub上的项目地址:
GitHub - dedemao/alipay: 一个PHP文件搞定支付宝支付系列,包括电脑网站支付,手机网站支付,现金红包、消费红包、扫码支付,JSAPI支付、单笔转账到支付宝账户、交易结算(分账、分润)、网页授权获取用户信息等
说明
我这里就只拿电脑网站支付来做示范。
而且光有营业执照还不行,如果没有网站经营授权函,支付界面截图等证明材料,就会有交易限额还只有30天时间用来补全材料。但毕竟只是用于示范,所以相关材料就先不准备了。
一级审核是由机器人完成的,只要营业执照号码和ICP备案查得到基本上就可以通过。
营业执照的审核基本上一天就可以完成,但是查询企业信息平台的同步就需要大概一天的时间,所以需要耐心等待。(申请一个网店经营的营业执照就可以了,具体操作就不示范了)
支付宝收款方和付款方不能是同一个账号。
每一个php文件都对应支付宝中应用需要开通的产品。
如果不开通在访问这个界面的时候就会报错!
获得应用私钥
首先在支付宝开放平台申请应用,
支付宝开放平台:登录 - 支付宝
产品大全地址:登录 - 支付宝
针对前面申请的应用记录下对应的appid
下载支付宝开放平台密钥工具!
选择RSA2加密方式
生成密钥,一个应用公钥,一个应用私钥,记录下生成的应用私钥,后面需要用到
然后在支付宝开放平台中选择开发设置,接口加签方式,上传刚刚生成的应用公钥,记录下返回的支付宝公钥
参考文档
小程序文档 - 支付宝文档中心
小程序文档 - 支付宝文档中心
最后在支付宝商家平台开通并绑定产品。
上传后等待一分钟基本上就短信提示通过了,下面就可以直接来进行代码操作了。
修改项目代码
以电脑网站支付为例
将下载好并解压的文件夹放在网站根目录下
比如说我就放在https://shop2.yiming1234.cn/alipay-master/pc.php 这个位置
打开相应文件,有几个参数需要修改为自己支付相关的信息,分别是:
$appid,$returnUrl,$notifyUrl,$rsaPrivateKey,$alipayPublicKey。就位于头部配置信息处,也就是下面的代码内容
相应参数修改完成后直接访问就可以到支付页面!
pc.php的内容:
<?php
header('Content-type:text/html; Charset=utf-8');
/*** 请填写以下配置信息 ***/
$appid = ''; //https://open.alipay.com 账户中心->密钥管理->开放平台密钥,填写添加了电脑网站支付的应用的APPID
$returnUrl = 'return.php'; //付款成功后的同步回调地址
$notifyUrl = 'notify.php'; //付款成功后的异步回调地址
$outTradeNo = uniqid(); //你自己的商品订单号,不能重复
$payAmount = 0.01; //付款金额,单位:元
$orderName = '支付测试'; //订单标题
$signType = 'RSA2'; //签名算法类型,支持RSA2和RSA,推荐使用RSA2
$rsaPrivateKey=''; //商户私钥,填写对应签名算法类型的私钥,如何生成密钥参考:https://docs.open.alipay.com/291/105971和https://docs.open.alipay.com/200/105310
/*** 配置结束 ***/
$aliPay = new AlipayService();
$aliPay->setAppid($appid);
$aliPay->setReturnUrl($returnUrl);
$aliPay->setNotifyUrl($notifyUrl);
$aliPay->setRsaPrivateKey($rsaPrivateKey);
$aliPay->setTotalFee($payAmount);
$aliPay->setOutTradeNo($outTradeNo);
$aliPay->setOrderName($orderName);
$sHtml = $aliPay->doPay();
echo $sHtml;class AlipayService
{protected $appId;protected $returnUrl;protected $notifyUrl;protected $charset;//私钥值protected $rsaPrivateKey;protected $totalFee;protected $outTradeNo;protected $orderName;public function __construct(){$this->charset = 'utf8';}public function setAppid($appid){$this->appId = $appid;}public function setReturnUrl($returnUrl){$this->returnUrl = $returnUrl;}public function setNotifyUrl($notifyUrl){$this->notifyUrl = $notifyUrl;}public function setRsaPrivateKey($saPrivateKey){$this->rsaPrivateKey = $saPrivateKey;}public function setTotalFee($payAmount){$this->totalFee = $payAmount;}public function setOutTradeNo($outTradeNo){$this->outTradeNo = $outTradeNo;}public function setOrderName($orderName){$this->orderName = $orderName;}/*** 发起订单* @return array*/public function doPay(){//请求参数$requestConfigs = array('out_trade_no'=>$this->outTradeNo,'product_code'=>'FAST_INSTANT_TRADE_PAY','total_amount'=>$this->totalFee, //单位 元'subject'=>$this->orderName, //订单标题);$commonConfigs = array(//公共参数'app_id' => $this->appId,'method' => 'alipay.trade.page.pay', //接口名称'format' => 'JSON','return_url' => $this->returnUrl,'charset'=>$this->charset,'sign_type'=>'RSA2','timestamp'=>date('Y-m-d H:i:s'),'version'=>'1.0','notify_url' => $this->notifyUrl,'biz_content'=>json_encode($requestConfigs),);$commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']);return $this->buildRequestForm($commonConfigs);}/*** 建立请求,以表单HTML形式构造(默认)* @param $para_temp 请求参数数组* @return 提交表单HTML文本*/protected function buildRequestForm($para_temp) {$sHtml = "正在跳转至支付页面...<form id='alipaysubmit' name='alipaysubmit' action='https://openapi.alipay.com/gateway.do?charset=".$this->charset."' method='POST'>";foreach($para_temp as $key=>$val){if (false === $this->checkEmpty($val)) {$val = str_replace("'","'",$val);$sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";} }//submit按钮控件请不要含有name属性$sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>";$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";return $sHtml;}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);//$data = iconv($fileType, $targetCharset.'//IGNORE', $data);}}return $data;}
}
return.php的内容(同步回调通知)
<?php
header('Content-type:text/html; Charset=utf-8');
//支付宝公钥,账户中心->密钥管理->开放平台密钥,找到添加了支付功能的应用,根据你的加密类型,查看支付宝公钥
$alipayPublicKey='';$aliPay = new AlipayService($alipayPublicKey);
//验证签名
$result = $aliPay->rsaCheck($_GET,$_GET['sign_type']);
if($result===true){//同步回调一般不处理业务逻辑,显示一个付款成功的页面,或者跳转到用户的财务记录页面即可。echo '<h1>付款成功</h1>';exit();
}
echo '不合法的请求';exit();
class AlipayService
{//支付宝公钥protected $alipayPublicKey;protected $charset;public function __construct($alipayPublicKey){$this->charset = 'utf8';$this->alipayPublicKey=$alipayPublicKey;}/*** 验证签名**/public function rsaCheck($params) {$sign = $params['sign'];$signType = $params['sign_type'];unset($params['sign_type']);unset($params['sign']);return $this->verify($this->getSignContent($params), $sign, $signType);}function verify($data, $sign, $signType = 'RSA') {$pubKey= $this->alipayPublicKey;$res = "-----BEGIN PUBLIC KEY-----\n" .wordwrap($pubKey, 64, "\n", true) ."\n-----END PUBLIC KEY-----";($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');//调用openssl内置方法验签,返回bool值if ("RSA2" == $signType) {$result = (bool)openssl_verify($data, base64_decode($sign), $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256);} else {$result = (bool)openssl_verify($data, base64_decode($sign), $res);}
// if(!$this->checkEmpty($this->alipayPublicKey)) {
// //释放资源
// openssl_free_key($res);
// }return $result;}/*** 校验$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);//$data = iconv($fileType, $targetCharset.'//IGNORE', $data);}}return $data;}
}
notify.php的内容(异步回调通知)
<?php
header('Content-type:text/html; Charset=utf-8');
//支付宝公钥,账户中心->密钥管理->开放平台密钥,找到添加了支付功能的应用,根据你的加密类型,查看支付宝公钥
$alipayPublicKey='';$aliPay = new AlipayService($alipayPublicKey);
//验证签名
$result = $aliPay->rsaCheck($_POST,$_POST['sign_type']);
if($result===true && $_POST['trade_status'] == 'TRADE_SUCCESS'){//处理你的逻辑,例如获取订单号$_POST['out_trade_no'],订单金额$_POST['total_amount']等//程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);echo 'success';exit();
}
echo 'error';exit();
class AlipayService
{//支付宝公钥protected $alipayPublicKey;protected $charset;public function __construct($alipayPublicKey){$this->charset = 'utf8';$this->alipayPublicKey=$alipayPublicKey;}/*** 验证签名**/public function rsaCheck($params) {$sign = $params['sign'];$signType = $params['sign_type'];unset($params['sign_type']);unset($params['sign']);return $this->verify($this->getSignContent($params), $sign, $signType);}function verify($data, $sign, $signType = 'RSA') {$pubKey= $this->alipayPublicKey;$res = "-----BEGIN PUBLIC KEY-----\n" .wordwrap($pubKey, 64, "\n", true) ."\n-----END PUBLIC KEY-----";($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');//调用openssl内置方法验签,返回bool值if ("RSA2" == $signType) {$result = (bool)openssl_verify($data, base64_decode($sign), $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256);} else {$result = (bool)openssl_verify($data, base64_decode($sign), $res);}
// if(!$this->checkEmpty($this->alipayPublicKey)) {
// //释放资源
// openssl_free_key($res);
// }return $result;}/*** 校验$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);//$data = iconv($fileType, $targetCharset.'//IGNORE', $data);}}return $data;}
}
效果展示
尾声
至此,开源商城系统支付板块的编辑就告一段落了。