php怎么写支付?php支付宝在线支付接口开发教程
1.什么是第三方支付
所谓第三方支付,就是一些和各大银行签约、并具备一定实力和信誉保障的第三方独立机构提供的交易支持平台。在通过第三方支付平台的交易中,买方选购商品后,使用第三方平台提供的账户进行货款支付,由第三方通知卖家货款到达。
目前提供第三方支付的机构很多,常见的有支付宝、财付通、快钱、网银在线、易宝支付、云网等各大支付平台。网站如果需要实现第三方支付首先应该向第三方支付平台申请一个账号并签署协议,协议生效后第三方支付平台将为其开通在线支付功能,通过程序将接口集成到网站中。
为什么要使用第三方支付?因为第三方支付平台已经与各大银行进行签约,网站主只需要在此平台申请一个账号即可支持几乎所有的种类的银行卡信用卡的交易。
2.第三方支付原理
以上简要说明了支付过程,当然其中省略了一些步骤(比如购物车,订单等),我们重点来看支付流程。
2.1用户向商城网站发起确认订单的请求
2.2商城网站接收到请求保存订单数据到数据库或其他存储介质
2.3返回订单确认页面,页面上应该显示订单金额等信息
2.4用户确认支付,发起支付请求。注:支付请求是发送到支付网关(比如支付宝、网银在线)而不是发送到商城网站。
2.5显示支付页面
2.6用户填写认证信息(账号密码等)提交
2.7这里有两个步骤一个是扣款成功后页面跳转到支付结果页面(展示给用户),另一个是支付通知,这两步没有先后顺序可能同时执行,商城网站接收到支付通知后根据验证规则验证信息的有效性,并作出相应的更改操作(例:有效则更改订单为已付款状态,无效则记录非法请求信息)。
以支付宝为例:如果实现在网站中集成支付宝接口,首先要有一个支付宝账号,接下来向支付宝申请在线支付业务,签署协议。协议生效后有支付宝一方会给网站方一个合作伙伴ID,和安全校验码,有了这两样东西就可以按照支付宝接口文档开发支付宝接口了,在上图的几个步骤中只有4和7两个步骤在商城与支付网关之间有信息交互。在步骤4中指将数据发送到支付网关(支付宝),在步骤7中是的通知验证部分,验证网关请求网站某地址,网站按验证规则对信息进行验证记录并作出响应,我们几乎在开发任何支付接口时,重点是这两部分的开发,明白支付接口原理,开发支付接口就不难了。
3.支付宝接口开发
3.1接口简介与测试
支付宝目前提供了,担保交易、标准即时到帐、双功能等几种接口,只是在功能上有些差异,网站集成方式是一样的。以标准即时到帐接口为例,在与支付宝签署协议后,还需要几个步骤才能完成集成。
选择“我要自助集成”接下来会看到的链接,点击下载技术文档。
在下载后的文件中有标准支付宝交易服务接口、商家工具、接口集成指南等接文档,另外还有几种语言写的demo.我们可以根据接口文档按规则全新开发,也可以再demo基础上修改集成到网站,需要注意的是开发支付接口需要在公网(服务器必须可以通过外网访问)才可以完成整个调试过程,如果服务器在外网访问不到,则无法接收到支付通知。
看一下demo中每个文件的作用:
这里已经下载好了(见资源目录pay文件夹),为了便于调试增加修改了若干文件,并增加了一张数据表保存订单信息,我们修改一下配置文件完成一个测试过程。
alipay_config.php是基础信息配置文件,我们需要将在支付宝后台获取的PID与Key写入到配置文件中。
配置项:
其中方框内的数据是我们需要重点修改的。支付通知地址与返回地址的区别,前面已经提到,在步骤7中有两项:支付结果页面与支付通知信息,支付结果页面是用户支付完成后会自动跳转到这个地址这里是返回地址($return_url)。
支付通知地址同样是用户支付完成后,支付宝会请求该地址($notify_url),但是支付通知是支付宝服务器直接请求,不会被用户看到。这两个地址必须是以http开头的完整路径格式为了完成测试过程,这里已经将/pay/alipay/notify_url.php改写,将$notify_url设置为可访问到此文件的URL即可。这几项配置好后再根据数据库脚本(pay/orders.sql)创建一张数据表。并根据数据库的配置信息修改mysql_config.php.通过对支付宝提供的demo做简单修改就可以完成创建支付请求(步骤4)了,这里更改了支付首页等页面(见源码包pay目录)。我们先测试一下:
数据库中增加了一条“订单信息”.
如果点击“确认支付”按钮或者确认支付 链接将会跳转到支付宝页面,点击按钮时通过表单POST方式将信息提交到支付网关,由于支付请求数据无需让用户看到,这里都写在隐藏域中了。确认支付 链接是通过URL传参,因为支付宝接口允许以POST或者GET方式提交,所以两种方式都可以。把参数提交给支付网关后,页面跳转到到支付页面。我们看到如下图所示:
我们看到支付宝为我们提供了两种支付方式,一种是通过支付宝账户支付,另一种是通过银行卡支付。例如选择使用银行卡支付,填写邮箱或手机号跳转到如下页面:
我们开单支付宝几乎支持所有的银行卡支付,同时有信用卡和网点方式付款,选择对应的银行下一步按提示付款即可。付款完成后页面会返回到我们在配置文件中配置的$return_url地址,同时“订单状态”也会发生改变。
注:测试时如果没有在外网测试(即支付通知地址无法在外网访问)则支付通知无法被请求到,无法自动完成订单状态的修改。
3.2支付宝接口规范与代码分析
支付宝接口规范可参考/pay/doc/标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf,里面已经有了比较详细的说明。
3.2.1如何创建支付请求
在前面的测试中我们点击了“确认支付”将信息将信息提交到了支付宝的支付网关,我们可以思考一下应该发送哪些参数给支付网关。关于请求参数列表可以参考标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf中的3.2.2.需要注意的是并不是我们把这些参数原封不动的提交到支付宝就可以了,为了保证数据安全支付宝目前使用的是MD5签名防止数据篡改机制。
在提交数据前需要将需要提交的数据以一定规则(见接口文档)组装成字符串,加上安全校验码(Key)组成一个新字符串,通过MD5生成一个32字节的签名,我们提交支付请求时还需要把这个签名也提交过去。看一下表单源码
支付宝接收到参数后会进行验证请求参数的合法性,验证无误后将显示支付页面,否则提示错误。
3.2.2 如何验证支付通知
在用户支付完成后,支付宝会请求网站支付通知地址(这个地址应在创建支付请求时作为参数传递过去)。返回参数列表参见标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf3.3.1.支付宝的返回数据中同样有一个签名串(采取和支付请求同样的签名方式),在支付通知文件中首先要对数据进行签名验证。除了验证签名,还需要将参数中的notify_id提交到支付宝的验证网关支付宝系统这个通知的真实性,通知验证。支付宝系统判断通知是否是自己发送,如果是以字符串格式返回 true,否则返回false,我们通过验证服务器返回的数据验证请求的真实性,如果都验证通过则可以进行更改订单数据、给用户发送邮件通知等操作。关于验证签名可以看一下通知文件中的源码。带demo中将参数中的notify_id提交到支付宝是通过POST方式提交并取得返回数据,代码片段:
这里重点就是fsockopen函数,在发送电子邮件时我们已经接触过,通过此函数打开套接字连接,类似于以前学过的fopen函数返回的是一个文件句柄,之后可以使用文件函数( fgets()、fgetss()、fputs()、fclose() feof()等)对其进行操作,代码中使用了fputs()(同fwrite())函数,写入数据来模拟表单以POST方式提交数据,最后通过fgets()函数获取返回的数据保存到数组中,最后进行验证,具体参照源码。
小编分享的这篇文章介绍了一个PHP实现的轻量级简单爬虫,不知道php怎么写爬虫的同学可以参考一下文中给出的实例代码。最近需要收集资料,在浏览器上用另存为的方式实在是很麻烦,而且不利于存储和检索。所以自己写了一个小爬虫,在网上爬东西,迄今为止,已经爬了近百 万张网页。现在正在想办法着手处理这些数据。
爬虫的结构:
爬虫的原理其实很简单,就是分析下载的页面,找出其中的连接,然后再下载这些链接,再分析再下载,周而复始。在数据存储方面,数据库是首选,便于检索,而 开发语言,只要支持正则表达式就可以了,数据库我选择了mysql,所以,开发脚本我选择了php。它支持perl兼容正则表达式,连接mysql很方 便,支持http下载,而且windows系统和linux系统都可以部署。
正则表达式:
正则表达式是处理文字的基本工具,要取出html中的链接和图片,使用的正则表达式如下。
"#<a[^>]+href=(['\"])(.+)\\1#isU" 处理链接
"#<img[^>]+src=(['\"])(.+)\\1#isU" 处理图片
其他问题:
写爬虫还需要注意的一个问题是,对于已经下载过的url,不能重复进行下载,而有些网页的链接会形成环路,所以需要处理这个问题,我的处理方法是计算已经 处理的url的MD5 值,并存入数据库,这样就可以检验是否已经下载过。当然还有更好的算法,有兴趣的话,可以在网上找一下。
相关协议:
爬虫也有自己的协议,有个robots.txt文件定义了那些是网站允许遍历的,但是由于我的时间有限,没有实现这个功能。
其他说明:
php支持类编程,我写的爬虫主要的类.
1.url处理web_site_info,主要用处理url,分析域名等。
2.数据库操作mysql_insert.php,处理和数据库相关的操作。
3.历史记录处理,记录已经处理的url。
4.爬虫类。
存在的问题和不足
这个爬虫在小数据量的情况下,运行良好,但是在大数据量的情况下,历史记录处理类的效率就不是很高,通过在数据库结构中,对相关字段进行了索引,速度有了 提高,但是需要不断得读取数据,可能和php本身的array实现有关系,如果一次加载10万条历史记录,速度非常慢。
不支持多线程,每次只能处理一个url。
php运行本身有内存使用量限制,有一次在抓取深度为20的页面的时候,内存用尽程序被杀。
下面的url是源码下载。
http://xiazai.jb51.net/201506/other/net_spider.rar
使用的时候,先在mysql中创建net_spider数据库,然后用db.sql创建相关表。再在config.php中设置mysql 的用户名口令。
最后
php -f spider.php 深度(数值) url
就可以开始工作。如
php -f spider.php 20 http://news.sina.com.cn
现在感觉下来,其实做个爬虫没那么复杂,难的是数据的存储和检索。我现在的数据库,最大一个数据表已经15G,正在想办处理这些数据,mysql进 行查询已经感觉有点力不从心了。这点上还真佩服google
代码如下 | 复制代码 |
<?php #加载页面 functioncurl_get($url){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HEADER,1); $result=curl_exec($ch); $code=curl_getinfo($ch,CURLINFO_HTTP_CODE); if($code!='404'&&$result){ return$result; } curl_close($ch); } #获取页面url链接 functionget_page_urls($spider_page_result,$base_url){ $get_url_result=preg_match_all("/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\]*).*?>/",$spider_page_result,$out); if($get_url_result){ return$out[1]; }else{ return; } } #相对路径转绝对路径 functionxdtojd($base_url,$url_list){ if(is_array($url_list)){ foreach($url_listas$url_item){ if(preg_match("/^(http:\/\/|https:\/\/|javascript:)/",$url_item)){ $result_url_list[]=$url_item; }else{ if(preg_match("/^\//",$url_item)){ $real_url=$base_url.$url_item; }else{ $real_url=$base_url."/".$url_item; } #$real_url='http://www.sumpay.cn/'.$url_item; $result_url_list[] =$real_url; } } return$result_url_list; }else{ return; } } #删除其他站点url functionother_site_url_del($jd_url_list,$url_base){ if(is_array($jd_url_list)){ foreach($jd_url_listas$all_url){ echo$all_url; if(strpos($all_url,$url_base)===0){ $all_url_list[]=$all_url; } } return$all_url_list; }else{ return; } } #删除相同URL functionurl_same_del($array_url){ if(is_array($array_url)){ $insert_url=array(); $pizza=file_get_contents("/tmp/url.txt"); if($pizza){ $pizza=explode("\r\n",$pizza); foreach($array_urlas$array_value_url){ if(!in_array($array_value_url,$pizza)){ $insert_url[]=$array_value_url; } } if($insert_url){ foreach($insert_urlas$key=>$insert_url_value){ #这里只做了参数相同去重处理 $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); foreach($pizzaas$pizza_value){ $update_pizza_value=preg_replace('/=[^&]*/','=leesec',$pizza_value); if($update_insert_url==$update_pizza_value){ unset($insert_url[$key]); continue; } } } } }else{ $insert_url=array(); $insert_new_url=array(); $insert_url=$array_url; foreach($insert_urlas$insert_url_value){ $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); $insert_new_url[]=$update_insert_url; } $insert_new_url=array_unique($insert_new_url); foreach($insert_new_urlas$key=>$insert_new_url_val){ $insert_url_bf[]=$insert_url[$key]; } $insert_url=$insert_url_bf; } return$insert_url; }else{ return; } }
$current_url=$argv[1]; $fp_puts=fopen("/tmp/url.txt","ab");//记录url列表 $fp_gets=fopen("/tmp/url.txt","r");//保存url列表 $url_base_url=parse_url($current_url); if($url_base_url['scheme']==""){ $url_base="http://".$url_base_url['host']; }else{ $url_base=$url_base_url['scheme']."://".$url_base_url['host']; } do{ $spider_page_result=curl_get($current_url); #var_dump($spider_page_result); $url_list=get_page_urls($spider_page_result,$url_base); #var_dump($url_list); if(!$url_list){ continue; } $jd_url_list=xdtojd($url_base,$url_list); #var_dump($jd_url_list); $result_url_arr=other_site_url_del($jd_url_list,$url_base); var_dump($result_url_arr); $result_url_arr=url_same_del($result_url_arr); #var_dump($result_url_arr); if(is_array($result_url_arr)){ $result_url_arr=array_unique($result_url_arr); foreach($result_url_arras$new_url) { fputs($fp_puts,$new_url."\r\n"); } } }while($current_url=fgets($fp_gets,1024));//不断获得url preg_match_all("/<a[^>]+href=[\"']([^\"']+)[\"'][^>]+>/",$spider_page_result,$out); #echoa href #var_dump($out[1]); ?> |
index.php
代码如下 | 复制代码 |
<html> <head> <title>First PHP</title> </head> <body> <form name="form_a" method="post", action="fa.php"> 用户名: <input name="user" type="text" value="" size="12" maxlength="1000"> <br/> 密码: <input name="pwd" type="password" value="" size="12" maxlength="20"> <br/> 性别: <input name="sex" type="radio" value="男" checked>男 <input name="sex" type="radio" value="女">女 <br/><br/> 购买书籍:<br/> <?php $books = array("Linux设计", "C++软件设计", "PHP网页开发"); foreach ($books as $i=>$book) { echo "<input name=\"books\" type=\"checkbox\" value=$i>$book\n<br>\n"; } ?> <br/> |
选择课程:
代码如下 | 复制代码 |
<select name="class" id="class"> <?php $classes = array("C++程序设计", "C程序设计", "MFC程序设计", "Qt编程", "网络编程", "SQL数据库设计"); foreach ($classes as $key=>$value) { echo '<option value="' .$key.'">' . $value . '</option>\n'; } ?> </select> <br/> <input name="submit" type="submit" value="提交"> </form> </body> </html> |
fa.php
代码如下 | 复制代码 |
<?php #echo 'user: ' . $_POST["user"]; print_r($_POST); ?> |
Windows下PHP安装配置
软件版本:php-5.3.1-Win32-VC6-x86.zip
这个不需要额外的安装.net的库,所以就用这个了。可以使用其他的。
1.PHP安装
使用绿色方式,下载Zip文件解压。
2.配置
在解压的根目录下找到php.ini-development,是用于开发环境的配置文件;还有一个php.ini-production,这个是用于生产环境的配置文件。使用php.in-development,复制一份,重命名为php.ini。开始编辑。
定位registe_globals =Off;
建议不要打开,区别在于这个值是用来打开全局变量的,比如表单送过来的值,如果这个值设为“Off”,就只能用“$_POST['变量名']、$_GET['变量名']”等来取得送过来的值,如果设为“On”,就可以直接使用“$变量名”来获取送过来的值,当然,设为“Off”就比较安全,不会让人轻易将网页间传送的数据截取。这个值是否改成“On”就看自己感觉了,是安全重要还是方便重要?
为了使php能够调用其他模块,可以以extension关键字搜索,定位到如下,去除选项前的分号,则打开此模块的支持。
加载的模块越多,占用的资源要稍微多些,可以忽略。比如要启用mysql的支持,则找到如下
;extension=php_mysql.dll
去除前面的";"注释就可以了。
所有的模块都放在php解压目录下的ext目录中,可以根据需要启用。
加载模块报错:
有时启动Apache的时候会提示“找不到指定模块”的错误,是因为没有指定这些模块文件的位置,定位关键字“extension_dir”,修改Windows下为你的PHP模块的目录。
比如我的PHP目录在 D:\PHP,则配置
extession_dir = "D:\PHP\ext"
这样启动Apache就不会报错了。
这里介绍一种最简单的方法,直接将php安装路径、里面的ext路径指定到windows系统路径中——在“我的电脑”上右键,“属性”,选择“高级”标签,点选“环境变量”,在“系统变量”下找到“Path”变量,选择,双击或点击“编辑”,将“;D:\php;D:\php\ext”加到原有值的后面,当然,其中的“D:\php”是我的安装目录,你要将它改为自己的php安装目录,如下图所示,全部确定。
3.与Apache协同工作
php以module方式与Apache相结合,打开Apache的配置文件,以关键字“LoadModule”定位,配置要加载的模块,
在最后添加如下两行:
LoadModule php5_module D:/php/php5apache2_2.dll
PHPIniDir "D:/php"
第一行“LoadModule php5_module D:/php/php5apache2_2.dll”是指以module方式加载php,第二行“PHPIniDir "D:/php"”是指明php的配置文件php.ini的位置,是当然,其中的“D:/php”要改成你先前选择的php解压缩的目录。
在php的解压目录下同时有php5apache2.dll和php5apache2_2.dll,因为我们的apache版本是2.2的,所以加载dll
使用php5apache2_2.dll,可以根据自己的情况配置。
以关键字AddType application搜索,可以定义能够执行php文件类型,
原文如下:AddType allows you to add to or override the MIME configuration
# file specified in TypesConfig for specific file types.
加入
AddType application/x-httpd-php .php
AddTypeapplication/x-httpd-php.html
两行,你也可以加入更多,实质就是添加可以执行php的文件类型,比如你再加上一行“AddTypeapplication/x-httpd-php .htm”,则.htm文件也可以执行php程序了,你甚至还可以添加上一行“AddTypeapplication/x-httpd-php .txt”,让普通的文本txt也能运行php程序。
PHP的基本配置完成。
相关文章
- 支付宝支付在国内算是大家了,我们到处都可以使用支付宝了,下文整理介绍的是在安卓app应用中使用支付宝进行支付的开发例子。 之前讲了一篇博客关与支付宝集成获取...2016-09-20
- PHP是一种解释型的语言,对于用户而言,我们精心的控制内存意味着easier prototyping和更少的崩溃!当我们深入到内核之后,所有的安全防线都已经被越过,最终还是要依赖于真正有责任心的软件工程师来保证系统的稳定运行。1、线...2015-11-08
- 为公司系统业务需要,这几天了解了一下微信和支付宝扫码支付的接口,并用c#实现了微信和支付宝扫码支付的功能。需要的朋友跟随小编一起看看吧...2020-06-25
- 那么今天我就用JavaScript代码来实现这个效果吧,那么首先介绍一下整个的思路,首先我们先将确定输入密码的位数,我的需求是5位,那么就用一个div标签包住5个input标签...2016-01-02
- Ecshop手机网页版本支持在网上找了很多需要花钱购买了,在这里小编整理了一个Ecshop 支付宝手机网页支付免费版供大家参考。 Ecshop 支付宝手机网页支付,针对ecshop...2016-11-25
- 这篇文章主要为大家详细介绍了js canvas仿支付宝芝麻信用分仪表盘,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-11-22
- 这篇文章主要为大家详细介绍了支付宝小程序实现省市区三级联动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-21
- PHP扩展开发不是所有开发者都会操作的一个东西,下面我来演示一个关于PHP扩展开发实现过程,各位同学有需要可进入参考。 我们先假设需要这样一个扩展,提供一个叫tao_s...2016-11-25
- OpenCart 开发支付宝,财付通,微信支付如果我们不注意可能出现很多的一些问题,主要就是参数错误但一般是看不了来的,这里有一站长分享了一篇不错的文章大家来看看吧。...2016-11-25
- 这篇文章主要介绍了jQuery插件开发精品教程让你的jQuery提升一个台阶 的相关资料,需要的朋友可以参考下...2016-01-29
- 这篇文章主要为大家详细介绍了C#支付宝新版支付请求接口调用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- sql语句是指我们在安卓开发中会经常碰到有大量的地方要查询数据库了,下面我来介绍在安卓中使用sql语句吧。 SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管...2016-09-20
- 一、选择支付类型目前有两种支付类型 JS API网页支付 Native原生支付如果没有特殊要求,两种都勾选。二、支付授权目录目前可以选择http还是https协议,没有特别要求,选择http。对安全要求比较高的企业,请选择https。...2014-05-31
- 近日,支付宝正式推送了“圈子邀请函”,例如“白领日记圈子”“海外代购圈子”“XX 市女人圈子”“XX 市高端单身交友圈”“海归精英圈”“美剧圈”等……网友纷纷在微博上晒图,除了对身份、性别外,对芝麻信用分也有一定要求。...2016-12-07
ASP.NET Core 2.0 使用支付宝PC网站支付实现代码
这篇文章主要介绍了ASP.NET Core 2.0 使用支付宝PC网站支付实现代码,需要的朋友可以参考下...2021-09-22支付宝开发中return_url和notify_url的区别介绍
在支付宝处理业务中return_url,notify_url是返回些什么状态呢,我们要根据它来做一些处理就必须了解return_url,notify_url的区别,下面我就来给各位介绍介绍。 问...2016-11-25- 小米MIX、小米Note 2现已支持支付宝指纹支付,目前已有10款小米机型支持该功能。文中介绍了开启方式,小米手机的用户,快来看看有没有你的手机...2016-12-15
- 支付牌照成为稀缺资源,计划涉足支付业务的电商企业不惜斥重金也要获取资质。3月20日,有消息称,国美将以5亿元的价格收购银盈通支付有限公司(以下简称“银盈通”)70%股权,后者为拥有支付牌照的支付机构,若消息属实,便意味着国美将正式获得布局互联网支付业务的资质。...2017-07-06
- 现在的手机app到处都并且一般的都是可以直接付款了,现在的支付宝付款接口是支持pc,手机及app版本了,在开始中我们会用到支付宝私钥与公钥问题了,下面整理了一篇文章一起...2016-09-20
- 这篇文章主要介绍了ASP.NET Core 2.0 支付宝扫码支付的实现代码,需要的朋友可以参考下...2021-09-22