搞了两天,踩了一大堆坑,终于对接好支付宝的支付了,下面记录 一下最近对接的心得。
先说效果,我建立了一个控制器,方法pay,传入订单ID,就可以支付这个订单了,回调建立方法,notify_url,有了回调数据,就可以直接将这个订单的状态进行修改。
下面说步骤。
1.要先申请支付宝的商家账号(个人的没试)。申请账号后,填信息实名认证,支付宝会给公户一个小额打款,验证了打款信息之后就可以使用了。这些应该不用详细介绍了,有手都会。
2.申请好支付宝账号之后,开通产品,手机支付,然后建立应用,应用添加手机支付的能力。这里需要网站有备案。这一步也不用详细介绍了,也是有手就会的内容。
3.当应用建立好,开通完支付渠道之后,需要设置应用。
画红框框的,需要填写
接口加密方式:选择秘钥,然后下载一个秘钥生成工具。设置好之后会给出两个公钥,一个是支付宝公钥,一个是应用公钥。
私钥与公钥都要保存好。
支付宝网关地址,不用管,默认的。
应用网关地址,填你的域名就行,需要带http(s)😕/
回调地址,需要你的回调方法的地址,比如http://www.csdn.net/notify_url
填写完毕之后就不用管这里了,这里的设置保持不变就行
4.现在你需要检测一下,是否能使用。支付宝有一个自助配置项检测工具。
https://open.alipay.com/api/check?examCode=E000001559
登录支付宝之后可以检查你的配置是否正确
这是我的检测,公钥整数与公钥,配置一个就可以。
5.上面的步骤全部弄完了之后,可以开始写代码啦。
当然啦,当代程序员写是不可能写的,这辈子都不可能写代码的,只能ctrl+c和ctrl+v。
支付宝准备了一个demo,下载这个demo就可以啦。
https://opendocs.alipay.com/common/02kkv5
下载php的(这句好像是废话)
这是下载的东西。
aop打包,传到extend里面。
在wappay里面,找到buildermodel文件夹,找到里面的AlipayTradeWapPayContentBuilder.php,复制到aop文件夹中
打开这个文件,给他一个namespace
namespace aop;
然后打开wappay\service,找到AlipayTradeService.php
同样把他放到aop中,打开这个文件,把引入删掉,加个namespace
namespace aop;
use aop\request\AlipayTradeWapPayRequest;
AlipayTradeWapPayRequest在aop/request中,找到这个文件,然后给个namespace
namespace aop\request;
这时候aop文件夹基本就不需要动了
对了,还有个地方需要改一下。
AopClient.php,这个打开,首先还是要给一个namespace,代码不贴了,跟上面一样,namespace aop;
然后找到第410行的这段代码
protected function buildRequestForm($para_temp) {
$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->gatewayUrl."?charset=".trim($this->postCharset)."' method='POST'>";
while (list ($key, $val) = each ($para_temp)) {
if (false === $this->checkEmpty($val)) {
//$val = $this->characet($val, $this->postCharset);
$val = str_replace("'","'",$val);
//$val = str_replace("\"",""",$val);
$sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
}
}
//submit按钮控件请不要含有name属性
$sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>";
$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
return $sHtml;
}
看到这个了吗
while (list ($key, $val) = each ($para_temp))
这个在7.2之后的php中会报错,所以把他修改成
foreach ($para_temp as $key=>$val)
这样就没问题了。
现在需要建立一个控制器,我取名叫alipay,里面整两个方法,一个回调,一个支付。
//这个方法需要传入一个订单的ID
public function pay($id)
{
//找到这个订单
$order=Db::name('order')->find($id);
//我建立的订单表中,iid表示商品的id,这里我通过iid找到这个商品
$goods=Db::name('goods')->find($order['iid']);
$config=[
//应用ID,您的APPID。
'app_id' => "这里是你的appid",
//商户私钥,您的原始格式RSA私钥
'merchant_private_key' => "这里填你的私钥",
//异步通知地址
'notify_url' => "这里是你接收通知的地址",
//同步跳转
'return_url' => "这里是当用户支付完成之后,需要跳转的地址",
//编码格式
'charset' => "UTF-8",
//签名方式(在你生成秘钥的时候,选择的加密方式)
'sign_type' => "RSA2",
//支付宝网关(这个是默认的,不用管它)
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "这里填你的公钥,注意是支付宝公钥",
//日志路径
'log_path' => "",
];
//超时时间
$timeout_express="1m";
//注意,这里有new,记得引入
$payRequestBuilder = new AlipayTradeWapPayContentBuilder();
//这个是商品的简单描述
$payRequestBuilder->setBody($goods['desc']);
//这个是商品的名称
$payRequestBuilder->setSubject($goods['title']);
//这个是订单号,要唯一的才行,如果支付过这个订单号,再打开支付宝进行支付就会显示已支付
$payRequestBuilder->setOutTradeNo($order['order_num']);
//这个是需要支付的金额,我在这里踩了一个坑,金额设置成了小数点保留4位,结果总是提示参数错误,但检查很久都没发现有错误
//最后在支付宝问答区的一个犄角旮旯里发现,金额只能设置小数点后两位
$payRequestBuilder->setTotalAmount($order['money']);
//这个是超时时间
$payRequestBuilder->setTimeExpress($timeout_express);
//这里有new,记得引入
$payResponse = new AlipayTradeService($config);
$payResponse->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']);
return ;
}
直接抄作业就行,执行这个方法,会自动跳转到支付宝支付
回调的方法
public function notify_url(){
$config=[
//应用ID,您的APPID。
'app_id' => "这里是你的appid",
//商户私钥,您的原始格式RSA私钥
'merchant_private_key' => "这里填你的私钥",
//异步通知地址
'notify_url' => "这里是你接收通知的地址",
//同步跳转
'return_url' => "这里是当用户支付完成之后,需要跳转的地址",
//编码格式
'charset' => "UTF-8",
//签名方式(在你生成秘钥的时候,选择的加密方式)
'sign_type' => "RSA2",
//支付宝网关(这个是默认的,不用管它)
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "这里填你的公钥,注意是支付宝公钥",
//日志路径
'log_path' => "",
];
//哈哈,被你发现了,我就是直接复制粘贴的上面那段
//这里有new 记得引入
$aop = new AopClient();
//不要较真为啥写字符串,因为这些代码也是我直接抄的
$aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
$aop->appId = $config['app_id'];
$aop->method = 'alipay.trade.wap.pay';
$aop->charset = 'utf-8';
$aop->signType = 'RSA2';
$aop->alipayrsaPublicKey = $config['alipay_public_key'];
$aop->rsaPrivateKey = $config['merchant_private_key'];
//使用rsaCheckV1方法检验回调数据是否合法,最后的返回值是一个布尔值
//按照我的直接写就行,中间的参数,它要的是公钥的路径,但是我再上面给公钥设置了值,所以直接填空就行,他就会找字符串的公钥
$check=$aop->rsaCheckV1($_POST,'',$_POST['sign_type']);
//这里判断一下$check
if($check){
//返回值里面$_POST['trade_status']是支付结果的信息,我给贴下面了,可以根据自己需求设置回调值
if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
//我这里设置的是,如果返回值是支付成功,那么就把这个订单状态给改成6
//out_trade_no这个是返回的订单号
Db::name('order')->where(['order_num'=>$_POST['out_trade_no']])->save(['status'=>6]);
//注意,一定要echo 一个success,因为支付宝没有在页面看到success的话,还会继续发回调信息
echo 'success';
}
}
}
https://opendocs.alipay.com/open/203/105286?ref=api
上面这个地址是异步回调的具体消息内容
这个是具体的交易状态的参数
OK,基本就这些了,拿着抄作业吧