model = new OrderModel; parent::_initialize(); //判断登录用户是否是员工 } /** * @ApiTitle( 课程第三方支付) * @ApiSummary(课程第三方支付(微信等支付)) * @ApiRoute(/api/school/pay/payment) * @ApiMethod(POST) * @ApiParams(name = "order_no", type = "string",required=true,description = "订单id或订单号") * @ApiParams(name = "type", type = "string",required=true,description = "服务商:alipay=支付宝,wechat=微信") * @ApiParams(name = "platform", type = "string",required=true,description = "平台:web=PC网页支付,wap=H5手机网页支付,app=APP支付,scan=扫码支付,mp=微信公众号支付,miniapp=微信小程序支付") * @ApiParams(name = "openid", type = "string",required=false,description = "用户openid(非必填)") * @ApiReturn({ * *}) */ public function payment() { $order_no = $this->request->post('order_no/s'); $type = $this->request->post('type/s'); $method = $this->request->post('platform/s'); $openid = $this->request->post('openid/s', ""); $platform = $method; try { //订单支付前校验 $this->model->checkPay($order_no,$type); $order = OrderModel::where('order_no', $order_no)->find(); $amount = $order["totalprice"]; } catch (\Exception $e) { $this->error($e->getMessage()); } if (!$amount || $amount < 0) { $this->error("支付金额必须大于0"); } if (!$type || !in_array($type, ['alipay', 'wechat'])) { $this->error("支付类型不能为空"); } if (in_array($method, ['miniapp', 'mp']) && !$openid) { // 微信公众号,小程序支付,必须有 openid if (isset($openid) && $openid) { // 如果传的有 openid } else { // 没有 openid 默认拿下单人的 openid $oauth = Third::where([ 'user_id' => $order->user_id, 'platform' => $type, 'apptype' => $platform ])->find(); $openid = $oauth ? $oauth->openid : ''; } if (!$openid) { // 缺少 openid $this->error("授权过期,请您重新授权登录"); } } //订单号 $out_trade_no = $order_no; //订单标题 $title = '课程订单['.$out_trade_no."]支付"; //回调链接 $notifyurl = $this->request->root(true) . '/api/school/pay/notifyx/paytype/' . $type. '/platform/' . $method; $returnurl = $this->request->root(true) . '/api/school/pay/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no; $response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid); return $response; } /** * @ApiTitle( 第三方支付支付成功回调) * @ApiSummary(第三方支付成功回调) * @ApiRoute(/api/school/pay/notifyx) * @ApiMethod(GET) * @ApiReturn({ * *}) */ public function notifyx() { $paytype = $this->request->param('paytype'); $platform = $this->request->param('platform'); $pay = Service::checkNotify($paytype); if (!$pay) { return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']); } $payment = $paytype; // 获取回调数据,V3和V2的回调接收不同 $data = Service::isVersionV3() ? $pay->callback() : $pay->verify(); Log::write('notifyx-result:'. json_encode($data)); $out_trade_no = $data['out_trade_no']; $out_refund_no = $data['out_biz_no'] ?? ''; // 判断是否是支付宝退款(支付宝退款成功会通知该接口) if ($paytype == 'alipay' // 支付宝支付 && $data['notify_type'] == 'trade_status_sync' // 同步交易状态 && $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭 && $out_refund_no // 退款单号 ) { // 退款回调 // $this->refundFinish($out_trade_no, $out_refund_no,$platform); return $pay->success()->send(); } // 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应 if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') { // 不是交易成功的通知,直接返回成功 return $pay->success()->send(); } if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) { // 微信交易未成功,返回 false,让微信再次通知 return false; } try { //微信支付V3返回和V2不同 if (Service::isVersionV3() && $paytype === 'wechat') { $data = $data['resource']['ciphertext']; $data['total_fee'] = $data['amount']['total']; } \think\Log::record($data); $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100; $out_trade_no = $data['out_trade_no']; \think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}"); //你可以在此编写订单逻辑 // 支付成功流程 //获取支付金额、订单号 $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100; //你可以在此编写订单逻辑 $order = OrderModel::getNopayOrder($out_trade_no); if (!$order || $order["status"] != '0') { // 订单不存在,或者订单已支付 return $pay->success()->send(); } $notify = [ 'order_no' => $data['out_trade_no'], 'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'], 'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])), 'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'], 'payment_json' => json_encode($data->all()), 'pay_fee' => $pay_fee, 'pay_type' => $payment, // 支付方式 'platform' => $platform, ]; $this->model->paySuccess($order['order_sn'],$notify,$pay_fee,true,true); } catch (Exception $e) { \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error"); } //下面这句必须要执行,且在此之前不能有任何输出 if (Service::isVersionV3()) { return $pay->success()->getBody()->getContents(); } else { return $pay->success()->send(); } } /** * 支付返回,网页支付版本(小程序忽略) */ public function returnx() { $paytype = $this->request->param('paytype'); $out_trade_no = $this->request->param('out_trade_no'); $pay = Service::checkReturn($paytype); if (!$pay) { $this->error('签名错误', ''); } //你可以在这里定义你的提示信息,但切记不可在此编写逻辑 $this->success("请返回网站查看支付结果", addon_url("epay/index/index")); } }