mini_id = get_mini_id(); $this->store_id = $store_id = $store_id ?: get_store_id(); if (\Yii::$app->prod_is_dandianpu() && !Store::hasIncoming($store_id) && self_mini() === false) { $alipay_config = Json::decode(Option::get('one_store_alipay_config', 0, 'saas', '')['value']); } else { $config_cache = \Yii::$app->cache->get('alipay_config_cache_' . $store_id); if ($config_cache) { $alipay_config = Json::decode($config_cache); } else { $alipay_config = Json::decode(Option::get(Option::OPTOPN_KEY, $store_id, 'alipay')['value']); } } $config = [ 'app_id' => $alipay_config['app_id'], 'notify_url' => pay_notify_url(self::$notify_url), 'return_url' => $return_url, 'private_key' => $alipay_config['app_private_key'], 'log' => [ // optional 'file' => \Yii::$app->basePath . '/runtime/logs/alipay.log', 'level' => 'debug', // 建议生产环境等级调整为 info,开发环境为 debug 'type' => 'single', // optional, 可选 daily. 'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天 ], 'ali_public_key' => $alipay_config['alipay_public_key'] // 'app_cert_public_key' => \Yii::$app->basePath. '/utils/Alipay/CRT/app_cert_public_key.crt', // 应用公钥证书路径 // 'ali_public_key' => \Yii::$app->basePath. '/utils/Alipay/CRT/alipay_cert_public_key.crt', // 支付宝公钥证书路径 // 'alipay_root_cert' => \Yii::$app->basePath. '/utils/Alipay/CRT/alipay_root_cert.crt', // 支付宝根证书路径 // 'mode' => 'dev' // optional,设置此参数,将进入沙箱模式 ]; if ($type) { $key = Option::ALIPAY_CONFIG_CERT; if (\Yii::$app->prod_is_dandianpu() && is_h5()){ $key = OptionSetting::ALIPAY_PAY_DANDIANPUH5; if(!Store::hasIncoming($store_id, 'alipay', is_h5())){ $store_id = 0; } } $config_cache = Option::get($key, $store_id, 'alipay')['value']; $config_cache = json_decode($config_cache, true); if (!empty($config_cache)) { $config = [ 'app_id' => $config_cache['app_id'], 'notify_url' => pay_notify_url(self::$notify_url), 'return_url' => $return_url, 'log' => [ // optional 'file' => \Yii::$app->basePath . '/runtime/logs/alipay.log', 'level' => 'debug', // 建议生产环境等级调整为 info,开发环境为 debug 'type' => 'single', // optional, 可选 daily. 'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天 ], 'private_key' => $config_cache['app_private_key'], 'app_cert_public_key' => $this->saveTempImage($config_cache['app_public_cert']), // 应用公钥证书路径 'ali_public_key' => $this->saveTempImage($config_cache['alipay_public_cert']), // 支付宝公钥证书路径 'alipay_root_cert' => $this->saveTempImage($config_cache['alipay_root_cert']), // 支付宝根证书路径 ]; } } self::$alipay = Pay::alipay($config); self::$alipay_conf = $config; } /** * 静态方法调用construct方法 * @param $return_url */ public static function init($return_url = '', $type = 0, $store_id = 0) { return new self($return_url, $type, $store_id); } //获取网络图片到临时目录 public function saveTempImage($url) { if (strpos($url, 'http') === false) { $url = 'http:' . trim($url); } if (!is_dir(\Yii::$app->runtimePath . '/crt')) { mkdir(\Yii::$app->runtimePath . '/crt'); } $save_path = \Yii::$app->runtimePath . '/crt/' . md5($url) . '.crt'; CurlHelper::download($url, $save_path); return $save_path; } /** * app支付 * @param $order * @param User $user * @param $subject * @param $balance_price * @param $return_url * @return Response | false | string | array */ public static function app($order, $subject, $user, $type = '', $total_pay_price = 0,$balance_price = 0, $return_url = '') { self::init($return_url, 1); $order1 = $order; if($type === OrderNo::ORDER_UNION){ $order = [ 'body' => '订单合并支付', 'out_trade_no' => OrderNo::getOrderNo(OrderNo::ORDER_UNION), 'total_amount' => $balance_price > 0 ? $total_pay_price - $balance_price : $total_pay_price, 'subject' => count($order1) . '笔订单合并支付', ]; $order_union = new OrderUnion(); $order_union->store_id = get_store_id(); $order_union->user_id = get_user()->id; $order_union->order_no = $order['out_trade_no']; $order_union->price = $order['total_amount']; $order_union->is_pay = 0; $order_union->created_at = time(); $order_union->is_delete = 0; $order_id_list = []; foreach ($order1 as $value) { $order_id_list[] = $value->id; } $order_union->order_id_list = json_encode($order_id_list); if (!$order_union->save()) { foreach ($order_union->errors as $error) { return [ 'code' => 1, 'msg' => $error ]; } } }else{ /** 逻辑开始 **/ $order = [ 'body' => $subject, 'out_trade_no' => $order->order_no, 'total_amount' => $balance_price > 0 ? ($order->pay_price - $balance_price) : $order->pay_price, 'subject' => $subject ]; } try { $res = self::$alipay->app($order)->getContent(); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } if($type === OrderNo::ORDER_UNION){ foreach($order1 as $value){ $value->order_union_id = $order_union->id; $value->save(); } } return [ 'code' => 0, 'msg' => 'success', 'data' => $res, 'res' => $res ]; } /** * 订单查询 * @param $order * @param $type 默认:wap: 普通订单,refund:退款订单,transfer: 转账订单 * @return array | Collection */ public static function find($order, $type = 'wap') { if (!in_array($type, self::$validFlag)) { return [ 'code' => 1, 'msg' => 'Params are wrong' ]; } self::init(); /** 逻辑开始 **/ $order = [ 'out_trade_no' => $order->order_no, ]; if ($type == self::FLAG_REFUND) { // 后端生成,唯一即可 $order['out_request_no'] = $order->order_no; } try { $res = self::$alipay->find($order, $type); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * wap支付 * @param $order * @param $subject * @param $return_url * @return array */ public static function wap($order, $subject, $return_url = '', $type = '', $total_pay_price = 0, $balance_price = 0, $payData = []) { if(!$return_url){ $return_url = pay_return_url(self::$h5_url); } self::init($return_url, 1); $order1 = $order; if($type == OrderNo::ORDER_UNION){ $order = [ 'body' => '订单合并支付', 'out_trade_no' => OrderNo::getOrderNo(OrderNo::ORDER_UNION), 'total_amount' => $balance_price > 0 ? $total_pay_price - $balance_price : $total_pay_price, 'subject' => count($order1) . '笔订单合并支付', 'buyer_id' => get_user()->alipay_open_id ]; $order_union = new OrderUnion(); $order_union->store_id = get_store_id(); $order_union->user_id = get_user()->id; $order_union->order_no = $order['out_trade_no']; $order_union->price = $order['total_amount']; $order_union->is_pay = 0; $order_union->created_at = time(); $order_union->is_delete = 0; $order_id_list = []; foreach ($order1 as $value) { $order_id_list[] = $value->id; } $order_union->order_id_list = json_encode($order_id_list); if (!$order_union->save()) { foreach ($order_union->errors as $error) { return [ 'code' => 1, 'msg' => $error ]; } } }else{ /** 逻辑开始 **/ $order = [ 'body' => $subject, 'out_trade_no' => $order->order_no, 'total_amount' => $order->pay_price, 'subject' => $subject, 'buyer_id' => get_user()->alipay_open_id ]; } try { $res = self::$alipay->wap($order); if ($res->getStatusCode() == 40004 || $res->getStatusCode() == 'ACQ.CONTEXT_INCONSISTENT') { $order->order_no = OrderNo::getOrderNo(OrderNo::ORDER_MALL); $order->save(); return self::wap($order, $subject, $return_url, $type, $total_pay_price, $balance_price, $payData); } if($type == OrderNo::ORDER_UNION){ foreach($order1 as $value){ $value->order_union_id = $order_union->id; $value->save(); } } return [ 'code' => 0, 'msg' => 'success', 'data' => $res->getContent() ]; } catch (\Exception $e) { return [ 'code' => 1, 'msg' => '支付失败'. $e->getMessage() ]; } } /** * web支付 * @param $order * @param $subject * @param $return_url * @return Response | false | string */ public static function web($order, $subject, $return_url = '') { self::init($return_url); /** 逻辑开始 **/ $order = [ 'body' => $subject, 'out_trade_no' => $order->order_no, 'total_amount' => $order->pay_price, 'subject' => $subject, ]; $res = self::$alipay->web($order)->send(); return $res->getContent(); } /** * 扫码支付 * @param $order * @param $subject * @param $return_url * @return Collection | array */ public static function scan($order, $subject, $return_url = '', $user_id = null) { self::init($return_url); /** 逻辑开始 **/ $order = [ 'body' => $subject, 'out_trade_no' => $order->order_no, 'total_amount' => $order->pay_price, 'subject' => $subject, 'buyer_id' => $user_id ]; try { $res = self::$alipay->mini($order); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 扫码支付 * @param $order * @param $subject 订单标题 * @param $return_url * @return Collection | array */ public static function scanNew($order, $subject, $return_url = '', $auth_code,$total_pay_price = 0,$balance_price = 0) { self::init($return_url); /** 逻辑开始 **/ $order = [ 'out_trade_no' => $order->order_no,//订单号 'total_amount' => $balance_price > 0 ? $total_pay_price - $balance_price : $total_pay_price, 'subject' => $subject,// 订单标题 'auth_code' => $auth_code, 'scene' => 'bar_code', ]; try { $res = self::$alipay->pos($order); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 转账 * @param $order * @param $mail * @param $return_url * @return Collection | array */ public static function transfer($order, $mail, $return_url = '') { if (empty($mail)) { return [ 'code' => 1, 'msg' => 'Params are wrong' ]; } self::init($return_url, 1); /** 逻辑开始 **/ $order = [ 'out_biz_no' => $order->order_no, 'trans_amount' => floatval(sprintf("%.2f", $order->pay_price)), 'biz_scene' => 'DIRECT_TRANSFER', 'product_code' => 'TRANS_ACCOUNT_NO_PWD', 'order_title' => '佣金提现', 'payee_info' => [ 'identity' => $mail, 'identity_type' => 'ALIPAY_LOGON_ID', 'name' => $order->name ], ]; try { $res = self::$alipay->transfer($order); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 批量转账 * @param $params * @return Collection | array */ public static function batchTransfer($params) { self::init(''); /** 逻辑开始 **/ $order = [ 'out_batch_no' => $params['out_batch_no'], 'product_code' => 'BATCH_API_TO_ACC_NO_PWD', 'biz_scene' => 'MESSAGE_BATCH_PAY', 'total_trans_amount' => $params['total_trans_amount'], 'total_count' => 1, 'trans_order_list' => [ [ 'out_biz_no' => $params['out_batch_no'], 'trans_amount' => $params['total_trans_amount'], 'payee_info' => [ 'identity' => $params['account'], 'identity_type' => 'ALIPAY_LOGON_ID', 'name' => $params['name'] ], 'remark' => $params['title'] ], ], 'order_title' => $params['title'], 'remark' => '转账', ]; try { $res = self::$alipay->batchtransfer($order); \Yii::error($res); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 退款 * @param $order * @param $return_url * @param $refund_fee * @return Collection | array */ public static function refund($order, $refund_fee, $return_url = '') { self::init($return_url, 1); /** 逻辑开始 **/ $data = [ 'out_trade_no' => $order->order_no, 'refund_amount' => $refund_fee, ]; try { $res = self::$alipay->refund($data); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 小程序支付 * @param $order * @param $subject * @param User $user * @param $return_url * @param $is_food * @return Collection | array */ public static function mini($order, $subject, $user, $return_url = '', $type = '', $total_pay_price = 0, $balance_price = 0, $payData = []) { $self = self::init($return_url); if (!$order || ($type != OrderNo::ORDER_UNION && empty($subject)) || !$user) { return [ 'code' => 1, 'msg' => '参数有误' ]; } $order1 = $order; if ($type == OrderNo::ORDER_UNION) { $order = [ 'body' => '订单合并支付', 'out_trade_no' => OrderNo::getOrderNo(OrderNo::ORDER_UNION), 'total_amount' => $balance_price > 0 ? $total_pay_price - $balance_price : $total_pay_price, 'subject' => count($order1) . '笔订单合并支付', 'buyer_id' => ($user->alipay_open_id ?? $user->ali_user_id) ]; $order_union = new OrderUnion(); $order_union->store_id = get_store_id(); $order_union->user_id = get_user()->id; $order_union->order_no = $order['out_trade_no']; $order_union->price = $order['total_amount']; $order_union->is_pay = 0; $order_union->created_at = time(); $order_union->is_delete = 0; $order_id_list = []; foreach ($order1 as $value) { $order_id_list[] = $value->id; } $order_union->order_id_list = json_encode($order_id_list); if (!$order_union->save()) { foreach ($order_union->errors as $error) { return [ 'code' => 1, 'msg' => $error ]; } } } else { try{ $goods_detail = []; $details = OrderDetail::findAll(['order_id' => $order->id]); foreach ($details as $detail) { $goods = Goods::findOne($detail->goods_id); $goods_detail[] = [ 'goods_id' => $goods->goods_no , 'goods_name' => $detail->goods_name, 'quantity' => $detail->num, 'price' => $detail->total_price / $detail->num, ]; } } catch (\Exception $e) { \Yii::error([__METHOD__, $order, $e]); } $order = [ 'body' => $subject, 'out_trade_no' => $order->order_no, 'total_amount' => $balance_price > 0 ? ($order->pay_price - $balance_price) : $order->pay_price, 'subject' => $subject, 'buyer_id' => ($user->alipay_open_id ?? $user->ali_user_id) ]; $goods_detail && $order['goods_detail'] = $goods_detail; } try { if($payData->ali_requireOrder && $payData->ali_sourceId){ $form = new \app\modules\admin\models\AlipayThirdForm(); $form->store_id = $self->store_id; $form->mini_id = $self->mini_id; $openOrder = $form->AlipayOpenMiniOrderCreate($order1, $order, $payData); if($openOrder['code'] != 0){ return $openOrder; } $order['extend_params'] = [ 'trade_component_order_id' => $openOrder['data'], ]; foreach($openOrder['biz_content']['order_detail']['item_infos'] as $item){ $order['goods_detail'][] = [ 'goods_id' => $item['goods_id'], 'goods_name' => $item['goods_name'], 'quantity' => $item['item_cnt'], 'price' => $item['sale_price'], 'out_item_id' => $item['out_item_id'], 'out_sku_id' => $item['out_sku_id'], ]; } } $order['product_code'] = 'JSAPI_PAY'; $res = self::$alipay->mini($order); if ($res && $res->code === '10000' && $res->msg === 'Success') { return [ 'code' => 0, 'msg' => 'success', 'data' => $res->toArray() ]; } if ($type == OrderNo::ORDER_UNION) { foreach ($order1 as $value) { $value->order_union_id = $value->id; $value->save(); } } return [ 'code' => $res->code, 'msg' => $res->msg, ]; } catch (GatewayException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidSignException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (InvalidConfigException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } }