热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php手机网站支付宝_php支付宝手机网页支付类实例

本文实例讲述了php支付宝手机网页支付类。分享给大家供大家参考。具体分析如下:此处注意:①该类是用在Yii框架里面的,没有去掉一些框架的东

本文实例讲述了php支付宝手机网页支付类。分享给大家供大家参考。具体分析如下:

此处注意:

① 该类是用在Yii框架里面的,没有去掉一些框架的东西。

② 本类不能不做任何修改而使用。

1. PHP代码部分如下:

namespace weixin\components;

use Yii;

/**

* 支付宝手机网页支付

*

* @example

*     创建支付请求

*     $params = []; //支付宝文档中所需的全部参数

*     $alipay = new Alipay();

*     $alipay->key = ''; //交易安全校验码

*     $this->alipay->alipay_config = $params;

*     $alipay->buildRequest();

*

*     验证异步通知

*     $this->alipay->key = ''; //交易安全校验码

*     $this->alipay->alipay_config = $data; //支付宝异步通知参数

*     $this->alipay->verifyNotify();

*

* @package Alipay

* @author Dyllen

* @since Version 0.2

*/

class Alipay {

/**

* 交易安全校验码

*

* @access public

* @var string

*/

public $key;

/**

* 请求参数配置,支付宝接口文档中所需的参数

*

* @access public

* @var array

*/

public $alipay_config=[];

/**

* HTTPS证书,用于cURL

* 默认和本类文件同级目录的cacert.pem文件

*

* @access public

* @var string

*/

public $credential;

public $notify_data = null;

/**

* 支付宝即时到账网关地址

*/

const ALIPAY_GATEWAY = 'https://mapi.alipay.com/gateway.do?';

/**

* HTTPS形式消息验证地址

*/

const HTTPS_VERIFY_URL = 'https://mapi.alipay.com/gateway.do?service=notify_verify&';

/**

* HTTP形式消息验证地址

*/

const HTTP_VERIFY_URL = 'http://notify.alipay.com/trade/notify_query.do?';

/**

* 移动网页支付网关

* @var string

*/

const ALIPAY_PAGE_GATEWAY = 'http://wappaygw.alipay.com/service/rest.htm?';

/**

* 创建支付包即时到账请求url

*

* @access public

* @return void

*/

public function buildRequest() {

$this->alipay_config['sign'] = $this->signData();

return self::ALIPAY_GATEWAY . $this->createQueryString('', true);

}

/**

* 创建支付宝手机网页支付链接

* @return string

*/

public function buildPageUrl()

{

$this->alipay_config['sign'] = $this->signData();

$url = self::ALIPAY_PAGE_GATEWAY. $this->createQueryString('');

$response = $this->getHttpResponseGET($url);

$res = $this->parseResponse(trim($response));

//重新组合支付请求参数

$this->alipay_config['service'] = 'alipay.wap.auth.authAndExecute';

$this->alipay_config['req_data'] = ''.$res['request_token'].'';

$this->alipay_config['sign'] = $this->signData();

return self::ALIPAY_PAGE_GATEWAY. $this->createQueryString('', true);

}

/**

* 验证支付宝异步通知参数合法性

*

* @access public

* @return boolean

*/

public function verifyNotify() {

$param_tmp = $this->filter(); //过滤待签名数据

if(!isset($this->alipay_config['notify_data'])) {

return false;

}

$this->notify_data = $this->xmlToArray($this->alipay_config['notify_data']);

$this->alipay_config['notify_id'] = $this->notify_data['notify_id'];

$responseTxt = 'true';

if( !empty( $this->alipay_config['notify_id'] ) ) {

$responseTxt = $this->getResponse();

}

unset($this->alipay_config['notify_id']);

$txt = 'service=';

$txt .= $this->alipay_config['service'];

$txt .= '&v='.$this->alipay_config['v'];

$txt .= '&sec_id='.$this->alipay_config['sec_id'];

$txt .= '¬ify_data='.$this->alipay_config['notify_data'];

$txt .= $this->key;

$sign = md5($txt);

if ( preg_match("/true$/i",$responseTxt) && ($sign == $this->alipay_config['sign']) ) {

return true;

} else {

return false;

}

}

/**

* 解析授权接口返回

* @param string $content 授权接口返回的文本数据

* @throws \Exception

* @return array

*/

private function parseResponse($content) {

parse_str($content, $arr);

$data = isset($arr['res_data']) ? $arr['res_data'] : $arr['res_error'];

$res_data = simplexml_load_string($data);

if(strlen($res_data->request_token) == 0 || strlen($res_data->msg) > 0) {

throw new \Exception('code:'.$res_data->code.','.$res_data->msg);

}

$arr['request_token'] = $res_data->request_token->__toString();

return $arr;

}

/**

* simpleXML对象转成数组

* @param string $xml

* @return multitype:NULL

*/

private function xmlToArray($xml)

{

$xml_obj = simplexml_load_string($xml, 'SimpleXMLIterator');

$arr = [];

$xml_obj->rewind(); //指针指向第一个元素

while (1) {

if( ! is_object($xml_obj->current()) )

{

break;

}

$arr[$xml_obj->key()] = $xml_obj->current()->__toString();

$xml_obj->next(); //指向下一个元素

}

return $arr;

}

/**

* 签名数据

* 签名规则:

*     sign和sign_type不参加签名,需要去掉

*     对参数数组依据键名按照字母顺序升序排序

*     排序完成之后键值对用&字符连接,组成URL的查询字符串形式待签名字符串,待签名数据不需用url encoding

*     MD5签名:私钥拼接到待签名字符串的后面,然后用md5对字符串运算,得到32位签名结果

*

* @return string 已签名数据

*/

private function signData() {

$param_tmp = $this->getSignString(); //待签名字符串

if( !isset($this->key) ) {

return FALSE;

}

$sign = '';

//签名数据

switch ($this->alipay_config['sec_id']) {

case '001': //rsa

$sign = $this->rsaSign($param_tmp);

break;

case 'DES':

break;

default:

$sign = $this->md5Sign($param_tmp);

}

return $sign;

}

/**

* MD5加密字符串

*

* @access private

* @param string $data 待加密字符串

* @return string

*/

private function md5Sign( $data ) {

return md5($data . $this->key);

}

/**

* RSA 加密字符串

*

* @param string $data 待加密字符串

* @return string

*/

private function rsaSign( $data ) {

return false;

}

/**

* 获得待签名数据

*

* @access private

* @return string

*/

private function getSignString() {

$param_tmp = $this->filter(); //过滤待签名数据

//排序

ksort($param_tmp);

reset($param_tmp);

//创建查询字符串形式的待签名数据

return $this->createQueryString($param_tmp);

}

/**

* 过滤待签名数据,去掉sing、sing_type及空值

*

* @access private

* @return array

*/

private function filter() {

$para_filter = array();

foreach($this->alipay_config as $key => $value){

if($key == "sign" || $key == "sign_type" || empty($value)) continue;

else $para_filter[$key] = $value;

}

return $para_filter;

}

/**

* 用&拼接字符串,形成URL查询字符串

*

* @access private

* @param array $data

* @param boolean $is_encode 是否对值做urlencode

* @return string

*/

private function createQueryString($data=NULL, $is_encode=false ) {

$arr = empty($data) ? $this->alipay_config : $data;

$arg = '';

foreach( $arr as $key => $value ) {

if($is_encode) {

$key = urlencode($key);

$value = urlencode($value);

}

$arg .= $key . '=' . $value . '&';

}

$arg = substr($arg, 0, strlen($arg)-1); //去掉最后一个&

//如果存在转义字符,那么去掉转义

if(get_magic_quotes_gpc()) {$arg = stripslashes($arg);}

return $arg;

}

/**

* 获取远程服务器ATN结果,验证返回URL

*

* 验证结果集:

* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空

* true 返回正确信息

* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟

*

* @access private

* @return 服务器ATN结果

*/

private function getResponse() {

//载入支付配置

$config = Yii::$app->params['alipay'];

$transport = strtolower(trim($config['transport']));

$partner = trim($config['partner']);

$veryfy_url = '';

if($transport == 'https') {

$veryfy_url = self::HTTPS_VERIFY_URL;

}

else {

$veryfy_url = self::HTTP_VERIFY_URL;

}

$veryfy_url = $veryfy_url."partner=" . $partner . "¬ify_id=" . $this->alipay_config['notify_id'];

$responseTxt = $this->getHttpResponseGET($veryfy_url);

return $responseTxt;

}

/**

* 取证书,用于cURL的请求

*

* @access private

* @return string 证书路径

*/

private function getCr() {

if( ! empty($this->credential) ) {

return $this->credential;

}

return __DIR__ . DIRECTORY_SEPARATOR .'cacert.pem';

}

/**

* 远程获取数据,POST模式

* 注意:

* 1.使用Crul需要修改服务器中php.ini文件的设置,找到php_curl.dll去掉前面的";"就行了

* 2.文件夹中cacert.pem是SSL证书请保证其路径有效,目前默认路径是:getcwd().'\\cacert.pem'

*

* @param $url 指定URL完整路径地址

* @param $cacert_url 指定当前工作目录绝对路径

* @param $para 请求的数据

* @param $input_charset 编码格式。默认值:空值

* return 远程输出的数据

*/

private function getHttpResponsePOST($url, $para, $input_charset = '') {

if (trim($input_charset) != '') {

$url = $url."_input_charset=".$input_charset;

}

$curl = curl_init($url);

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证

curl_setopt($curl, CURLOPT_CAINFO,$this->getCr());//证书地址

curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);// 显示输出结果

curl_setopt($curl, CURLOPT_POST,true); // post传输数据

curl_setopt($curl, CURLOPT_POSTFIELDS,$para);// post传输数据

$responseText = curl_exec($curl);

//var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容

curl_close($curl);

return $responseText;

}

