Files
xk-api-yii/common/services/EplPayService.php
2024-09-19 11:32:39 +08:00

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;
}
}