记录一下支付宝接入,并非用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='支付宝付款表';
可以用沙箱支付宝客户端测试(安卓)
vue2 Implicit conversion from float int loses precision php8Implicit Mysql8新增用户,mysql8配置权限,mysql8配置,mysql8配置文件 Linux命令,scp,scp命令,Linux复制 git commit git add centos git 搭建FTP,Linux FTP,禁止FTP登录ssh 上传文件,阿里云OSS上传,文件上传到OSS,OSS文件上传,OSS上传 微信支付,微信支付V3,PHP微信支付,微信nativePay支付,微信jsapi支付 微信支付,微信支付V3,PHP微信支付 bootstrap4 modal, lavarel The subversion command line tools are no longer provided by Xcode. 银联支付,tp5.1银联支付 支付宝即时到账,PHP支付宝 system libzip must be upgraded to version >= 0.11 CMake 3.0.2 or higher is required