/**

* 远程获取数据,GET模式

* 注意:

* 1.使用Crul需要修改服务器中php.ini文件的设置,找到php_curl.dll去掉前面的";"就行了

* 2.文件夹中cacert.pem是SSL证书请保证其路径有效,目前默认路径是:getcwd().'\\cacert.pem'

*

* @param $url 指定URL完整路径地址

* @param $cacert_url 指定当前工作目录绝对路径

* return 远程输出的数据

*/

private function getHttpResponseGET($url) {

$curl = curl_init($url);

curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);// 显示输出结果

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证

curl_setopt($curl, CURLOPT_CAINFO,$this->getCr());//证书地址

$responseText = curl_exec($curl);

//var_dump( curl_error($curl) );exit;//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容

curl_close($curl);

return $responseText;

}

}

2. 使用方法:

//授权接口请求参数

$sum = 0.01; //测试用金额

$req_data = '充值';

$req_data .= ''.$orderNo.'';

$req_data .= ''.$sum.'';

$req_data .= ''.Url::toRoute(['payment/return'], true).'';

$req_data .= ''.Url::toRoute(['payment/notify'], true).'';

$req_data .= ''.Yii::$app->params['alipay']['seller_email'].'';

$req_data .= '';

$params = [

'service' => 'alipay.wap.trade.create.direct',

'format' => 'xml',

'v' => '2.0',

'partner' => Yii::$app->params['alipay']['partner'], //合作者省份ID

'req_id' => date('Ymdhis'),

'sec_id' => Yii::$app->params['alipay']['sign_type'],

'req_data' => $req_data,

];

$alipay = new Alipay();

$alipay->key = Yii::$app->params['alipay']['key'];

$alipay->alipay_config = $params;

$url = $alipay->buildPageUrl();

$this->redirect($url);

3. 配置示例:

//支付宝相关配置

'alipay' => [

'key' => 'XXXXX',  //交易安全校验码,用于签名的32位密钥

'transport' => 'https',         //消息验证地址使用访问方式

'seller_email' => 'XXXX', //卖家支付宝账号,即收款账户

'service' => 'create_direct_pay_by_user', //接口名称

'partner' => 'XXXX', //合作者省份ID

'_input_charset' => 'utf-8', //参数编码字符集

'sign_type' => 'MD5', //签名方式,不参加签名,目前只能是MD5

//以下两个参数没用

'notify_url' => '', //服务器异步通知页面路径

'return_url' => '', //页面跳转通知页面路径

],

希望本文所述对大家的php程序设计有所帮助。



推荐阅读
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • (三)多表代码生成的实现方法
    本文介绍了一种实现多表代码生成的方法,使用了java代码和org.jeecg框架中的相关类和接口。通过设置主表配置,可以生成父子表的数据模型。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
author-avatar
痛彻心扉哥哥_742
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有