1、首先注册一个企业支付宝帐号:https://b.alipay.com
2、点击产品管理申请开通APP支付。
3、入驻开放平台开发者:
https://developers.alipay.com/develop/manage
创建移动应用,并且审核通过,创建时需要安卓签名和包名,如下介绍:
安卓应用包名和签名:包名是uniapp打包时填写的包名,需要一致;证书可以使用360加固保制作一个证书文件,参考:如何制作一个APP证书,证书制作好以后,使用这个证书在uniapp重新打包APP,签名需要和uniapp打包时的签名一致。打包好APP以后在手机里安装好,安装好以后,使用安卓签名生成工具获取应用的签名字符串。
签名获取的是MD5去掉冒号的小写签名,如下图:
如果是Gensignature生成的,则是:
如果是Android签名生成工具生成的则是:
4、申请应用并等待应用审核通过,如下图:
申请链接:https://open.alipay.com/develop/manage
注意,申请的时候填写的安卓签名格式如下图:
4.1、应用创建以后,需要绑定,帐号中心-APPID绑定,传送门:https://b.alipay.com/page/account-manage-oc/bind/appIdBindList
4.2、给应用开放能力
5、进行开发设置,这里介绍的是正式环境,如果想先测试,可以使用沙箱测试环境,点击这里。
5.1、设置应用网关,填写主域名即可,这一步会先跳出5.5,用工具生成,然后填写完以后,会提示填写网关,填写好以后保存就可以看到支付宝公钥了。这里千万注意支付宝公钥是在开放平台生成后获得的,不是工具生成时的密钥,工具生成的是应用公钥和应用私钥,很多人把密钥搞错导致对接支付的时候回调报错哦!
5.2、填写授权回调地址,这里其实在程序中会定义,程序中定义的回调地址会覆盖这个,填错应该也没事。
5.3、设置接口加签方式:
5.4、 使用工具生成密钥:应用私钥和应用公钥,选非JAVA模式
5.5、把生成的应用私钥和应用公钥保存好,然后把信息填写进去生成支付宝公钥
5.6、保存后生成支付宝公钥,如果需要使用资金支出的接口,比如退款接口,就要选证书模式。
6、回到fastadmin后台,插件管理,安装好微信支付宝整合插件。
点击配置,选到支付宝配置。
这个插件有一个BUG,不管签名方式选公钥还是公钥证书,保存以后都会自动选中公钥证书,所以这个要注意一下。如果选的是公钥方式,只需要配置应用私钥和支付宝公钥即可。
注意这里还有一个沙箱环境,沙箱环境的网关地址和正式环境是不一样的,有时候配置错误容易在回调的时候报错。
7、下面是uniapp发起支付的代码。
if(this.paytype == 'alipay'){
let that = this;
//请求服务端获取orderInfo
uni.request({
url: that.api_url+'api/pay/pay', //仅为示例,并非真实接口地址。
header: {
// 'X-Auth-Token': 123456, //授权token
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'token':that.token,
},
method:'POST',
data: {
'type':'alipay',
'method':'app',
'order_id':that.order_id,
},
success: (res) => {
if(res.data.code == 1){
that.orderInfo = res.data.data,
console.log(res.data.data);
//发起支付
uni.requestPayment({
provider: 'alipay',
"orderInfo": that.orderInfo,
success: function (res) {
console.log('success:' + JSON.stringify(res));
uni.showToast({
title:'支付成功',
duration: 2000
});
setTimeout(function(){
uni.navigateTo({
url:'/pages/order/list'
})
},2000);
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
uni.showToast({
title:'支付失败',
duration: 2000
});
setTimeout(function(){
uni.navigateTo({
url:'/pages/order/list'
})
},2000);
}
});
}else{
uni.showToast({
title: '请求支付失败1!',
duration: 2000
});
}
},
fail:(err) => {
uni.showToast({
title: '请求支付失败2!',
duration: 2000
});
}
});
}
8、然后是后端代码。参考fastadmin微信支付宝整合插件路径:addons/epay/controller/index.php
8.1、后端支付代码:api目录下api/pay/pay 前端代码请求获得orderinfo,然后发起支付,代码如下:
/**
* 支付
*
* @ApiMethod (POST)
*/
public function pay(){
$user = $this->auth->getUser();
$type = input('type','alipay','htmlspecialchars');
$method = input('method','app','htmlspecialchars');
$order_id = input('order_id',0,'intval');
if(!$order = OrderProjectModel::where(['user_id'=>$user['id'],'id'=>$order_id,'pay_status'=>0])->find()){
$this->error('订单不存在');
}else if (!$type || !in_array($type, ['alipay', 'wechat','moneypay'])) {
$this->error("支付类型不能为空");
}else if(($type == 'moneypay') && ($user['money'] < $order['amount'])){
$this->error("账户余额不足");
}else{
$out_trade_no = 'OrderProject'.$order['id'];
$paytypedata = [
'moneypay' => 0,
'wechat' => 1,
'alipay' => 2
];
//临时改变订单价格
$order['amount'] = 0.01;
//生成支付订单
$payorderdata = [
'out_trade_no' => $out_trade_no,
'user_id' => $user['id'],
'order_id' => $order_id,
'pay_type' => $paytypedata[$type],
'order_price' => $order['amount'],
'total_amount' => $order['amount'],
'createtime' => time(),
];
//如果生成成功
if($payorderid = PayOrderModel::insertGetId($payorderdata)){
switch($type){
//支付宝支付
case 'alipay':
//订单标题
$title = '用户下单:项目订单'.$order['id'];
//回调链接
$notifyurl = $this->request->root(true) . '/addons/epay/index/notifyx/paytype/' . $type;
//$returnurl = $this->request->root(true) . '/addons/epay/index/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
$returnurl = $this->request->root(true);
$response = Service::submitOrder($order['amount'], $out_trade_no, $type, $title, $notifyurl, $returnurl, $method);
$this->success(__('Operation completed'), $response);
break;
//余额支付
case 'moneypay':
//用户扣款
$memo = '下单消费'.$order['amount'].'元';
UserModel::money(($order['amount']*(-1)),$order['user_id'],$memo);
UserMsgModel::insert(['user_id'=>$order['user_id'],'title'=>'用户下单消费','content'=>$memo,'createtime'=>time()]);
PayOrderModel::where('id',$payorderid)->update(['pay_status'=>1]);
OrderProjectModel::where('id',$order['id'])->update(['pay_status'=>1,'status'=>1]);
$this->success(__('Operation completed'), true);
break;
//微信支付
case 'wechat':
break;
}
}else{
$this->error('订单生成出错');
}
}
}
8.2、然后是回调方法,小编把addons/epay/controller/index.php中的notifyx方法复制,放到api/pay/notifyx,结果一直报签名错误,始终找不到原因,最后还是使用插件默认的目录
/addons/epay/index/notifyx/paytype/' . $type;
8.3、就是这个回调目录,插件中epay原本的方法,代码如下:
/**
* 回调函数(正式)
*/
public function notifyx(){
$paytype = $this->request->param('paytype');
$pay = Service::checkNotify($paytype);
if (!$pay) {
return false;
}
$data = $pay->verify();
Log::write('签名正确');
try {
if($paytype == 'alipay'){
$out_trade_no = $data['out_trade_no'];
$total_amount = $data['total_amount'];
$param_status = $data['trade_status'];
//找到对应支付订单
if($payorder = PayOrderModel::where(['out_trade_no'=>$out_trade_no,'pay_status'=>0,'total_amount'=>$total_amount])->find()){
//并且找到对应项目订单
if($order = OrderProjectModel::where(['status'=>0,'user_id'=>$payorder['user_id'],'id'=>$payorder['order_id'],'pay_status'=>0])->find()){
//回调参数,支付成功
if($param_status == 'TRADE_SUCCESS'){
Log::write(123456);
PayOrderModel::where('id',$payorder['id'])->update(['pay_status'=>1]);
OrderProjectModel::where('id',$payorder['order_id'])->update(['status'=>1,'pay_status'=>1]);
}
}
}
}
//你可以在此编写订单逻辑
} catch (Exception $e) {
}
//下面这句必须要执行,且在此之前不能有任何输出
return $pay->success()->send();
}
发表评论 取消回复