支付宝支付需要签约,并有商家号,但是测试环境中,我们可以使用支付宝提供的沙箱环境,在这个后台中进行配置,接通后,可以进行模拟支付。正式开发时,需要到开发者中心创建应用,并选择要使用的功能,以及签约。
框架:ThinkPHP 5.0
演示的支付接口:支付宝电脑网站支付(手机网站支付操作一样)
下载官方 Demo
进入支付宝开放平台,选择文档中心,在选择电脑网站支付,找到 demo 进行下载。下载解压后,将目录名修改为 “AlipayTradePagePay”,由于是手动下载的第三方类库,所以放置到框架的 extend 目录下,如下图:
附功能说明图:
完善配置项
demo 中有个 config.php 文件,我们为了方便,将这个文件中的配置项先复制下来,到 application/extra 目录下,创建名为 alipay.php 配置文件,并将刚复制的配置项放置在这里。extra 目录下是放置扩展配置文件的,完成后效果如下:
application/extra/alipay.php
<?php
return [
//应用ID,您的APPID。
'app_id' => "",
//商户私钥,也就是支付宝开发助手上生成的应用私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "http://zhifu.acier.cn/index/index/notify_url",
//同步跳转
'return_url' => "http://zhifu.acier.cn/index/index/return_url",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关,沙箱环境和正式环境不一样,这里使用沙箱环境
'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "",
];
完善上述配置,打开支付宝沙箱环境页面,在“必看部分”可以看到 APPID ,支付宝网关的信息,然后设置 RSA2(SHA256)密钥,这部分内容和之前写过支付宝第三方登录获取公钥私钥是一样的,首先需要下载“支付宝开放平台开发助手”这个工具,打开工具,选择下图所示选项,然后点击 “生成密钥” 按钮,就生成了应用私钥和应用公钥了。
在沙箱环境的“RSA2(SHA256)密钥”选项处点击“设置/查看”按钮,将应用公钥复制到弹出的框内:
保存设置,然后就能生成支付宝公钥,如下图:
将商户私钥(应用私钥)和支付宝公钥粘贴到配置文件中,notify_url 和 return_url 自己设定。
访问:域名/index/index/index
控制器代码:
<?php
namespace app\index\controller;
class Index
{
public function index()
{
dump(config('alipay'));
}
}
访问后,确保刚配置的信息可以正常打印出来。
创建函数文件
位置:application/index/common.php,内容如下:
<?php
//生成唯一订单号
function build_order_no(){
return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
/**
* 支付宝 电脑网站支付
* @auhor hongweizhiyuan
* @param $out_trade_no 商户订单号
* @param $subject 订单名称
* @param $total_amount 订单金额
* @param $body 商品描述
* @example alipayPagepay('201791711599526','商品标题','0.01','商品描述');
*/
function alipayPagepay($out_trade_no,$subject,$total_amount,$body)
{
//step1:获取配置
import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=config('alipay');
$aop=new AlipayTradeService($config);
//step2:加载表单,构造参数
import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradePagePayContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站支付
$payRequestBuilder = new AlipayTradePagePayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setOutTradeNo($out_trade_no);
//step3:创建支付
$response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
//输出表单
var_dump($response);
}
/**
* 支付宝 电脑网站 交易查询
* @param $WIDTQout_trade_no 商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
* @param $WIDTQtrade_no 支付宝交易号(请二选一设置)
*/
function alipayQuery($WIDTQout_trade_no,$WIDTQtrade_no)
{
//step1:获取配置
import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=config('alipay');
$aop = new AlipayTradeService($config);
//step2:加载表单,构造参数
import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeQueryContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站支付查询接口
$RequestBuilder = new AlipayTradeQueryContentBuilder();
$RequestBuilder->setOutTradeNo($WIDTQout_trade_no);
$RequestBuilder->setTradeNo($WIDTQtrade_no);
/**
* alipay.trade.query (统一收单线下交易查询)
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @return $response 支付宝返回的信息
*/
$response = $aop->Query($RequestBuilder);
var_dump($response);
}
/**
* 支付宝 电脑网站 退款
* @param $out_trade_no 商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
* @param $trade_no 支付宝交易号(请二选一设置)
* @param $refund_amount 需要退款的金额,该金额不能大于订单金额,必填
* @param $refund_reason 退款的原因说明
* @param $out_request_no 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
*/
function alipayRefund($out_trade_no,$trade_no,$refund_amount,$refund_reason,$out_request_no)
{
//step1:获取配置
import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=config('alipay');
$aop = new AlipayTradeService($config);
//step2:加载表单,构造参数
import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeRefundContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站支付退款接口
$RequestBuilder=new AlipayTradeRefundContentBuilder();
$RequestBuilder->setOutTradeNo($out_trade_no);
$RequestBuilder->setTradeNo($trade_no);
$RequestBuilder->setRefundAmount($refund_amount);
$RequestBuilder->setOutRequestNo($out_request_no);
$RequestBuilder->setRefundReason($refund_reason);
/**
* alipay.trade.refund (统一收单交易退款接口)
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @return $response 支付宝返回的信息
*/
$response = $aop->Refund($RequestBuilder);
var_dump($response);;
}
/**
* 支付宝 电脑网站 退款查询
* @param $out_trade_no 商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
* @param $trade_no 支付宝交易号(请二选一设置)
* @param $out_request_no 请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号,必填
*/
function alipayRefundQuery($out_trade_no,$trade_no,$out_request_no)
{
//step1:获取配置
import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=config('alipay');
$aop = new AlipayTradeService($config);
//step2:加载表单,构造参数
import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeFastpayRefundQueryContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站 统一收单交易退款查询
$RequestBuilder=new AlipayTradeFastpayRefundQueryContentBuilder();
$RequestBuilder->setOutTradeNo($out_trade_no);
$RequestBuilder->setTradeNo($trade_no);
$RequestBuilder->setOutRequestNo($out_request_no);
/**
* 退款查询 alipay.trade.fastpay.refund.query (统一收单交易退款查询)
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @return $response 支付宝返回的信息
*/
$response = $aop->refundQuery($RequestBuilder);
var_dump($response);
}
/**
* 支付宝 电脑网站 交易关闭
* @param $out_trade_no 商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
* @param $trade_no 支付宝交易号(请二选一设置)
*/
function alipayClose($out_trade_no,$trade_no)
{
//step1:获取配置
import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=C('ALIPAY_CONFIG');
$aop = new AlipayTradeService($config);
//step2:加载表单,构造参数
import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeCloseContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站 统一收单交易关闭接口
$RequestBuilder=new AlipayTradeCloseContentBuilder();
$RequestBuilder->setOutTradeNo($out_trade_no);
$RequestBuilder->setTradeNo($trade_no);
/**
* alipay.trade.close (统一收单交易关闭接口)
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @return $response 支付宝返回的信息
*/
$response = $aop->Close($RequestBuilder);
var_dump($response);
}
开始使用
本功能官方文档:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay
设置 demo 中 log.txt 权限为 777。
访问:域名/index/index/pagepayTest
方法代码:
public function pagepayTest()
{
alipayPagepay(build_order_no(),'商品标题','666','商品描述');
}
访问后,如果使用 PHP 7.2 版本,会发现有报错。打开框架配置文件 applica/config.php
,开启调试模式和应用Trace,可以看到错误提示:
发现是 each() 这个函数已经废弃了,并且框架把错误的代码也贴出来了。将鼠标放在错误提示上,即可看到错误位置的具体路径:
根据提示,查找到 /extend/AlipayTradePagePay/aop/AopClient.php
这个文件的413行,将:
while (list ($key, $val) = each ($para_temp)) {
替换为:
foreach ($para_temp as $key => $val) {
发现可以正常访问了。若出现以下情况:
可以通过尝试更换浏览器解决。正常情况是可以扫码支付了。
这里不能用我们自己的支付宝扫码支付,需要下载沙箱环境专用的支付宝APP来进行支付,在沙箱应用中有下载地址。
支付后的回调
刚在支付宝配置文件中我们设置了 同步跳转 和 异步通知地址,简单来说,同步跳转 是当用户支付完成后,页面要跳到的地址,使用户能够回到项目中继续其他操作。而 异步通知 是支付后用来处理业务逻辑信息的,例如修改数据库中该件商品的支付状态,减库存等等。
支付后,同步跳转 return_url() 方法会接收到如下参数:
out_trade_no:商户订单号
total_amount:交易金额
trade_no:支付宝交易号
seller_id:收款支付宝账号对应的支付宝唯一用户号
在 demo 中,已经集成了 return_url.php 和 notify_url.php 两个文件,分别对应这两种回调类型,可以参考。
最后再说一下,异步通知中,因为是支付宝主动发送,cookie 和 session 会失效。若支付后,参数 trade_status 有两种值,TRADE_FINISHED 和 TRADE_SUCCESS ,前者是交易完结了,后续不会有其它操作了,如退款。后者仅代表本次交易成功,后续可能会有退款,若没有,三个月后,会再次发送过来 TRADE_FINISHED 值。数据库设计中,应确保有这两个字段。即时到账普通版接口没有退款,高级版有退款。
还有最重要一点,异步通知程序执行完后,一定要打印输出 “success” 这七个字符,否则支付宝服务器会不断重发通知,直到超过24小时22分钟。在25小时内完成6~10次通知(通知频率:5s,2m,10m,15m,1h,2h,6h,15h)。
其他接口,例如订单查询,退款等,都在 common.php 中已经写好,组织好参数调用即可。
手机网站支付
手机网页上使用支付宝支付,需要下载手机网站支付 demo ,下载后使用方式和电脑支付一样,只是载入的类名不一样,配置文件和电脑支付都是一样的,可以共用。同样,这里我们也封装在函数里,下面演示一下:
/**
* 支付宝 手机网站支付
* @auhor hongweizhiyuan
* @param $out_trade_no 商户订单号
* @param $subject 订单名称
* @param $total_amount 订单金额
* @param $body 商品描述
* @example alipayPagepay('201791711599526','商品标题','0.01','商品描述');
*/
function alipayWappay($out_trade_no,$subject,$total_amount,$body)
{
//step1:获取配置
import('AlipayTradeWapPay.wappay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
$config=config('alipay');
$aop=new AlipayTradeService($config);
//超时时间
$timeout_express="1m";
//step2:加载表单,构造参数
import('AlipayTradeWapPay.wappay.buildermodel.AlipayTradeWapPayContentBuilder',EXTEND_PATH,'.php'); // 支付宝电脑网站支付
$payRequestBuilder = new AlipayTradeWapPayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setOutTradeNo($out_trade_no);
$payRequestBuilder->setTimeExpress($timeout_express);
//step3:创建支付
$response = $aop->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']);
//输出表单
var_dump($response);
}
发表评论
沙发空缺中,还不快抢~