params['eplpay']; if(!$eplConfig['customerCode'] || !$eplConfig['url']){ throw new Exception('缺少易票联相关配置'); } $this->eplConfig = $eplConfig; $this->wechatConfig = \Yii::$app->params['wechat']; } public static function getInstance($module = null) { if(empty(self::$instance)){ self::$instance = new self($module); } return self::$instance; } // 微信小程序支付 public function WxJsapiPayment($params){ $url = $this->eplConfig['url'].'/api/txs/pay/WxJSAPIPayment'; $param = [ 'outTradeNo' => $params['order_no'], 'customerCode' => $this->eplConfig['customerCode'], 'appId' => $this->wechatConfig['app_id'], 'openId' => $params['openId'], 'orderInfo' => $params['orderInfo'], 'payAmount' => bcmul($params['total_pay_price'], 100, 0), 'payCurrency' => 'CNY', 'payMethod' => 35, 'notifyUrl' => $this->eplConfig['pay_notify_url'], 'transactionStartTime' => date('YmdHis'), 'areaInfo' => '330102', 'nonceStr' => FuncHelper::uuid(), 'version' => '3.0' ]; $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('获取支付参数失败'); } return Json::decode($result[1]); } //查询支付结果 public function queryPayment($params){ $url = $this->eplConfig['url'].'/api/txs/pay/PaymentQuery'; $param = [ 'outTradeNo' => $params['pay_order_no'], 'customerCode' => $this->eplConfig['customerCode'], 'nonceStr' => FuncHelper::uuid() ]; $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('查询支付结果失败'); } return Json::decode($result[1]); } // 退款 public function refund($params){ $url = $this->eplConfig['url'].'/api/txs/pay/Refund/V2'; $param = [ 'outRefundNo' => $params['refund_no'], 'customerCode' => $this->eplConfig['customerCode'], 'transactionNo' => $params['transaction_id'], 'amount' => bcmul($params['total_pay_price'], 100, 0), 'refundAmount' => bcmul($params['refund_price'], 100, 0), 'notifyUrl' => $this->eplConfig['refund_notify_url'], 'transactionStartTime' => date('YmdHis'), 'nonceStr' => FuncHelper::uuid(), 'version' => '3.0' ]; $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('退款失败'); } return Json::decode($result[1]); } //查询退款结果 public function queryRefund($params){ $url = $this->eplConfig['url'].'/api/txs-query/refundOrderQuery'; $param = [ 'outRefundNo' => $params['refund_no'], 'customerCode' => $this->eplConfig['customerCode'], 'nonceStr' => FuncHelper::uuid() ]; $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('查询退款结果失败'); } return Json::decode($result[1]); } //单笔提现 public function withDraw($params){ $url = $this->eplConfig['url'].'/api/txs/pay/withdrawalToCard'; $param = [ 'outTradeNo' => $params['order_no'], 'customerCode' => $this->eplConfig['customerCode'], 'amount' => bcmul($params['apply_cash'], 100, 0), 'arrivalType' => 0,// 到账类型 0当日 1次日 最大99 'procedureType' => 'inner', //inner内扣 outer外扣 'bankUserName' => $this->public_encrypt($params['bank_user_name']), //开户人姓名 'bankCardNo' => $this->public_encrypt($params['bank_card']), //银行卡号 'bankName' => $params['bank_name'],// 银行名称 'bankAccountType' => $params['bank_account_type'], //1对公 2对私 5存折 'notifyUrl' => $this->eplConfig['withdraw_notify_url'], 'payCurrency' => 'CNY', 'nonceStr' => FuncHelper::uuid() ]; if($params['bank_account_type'] != '2' || substr($params['bank_card'],0,2) != '62'){ $param['bankNo'] = $params['bank_no']; } $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('提现失败'); } return Json::decode($result[1]); } //查询提现结果 public function queryWithdraw($params){ $url = $this->eplConfig['url'].'/api/txs/pay/withdrawalToCardQuery'; $param = [ 'outTradeNo' => $params['withdraw_order_no'], 'customerCode' => $this->eplConfig['customerCode'], 'nonceStr' => FuncHelper::uuid() ]; $sign = $this->sign(Json::encode($param)); $result = $this->http_post_json($url,Json::encode($param),$sign); if(!$result || $result[0] != 200){ throw new Exception('查询提现结果失败'); } return Json::decode($result[1]); } protected function sign($data) { $certs = []; openssl_pkcs12_read(file_get_contents($this->eplConfig['rsaPrivateKeyFilePath']), $certs, $this->eplConfig['password']); //其中password为你的证书密码 if(!$certs){ throw new Exception('请检查RSA私钥配置'); } openssl_sign($data, $sign, $certs['pkey'], OPENSSL_ALGO_SHA256); $sign = base64_encode($sign); return $sign; } protected function http_post_json($url, $jsonStr, $sign) { $ch = curl_init(); $headers = array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($jsonStr), 'x-efps-sign-no:'.$this->eplConfig['signNo'], 'x-efps-sign-type:SHA256withRSA', 'x-efps-sign:'.$sign, 'x-efps-timestamp:'.date('YmdHis'), ); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 跳过检查 //curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); return [$httpCode, $response]; } // 公钥加密 protected function public_encrypt($data) { //读取公钥文件 $pubKey = file_get_contents($this->eplConfig['publicKeyFilePath']); $res = openssl_get_publickey($pubKey); if(!$res){ throw new Exception('RSA公钥错误。请检查公钥文件格式是否正确'); } $crypttext = ""; openssl_public_encrypt($data,$crypttext, $res ); if(!$this->checkEmpty($this->eplConfig['publicKeyFilePath'])) { //释放资源 if (PHP_VERSION_ID < 80000) { openssl_free_key($res); } } return(base64_encode($crypttext)); } /** * 校验$value是否非空 * if not set ,return true; * if is null , return true; **/ protected function checkEmpty($value) { if (!isset($value)) return true; if ($value === null) return true; if (trim($value) === "") return true; return false; } }