支付宝电脑网站支付

您所在的位置:网站首页 支付宝电脑版官方登录 支付宝电脑网站支付

支付宝电脑网站支付

#支付宝电脑网站支付| 来源: 网络整理| 查看: 265

前期准备:

1.下载SDK,里面还有Demo,可以参照Demo里面的内容快速接入

支付宝电脑网站支付SDK&Demo

2.把下载的zip文件解压,放到项目目录里,这里作者放在app文件夹里,方便查看

3.因为Laravel框架的原因,文件的入口在/public/index.php这个文件这里,所以所有需要require的文件的路径都要在相应的文件里修改一下,这里作者的路劲修改后举例为:

require_once '../app/AliPay/config.php';

为了方便使用,对部分类文件使用命名空间,这样使用起来目标明确,虽然会额外费点功夫,但作者觉得思路最重要。

因为是支付这块的内容,然后为了区别微信支付还有网银支付,所以命名空间定为:

namespace APP\Pay\Alipay;

4.为了方便日后管理,把一些相关的类文件集中起来放置在一个文件夹里,文件夹名为 qy ,意为为企业支付建立的这个文件夹

qy文件夹内有2个目录:

buildermodel : 存放构造供接口使用的builder

service : 存放相关的接口实现类

这里对部分需要引入命名空间的文件列举一下(目前只做了支付,退款还没做,所以退款涉及的类文件不做举例)

//支付宝电脑网站支付(alipay.trade.page.pay)接口业务参数封装 /app/Alipay/qy/buildermodel/AlipayTradePagePayContentBuilder.php //支付宝电脑网站支付查询接口(alipay.trade.query)接口业务参数封装 /app/Alipay/qy/buildermodel/AlipayTradeQueryContentBuilder.php //支付宝电脑网站支付接口实现类 /app/Alipay/qy/service/AlipayTradeServicePC.php

这里特别要注意,在引入命名空间后,要执行一下composer的自动加载类命令(应该是这个意思)

首先,进入项目的根目录,然后执行下面的命令

composer dump-autoload

这个命令很重要,不然上面引入命名空间的类文件无法被识别

作者就在这里吃了大亏,说到底是对这个框架不熟悉

5.配置支付宝接口需要的基础信息,在/app/Alipay/config.php这个文件里设置,主要为以下几个变量

//应用ID,您的APPID。 'app_ id' => "", //收款支付宝账号 'seller_id' => "", //支付宝公钥 'alipay_public_key' => "", //商户私钥 'merchant_private_key' => "", //异步通知地址,只有扫码支付预下单可用 'notify_url' => 'http://'.$_SERVER['HTTP_HOST']."/Notify/AlipayCallBack", //同步通知地址,个人认为相当于一个跳转回原页面的中间页,好像是可以不设置,会自动跳回员阿里的下单页面 'return_url' => 'http://'.$_SERVER['HTTP_HOST']."/user/check",

开始调用接口

6.前端 - 传递下单的金额,调用后端下单接口,即第7步的接口

//充值按钮绑定事件 $("#btnRecharge").click(function(){ $_money = $("input#money"); var money = $_money.val(); var min = "1"; var msg = ""; if(money==""){ msg = "请填写充值金额"; } if(parseFloat(money)has('money') || floatval($request->money)jsonError('参数错误'); return false; } //付款金额,必填 $money = $request->money; $totalAmount = 0.01; require_once '../app/AliPay/config.php'; //商户订单号,商户网站订单系统中唯一订单号,必填 //这里自己按需要写个方法生成,方便多个地方调用 $outTradeNo = $this->getOutTradeNo(16); //订单名称,必填 $subject = $this->getSubject(); //商品描述,可空 $body = $this->getBody(); //最晚付款时间,逾期将关闭交易 $timeExpress = "5m"; $selleId = $config['seller_id']; //构造参数 $paybuilder = new AlipayTradePagePayContentBuilder(); $paybuilder->setBody($body); $paybuilder->setSubject($subject); $paybuilder->setTotalAmount($totalAmount); $paybuilder->setOutTradeNo($outTradeNo); $paybuilder->setTimeExpress($timeExpress); $aop = new AlipayTradeServicePC($config); /** * pagePay 电脑网站支付请求 * @param $builder 业务参数,使用buildmodel中的对象生成。 * @param $return_url 同步跳转地址,公网可以访问 * @param $notify_url 异步通知地址,公网可以访问 * @return $response 支付宝返回的信息 */ $response = $aop->pagePay($paybuilder,$config['return_url'],$config['notify_url']); //预生成充值订单 - PC端 $remarks = json_encode(Array('app_id'=>Config('recharge.alipayPartner'), 'seller_id'=>$selleId)); $this->addChargeRecord($money, "alipay", $outTradeNo, 0, $remarks); //输出表单 var_dump($response); }

