log(1, $pay_type_name, $data['amount'], $op, $data['order_no'], Pay::ORDER_STATUS_NON, \YunShop::app()->getMemberId()); if (empty(\YunShop::app()->getMemberId())) { throw new AppException('无法获取用户ID'); } $client_type = \YunShop::request()->type ?: $payType; $is_h5 = request()->type == 5 ? 1 : 0; $config = new WxPayConfig(); $openid = Member::getOpenIdForType(\YunShop::app()->getMemberId(), $client_type); $data['trade_type'] = 'JSAPI'; if ($is_h5){ $data['trade_type'] = 'MWEB'; } /* 支付请求对象 */ $wxPay = new WxPayUnifiedOrder(); //设置商品或支付单简要描述 $wxPay->SetBody(mb_substr($data['subject'], 0, 120)); //设置商家数据包,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 $wxPay->SetAttach(\YunShop::app()->uniacid . ':' . self::$attach_type .':'.(new WxPayConfig())->GetProfitSharing().':'.request()->store_id); //设置商户系统内部的订单号 $wxPay->SetOut_trade_no($data['order_no']); //设置订单总金额 $wxPay->SetTotal_fee($data['amount'] * 100); $wxPay->SetDevice_info('yun_shop'); if ($config->getIndependent()) { $wxPay->SetSubOpenid($openid); } else { $wxPay->SetOpenid($openid); } // $wxPay->SetAttach((new WxPayConfig())->GetProfitSharing()); $wxPay->SetTrade_type($data['trade_type']); $wxPay->SetNotify_url(Url::shopSchemeUrl('payment/wechat/jsapiNotifyUrl.php')); //请求数据日志 self::payRequestDataLog($data['order_no'], $pay_order_model->type, $pay_order_model->third_type, json_encode($data)); $result = WxPayApi::unifiedOrder($config, $wxPay); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $pay_order_model->status = Pay::ORDER_STATUS_WAITPAY; $pay_order_model->trade_no = ''; $pay_order_model->save(); } elseif ($result['return_code'] == 'SUCCESS') { throw new AppException($result['err_code_des']); } else { throw new AppException($result['return_msg']); } if ($is_h5){ $config = $result; }else{ $config = $this->GetJsApiParameters($result, $config); } // $url = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; // $nonce = WxPayApi::getNonceStr(); // $ticket = $this->ticket(); // $timestamp = time(); // $signPackage = [ // 'appId' => $result['appid'], // 'nonceStr' => $nonce, // 'timestamp' => $timestamp, // 'url' => $url, // 'signature' => sha1("jsapi_ticket={$ticket}&noncestr={$nonce}×tamp={$timestamp}&url={$url}"), // 'debug' => false, // 'beta' => false, // 'jsApiList' => ['chooseWXPay'] // ]; return [ 'config'=>$config, // 'js'=>json_encode($signPackage) ]; } /** * 退款 * * @param $out_trade_no 订单号 * @param $totalmoney 订单总金额 * @param $refundmoney 退款金额 * @return mixed */ public function doRefund($out_trade_no, $totalmoney, $refundmoney) { $totalmoney = intval(bcmul($totalmoney, 100, 0)); $refundmoney = intval(bcmul($refundmoney, 100, 0)); $this->getSubMchId($out_trade_no); $wxPayApi = new WxPayApi; $config = new WxPayConfig; $wxPayRefund = new WxPayRefund; $wxPayRefund->SetOut_trade_no($out_trade_no); $wxPayRefund->SetTotal_fee($totalmoney); $wxPayRefund->SetRefund_fee($refundmoney); $outRefundNo = createNo('RN', 20, true); //生产唯一的订单号; $wxPayRefund->SetOut_refund_no($outRefundNo); if (!$config->GetSubMerchantId()) { throw new AppException('请先配置门店子商户参数'); } $wxPayRefund->SetSubMchId($config->GetSubMerchantId()); $payTypeId = OrderPay::get_paysn_by_pay_type_id($out_trade_no); $payTypeName = PayType::get_pay_type_name($payTypeId); $op = '微信退款 订单号:' . $out_trade_no . '退款单号:' . $outRefundNo . '退款总金额:' . $totalmoney; $payOrderModel = $this->refundlog(Pay::PAY_TYPE_REFUND, $payTypeName, $refundmoney, $op, $out_trade_no, Pay::ORDER_STATUS_NON, 0); $result = $wxPayApi::refund($config, $wxPayRefund); \Log::debug('微信服务商退款记录', $result); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { $payOrderModel->status = Pay::ORDER_STATUS_COMPLETE; $payOrderModel->trade_no = $result['transaction_id']; $payOrderModel->save(); return true; } elseif ($result['return_code'] == 'SUCCESS') { throw new AppException($result['err_code_des']); } else { throw new AppException($result['return_msg']); } } /** * 提现 * * @param $member_id 提现者用户ID * @param $out_trade_no 提现批次单号 * @param $money 提现金额 * @param $desc 提现说明 * @param $type 只针对微信 1-企业支付(钱包) 2-红包 * @return mixed */ function doWithdraw($member_id, $out_trade_no, $money, $desc, $type) { // TODO: Implement doWithdraw() method. } /** * 构造签名 * * @return mixed */ function buildRequestSign() { // TODO: Implement buildRequestSign() method. } /** * * 获取jsapi支付的参数 * @param array $UnifiedOrderResult 统一支付接口返回的数据 * @param WxPayConfig $config 设置 * @throws WxPayException * * @return array 数据,可直接填入js函数作为参数 */ public function GetJsApiParameters($UnifiedOrderResult, $config) { if(!array_key_exists("appid", $UnifiedOrderResult) || !array_key_exists("prepay_id", $UnifiedOrderResult) || $UnifiedOrderResult['prepay_id'] == "") { throw new WxPayException("参数错误"); } $jsapi = new WxPayJsApiPay(); if (\YunShop::request()->type == 2 && !$config->set['is_independent'] && $config->set['sub_mini_appid']) { $jsapi->SetAppid($UnifiedOrderResult["sub_appid"]); } else { $jsapi->SetAppid($UnifiedOrderResult["appid"]); } $timeStamp = time(); $jsapi->SetTimeStamp("$timeStamp"); $jsapi->SetSignType("MD5"); $jsapi->SetNonceStr(WxPayApi::getNonceStr()); $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']); $config = new WxPayConfig(); $jsapi->SetPaySign($jsapi->MakeSign($config)); $parameters = $jsapi->GetValues(); return $parameters; } // 获取门店子商户号 private function getSubMchId($outTradeNo) { if (app('plugins')->isEnabled('store-cashier')) { $orderPay = OrderPay::where('pay_sn', $outTradeNo)->first(); $storeId = \Yunshop\StoreCashier\common\models\StoreOrder::where('order_id', $orderPay->orders->first()->id)->value('store_id'); if ($storeId) { request()->offsetSet('store_id', $storeId); } } if (!isset($storeId)) { throw new AppException('请确认订单是否属于门店订单'); } } }