247 lines
8.6 KiB
PHP
247 lines
8.6 KiB
PHP
<?php
|
|
namespace common\services;
|
|
|
|
use common\helpers\FuncHelper;
|
|
use yii\base\Exception;
|
|
use yii\helpers\Json;
|
|
|
|
class EplPayService
|
|
{
|
|
private static $instance = null;
|
|
public $eplConfig;
|
|
public $wechatConfig;
|
|
|
|
private function __clone()
|
|
{
|
|
|
|
}
|
|
|
|
private function __construct($module = null)
|
|
{
|
|
$eplConfig = \Yii::$app->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;
|
|
}
|
|
|
|
}
|