APP(UniAPP) 支付宝支付操作指导 + 遇到的坑(PHP实现)

前言

  • 近期进行 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"}

☞☞☞ >>> 源码下载>>>

☛ 附录

  1. PHP 支付宝退款操作+注意事项
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
//微信充值 //支付接口测试 function balance(url, data) { uni.request({ url: cfg.originUrl + '/wx/mp/js_sig.do', data: { route: url }, method: 'GET', success: (res) => { jweixin.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来 appId: res.data.appId, // 必填,公众号的唯一标识 timestamp: res.data.timestamp, // 必填,生成签名的时间戳 nonceStr: res.data.nonceStr, // 必填,生成签名的随机串 signature: res.data.signature, // 必填,签名 jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表 }); jweixin.ready(function() { uni.request({ url: cfg.originUrl + '/wx/recharge/pay.do', method: 'POST', header: { 'Content-type': "application/x-www-form-urlencoded", }, data: JSON.stringify(data), success: function(res) { alert("下单成功"); alert(JSON.stringify(res)); alert(res.data.order_id); all.globalData.orderId = res.data.order_id; uni.setStorageSync('orderId', res.data.order_id); jweixin.chooseWXPay({ timestamp: res.data.payParams.timeStamp, // 支付签名时间戳 nonceStr: res.data.payParams.nonceStr, // 支付签名随机串 package: res.data.payParams.package, // 接口返回的prepay_id参数 signType: res.data.payParams.signType, // 签名方式 paySign: res.data.payParams.paySign, // 支付签名 success: function(e) { alert("支付成功"); alert(JSON.stringify(e)); // 支付成功后的回调函数 } }); } }) }); jweixin.error(function(res) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 console.log("验证失败!") }); } }) }
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值