order,OrderNo::ORDER_ALLIANCE, $goods_names, 0, false, $balance_price); if ($is_app) { $from_type = WechatConfig::TYPE_CONFIG_APP; } else if ($is_official) { $from_type = WechatConfig::TYPE_CONFIG_MP; } else { $from_type = WechatConfig::TYPE_CONFIG_MINI; } try { //parent::init($order->store_id, $order->is_platform, 0, $from_type); parent::initBusiness($from_type); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } if (!$order || !in_array($type, OrderNo::$validOrderType) || ($type != OrderNo::ORDER_UNION && !$goods_names)) { return [ 'code' => 1, 'msg' => '订单信息或订单类型错误' ]; } $store_wechat = WechatConfig::find()->where([ 'and', ['store_id' => $order->store_id], [ '>', 'mch_id', 0 ] ])->one(); if ($is_app) { $open_id = ''; } else { if(get_saas_user()){ $open_id = get_saas_user()->platform_open_id; }else{ $access_token = input_params('access_token'); $saas_user = SaasUser::find()->where(['access_token' => $access_token])->one(); $open_id = $saas_user->platform_open_id; } } $pay_price = $order->pay_price; // if ($type != OrderNo::ORDER_RECHARGE) { // if (isset($order->is_delivery) && $order->is_delivery == 1) { // $deliveryInfo = DeliveryInfo::find()->where(['order_no' => $order->order_no])->one(); // if ($deliveryInfo) { // $pay_price += $deliveryInfo->fee; // } // } // } $config = [ 'body' => $goods_names, 'out_trade_no' => $order->order_no, 'total_fee' => $balance_price > 0 ? floatval($pay_price - $balance_price) * 100 : $pay_price * 100, 'notify_url' => self::pay_alliance_notify_url(self::$notify_url,$order->store_id), 'sub_openid' => $open_id, 'sub_mch_id' => $store_wechat->mch_id ]; if ($is_app) { unset($config['openid']); $config['trade_type'] = 'APP'; } else { $config['trade_type'] = 'JSAPI'; } // 判断是否走服务商支付 $keys = [ 'platform_appid' ]; //商盟走分账 if (is_profit_sharing()) { $config['profit_sharing'] = 'Y'; } // $wechatPay = \Yii::$app->controller->wechatPay ?? null; $wechatPay = self::$wechat_pay; if (!$wechatPay) { return [ 'code' => 1, 'msg' => '登录异常' ]; } try { $res = $wechatPay->order->unify($config); \Yii::error($res); } catch (GuzzleException $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } if (!$res) { return [ 'code' => 1, 'msg' => '支付失败', ]; } if ($res['return_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '支付失败,' . (isset($res['return_msg']) ? $res['return_msg'] : ''), 'res' => $res, ]; } if ($res['result_code'] != 'SUCCESS') { if ($res['err_code'] == 'INVALID_REQUEST') { //商户订单号重复 $order->order_no = OrderNo::getOrderNo($type); $order->save(); if ($type != OrderNo::ORDER_UNION) { if ($is_app) { return self::orderUnify($order, $type, $goods_names, 0, true, $balance_price); } else if ($is_h5) { return self::orderUnify($order, $type, $goods_names, 0, false, $balance_price, true); } else if ($is_official) { return self::orderUnify($order, $type, $goods_names, 0, false, $balance_price, false, true); } else { return self::orderUnify($order, $type, $goods_names, 0, false, $balance_price); } } if ($is_app) { return self::orderUnify($order, $type, '', $total_pay_price, true, $balance_price); } else if ($is_h5) { return self::orderUnify($order, $type, '', $total_pay_price, false, $balance_price, true); } else if ($is_official) { return self::orderUnify($order, $type, '', $total_pay_price, false, $balance_price, false, true); } else { return self::orderUnify($order, $type, '', $total_pay_price, false, $balance_price); } } else { return [ 'code' => 1, 'msg' => '支付失败,' . (isset($res['err_code_des']) ? $res['err_code_des'] : ''), 'res' => $res, ]; } } if ($is_app) { $pay_data = $wechatPay->jssdk->appConfig($res['prepay_id'], false); } else { $pay_data = $wechatPay->jssdk->bridgeConfig($res['prepay_id'], false); } $return = [ 'code' => 0, 'msg' => 'success', 'res' => $res, 'data' => $pay_data ]; if ($type == OrderNo::ORDER_UNION) { foreach ($order as $value) { $value->order_union_id = $value->id; $value->save(); } $return['order_no'] = $config['out_trade_no']; $return['body'] = $config['body']; } if ($is_h5) { $return['res']['mweb_url'] = $return['res']['mweb_url'] . '&redirect_url=' . \Yii::$app->request->hostInfo . '/h5/#/order/order/order'; } return $return; } public static function pay_alliance_notify_url($suffix,$store_id) { $hostInfo = \Yii::$app->request->hostInfo; if (\Yii::$app->request->getIsSecureConnection()) { $hostInfo = str_replace('http:', 'https:', $hostInfo); } else { $hostInfo = str_replace('https:', 'http:', $hostInfo); } $hostInfo .= '/index.php/' . $suffix . '/' . $store_id; return $hostInfo; } /** * 退款 * @param Object $order * @param string $orderRefundNo * @param string $type * @param integer $refundFee * @param $refund_account * @return array */ public static function orderRefund($order, $type, $refundFee, $orderRefundNo, $refund_account = null) { try { parent::init(get_store_id(), $order->is_platform); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } if ($type != OrderNo::ORDER_UNION) { $payPrice = $order->pay_price; } else { // 联合订单支付的总额 $payPrice = $order->price; } $data = [ 'out_trade_no' => $order->order_no, 'out_refund_no' => $orderRefundNo, 'total_fee' => $payPrice * 100, 'refund_fee' => $refundFee * 100, ]; if (isset($order->order_union_id) && $order->order_union_id != 0) { // 多商户合并订单退款 $orderUnion = OrderUnion::findOne($order->order_union_id); if (!$orderUnion) { return [ 'code' => 1, 'msg' => '订单取消失败,合并支付订单不存在。', ]; } $data['out_trade_no'] = $orderUnion->order_no; $data['total_fee'] = $orderUnion->price * 100; } $config = []; if ($refund_account) { $config['refund_account'] = $refund_account; } try { $res = self::$wechat_pay->refund->byOutTradeNumber($data['out_trade_no'], $orderRefundNo, $data['total_fee'], $data['refund_fee'], $config); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } if (!$res) { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,服务端配置出错', ]; } if ($res['return_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,' . $res['return_msg'], 'res' => $res, ]; } if (isset($res['err_code']) && $res['err_code'] == 'NOTENOUGH' && !$refund_account) { // 交易未结算资金不足,请使用可用余额退款 return self::orderRefund($order, $type, $refundFee, $orderRefundNo, 'REFUND_SOURCE_RECHARGE_FUNDS'); } if ($res['result_code'] != 'SUCCESS') { $refundQuery = self::$wechat_pay->order->queryByOutTradeNumber($order->order_no); if ($refundQuery['return_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,' . $refundQuery['return_msg'], 'res' => $refundQuery, ]; } if ($refundQuery['result_code'] == 'FAIL') { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,' . $res['err_code_des'], 'res' => $res, ]; } if ($refundQuery['result_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,' . $refundQuery['err_code_des'], 'res' => $refundQuery, ]; } if ($refundQuery['refund_status_0'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '订单取消失败,退款失败,' . $refundQuery['err_code_des'], 'res' => $refundQuery, ]; } } return [ 'code' => 0, 'msg' => 'success', 'data' => true ]; } /** * 转账 * @param string $trade_no 商户订单号 * @param integer $amount * @param integer $user_name * @param string $desc * @param string $openid * @return array * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \GuzzleHttp\Exception\GuzzleException */ public static function transfer($trade_no, $amount, $user_name, $openid, $desc = null) { if (!$trade_no || $amount <= 0 || empty($amount) || empty($openid)) { return [ 'code' => 1, 'msg' => '缺少必要参数' ]; } try { parent::init(); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } $data = [ 'partner_trade_no' => $trade_no, 'openid' => $openid, 'check_name' => 'FORCE_CHECK', // 强校验用户姓名 NO_CHECK:不校验用户姓名 're_user_name' => $user_name, 'amount' => $amount * 100, 'desc' => $desc ? $desc : '转账' ]; $res = self::$wechat_pay->transfer->toBalance($data); if ($res['return_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '转账失败:,' . $res['return_msg'], 'res' => $res, ]; } if ($res['result_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '转账失败:' . $res['err_code_des'], 'res' => $res, ]; } return [ 'code' => 0, 'msg' => 'success', 'data' => true ]; } /** * 转账 * @param string $trade_no 商户订单号 * @param integer $amount * @param integer $user_name * @param string $desc * @param string $openid * @return array * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \GuzzleHttp\Exception\GuzzleException */ public static function saasTransfer($trade_no, $amount, $user_name, $openid, $desc = null) { if (!$trade_no || $amount <= 0 || empty($amount) || empty($openid)) { return [ 'code' => 1, 'msg' => '缺少必要参数' ]; } try { parent::initSaas(WechatProfit::WECHAT_KIND_PAY); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } $data = [ 'partner_trade_no' => $trade_no, 'openid' => $openid, 'check_name' => 'NO_CHECK', // FORCE_CHECK:强校验用户姓名, NO_CHECK:不校验用户姓名 're_user_name' => $user_name, 'amount' => $amount * 100, 'desc' => $desc ? $desc : '转账' ]; $res = self::$wechat_pay->transfer->toBalance($data); if ($res['return_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '转账失败:,' . $res['return_msg'], 'res' => $res, ]; } if ($res['result_code'] != 'SUCCESS') { return [ 'code' => 1, 'msg' => '转账失败:' . $res['err_code_des'], 'res' => $res, ]; } return [ 'code' => 0, 'msg' => 'success', 'data' => true ]; } /** * 查询订单 * @param $trade_no * @return array */ public static function find($trade_no) { if (!$trade_no) { return [ 'code' => 1, 'msg' => '缺少必要参数' ]; } try { parent::init(); } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } try { $res = self::$wechat_pay->order->queryByOutTradeNumber($trade_no); if ($res['trade_state'] == 'SUCCESS') { return [ 'code' => 0, 'msg' => 'success', 'res' => $res, ]; } } catch (Exception $e) { \Yii::warning(['WECHAT QUERY ORDER <==========>', $trade_no, $e->getMessage()]); } return [ 'code' => 1, 'msg' => 'fail', 'data' => false ]; } }