from('{{%ybwm_core_system}}') ->where(['ident' => 'weChatServicePaySerialNo', 'uniacid' => $uniacid]) ->one(); $payData=Config::getSystemSet('payConfig',$uniacid); // 商户相关配置 // $merchantId = '1556224401'; // 商户号 // $merchantSerialNumber = '7816CD8F2C3D62D6B243C2C4905770AEF62DA9A7'; // 商户API证书序列号 $merchantSerialNumber = $payData['servicePayNo']; // 商户API证书序列号 $merchantId = $payData['serviceMchId']; // 商户号 $merchantPrivateKey = PemUtil::loadPrivateKey(Yii::$app->basePath."/payment/" . 'service_apiclient_key_' . $uniacid . '.pem'); // 商户私钥 // 微信支付平台配置 $wechatpayCertificate = PemUtil::loadCertificate(Yii::$app->basePath."/payment/" . 'wechatpay_'.$weChatPaySerialNo['data'].'.pem'); // 微信支付平台证书 // 构造一个WechatPayMiddleware $wechatpayMiddleware = WechatPayMiddleware::builder() ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey)// 传入商户相关配置 ->withWechatPay([$wechatpayCertificate])// 可传入多个微信支付平台证书,参数类型为array ->build(); // 将WechatPayMiddleware添加到Guzzle的HandlerStack中 $stack = HandlerStack::create(); $stack->push($wechatpayMiddleware, 'wechatpay'); // 创建Guzzle HTTP Client时,将HandlerStack传入 return new Client(['handler' => $stack]); }catch (\Exception $exception){ return []; } } public static function test($uniacid, $origin, $outTradeNo, $money, $notifyUrl, $note, $module, $openId, $storeId, $profit_sharing) { $client = self::getPayConfig($uniacid); if (Yii::$app->params['isDev'] == true) { $url = Yii::$app->request->hostInfo . '/addons/' . $module . '/index.php/' . $notifyUrl; } else { $url = Yii::$app->request->hostInfo . '/index.php/' . $notifyUrl; } try { $resp = $client->request( 'POST', 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi', //请求URL [ // JSON请求体 'json' => [ "mchid" => "1556224401", "appid" => "wx2f926923ad50c5e5", "payer" => [ "openid" => $openId, ], "amount" => [ "total" => $money * 100, ], "description" => $note, "notify_url" => $url, "out_trade_no" => $outTradeNo, ], 'headers' => ['Accept' => 'application/json'] ] );// $statusCode = $resp->getStatusCode(); if ($statusCode == 200) { //处理 $prepay_id = json_decode($resp->getBody()->getContents(), true)['prepay_id']; $params = [ 'appId' => 'wx2f926923ad50c5e5', 'timeStamp' => strval(time()), 'nonceStr' => uniqid(), 'package' => "prepay_id=$prepay_id", ]; $var = ''; foreach ($params as $key => $value) { $var .= $value . PHP_EOL; } $mch_private_key = PemUtil::loadPrivateKey(Yii::$app->basePath."/payment/" . 'apiclient_key_' . $uniacid . '.pem'); openssl_sign($var, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); // echo base64_encode($raw_sign);die; $params['signType'] = 'RSA'; $params['paySign'] = base64_encode($raw_sign); return $params; } else if ($statusCode == 204) { //处理成功,无返回Body echo "success"; } } catch (RequestException $e) { // 进行错误处理 echo $e->getMessage() . "\n"; if ($e->hasResponse()) { echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n"; } return; } // /www/server/php/72/bin/php tool/CertificateDownloader.php -k admin888admin888admin888admin888 -m 1541578721 -f /www/wwwroot/bkycms.com/addons/yb_wm/payment/service_apiclient_key_39.pem -s 1E6373075BB556DEB62105E3300E51A0725C95D0 -o /www/wwwroot/bkycms.com/addons/yb_wm/payment/ } public static function downloadCert($opts){ try { // 构造一个WechatPayMiddleware $builder = WechatPayMiddleware::builder() ->withMerchant($opts['mchid'], $opts['serialno'], PemUtil::loadPrivateKey($opts['privatekey'])); // 传入商户相关配置 if (isset($opts['wechatpay-cert'])) { $builder->withValidator(new NoopValidator()); // 临时"跳过”应答签名的验证 // $builder->withWechatPay([ PemUtil::loadCertificate($opts['wechatpay-cert']) ]); // 使用平台证书验证 } else { $builder->withValidator(new NoopValidator()); // 临时"跳过”应答签名的验证 } $wechatpayMiddleware = $builder->build(); // 将WechatPayMiddleware添加到Guzzle的HandlerStack中 $stack = HandlerStack::create(); $stack->push($wechatpayMiddleware, 'wechatpay'); // 创建Guzzle HTTP Client时,将HandlerStack传入 $client = new Client(['handler' => $stack]); // 接下来,正常使用Guzzle发起API请求,WechatPayMiddleware会自动地处理签名和验签 $resp = $client->request('GET', 'https://api.mch.weixin.qq.com/v3/certificates', [ 'headers' => [ 'Accept' => 'application/json' ] ]); if ($resp->getStatusCode() < 200 || $resp->getStatusCode() > 299) { return "download failed, code={$resp->getStatusCode()}, body=[{$resp->getBody()}]"; } $list = json_decode($resp->getBody(), true); $plainCerts = []; $x509Certs = []; $decrypter = new AesUtil($opts['key']); foreach ($list['data'] as $item) { $encCert = $item['encrypt_certificate']; $plain = $decrypter->decryptToString($encCert['associated_data'], $encCert['nonce'], $encCert['ciphertext']); if (!$plain) { return "加密证书解密失败!"; } // 通过加载对证书进行简单合法性检验 $cert = \openssl_x509_read($plain); // 从字符串中加载证书 if (!$cert) { return "下载证书检查失败"; } $plainCerts[] = $plain; $x509Certs[] = $cert; } $validator = new WechatPay2Validator(new CertificateVerifier($x509Certs)); if (!$validator->validate($resp)) { return "使用下载的证书验证响应失败!"; } $effective_time=0; $wechatpayCertificate=[];//平台证书 // 输出证书信息,并保存到文件 foreach ($list['data'] as $index => $item) { if((new \DateTime($item['effective_time']))->getTimestamp()>$effective_time){ $effective_time=(new \DateTime($item['effective_time']))->getTimestamp(); $wechatpayCertificate=[ 'serial_no'=>$item['serial_no'], 'text'=> $plainCerts[$index], 'effective_time'=> (new \DateTime($item['effective_time']))->getTimestamp(), 'expire_time'=> (new \DateTime($item['expire_time']))->getTimestamp(), ]; } } $info = (new \yii\db\Query()) ->from('{{%ybwm_core_system}}') ->where(['ident' => 'weChatServicePaySerialNo', 'uniacid' => $opts['uniacid']]) ->one(); if($info){ $data['changeAt']=time(); $data['data']=$wechatpayCertificate['serial_no']; Yii::$app->db->createCommand()->update('{{%ybwm_core_system}}',$data,['id'=>$info['id']] )->execute(); }else{ $data['data']=$wechatpayCertificate['serial_no']; $data['createdAt']=time(); $data['ident']='weChatServicePaySerialNo'; $data['name']='微信支付平台证书序列号'; $data['uniacid']=$opts['uniacid']; Yii::$app->db->createCommand()->insert('{{%ybwm_core_system}}', $data)->execute(); } $outpath = $opts['output'].'wechatpay_'.$wechatpayCertificate['serial_no'].'.pem'; $res=file_put_contents($outpath, $wechatpayCertificate['text']); if($res){ return true; }else{ return '证书生成失败'; } } catch (RequestException $e) { echo "download failed, message=[{$e->getMessage()}] "; if ($e->hasResponse()) { return "code={$e->getResponse()->getStatusCode()}, body=[{$e->getResponse()->getBody()}]\n"; } } catch (\Exception $e) { return "download failed, message=[{$e->getMessage()}]\n"; } return '证书生成失败'; } /** * @param $orderId * @param string $status * @param int $type[1.外卖2店内3快餐] * @return bool|string * @throws \GuzzleHttp\Exception\GuzzleException */ public static function reporting($orderId,$status='CREATE_DEAL',$type=1){ if($type==1){ $order = (new \yii\db\Query()) ->from('{{%ybwm_takeout_order}}') ->where('id=:id', [':id' => $orderId])->one(); $originMoney=bcadd(bcadd($order['originMoney'],$order['deliveryMoney'],2),$order['boxMoney'],2); $discount_amount=bcsub($order['money'],$originMoney,2); }else{ $order = (new \yii\db\Query()) ->from('{{%ybwm_instore_order}}') ->where('id=:id', [':id' => $orderId])->one(); $originMoney=bcadd($order['originMoney'],$order['tablewareMoney'],2); $discount_amount=bcsub($order['money'],$originMoney,2); } $payData=Config::getSystemSet('payConfig',$order['uniacid']); if($payData['smOpen']!=1){ return false; } $client = self::getPayConfig($order['uniacid']); if(!$client){ return false; } $config=Config::getSystemSet('miniConfig',$order['uniacid']); $payConfig=Config::getSystemSet('payConfig',$order['uniacid']);//服务商配置 $storeSet=Config::getStoreSet('serviceCharge',$order['storeId']);//商户子商户号设置 $subMchId=$storeSet['subMchId']?:$payConfig['sonMchId']; $goods=(new \yii\db\Query()) ->from('{{%ybwm_order_goods}}') ->where('orderId=:orderId AND item='.$type, [':orderId' => $orderId])->all(); $goodsArr=[]; for($i=0;$i$goods[$i]['goodsId'], 'name'=>$goods[$i]['name'], 'price'=>$goods[$i]['money']*100, 'unit'=>'BY_SHARE', 'count'=>floatval($goods[$i]['num']), ]; } $user=(new \yii\db\Query()) ->from('{{%ybwm_member}}') ->where('id=:id', [':id' => $order['userId']])->one(); $data=[ 'sp_appid'=>$payConfig['serviceAppId'], 'sp_mchid'=>$payConfig['serviceMchId'], 'sub_mchid'=>$subMchId, 'sub_appid'=>$config['appId'], 'out_shop_no'=>$order['storeId'], 'sub_openid'=>$user['openId'], 'login_token'=>$user['login_token'], 'order_entry'=>'yb_wm/index/goods', 'total_amount'=>$originMoney*100, 'discount_amount'=>$discount_amount*100, 'user_amount'=>$order['money']*100, 'status'=>$status, 'action_time'=>date(DATE_RFC3339), 'out_trade_no'=>$order['outTradeNo'], 'out_order_no'=>$order['outTradeNo'], 'dish_list'=>$goodsArr, ]; if($status=='PAY_SUCCESS'){ $data['pay_time']=date(DATE_RFC3339); $data['transaction_id']=$order['transaction_id']; } try { $resp = $client->request( 'POST', 'https://api.mch.weixin.qq.com/v3/catering/orders/sync-status', //请求URL [ // JSON请求体 'json' => $data, 'headers' => ['Accept' => 'application/json'] ] ); $statusCode = $resp->getStatusCode(); if ($statusCode == 200) { //处理成功 // $res = json_decode($resp->getBody()->getContents(), true); return true; } else if ($statusCode == 204) { //处理成功,无返回Body return true; } } catch (RequestException $e) { // 进行错误处理 if ($e->hasResponse()) { return "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n"; } } return false; } }