付 款
- 支付宝版权所有 2015-2018 ALIPAY.COM
引用:
https://blog.csdn.net/weixin_42122979/article/details/80899552
https://github.com/dream2023/ThinkPHP5-alipay
http://www.thinkphp.cn/code/3593.html
extend
目录为支付扩展目录, application\extra\alipay.php
为配置文件application\extra\alipay.php
中填写必要的参数(TP5.1版本,这个用法不行)config/app.php文件中
// +----------------------------------------------------------------------
// | 支付宝支付参数
// +----------------------------------------------------------------------
// 'alipay'=>[
// //应用ID,您的APPID。
// 'app_id' => "2016090000241",
//
// //商户私钥
// 'merchant_private_key' => "MIIEowIBAAKCAQEAsBUqNm8NAKnukhMSFNBUlogaiZxwbM3usQQQrnpcCPhmuwqdekjkSS7eBnql5K21N641uR05G+7M1teqz1nn39lPO1pmOQj21jxwEyIZvAFn+RJGQCO+C/853nOEQ7/WACg4FUplTHZukMZA9z438yomc2C+DqcUD/j9XgIC5W2ZdQfXy0elL4Ciq7IT0HYJojS0/Vk1Qf2kPDFCNcNOB1irNL99eZ1ENsuf82CCmw9tVrcWhZ5Jt6n7vyVOp8P5IIsamTk/KvG6Px/8iqccY83Fg0wvn2sWw49vB3YHD7lTQfwBnZHwQ4WmKh6j+na/MdmEat96StMjaylf4hF/TQIDAQABAoIBAGtWG4tfGqAC9qkY8va5IDc69GJaeLX6urwxbDHP6PaW5ZizGdgHQxHRfgqZDTNfKI6upZUYWU3LvhZhFYCcn5p3D7Nwocu2yTFDWlZvfRx8BvNvzl8e6qTJim8uH7xk3oDuA3IHDcUUlMWv9L5CsTyLvzCqEnFALByofVqnAzjzGHFO/PRWpGyPw6gvQyR1yrL8BMQOn+RIUGeJl25TuJzS+X6uOVbdO3I3WKyyyJ6tZbKAxlUY0H2XruPwH/cJZ0h8sLRihRn1ZDnzhJiKPvirwAoLvVU7KwmA5wikFbU7voTqCtxzrrR+zKLzjpu/qQbOQKBgG4iZDMngawdxr/FfNA2uPJKTOniF3TD6roGDjcCmR/Y/47r1CUpEaIOLwuG4GXyRnWT3Lo7a1ve4oTudUhGKtrjPlxPGFqC7MMabknREEDnfjAqLM0tPkhnb1qvRMltepe5fS0kEDEg5Qo9aktJd1wLJ09dWnv7ijh+Bc6l+gin",
//
// //异步通知地址
// 'notify_url' => "http://www.81.com/00/notify_url.php",
//
// //同步跳转
// 'return_url' => "http://www.81.com/00/return_url.php",
//
// //编码格式
// 'charset' => "UTF-8",
//
// //签名方式
// 'sign_type'=>"RSA2",
//
// //支付宝网关
// 'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
//
// //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
// 'alipay_public_key' => "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QV6KrPDrmAPdFc1EqTsPO7kdlHhvs09noSEV4NUxO4XPyz5E62eJRxPlcBuSD1yzM84xBTNXo6WgTM6XuxvM74Bs6hXVm/WcZxSLIGAZ5N9tymx9+09fOMejOObydP/HIi6sfcyQeHBR7owHe9GP4fsSzMQIDAQAB",
// ]
方法二:动态值法 就是把这些参数保存到数据库中,然后再读出来
在公共文件中读出(路径:/application/common.php),组成数组$config
//支付宝支付参数
function alipay_confing(){
$config['app_id']='20100919000241';
$config['merchant_private_key']='MIIEowIBAAKCAQEAsBUqNm8NAKnukhMSFNBUlogaiZxwbM3usQQQrnpcCPhmuwqdekjkSS7eBnql5K21N641uR05G+7M1teqz1ng5Qo9aktJd1wLJ09dWnv7ijh+Bc6l+gin';
$config['notify_url']='';
$config['return_url']='';
$config['charset']='UTF-8';
$config['sign_type']='RSA2';
$config['gatewayUrl']='https://openapi.alipaydev.com/gateway.do';
$config['alipay_public_key']='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QV6KrPDrmAPdFc1EqTsPO7kdlHhvs09noSEV4NUxO4XPyz5E62eJRxPlcBuSD1yzM84xBTNXo6WgTM6XuxvM74Bs6hXVm/WcZxSLIGAZ5N9tymx9+09fOMejOObydP/GOrEAV4KF5tB65+/aq4+rvp0w/QlhfmMHwjaazLXmdBjSzXj5x1v0Ep2uzPG4SgH+XCvM6SCN0mvSIKdZDPtIowPlpLXOqzMQIDAQAB';
return $config;
}
调用:在\extend\alipay\Pagepay.php文件中调用
$config=alipay_confing();
错误采用抛出异常的方式, 可根据自己的业务在统一接口进行修改
电脑网站支付 Pagepay.php
调用 \alipay\Pagepay::pay($params)
即可
手机网站支付 Wappay.php
调用 \alipay\Wappay::pay($params)
即可
交易查询接口 Query.php
调用 \alipay\Query::exec($query_no)
即可
交易退款接口 Refund.php
调用 \alipay\Refund::exec($params)
即可
退款统一订单查询 RefundQuery.php
调用 \alipay\RefundQuery::exec($params)
即可
交易关闭接口 Close.php
调用 \alipay\Close::exec($query_no)
即可
查询账单下载地址接口 Datadownload.php
调用 \alipay\Datadownload::exec($bill_type, $bill_date)
即可
验签 Notify.php
调用 \alipay\Notify::check($params)
即可
通知处理步骤建议
一下两个类仅为建议, 帮助理解, 可根据具体业务进行变更, 详细理解可参考官方文档和SDK
application\common\NotifyHandler.php
通知操作的处理类application\example\Notify.php
具体实现
5.1版取消了import()这种引入类方法
所以需要上面用到import()方法的,都要换成require
//Loader::import('alipay.pay.service.AlipayTradeService');
require '../extend/alipay/pay/service/AlipayTradeService.php';
调用:
class Notify extends NotifyHandler
{
protected $params; // 订单信息
public function index()
{
parent::init();
}
public function play()
{
$this->getorder();
$ass = \alipay\Pagepay::pay($this->params);
}
/**
* 获取订单信息, 必须包含订单号和订单金额
*
* @return string $params['out_trade_no'] 商户订单
* @return float $params['total_amount'] 订单金额
*/
public function getOrder()
{
// 以下仅示例
// $out_trade_no = $_POST['out_trade_no'];
// $order = Db::name('order')->where('out_trade_no', $out_trade_no)->find();
$out_trade_no = time().rand(1000,9999);
// $order = arrar(
// 'out_trade_no' = $out_trade_no,
// 'total_amount' = 0.1,
// 'status' = 0,
// 'id' = 1,
// 'subject' = '测试',
// );
$params = [
'out_trade_no' => $out_trade_no,
'total_amount' => 0.1,
'status' => 0,
'id' => 1,
'subject' => '测试'
];
$this->params = $params;
}
/**
* 检查订单状态
*
* @return Boolean true表示已经处理过 false表示未处理过
*/
public function checkOrderStatus()
{
// 以下仅示例
if($this->params['status'] == 0) {
// 表示未处理
return false;
} else {
return true;
}
}
/**
* 业务处理
* @return Boolean true表示业务处理成功 false表示处理失败
*/
public function handle()
{
// 以下仅示例
$result = Db::name('order')->where('id', $this->params['id'])->update(['status'=>1]);
if($result) {
return true;
} else {
return false;
}
}
}
例子:
1、把支付宝文件放到:\extend\alipay\里边
支付宝文件包在这里下载:https://download.csdn.net/download/haibo0668/10558364
2、在TP5.1控制器中代码
assign([
'number' => $number
]);
return $this->fetch();
}
//支付
public function payment()
{
//$params=input('post.');
$this->getOrder();
//\alipay\Pagepay::pay($this->params);//支付宝电脑PC扫码支付
\alipay\Wappay::pay($this->params);//支付宝移动支付
}
/**
* 获取订单信息, 必须包含订单号和订单金额
*
* @return string $params['out_trade_no'] 商户订单
* @return float $params['total_amount'] 订单金额
*/
public function getOrder()
{
$number=input('WIDout_trade_no');//订单号
$title=input('WIDsubject');//订单名称
$price=input('WIDtotal_amount');//总价格 如果购买多个商品,就是多个商品的总价
$state=0;//状态 0未支付 1已支付
$type=4;//支付类型 1=微信扫码 2=微信公众号 3=微信H5支付 4=支付宝PC电脑扫码 5=支付宝移动 6=银联
$type_state=0;//订单类型 0单个购买 1购买多个商品
$data['number']=$number;
$data['title']=$title;
$data['price']=$price;
$data['state']=$state;
$data['type']=$type;
$data['type_state']=$type_state;
//生成订单表
if(!$number || !$price || !$title){
$this->error('错误:订单号、价格、3标题不能为空!',url('index'));
}
$order_rs=db('order')->insert($data);
if($order_rs){
//传递参数到支付宝接口文件中
$params['out_trade_no']=$number;
$params['subject']=$title;
$params['total_amount']=$price;
}else{//生成订单失败 返回错误信息
$this->error('生成订单表失败!',url('index'));
}
$this->params = $params;
}
/* *
* 功能:支付宝页面跳转同步通知页面
* 版本:2.0
* 修改日期:2017-05-01
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*************************页面功能说明*************************
* 该页面可在本机电脑测试
* 可放入HTML等美化页面的代码、商户业务逻辑程序代码
*/
public function return_url()
{
$params=input('get.');
$result = \alipay\Notify::check($params);
//$result = \alipay\Notify::check($this->params);
if($result) {//验证成功
//获取支付成功后支付宝返回的参数
$out_trade_no = htmlspecialchars(input('out_trade_no'));//商户订单号
$total_amount=htmlspecialchars(input('total_amount'));//价格
$app_id=htmlspecialchars(input('app_id'));//应用ID
$trade_no = htmlspecialchars(input('trade_no'));//支付宝交易号
$data['state']=1;
$data['pay_number']=$trade_no;
$data['pay_time']=date("Y-m-d H:i:s",time());
Db::name('order')->where('number', $out_trade_no)->update($data);
echo "支付成功!";
} else {
//验证失败
echo "支付失败3";die;
}
}
/* *
* 功能:支付宝服务器异步通知页面
* 版本:2.0
* 修改日期:2017-05-01
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*************************页面功能说明*************************
* 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
* 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
* 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
* 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;
* 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如:request.Form(“out_trade_no”)、$_POST[‘out_trade_no’];
* 支付宝主动发起通知,该方式才会被启用;
* 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账交易状态为“等待买家付款”的状态默认是不会发送通知的);
* 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;
* 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅会返回同步处理结果,而且服务器异步通知页面也会收到支付宝发来的处理结果通知;
* 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
* 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
* cookies、session等在此页面会失效,即无法获取这些数据;
* 该方式的调试与运行必须在服务器上,即互联网上能访问;
* 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;
* 当商户收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。也就是说在支付宝发送同一条异步通知时(包含商户并未成功打印出success导致支付宝重发数次通知),服务器异步通知参数notify_id是不变的。
*
* 需要严格按照如下描述校验通知数据的正确性。
* 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
* 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
* 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),
* 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
*状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;
*交易状态TRADE_FINISHED的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。
*/
public function notify_url()
{
// //require_once 'config.php';
// //require_once 'pagepay/service/AlipayTradeService.php';
// require '../extend/alipay/pay/service/AlipayTradeService.php';
//
//$params=input('');
// $arr=input('post.');
// $config=alipay_confing();//传入支付宝参数
// $alipaySevice = new AlipayTradeService($config);
// $alipaySevice->writeLog(var_export($_POST,true));
$params=input('post.');
$result = \alipay\Notify::check($params);
//$result = \alipay\Notify::check($this->params);
if($result) {//验证成功
//获取支付成功后支付宝返回的参数
$out_trade_no = htmlspecialchars(input('out_trade_no'));//商户订单号
$total_amount=htmlspecialchars(input('total_amount'));//价格
$app_id=htmlspecialchars(input('app_id'));//应用ID
$trade_no = htmlspecialchars(input('trade_no'));//支付宝交易号
$trade_status = htmlspecialchars(input('trade_status'));//交易状态
$out_biz_no = htmlspecialchars(input('out_biz_no'));//商户业务ID,主要是退款通知中返回退款申请的流水号
$gmt_payment = htmlspecialchars(input('gmt_payment'));//交易付款时间
$buyer_id = htmlspecialchars(input('buyer_id'));//买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字
//判断转跳通知中是否成功记录
$rs=db('order')->where('number', $out_trade_no)->where('pay_number',$trade_no)->find();
if($rs['state']){//state=1 成功记录
$data['pay_time']=$gmt_payment;
$data['pay_biz']=$out_biz_no;
$data['pay_buyer_id']=$buyer_id;
Db::name('order')->where('number', $out_trade_no)->update($data);
echo "success"; //请不要修改或删除
}else{//转跳通知不成功记录 需要重新记录
if($trade_status=="TRADE_SUCCESS" || $trade_status=="TRADE_FINISHED"){//支付成功
$data['state']=1;
//$data['pay_number']=$trade_no;
//$data['pay_time']=date("Y-m-d H:i:s",time());
$data['pay_time']=$gmt_payment;
$data['pay_biz']=$out_biz_no;
$data['pay_buyer_id']=$buyer_id;
Db::name('order')->where('number', $out_trade_no)->update($data);
echo "success"; //请不要修改或删除
}else{
echo "fail";
}
}
}else {
//验证失败
echo "fail";
}
}
}
公共文件的函数
//生成唯一订单号
function generate_order_number(){
return date('YmdHis').rand(100,999);
//return date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
模板:
支付宝电脑网站支付
支付宝电脑网站支付体验入口页
付 款
-
支付宝版权所有 2015-2018 ALIPAY.COM