前期准备:

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)<parseFloat(min)){msg = "充值金额不能小于充值最小金额,请重新填写";}if(msg!=""){$_money.val(money).focus();alert(msg);return false;}var send = {_token:$('meta[name="csrf-token"]').attr('content'),money:money};$.ajax({url : "/user/AlipayOrder",type : "POST",datatype : "json",data : send,success : function(json){//下单成功,直接输出下单结果document.write(json);},error : function(xhr){//...}});
});

7.后端 - 生成支付订单,打印(返回)下单结果(不知道这样子描述是否有误。。)


use APP\Pay\Alipay\AlipayTradeServicePC;
use APP\Pay\Alipay\AlipayTradePagePayContentBuilder;
use APP\Pay\Alipay\AlipayTradeQueryContentBuilder;
use APP\Pay\Alipay\Tool;public function AlipayOrder(Request $request){//检查参数是否正确if(!$request->has('money') || floatval($request->money)<floatval(config('recharge.minRecharge'))){$this->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_idif($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);}}
}

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

Laravel 集成支付宝电脑网站支付相关推荐

  1. Spring Boot集成支付宝电脑网站支付功能

    Spring Boot集成支付宝电脑网站支付功能 接入准备 登录 创建应用 添加能力 生成私钥与公钥 开发设置 沙箱环境 示例Demo的使用与学习 下载Demo 启动项目 参数配置 执行测试 Spri ...

  2. SpringBoot(二)集成支付宝 - 电脑网站支付和查询账单案例

    一.简介 电脑支付常用于电商和后台管理系统的账户充值等场景. 电脑网站支付 文档 电脑网站支付流程图 项目源代码(含数据库):码云Gitee 二.集成步骤 0.创建应用.配置密钥 集成前需要先创建应用 ...

  3. Laravel 集成支付宝手机网站支付

    前期准备: 1.下载SDK,里面还有Demo,可以参照Demo里面的内容快速接入 支付宝 手机网站支付SDK&Demo 2.把下载的zip文件解压,放到项目目录里,这里作者放在app文件夹里, ...

  4. 支付宝开放平台开发助手_支付宝:如何创建和接入支付宝电脑网站支付-新手必备...

    1.登录支付宝 1.打开支付宝官网,以"我是支付宝商家"用户登录 https://www.alipay.com/ 2.进入"产品中心",选择并申请支付类型 2. ...

  5. 支付宝电脑网站支付 demo 启动过程

    接支付的这个需求,想了很久,看了官网总是没有头绪,依旧不知道怎么做,于是把demo下载下来跑一下,由于太菜,弄了一天. 准备工作: 支付宝开发平台登录后注册获取APPID,支付宝公钥,私钥 (http ...

  6. 支付宝-电脑网站支付初长成

    前言 企业制定金额生成微信二维码集成完后,客户需要再集成支付宝,经过差文档及看博客终于实现出来(支付宝生成指定金额二维码,需要在"蚂蚁金服开放平台"注册账号,并且开通"电 ...

  7. 接入支付宝电脑网站支付实现JAVA版

    简介 首先要说明的是个人感觉接入支付宝比微信简单多了,很轻松的,所以同学们不要紧张~ 当然还是老规矩啦,上来肯定的贴上官网地址,因为我这些服务天天在更新,而我的文章是教大家方法,而让你不是照葫芦画瓢 ...

  8. 支付宝电脑网站支付及回调

    官方文档:https://docs.open.alipay.com/270 支付 电脑网站支付的支付接口 alipay.trade.page.pay 调用时序图如下: 调用顺序如下: 商户系统请求支付 ...

  9. 支付宝电脑网站支付(新版)

    前言 继前面几篇文章以后,查看了常用的支付方式,发现还有电脑网站的支付方式,因此,这里稍微整理了一下,其实原理和手机网站支付差不多,只是使用沙箱测试的时候可能会遇到一点小坑. 沙箱采坑 因为在本地测试 ...

最新文章

  1. Embedding external files using [Embed] (转载:学习如何嵌入外部文件)
  2. 如果现在还要设计一个新系统,为什么选择 Kafka 而不是 RabbitMQ?
  3. WPF绘制光滑连续贝塞尔曲线
  4. EMR StarRocks 极速数据湖分析原理解析
  5. hdu 1806 Frequent values 线段树
  6. “618”台前幕后的那些事
  7. python怎么输出数组全部数据_打印numpy数组的全部内容
  8. 如何获取类(接口)的成员
  9. ACDSee技巧 - 1
  10. 「leetcode」454.四数相加II:其实需要哈希的地方都能找到map的身影
  11. 批量修改文件夹及文件用户权限和用户组权限 centos
  12. 蓝牙 - BQB认证测试
  13. 仿秒秒测日历页面和部分功能
  14. 中国黑客传说:游走在黑暗中的精灵
  15. 计算机基础的课程标准,《计算机基础》课程标准
  16. 【编译原理】语言认知之Java、Python、C++快速排序三者运行效率与开发效率比较
  17. 史上最全的Win8快捷键大全
  18. 选择器:id与name
  19. LAMP - 学习/实践
  20. Java中线程是如何实现的

热门文章

  1. 信用卡分期究竟是不是套路?你会选择分期业务吗
  2. 《秘密》卷一:秘密-秘密的发现
  3. 苹果手机PD快充电压电流全程详解
  4. 我爱我家副总裁胡景晖离职:左晖给谢勇一个电话就切割了我
  5. 阿里巴巴干儿子奥哲完成数亿元C轮融资,用低代码让数字化触手可及
  6. python读取pdf内容转word_Python实现PDF转Word
  7. Spring基本概念:IoC,DI,Wiring
  8. 程序员拿到阿里巴巴的offer,却因为工资“低”不想去?狂妄!
  9. bat批量检测HTTP代理是否正常
  10. [数字后端]LVT, RVT, HVT 的区别