支付宝支付
app\common\service\Alipay.php
<?php /** * Created by PhpStorm. * Date: 2020/6/17 * Time: 0:01 */ namespace app\common\service; use app\common\model\LogModel; use think\Request; class Alipay { private $config; public function __construct( $config = [] ) { if( !empty($config) ){ $this->config = $config; }else{ $this->config = config('alipay'); } } //支付宝app支付 public function appPay($param){ $aliset = $this->config; import('alipay.AopClient',EXTEND_PATH); import('alipay.request.AlipayTradeAppPayRequest',EXTEND_PATH); $log=[]; $log['title']='支付宝APP支付'; $log['content']['param']= $param; $aop = new \AopClient(); // new AopClient; $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do"; $aop->appId = $aliset['app_id']; $aop->rsaPrivateKey = $aliset['private_key']; $aop->format = "json"; $aop->charset = "UTF-8"; $aop->signType = "RSA2"; $aop->alipayrsaPublicKey = $aliset['ali_public_key']; //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay $request = new \AlipayTradeAppPayRequest(); //new AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数 $bizcontent = "{\"body\":\"支付宝APP支付\"," . "\"subject\": \"{$param['subject']}\"," . "\"out_trade_no\": \"{$param['out_trade_no']}\"," . "\"timeout_express\": \"30m\"," . "\"total_amount\": \"{$param['total_amount']}\"," . "\"product_code\":\"QUICK_MSECURITY_PAY\"" . "}"; $request->setNotifyUrl($param['notify_url']); $request->setBizContent($bizcontent); //这里和普通的接口调用不同,使用的是sdkExecute $response = $aop->sdkExecute($request); LogModel::add($log); //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题 return $response;//htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。 } }
调用控制器方法
function num_random($length = 6) {
$pool = '0123456789';
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}
protected function makeToken($uid, $money)
{
$k = $uid . md5($money) . $uid;
$k = md5(sha1($k));
return $k;
}
$token = $this->makeToken($model->id, $money);
$data = ['id' => $model->id, 'money' => $money, 'app_token' => $token, 'notify_type' => 'device_notify'];
$data['type'] = 'alipay';
$sign = base64_encode(json_encode($data));
$order = [
'out_trade_no' => $user_info['id'] . time() . num_random(4),
'subject' => '商品支付',
'total_amount' => $money,
'notify_url' => $app_host . 'scan_doctor_app/notify_service/device_notify/' . $sign];
$alipay = new Alipay();
// $this->alipay($order,config('alipay'));
$pay = [];
$pay['pay_info'] = $alipay->appPay($order);
支付回调(微信及支付宝支付通用型回调,处理后续业务逻辑)
支付回调接口的请求格式必须是restful风格的:Route::any(‘/scan_doctor_app/notify_service/device_notify/:sign’, ‘scan_doctor_app/v1.notify_service/device_notify’);
// 成功回调 public function device_notify($sign) { try { //$sign = input('sign'); $log = []; $log['title'] = '支付回调'; $log['content']['request'] = $_REQUEST; $log['content']['msg'] = ''; $log['content']['sign'] = empty($sign) ? '未传参' : $sign; $signData = json_decode(base64_decode($sign), true); $token = $this->makeToken($signData['id'], $signData['money']); $log['content']['signData'] = $signData; if ($token != $signData['app_token']) { throw new Exception('token错误'); } // 获取商品信息 /*$orderModel = DeviceBuy::get(function ($query) use($signData) { $query->where('id', $signData['id']); });*/ $orderModel = DeviceBuy::where('id', $signData['id'])->find(); if (!in_array($orderModel->getData('status'), [0, 1])) { throw new Exception('错误_非待支付'); } $payment_account = ''; //获取医生信息 // $diagDoctorWechatModel = ScanDoctorWechat::where('scan_doctor_id', $orderModel['scan_doctor_id'])->find(); $diagDoctorModel = ScanDoctor::where('id', $orderModel['scan_doctor_id'])->find(); if ($diagDoctorModel) { $payment_account = $diagDoctorModel['name']; } $payment_flow = ''; $out_trade_no = ''; $content = ''; if ($signData['type'] == 'alipay') { $payment_flow = input('trade_no'); $out_trade_no = input('out_trade_no'); $content = json_encode($_REQUEST); $orderModel->pay_type = 2; $orderModel->payment_flow = input('trade_no'); // $alipayRes = $orderModel->save(); // $log['content']['alipayRes'] = $alipayRes; }else{ //微信支付, $input_value = !empty( file_get_contents('php://input') ) ? file_get_contents('php://input') : ''; $curlData = simplexml_load_string($input_value, 'SimpleXMLElement', LIBXML_NOCDATA); $curlData = json_decode(json_encode($curlData), true); $log['content']['input'] = $curlData; // $curlData['wxBackData']['transaction_id']; if( !empty($curlData) ){ $payment_flow = $curlData['transaction_id']; $out_trade_no = $curlData['out_trade_no']; $content = json_encode($curlData); $orderModel->payment_flow = $payment_flow; } } //支付信息记录表 关联DeviceBuy if( !empty($payment_flow) ){ $payment_lsit = PaymentList::where('data_id', $signData['id'])->where('out_trade_no', $out_trade_no)->find(); if( !$payment_lsit ){ $payment_lsit = new PaymentList; //数据库不存在的情况新增数据 $payment_lsit->out_trade_no = $out_trade_no; $payment_lsit->payment_flow = $payment_flow; $payment_lsit->data_id = $signData['id']; $payment_lsit->content = $content; $payment_lsit->type = 1; $payment_lsit->save(); } } $orderModel->payment_account = $payment_account; /*$orderData = DeviceBuy::where('id', $orderModel['id'])->find(); if ($orderData) { $orderData->payment_account = $payment_account; $orderData->save(); }*/ if ($orderModel->scale == 0) { // 不分期 $orderModel->money = $signData['money']; $orderModel->pay = $signData['money']; $orderModel->status = 2; } else { if ($orderModel->getData('status') == 0) { // 付第一期 $orderModel->money = $signData['money']; $orderModel->pay = $signData['money']; $orderModel->status = 1; } else { // 付第二期 if ( empty( $signData['erqi'] ) || $signData['erqi'] != true) { throw new Exception('非二期请求'); } $orderModel->money += $signData['money']; $orderModel->pay += $signData['money']; $orderModel->status = 2; } } $log['content']['DeviceBuyStatus'] = $orderModel->status; $deviceBuyRes = $orderModel->save(); $log['content']['deviceBuyRes'] = $deviceBuyRes; $streamModel = new DeviceStream(); $streamModel->scan_doctor_id = $orderModel->scan_doctor_id; $streamModel->device_buy_id = $orderModel->id; $streamModel->type = 0; $streamModel->money = $signData['money']; $streamModel->content = '购买设备'; $deviceStreamRes = $streamModel->save(); $log['content']['money'] = $signData['money']; $log['content']['deviceStreamRes'] = $deviceStreamRes; //$checkStatusRes = Check::where('order_id',$orderModel->id)->update(['status' => 1]); //$log['content']['check_status_res'] = $checkStatusRes; $log['content']['msg'] = 'success'; LogModel::add($log); $response = \wxpay\Wxpay::success(); return $response; } catch (Exception $e) { $log['content']['msg'] = $e->getMessage(); LogModel::add($log); return errorResponse($e->getMessage()); } } // 生成充值token protected function makeToken($uid, $money) { $k = $uid . md5($money) . $uid; $k = md5(sha1($k)); return $k; }