8.后端 - 支付结果异步通知接口 

use APP\Pay\Alipay\AlipayTradeServicePC; public function AliPayCallbackHandler(Request $request){ require_once '../app/AliPay/config.php'; $arr=$request->all(); $alipaySevice = new AlipayTradeServicePC($config); //$alipaySevice->writeLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); if($result) { //商户订单号 $out_trade_no = $arr['out_trade_no']; //支付宝交易号 $trade_no = $arr['trade_no']; //交易状态 $trade_status = $arr['trade_status']; $buyer_id = $arr['buyer_id']; $seller_id = $arr['seller_id']; $app_id = $arr['app_id']; $total_amount = $arr['total_amount']; if($arr['trade_status'] == 'TRADE_FINISHED') { //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 $this->UserCharge($total_amount,'alipay',$out_trade_no, $buyer_id, 2, $seller_id, $app_id); } else if ($arr['trade_status'] == 'TRADE_SUCCESS') { //注意: //付款完成后,支付宝系统发送该交易状态通知 $this->UserCharge($total_amount,'alipay',$out_trade_no, $buyer_id, 1, $seller_id, $app_id); } echo "success"; //请不要修改或删除 }else { //验证失败 echo "fail"; } } /** * [会员充值回调处理,调用UserPayController写好的回调处理接口,与查询接口共用] * @param int $money [订单金额] * @param int $payType [订单类型] * @param int $outTradeNo [商户订单号] * @param int $payAccount [支付账号] * @param int $status [支付状态] */ function UserCharge($money, $payType, $outTradeNo, $payAccount, $status, $seller_id, $app_id){ $UserPayController = new UserPayController(); $UserPayController->UserCharge($money, $payType, $outTradeNo, $payAccount, $status, $seller_id, $app_id); }

9.支付接口、查询接口对应的回调处理

/** * [会员充值回调处理] * @param int $money [订单金额] * @param int $payType [订单类型 weixin|alipay] * @param int $outTradeNo [商户订单号] * @param int $payAccount [支付账号] * @param int $status [支付状态] * @param int $appID [商务ID] * @param int $smId [收款支付宝账号对应的支付宝唯一用户号/微信支付分配的商户号] */ function UserCharge($money, $payType, $outTradeNo, $payAccount, $status, $smId, $appID=null){ //支付类型 判断设置 日志类型 $payLogType = ""; if($payType=="alipay") $payLogType='Alipay'; else if($payType=="weixin") $payLogType='WechatPay'; //防止异步支付通知接口与查询接口同时调用回调处理,使用事务,通知在事务内使用lockForUpdate阻止同时读取修改用户的信息 DB::beginTransaction(); $Function= new Function(); //按照商务订单号获取预充值订单 $record = $Function->getUserChargeRecordByOutTradeNo($outTradeNo); $record = json_decode(json_encode($record),true); $remarks = json_decode($record['remarks'],true); if($record['status']!="0"){ //已经处理过充值回调,直接返回true //防止多次处理 return true; } /* -------------------- 检验 开始 -------------------- */ $msg = ""; $checkResult=1; //检验1:out_trade_no 商务订单号 if($outTradeNo != $record['trade_no']){ $msg = "商务订单号参数错误"; $checkResult = 0; } //检验2:total_amount/total_fee 实际金额 if($checkResult==1 && floatval($money) != floatval($record['money'])){ $msg = "订单金额参数错误"; $checkResult = 0; } //检验3:app_id/appid 商务号ID //支付宝查询订单时未返回这个参数,跳过这个检查 if($checkResult==1 && $appID != null){ if($payType == "alipay" && $appID != $remarks['app_id']){ $msg = "支付宝分配给开发者的应用ID参数错误"; $checkResult = 0; } else if($payType == "weixin" && $appID != $remarks['appid']){ $msg = "微信支付分配的公众账号ID参数错误"; $checkResult = 0; } } //检验4:seller_id/mch_id if($checkResult==1 && $payType == "alipay" && $smId != $remarks['seller_id']){ $msg = "收款支付宝账号参数错误"; $checkResult = 0; } else if($checkResult==1 && $payType == "weixin" && $smId != $remarks['mch_id']){ $msg = "商户号参数错误"; $checkResult = 0; } if($checkResult == 0){ Log::error("用户充值失败,out_trade_no为{$outTradeNo},原因为{$msg}"); $this->writePayLog("用户充值失败,out_trade_no为{$outTradeNo},原因为{$msg}", $payLogType); //更新用户预充值记录信息 $res = ...; if(!$res){ DB::rollback(); Log::error("用户充值失败,更新充值表失,out_trade_no为{$outTradeNo},原因为{$msg}"); $this->writePayLog("用户充值失败,更新充值表失败,out_trade_no为{$outTradeNo},原因为{$msg}", $payLogType); } else{ DB::commit(); Log::info("用户充值失败,更新充值表成功,out_trade_no为{$outTradeNo},原因为{$msg}"); $this->writePayLog("用户充值失败,更新充值表成功,out_trade_no为{$outTradeNo},原因为{$msg}", $payLogType); } return Array('result'=>0,'msg'=>$msg); } /* -------------------- 检验 结束 -------------------- */ //检验通过,开始处理业务流程 //更新充值表 ... //更新用户余额 ... DB::commit(); }

10.实现查询接口,作者在第4步设置的同步通知地址里使用。该地址会传递商务订单号(out_trade_no),使用该参数进行查询轮询

前端  - 调用查询接口

$(function(){ //支付宝轮询充值结果 function queryOrderAliPay() { var out_trade_no = URL.getUrlParam('out_trade_no'); if(out_trade_no==null) return false; load(); //设置每隔500毫秒执行一次load() 方法 轮询订单 var myIntval = setInterval(function () { load() }, 500); function load() { $.ajax({ type: "POST", url: "{{ route( 'filling.queryOrderAliPay')}}", dataType: "json", data: {'_token': '{{csrf_token()}}',out_trade_no:out_trade_no}, success: function (json) { if(json.trade_status == 'TRADE_SUCCESS' || json.trade_status == 'TRADE_FINISHED'){ setTimeout(function(){ window.location.href="..."; //充值成功,跳转回充值页面 clearInterval(myIntval); },500); } } }); } } queryOrderAliPay(); });

后端 - 实现查询功能

//查询支付宝订单 public function queryOrderAliPay(Request $request){ require_once '../app/AliPay/config.php'; //商户订单号,商户网站订单系统中唯一订单号 $out_trade_no = trim($request->out_trade_no); //构造参数 $builder = new AlipayTradeQueryContentBuilder(); $builder->setOutTradeNo($out_trade_no); $aop = new AlipayTradeServicePC($config); //调用支付宝查询接口 $response = $aop->Query($builder); $response = json_decode(json_encode($aop->query($builder)), true); if(array_key_exists("code", $response) && $response['code']==10000){ if($response['trade_status']=="TRADE_SUCCESS" || $response['trade_status']=="TRADE_FINISHED"){ DB::beginTransaction(); $outTradeNo = $response['out_trade_no']; $record = ...; //按商务订单号获取预生成的订单信息 $record = json_decode(json_encode($record),true); if($record['status']==="0"){ Log::info(" 充值后轮询更新用户信息 "); $status = $response['trade_status']=="TRADE_SUCCESS" ? 1 : ($response['trade_status']=="TRADE_FINISHED" ? 2 : 0); $this->UserCharge(floatval($response['total_amount']),'alipay',$outTradeNo,$response['buyer_user_id'],$status,$config['seller_id'],$config['app_id']); } DB::commit(); return json_encode([ 'return_code'=>$response["code"], 'trade_status'=>$response["trade_status"] ],true); } } }

 

后续有时间再做完善这篇文章



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3