前言
- 近期进行
Uniapp
的开发学习,最后阶段用到了支付宝支付
,相对移动应用的开发周期和专业复杂度,个人觉得这个前端框架还是很有可取之处的 - 本人在此记录一下,初涉此框架遇到的极有可能入坑的地方,希望道友们引以为鉴 …
指导文档 UniAPP 平台支付流程指导 —— 支付宝 APP支付指导 [文档]
开发框架 : ThinkPHP5.1.2
前端编辑器: HBuilderX
测试手机 : 魅族、iphone7
支付场景: APP-支付宝支付
整理时间: 2019-06-18
☛ 前端代码
- 首先
Uniapp
提供的官方Demo
已经比较全面了,而服务端是需要我们自行编写的,除了前端样式的变动,我用的都是Demo
中给的代码,针对于支付宝支付的使用,截取核心代码如下:
async requestPayment(pay_sn,pay_type,actual_payment,discount_payment) {
var _this = this;
let orderInfo = await this.getOrderPayInfo(pay_sn,pay_type);
//console.log("得到订单信息:"+JSON.stringify(orderInfo));
if(orderInfo.data.status == 0){
uni.showModal({
content: orderInfo.data.message,
showCancel: false
})
return;
}
if (orderInfo.statusCode !== 200) {
uni.showModal({
content: "获得订单信息失败",
showCancel: false
})
return;
}
uni.requestPayment({
provider: pay_type,
orderInfo: orderInfo.data,
success: (e) => {
uni.showToast({
title: "支付成功"
})
},
fail: (e) => {
uni.showModal({
//content: "支付失败,原因为: " + e.errMsg,
content: "抱歉,您的支付不成功",
showCancel: false
})
},
complete: () => {
}
})
},
getOrderPayInfo(pay_sn,pay_type) {
let appid = "";
// #ifdef APP-PLUS
appid = plus.runtime.appid;
// #endif
let url = GLOBAL.DOMAIN_URL+"/api/pay/payment?pay_sn="+pay_sn+"&pay_type="+pay_type;
return new Promise((res) => {
uni.request({
url: url,
success: (result) => {
res(result);
},
fail: (e) => {
res(e);
}
})
})
}
注意: 方法
getOrderPayInfo()
中的请求url
,此为服务端进行处理的地址controller\Payment->payment()
,重中之重 !
☛ 服务端唤醒支付宝代码
- 1 首先是支付宝唤醒操作
以我的代码整合为例,SDK 源码存放于extend
目录,同时注意类的正确引用
- 核心处理代码如下:
/**
* 支付宝 支付订单号
* @param array $waitPayOrderInfo
* @return string
*/
public function aliPay($waitPayOrderInfo = [])
{
$aop = new AopClient();
$aop->gatewayUrl = $this->gatewayUrl;
$aop->appId = $this->appID;
$aop->rsaPrivateKey = $this->rsaPrivateKey;
$aop->alipayrsaPublicKey = $this->alipayrsaPublicKey;
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset = 'utf-8';
$aop->format = 'json';
$ali_body = $waitPayOrderInfo['ali_body'];
$ali_total_amount = $waitPayOrderInfo['pay_amount'];
$ali_out_trade_no = $waitPayOrderInfo['ali_out_trade_no'];
$request = new AlipayTradeAppPayRequest();
$request->setBizContent("{" .
//TODO 商户网站唯一订单号
"\"out_trade_no\":\"$ali_out_trade_no\"," .
"\"total_amount\":\"$ali_total_amount\"," .
//TODO 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body
"\"body\":\"$ali_body\"," .
//TODO 商品的标题/交易标题/订单标题/订单关键字等
"\"subject\":\"瑞生活1314\"," .
"\"product_code\":\"QUICK_MSECURITY_PAY\"," .
//TODO 该笔订单允许的最晚付款时间,逾期将关闭交易
"\"timeout_express\":\"90m\"," .
" }");
//TODO 回调地址的设置,官方文档个人认为有误
$request->setNotifyUrl($this->ali_notify_url);
$result = $aop->sdkExecute($request);
$message = $result;
return $message;
}
建议对比官方文档指导 —— API / 支付API / app支付接口2.0 的PHP代码示例,你可以发现写法的不同
- 注意注意!!! 我就是卡在这里一两天,网上找了N篇文章才解决,强烈差评
//TODO 回调地址的设置,官方文档个人认为有误
$request->setNotifyUrl($this->ali_notify_url);
//注意使用的是 sdkExecute(),认为文档有坑
$result = $aop->sdkExecute($request);
- 再者,对
payment(Request $request)
的处理,要求使用echo $message
,进行数据的输出,不然无法唤醒支付宝
☛ 支付回调处理
-
单纯的前端支付完成,直接进行后续逻辑的更新操作是不符合规范的,个人建议后续的处理要在回调地址内进行编写
核心代码参考:
/**
* 此处进行处理 支付回调操作 ,更新数据库
* @param Request $request
*/
public function aliNotify(Request $request)
{
$out_trade_no = $request->param('out_trade_no', null);
$trade_no = $request->param('trade_no',null);
$total_amount = $request->param('total_amount', '0.00');
$subject = $request->param('subject', 'Null');
$body = $request->param('body', 'Null');
$timestamp = $request->param('timestamp',date("Y-m-d H:i:s"));
$resArr = [
"out_trade_no" => $out_trade_no,
"trade_no" => $trade_no,
"total_amount" => $total_amount,
"subject" => $subject,
"body" => $body,
"timestamp" => $timestamp];
$json_str_notify = json_encode($resArr);
//TODO 此时进行更新操作
if ($out_trade_no){
//以“A” 分割是我对订单号的自定义处理
$order_sn = explode("A",$out_trade_no)[0];
$orderInfoModel = new XorderInfos();
//TODO 将前面的 $json_str_notify 写入订单记录,方便后期退款,并进行业务更新操作
$orderInfoModel->updatePayResultForNotify($order_sn, 1,$json_str_notify);
//echo file_put_contents("ali_pay.txt", $json_str_notify);
}
}
- 存储的
json格式
如下:
{"out_trade_no":"201906109532174488A531178",
"trade_no":"2019061022001445431043252624",
"total_amount":"1.43",
"subject":"\u745e\u751f\u6d3b1314",
"body":"MEDIHEAL \u53ef\u83b1\u4e1d\u7ecf\u5178\u9488\u5242\u6c34\u5e93 \u8865\u6c34\u4fdd\u6e7f\u9762\u819c + \u97e9\u56fdLets diet\u7761\u8863\u516b\u4ef6\u5957",
"timestamp":"2019-06-10 15:14:36"}