记录一下支付宝接入,并非用composer而是用的引入,配置信息放在config/app.php里,当然也可以放在数据库里。
在蚂蚁金服开放平台注册开发者账户,进入沙箱环境配置信息:
支付宝支付分网页支付和WAP支付2种(官方有示例),为方便理解,我分开获取的配置信息,可以放在一个方法里获取,做个判断即可。
以下几个方法是写在common.php(application/common.php)里的,方便调用:
/**
* 支付宝(网页)支付参数
* @author Mr.Lv 3063306168@qq.com
* @return array
*/
function alipay_confing(){
$config['app_id'] = config('app.alipay.app_id');
$config['merchant_private_key'] = config('app.alipay.merchant_private_key');
$config['notify_url'] = getHostDomain().config('app.alipay.notify_url');
$config['return_url'] = getHostDomain().config('app.alipay.return_url');
$config['charset'] = config('app.alipay.charset');
$config['sign_type'] = config('app.alipay.sign_type');
$config['gatewayUrl'] = config('app.alipay.gatewayUrl');
$config['alipay_public_key'] = config('app.alipay.alipay_public_key');
//这里是个大坑,应用的公钥和私钥都是支付宝的RSA工具生成的,并且只把公钥填写给支付宝。
填写之后,【设置应用公钥】之后有个【查看支付宝公钥】,那里面拷贝出来的是支付宝回给你的公钥,和自己应用的公钥是不一样的。
所以不是你生成的那个,而是支付宝回给你的那个。
不然会报:sign check fail: check Sign and Data Fail!JSON also!这个错。
return $config;
}
/**
* 支付宝 电脑网站支付
* @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:获取配置
require Env::get('root_path') .'extend/alipay/AlipayTradePagePay/pagepay/service/AlipayTradeService.php';
$config = alipay_confing();
$aop = new \AlipayTradeService($config);
//step2:加载表单,构造参数
require Env::get('root_path') .'extend/alipay/AlipayTradePagePay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.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);
}
/**
* 读取支付宝(WAP)支付参数
* @author Mr.Lv 3063306168@qq.com
* @return array
*/
function alipay_wapconfing(){
$config['app_id'] = config('app.alipay.app_id');
$config['merchant_private_key'] = config('app.alipay.merchant_private_key');
$config['notify_url'] = getHostDomain().config('app.alipay.wap_notify_url');
$config['return_url'] = getHostDomain().config('app.alipay.wap_return_url');
$config['charset'] = config('app.alipay.charset');
$config['sign_type'] = config('app.alipay.sign_type');
$config['gatewayUrl'] = config('app.alipay.gatewayUrl');
$config['alipay_public_key'] = config('app.alipay.alipay_public_key');
return $config;
}
/**
* 支付宝 手机支付
* @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)
{
//超时时间
$timeout_express = "10m";
//step1:获取配置
require Env::get('root_path') .'extend/alipay/AlipayTradeWapPay/wappay/service/AlipayTradeService.php';
$config = alipay_wapconfing();
$aop = new \AlipayTradeService($config);
//step2:加载表单,构造参数
require Env::get('root_path') .'extend/alipay/AlipayTradeWapPay/wappay/buildermodel/AlipayTradeWapPayContentBuilder.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);
}
/**
* 判断是否手机端(网上找的方法)
* @auhor Mr.Lv 3063306168@qq.com
*/
function checkWap(){
if(isset($_SERVER['HTTP_VIA'])){
// 先检查是否为wap代理,准确度高
if(stristr($_SERVER['HTTP_VIA'],"wap")){
return true;
}
// 检查浏览器是否接受 WML.
elseif(strpos(strtoupper($_SERVER['HTTP_ACCEPT']),"VND.WAP.WML") > 0){
return true;
}
//检查USER_AGENT
elseif(preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])){
return true;
}
else{
return false;
}
}else{
if(preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])){
return true;
}
else{
return false;
}
}
}
然后在控制器里写好业务逻辑之后调用支付宝支付:
//支付宝在线付款
public function alipayWeb(){
$id = input('id');
$row = db('order')->where(['id'=>$id])->find();
if($row){
if(checkWap() === true){
alipayWappay("订单号","订单名称","订单金额","商品描述");
}else{
alipayPagepay("订单号","订单名称","订单金额","商品描述");
}
}else{
exit("订单不存在!");
}
}
支付宝回调方法:
/**
* @function alipayNotifyCallback
* @intro 支付宝回调
* @return string
*/
public function alipayNotifyCallback()
{
alipayNotifyCallBackLog(json_encode($_POST));//这里是记录日志(可选)
require Env::get('root_path') .'extend/alipay/AlipayTradePagePay/pagepay/service/AlipayTradeService.php';
$config = alipay_confing();
$aop = new \AlipayTradeService($config);
$result = $aop->check($_POST);
if($result == 1){
if($_POST['trade_status'] == 'TRADE_SUCCESS' || $_POST['trade_status'] == 'TRADE_FINISHED'){//付款成功
//保存支付宝返回的信息
$alipayData = [];
$alipayData['trade_no'] = $_POST['trade_no'];
$alipayData['app_id'] = $_POST['app_id'];
$alipayData['out_trade_no'] = $_POST['out_trade_no'];
$alipayData['out_biz_no'] = isset($_POST['out_biz_no']) ? $_POST['out_biz_no'] : '';
$alipayData['buyer_id'] = isset($_POST['buyer_id']) ? $_POST['buyer_id'] : '';
$alipayData['seller_id'] = isset($_POST['seller_id']) ? $_POST['seller_id'] : '';
$alipayData['trade_status'] = isset($_POST['trade_status']) ? $_POST['trade_status'] : '';
$alipayData['total_amount'] = isset($_POST['total_amount']) ? $_POST['total_amount'] : '';
$alipayData['receipt_amount'] = isset($_POST['receipt_amount']) ? $_POST['receipt_amount'] : '';
$alipayData['invoice_amount'] = isset($_POST['invoice_amount']) ? $_POST['invoice_amount'] : '';
$alipayData['buyer_pay_amount'] = isset($_POST['buyer_pay_amount']) ? $_POST['buyer_pay_amount'] : '';
$alipayData['point_amount'] = isset($_POST['point_amount']) ? $_POST['point_amount'] : '';
$alipayData['refund_fee'] = isset($_POST['refund_fee']) ? $_POST['refund_fee'] : '';
$alipayData['subject'] = isset($_POST['subject']) ? $_POST['subject'] : '';
$alipayData['body'] = isset($_POST['body']) ? $_POST['body'] : '';
$alipayData['gmt_create'] = isset($_POST['gmt_create']) ? strtotime($_POST['gmt_create']) : '';
$alipayData['gmt_payment'] = isset($_POST['gmt_payment']) ? strtotime($_POST['gmt_payment']) : '';
$alipayData['gmt_refund'] = isset($_POST['gmt_refund']) ? $_POST['gmt_refund'] : '';
$alipayData['gmt_close'] = isset($_POST['gmt_close']) ? $_POST['gmt_close'] : '';
$alipayData['fund_bill_list'] = isset($_POST['fund_bill_list']) ? $_POST['fund_bill_list'] : '';
$alipayData['voucher_detail_list'] = isset($_POST['voucher_detail_list']) ? $_POST['voucher_detail_list'] : '';
$alipayData['passback_params'] = isset($_POST['passback_params']) ? $_POST['passback_params'] : '';
$id = db('alipay_record')->insertGetId($alipayData);
if(!$id){
echo 'fail';
exit();
}
//这里是你的业务逻辑
echo "success";
}else{
//验证失败
echo "fail";
}
}
}
以上是程序方面的逻辑,付款成功之后跳转的页面程序里需判断一下支付是否成功
public function alipayCheckOrder()
{
require Env::get('root_path') .'extend/alipay/AlipayTradePagePay/pagepay/service/AlipayTradeService.php';
$config = alipay_confing();
$aop = new \AlipayTradeService($config);
$result = $aop->check($_GET);
if($result){
echo "支付是成功的";
}else{
echo "支付失败了";
}
}
数据表结构:
--
-- 表的结构 `alipay_record`
--
CREATE TABLE `alipay_record` (
`id` int(11) NOT NULL,
`trade_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付宝交易号',
`app_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '开发者的app_id',
`out_trade_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '商户订单号',
`out_biz_no` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商户业务号',
`buyer_id` varchar(16) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '买家支付宝用户号',
`seller_id` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卖家支付宝用户号',
`trade_status` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '交易状态',
`total_amount` decimal(9,2) DEFAULT NULL COMMENT '订单金额单位为人民币(元)',
`receipt_amount` decimal(9,2) DEFAULT NULL COMMENT '实收金额',
`invoice_amount` decimal(9,2) DEFAULT NULL COMMENT '开票金额',
`buyer_pay_amount` decimal(9,2) DEFAULT NULL COMMENT '付款金额',
`point_amount` decimal(9,2) DEFAULT NULL COMMENT '集分宝金额',
`refund_fee` decimal(9,2) DEFAULT NULL COMMENT '总退款金额',
`subject` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单标题',
`body` text COLLATE utf8mb4_general_ci COMMENT '商品描述 ',
`gmt_create` int(10) DEFAULT NULL COMMENT '交易创建时间',
`gmt_payment` int(10) DEFAULT NULL COMMENT '交易付款时间',
`gmt_refund` int(10) DEFAULT NULL COMMENT '交易退款时间',
`gmt_close` int(10) DEFAULT NULL COMMENT '交易结束时间',
`fund_bill_list` text COLLATE utf8mb4_general_ci COMMENT '支付金额信息',
`voucher_detail_list` text COLLATE utf8mb4_general_ci COMMENT '优惠券信息',
`passback_params` text COLLATE utf8mb4_general_ci COMMENT '回传参数'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='支付宝付款表';
可以用沙箱支付宝客户端测试(安卓)