1, 'msg' => $e->getMessage() ]; } if (!$order || !in_array($type, OrderNo::$validOrderType) || ($type != OrderNo::ORDER_UNION && !$goods_names)) { return [ 'code' => 1, 'msg' => '订单信息或订单类型错误' ]; } if ($is_app) { //$open_id = get_user()->wechat_app_open_id; } else if ($is_official) { //$open_id = get_user()->wechat_platform_open_id; } else { // $open_id = get_saas_user()->platform_open_id; if(get_saas_user()){ $open_id = get_saas_user()->platform_open_id; if(is_merchant() && get_saas_user()->platform_open_id_merchant){ $open_id = get_saas_user()->platform_open_id_merchant; } }else{ $access_token = input_params('access_token'); $saas_user = \app\models\SaasUser::find()->where(['access_token' => $access_token])->one(); $open_id = $saas_user->platform_open_id; if(is_merchant() && $saas_user->platform_open_id_merchant){ $open_id = $saas_user->platform_open_id_merchant; } } } if ($type == OrderNo::ORDER_UNION) { $config = [ 'body' => count($order) . '笔订单合并支付', 'out_trade_no' => OrderNo::getOrderNo(OrderNo::ORDER_UNION), 'total_fee' => $balance_price > 0 ? round(floatval($total_pay_price - $balance_price) * 100) : $total_pay_price * 100, 'notify_url' => pay_notify_url(self::$notify_url), 'openid' => $open_id, ]; if ($is_h5) { $config['trade_type'] = 'MWEB'; } else { $config['trade_type'] = 'JSAPI'; } if ($is_app) { $config['trade_type'] = 'APP'; } $order_union = new OrderUnion(); $order_union->store_id = get_store_id(); $order_union->user_id = get_user()->id ? get_user()->id : 0; $order_union->order_no = $config['out_trade_no']; $order_union->price = $total_pay_price; $order_union->is_pay = 0; $order_union->created_at = time(); $order_union->is_delete = 0; $order_union->type = substr($order[0]->order_no, 0, 2); $order_id_list = []; foreach ($order 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 { $config = [ 'body' => $goods_names, 'out_trade_no' => $order->order_no, 'total_fee' => $balance_price > 0 ? round(floatval($order->pay_price - $balance_price) * 100) : $order->pay_price * 100, 'notify_url' => pay_notify_url(self::$notify_url), 'openid' => $open_id, ]; if ($is_h5) { $config['trade_type'] = 'MWEB'; } else { $config['trade_type'] = 'JSAPI'; } if ($is_app) { $config['trade_type'] = 'APP'; } } try { $res = self::$wechat_pay->order->unify($config); } 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 ($is_app) { return self::orderUnify($order, $type, $goods_names, $total_pay_price, true, $balance_price); } else if ($is_h5) { return self::orderUnify($order, $type, $goods_names, $total_pay_price, false, $balance_price, true); } else if ($is_h5) { return self::orderUnify($order, $type, $goods_names, $total_pay_price, false, $balance_price, false, true); } else { return self::orderUnify($order, $type, $goods_names, $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 = self::$wechat_pay->jssdk->appConfig($res['prepay_id']); } else { $pay_data = self::$wechat_pay->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 = $order_union->id; $value->save(); } $return['order_no'] = $config['out_trade_no']; $return['body'] = $config['body']; } \Yii::error($return); return $return; } /** * 退款 * @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(-1, Wechat::WECHAT_KIND_PAY); } 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(get_store_id(), Wechat::WECHAT_KIND_PAY); } 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 $trade_no * @return array */ public static function find($trade_no) { if (!$trade_no) { return [ 'code' => 1, 'msg' => '缺少必要参数' ]; } try { parent::init(get_store_id(), Wechat::WECHAT_KIND_PAY); } 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 ]; } //只用去吊起支付 public static function BussinessWechatPay(){ parent::init(-1, Wechat::WECHAT_KIND_PAY); return self::$wechat_pay; } //只用去吊起支付 public static function BussinessWechatMini(){ parent::init(-1); return self::$wechat_mini; } }