Commit a5f487df by wulei

lakala支付

1 parent d9e51dc9
Showing with 3251 additions and 87 deletions
{ {
"name": "ldy/payment", "name": "ldy/payment",
"type": "library", "type": "library",
"version": "3.6.6", "version": "3.6.7",
"description": "支付宝支付、微信支付、招商一网通支付、通联支付、米付支付、利楚扫呗、富友支付、联拓付、易生支付、银盛支付、微诺付、汇收钱 php SDK。", "description": "支付宝支付、微信支付、招商一网通支付、通联支付、米付支付、利楚扫呗、富友支付、联拓付、易生支付、银盛支付、微诺付、汇收钱 php SDK。",
"keywords": ["alipay", "weixin", "支付宝支付", "微信支付","通联支付", "集成支付接口SDK", "招商一网通", "一网通", "利楚扫呗", "富友支付","微诺付","汇收钱"], "keywords": ["alipay", "weixin", "支付宝支付", "微信支付","通联支付", "集成支付接口SDK", "招商一网通", "一网通", "利楚扫呗", "富友支付","微诺付","汇收钱"],
"homepage": "", "homepage": "",
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
"endroid/qrcode": "~1.9" "endroid/qrcode": "~1.9"
}, },
"autoload": { "autoload": {
"psr-4": {"Payment\\": "src/"} "psr-4": {
"Payment\\": "src/"
}
} }
} }
<?php <?php
/** /**
* @author: yeran * @author: yeran
* @createTime: 2018-04-22 17:42 * @createTime: 2018-04-22 17:42
...@@ -8,6 +9,7 @@ ...@@ -8,6 +9,7 @@
namespace Payment; namespace Payment;
use Payment\Cancel\FuCancel; use Payment\Cancel\FuCancel;
use Payment\Charge\Lakala\LakalaCancel;
use Payment\Charge\LTF\LTFCancel; use Payment\Charge\LTF\LTFCancel;
use Payment\Charge\MiPay\MiCancel; use Payment\Charge\MiPay\MiCancel;
use Payment\Charge\Sw\SwCancel; use Payment\Charge\Sw\SwCancel;
...@@ -22,7 +24,8 @@ use Payment\Common\PayException; ...@@ -22,7 +24,8 @@ use Payment\Common\PayException;
* *
* @package Payment * @package Payment
*/ */
class CancelContext{ class CancelContext
{
/** /**
* 退款的渠道 * 退款的渠道
...@@ -40,9 +43,10 @@ class CancelContext{ ...@@ -40,9 +43,10 @@ class CancelContext{
* @see Config * @see Config
* @author yeran * @author yeran
*/ */
public function initCancelHandler($channel, array $config){ public function initCancelHandler($channel, array $config)
try{ {
switch($channel){ try {
switch ($channel) {
case Config::TL_CHANNEL_LITE: case Config::TL_CHANNEL_LITE:
$this->cancelHandler = new TLCancel($config); $this->cancelHandler = new TLCancel($config);
break; break;
...@@ -52,22 +56,25 @@ class CancelContext{ ...@@ -52,22 +56,25 @@ class CancelContext{
case Config::SW_CHARGE: case Config::SW_CHARGE:
$this->cancelHandler = new SwCancel($config); $this->cancelHandler = new SwCancel($config);
break; break;
case Config::SW_T_CHARGE: case Config::SW_T_CHARGE:
$this->cancelHandler = new SwThreeCancel($config); $this->cancelHandler = new SwThreeCancel($config);
break; break;
case Config::FU_CHARGE: case Config::FU_CHARGE:
$this->cancelHandler = new FuCancel($config); $this->cancelHandler = new FuCancel($config);
break; break;
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->cancelHandler = new LTFCancel($config); $this->cancelHandler = new LTFCancel($config);
break; break;
case Config::YS_CHARGE: case Config::YS_CHARGE:
$this->cancelHandler = new YSCancel($config); $this->cancelHandler = new YSCancel($config);
break; break;
case Config::LAKALA_CHARGE:
$this->cancelHandler = new LakalaCancel($config);
break;
default: default:
throw new PayException('当前仅支持:通联支付平台'); throw new PayException('当前仅支持:通联支付平台');
} }
}catch(PayException $e){ } catch (PayException $e) {
throw $e; throw $e;
} }
} }
...@@ -80,14 +87,15 @@ class CancelContext{ ...@@ -80,14 +87,15 @@ class CancelContext{
* @throws PayException * @throws PayException
* @author yeran * @author yeran
*/ */
public function cancel(array $data){ public function cancel(array $data)
if(!$this->cancelHandler instanceof BaseStrategy){ {
if (!$this->cancelHandler instanceof BaseStrategy) {
throw new PayException('请检查初始化是否正确'); throw new PayException('请检查初始化是否正确');
} }
try{ try {
return $this->cancelHandler->handle($data); return $this->cancelHandler->handle($data);
}catch(PayException $e){ } catch (PayException $e) {
throw $e; throw $e;
} }
} }
......
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Charge\BackAliChargeData;
use Payment\Common\Lakala\Data\Charge\AliChargeData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
* Class LakalaAliCharge
*
* 拉卡拉支付宝支付
*/
class LakalaAliCharge extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return AliChargeData::class;
}
/**
* 处理小程序支付的返回值
* @param array $ret
*
* @return array $backData
*/
protected function retData(array $ret)
{
$back = new BackAliChargeData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Cancel\BackCancelData;
use Payment\Common\Lakala\Data\Cancel\CancelData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
* Class LakalaCancel
*
* 拉卡拉取消订单
* 1)撤销交易只能撤销当天的交易,当天指按账户端认定的交易时间为当天的交易,不是以自然日零点分界的。
* 2)仅支持被扫交易的撤销。
* 3)支付成功的交易才能撤销,撤销后资金会退还给用户。
*
* @package Payment\Charge\Lakala
*
*/
class LakalaCancel extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return CancelData::class;
}
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::CANCEL_URL);
}
/**
* 处理小程序支付的返回值
* @param array $ret
*
* @return array $backData
*
*
*/
protected function retData(array $ret)
{
$back = new BackCancelData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Cancel\BackCloseData;
use Payment\Common\Lakala\Data\Cancel\CloseData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaClose extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return CloseData::class;
}
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::CLOSE_URL);
}
/**
* 处理小程序支付的返回值
* @param array $ret
*
* @return array $backData
*
*
*/
protected function retData(array $ret)
{
$back = new BackCloseData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Charge\BackLiteChargeData;
use Payment\Common\Lakala\Data\Charge\LiteChargeData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
* Class LakalaLiteCharge
*
* 拉卡拉小程序支付
*/
class LakalaLiteCharge extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return LiteChargeData::class;
}
/**
* 处理小程序支付的返回值
* @param array $ret
*
* @return array $backData
*/
protected function retData(array $ret)
{
$back = new BackLiteChargeData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Charge\BackPubChargeData;
use Payment\Common\Lakala\Data\Charge\PubChargeData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
*
* 拉卡拉微信公众号支付
*
* @package Payment\Charge\Lakala
*
*/
class LakalaPubCharge extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return PubChargeData::class;
}
/**
* 处理公众号支付的返回值。直接返回与微信文档对应的字段
* @param array $ret
*
* @return array $data 包含以下键
*
* ```php
* $data = [
* 'appId' => '', // 公众号id
* 'package' => '', // 订单详情扩展字符串 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
* 'nonceStr' => '', // 随机字符串
* 'timeStamp' => '', // 时间戳
* 'signType' => '', // 签名算法,暂支持MD5
* 'paySign' => '', // 签名
* ];
* ```
*
* @throws \Payment\Common\PayException
*/
protected function retData(array $ret)
{
$back = new BackPubChargeData($this->config, $ret);
// $back->setSign();
$backData = $back->getData();
// $backData['paySign'] = $backData['sign'];
// 移除sign
unset($backData['sign']);
// 公众号支付返回数组结构
return $backData;
}
}
<?php
namespace Payment\Charge\Lakala;
use Payment\Common\Lakala\Data\Charge\BackScanChargeData;
use Payment\Common\Lakala\Data\Charge\ScanChargeData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
* Class LakalaScanCharge
*
* 扫呗扫码支付
*
* @package Payment\Charge\Lakala
*
*/
class LakalaScanCharge extends LakalaBaseStrategy
{
/**
* @inheritDoc
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::SCANPAY_URL);
}
public function getBuildDataClass()
{
return ScanChargeData::class;
}
/**
* 处理扫码支付的返回值
* @param array $ret
*
* @return array $backData
*/
protected function retData(array $ret)
{
$back = new BackScanChargeData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
...@@ -50,7 +50,10 @@ use Payment\Charge\WNFPay\WNFCharge; ...@@ -50,7 +50,10 @@ use Payment\Charge\WNFPay\WNFCharge;
use Payment\Charge\YSE\YSEPubCharge; use Payment\Charge\YSE\YSEPubCharge;
use Payment\Charge\Hsq\HsqPubCharge; use Payment\Charge\Hsq\HsqPubCharge;
use Payment\Charge\Lakala\LakalaAliCharge;
use Payment\Charge\Lakala\LakalaLiteCharge;
use Payment\Charge\Lakala\LakalaPubCharge;
use Payment\Charge\Lakala\LakalaScanCharge;
use Payment\Common\BaseStrategy; use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
...@@ -232,6 +235,20 @@ class ChargeContext ...@@ -232,6 +235,20 @@ class ChargeContext
case Config::HSQ_CHANNEL_JS: case Config::HSQ_CHANNEL_JS:
$this->channel = new HsqJSCharge($config); $this->channel = new HsqJSCharge($config);
break; break;
// 拉卡拉
case Config::LAKALA_CHANNEL_PUB:
$this->channel = new LakalaPubCharge($config);
break;
case Config::LAKALA_CHANNEL_LITE:
$this->channel = new LakalaLiteCharge($config);
break;
case Config::LAKALA_CHANNEL_ALI: // 支付宝
$this->channel = new LakalaAliCharge($config);
break;
case Config::LAKALA_CHANNEL_SCAN: // 被扫
$this->channel = new LakalaScanCharge($config);
break;
default: default:
throw new PayException('当前支持:支付宝、微信、招商一网通、通联支付、米付支付、扫呗支付、富友支付、联拓富、易生支付、微诺付、慧收钱。'); throw new PayException('当前支持:支付宝、微信、招商一网通、通联支付、米付支付、扫呗支付、富友支付、联拓富、易生支付、微诺付、慧收钱。');
} }
......
...@@ -45,6 +45,8 @@ class Cancel ...@@ -45,6 +45,8 @@ class Cancel
Config::LTF_CHARGE, Config::LTF_CHARGE,
Config::YS_CHARGE,//易生支付 Config::YS_CHARGE,//易生支付
Config::LAKALA_CHARGE, // 拉卡拉
]; ];
/** /**
......
...@@ -74,6 +74,11 @@ class Charge ...@@ -74,6 +74,11 @@ class Charge
Config::HSQ_CHANNEL_APP, Config::HSQ_CHANNEL_APP,
Config::HSQ_CHANNEL_JS, Config::HSQ_CHANNEL_JS,
// 拉卡拉
Config::LAKALA_CHANNEL_PUB,
Config::LAKALA_CHANNEL_LITE,
Config::LAKALA_CHANNEL_ALI,
Config::LAKALA_CHANNEL_SCAN,
]; ];
/** /**
......
...@@ -12,14 +12,16 @@ use Payment\Config; ...@@ -12,14 +12,16 @@ use Payment\Config;
* Class Close * Class Close
* @package Payment\Client * @package Payment\Client
*/ */
class Close { class Close
{
private static $supportChannel = [ private static $supportChannel = [
Config::SW_CHARGE, //扫呗支付关闭订单 Config::SW_CHARGE, //扫呗支付关闭订单
Config::SW_T_CHARGE, //扫呗支付(3.0)关闭订单 Config::SW_T_CHARGE, //扫呗支付(3.0)关闭订单
Config::FU_CHARGE, //富友支付关闭订单 Config::FU_CHARGE, //富友支付关闭订单
Config::LTF_CHARGE,//联拓富支付关闭订单 Config::LTF_CHARGE, //联拓富支付关闭订单
Config::YS_CHARGE,//易生支付关闭订单 Config::YS_CHARGE, //易生支付关闭订单
Config::LAKALA_CHARGE, //易生支付关闭订单
]; ];
/** /**
...@@ -28,7 +30,8 @@ class Close { ...@@ -28,7 +30,8 @@ class Close {
protected static $instance; protected static $instance;
protected static function getInstance($channel, $config){ protected static function getInstance($channel, $config)
{
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
static::$instance = new CloseContext(); static::$instance = new CloseContext();
......
...@@ -33,13 +33,16 @@ class Notify ...@@ -33,13 +33,16 @@ class Notify
Config::LTF_CHARGE, //联拓富 Config::LTF_CHARGE, //联拓富
Config::YS_CHARGE, //易生 Config::YS_CHARGE, //易生
Config::YSE_CHARGE, //银盛 Config::YSE_CHARGE, //银盛
Config::HSQ_CHARGE, //慧收钱 Config::HSQ_CHARGE, //慧收钱
Config::HSQ_TRANSFER, //慧收钱代付 Config::HSQ_TRANSFER, //慧收钱代付
Config::LAKALA_CHARGE,// 拉卡拉
Config::LAKALA_TRANSFER,// 拉卡拉
]; ];
/** /**
......
...@@ -56,7 +56,7 @@ class Query ...@@ -56,7 +56,7 @@ class Query
Config::HSQ_QUERY_REFUND, //慧收钱查询退款 Config::HSQ_QUERY_REFUND, //慧收钱查询退款
Config::HSQ_QUERY_TRANSFER, //宝付代付交易状态查证接口 Config::HSQ_QUERY_TRANSFER, //宝付代付交易状态查证接口
Config::LAKALA_QUERY,//拉卡拉
]; ];
/** /**
......
...@@ -45,6 +45,8 @@ class Refund ...@@ -45,6 +45,8 @@ class Refund
Config::WNF_REFUND, //微诺付 Config::WNF_REFUND, //微诺付
Config::HSQ_REFUND, //微诺付 Config::HSQ_REFUND, //微诺付
Config::LAKALA_REFUND, //拉卡拉
]; ];
/** /**
......
...@@ -28,7 +28,7 @@ class Transfer ...@@ -28,7 +28,7 @@ class Transfer
Config::HSQ_TRANSFER, //慧收钱代付交易接口 Config::HSQ_TRANSFER, //慧收钱代付交易接口
Config::LAKALA_TRANSFER, // 拉卡拉转账
]; ];
/** /**
...@@ -62,14 +62,14 @@ class Transfer ...@@ -62,14 +62,14 @@ class Transfer
public static function run($channel, $config, $metadata) public static function run($channel, $config, $metadata)
{ {
if (!in_array($channel, self::$supportChannel)) { if (!in_array($channel, self::$supportChannel)) {
throw new PayException('sdk当前不支持该转账渠道,当前仅支持:' . implode(',', self::$supportChannel)); throw new PayException('sdk当前不支持该转账渠道' . $channel . ',当前仅支持:' . implode(',', self::$supportChannel));
} }
try { try {
$instance = self::getInstance($channel, $config); $instance = self::getInstance($channel, $config);
$ret = $instance->transfer($metadata); $ret = $instance->transfer($metadata);
} catch (PayException $e) { } catch (PayException $e) {
throw $e; throw $e;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace Payment; namespace Payment;
use Payment\Charge\Fu\FuClose; use Payment\Charge\Fu\FuClose;
use Payment\Charge\Lakala\LakalaClose;
use Payment\Charge\LTF\LTFClose; use Payment\Charge\LTF\LTFClose;
use Payment\Charge\Sw\SwClose; use Payment\Charge\Sw\SwClose;
use Payment\Charge\SwThree\SwThreeClose; use Payment\Charge\SwThree\SwThreeClose;
...@@ -15,7 +16,8 @@ use Payment\Common\PayException; ...@@ -15,7 +16,8 @@ use Payment\Common\PayException;
* *
* @package Payment * @package Payment
*/ */
class CloseContext{ class CloseContext
{
/** /**
* 关闭订单的渠道 * 关闭订单的渠道
...@@ -33,28 +35,32 @@ class CloseContext{ ...@@ -33,28 +35,32 @@ class CloseContext{
* @see Config * @see Config
* @author yeran * @author yeran
*/ */
public function initCloseHandler($channel, array $config){ public function initCloseHandler($channel, array $config)
try{ {
switch($channel){ try {
switch ($channel) {
case Config::SW_CHARGE: case Config::SW_CHARGE:
$this->closeHandler = new SwClose($config); $this->closeHandler = new SwClose($config);
break; break;
case Config::SW_T_CHARGE: case Config::SW_T_CHARGE:
$this->closeHandler = new SwThreeClose($config); $this->closeHandler = new SwThreeClose($config);
break; break;
case Config::FU_CHARGE: case Config::FU_CHARGE:
$this->closeHandler = new FuClose($config); $this->closeHandler = new FuClose($config);
break; break;
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->closeHandler = new LTFClose($config); $this->closeHandler = new LTFClose($config);
break; break;
case Config::YS_CHARGE: //易生支付 case Config::YS_CHARGE: //易生支付
$this->closeHandler = new YSClose($config); $this->closeHandler = new YSClose($config);
break; break;
case Config::LAKALA_CHARGE: // 拉卡拉
$this->closeHandler = new LakalaClose($config);
break;
default: default:
throw new PayException('当前仅支持:SW_CHARGE、FU_CHARGE、LTF_CHARGE'); throw new PayException('当前仅支持:SW_CHARGE、FU_CHARGE、LTF_CHARGE');
} }
}catch(PayException $e){ } catch (PayException $e) {
throw $e; throw $e;
} }
} }
...@@ -67,14 +73,15 @@ class CloseContext{ ...@@ -67,14 +73,15 @@ class CloseContext{
* @throws PayException * @throws PayException
* @author yeran * @author yeran
*/ */
public function close(array $data){ public function close(array $data)
if(!$this->closeHandler instanceof BaseStrategy){ {
if (!$this->closeHandler instanceof BaseStrategy) {
throw new PayException('请检查初始化是否正确'); throw new PayException('请检查初始化是否正确');
} }
try{ try {
return $this->closeHandler->handle($data); return $this->closeHandler->handle($data);
}catch(PayException $e){ } catch (PayException $e) {
throw $e; throw $e;
} }
} }
......
...@@ -60,22 +60,28 @@ abstract class BaseData ...@@ -60,22 +60,28 @@ abstract class BaseData
} elseif ($config instanceof FuConfig) { } elseif ($config instanceof FuConfig) {
$this->channel = Config::FU_PAY; $this->channel = Config::FU_PAY;
} elseif ($config instanceof LTFConfig) { } elseif ($config instanceof LTFConfig) {
$this->channel = Config::LTF_PAY; $this->channel = Config::LTF_PAY;
} elseif ($config instanceof YSConfig) { } elseif ($config instanceof YSConfig) {
$this->channel = Config::YS_PAY; $this->channel = Config::YS_PAY;
}elseif ($config instanceof YSEConfig) { } elseif ($config instanceof YSEConfig) {
$this->channel = Config::YSE_PAY; $this->channel = Config::YSE_PAY;
}elseif ($config instanceof SwThreeConfig) { } elseif ($config instanceof SwThreeConfig) {
$this->channel = Config::SW_T_PAY; $this->channel = Config::SW_T_PAY;
}elseif ($config instanceof WnfConfig) { } elseif ($config instanceof WnfConfig) {
$this->channel = Config::WNF_PAY; $this->channel = Config::WNF_PAY;
}elseif ($config instanceof HsqConfig) { } elseif ($config instanceof HsqConfig) {
$this->channel = Config::HSQ_PAY; $this->channel = Config::HSQ_PAY;
}elseif ($config instanceof HsqTransConfig) { } elseif ($config instanceof HsqTransConfig) {
$this->channel = Config::BAOFOO_PAY; $this->channel = Config::BAOFOO_PAY;
$tmp = $reqData;unset($reqData);$reqData['reqData'] = $tmp; $tmp = $reqData;
unset($reqData);
$reqData['reqData'] = $tmp;
} elseif ($config instanceof LakalaConfig) {
$this->channel = Config::LAKALA_PAY;
} }
$this->data = array_merge($config->toArray(), $reqData);//配置信息合并
$this->data = array_merge($config->toArray(), $reqData); //配置信息合并
try { try {
$this->checkDataParam(); $this->checkDataParam();
} catch (PayException $e) { } catch (PayException $e) {
...@@ -143,8 +149,11 @@ abstract class BaseData ...@@ -143,8 +149,11 @@ abstract class BaseData
break; break;
case Config::MI_PAY: case Config::MI_PAY:
$basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR; $basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR;
$this->cacertPath = "{$basePath}mipay" . DIRECTORY_SEPARATOR . "ldy_private_key.pem"; $this->cacertPath = "{$basePath}mipay" . DIRECTORY_SEPARATOR . "api_private_key.pem";
$this->retData['sign'] = ArrayUtil::SignRSA($data, $this->cacertPath);//签名 $this->retData['sign'] = ArrayUtil::SignRSA($data, $this->cacertPath); //签名
break;
case Config::LAKALA_PAY:
$this->retData['sign'] = $this->makeSign(json_encode($this->retData)); //签名
break; break;
case Config::SW_PAY: case Config::SW_PAY:
//添加令牌,参数由makesign函数自由控制 //添加令牌,参数由makesign函数自由控制
...@@ -168,13 +177,13 @@ abstract class BaseData ...@@ -168,13 +177,13 @@ abstract class BaseData
$this->retData['sign'] = $this->makeSign(mb_convert_encoding(ArrayUtil::createLinkstring($signData), 'gbk', 'utf-8')); $this->retData['sign'] = $this->makeSign(mb_convert_encoding(ArrayUtil::createLinkstring($signData), 'gbk', 'utf-8'));
unset($signData); unset($signData);
break; break;
case Config::LTF_PAY: case Config::LTF_PAY:
$signData = $data; $signData = $data;
$values = ArrayUtil::removeKeys($signData, ['sign']); $values = ArrayUtil::removeKeys($signData, ['sign']);
$values = ArrayUtil::arraySort($values); $values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values); $signStr = ArrayUtil::createLinkstring($values);
$this->makeSign($signStr); $this->makeSign($signStr);
break; break;
case Config::YS_PAY: case Config::YS_PAY:
$values = ArrayUtil::removeKeys($data, ['sign']); $values = ArrayUtil::removeKeys($data, ['sign']);
$values = ArrayUtil::arraySort($values); $values = ArrayUtil::arraySort($values);
......
<?php
namespace Payment\Common\Lakala\Data\Cancel;
use Payment\Common\Lakala\Data\LakalaBaseData;
/**
* Class BackCancelData
*
*
* @package Payment\Common\Sw\Data
*
*/
class BackCancelData extends LakalaBaseData
{
public function getData()
{
$this->retData['package'] = [
'recall' => $this->recall,//是否重新发起撤销
];
$this->retData['other'] = [
'merchant_no' => $this->merchant_no??'',
'trade_no' => $this->out_trade_no??'',
'out_trade_no' => $this->trade_no??'',
'trade_time' => $this->trade_time??'',
];
return parent::getData(); // TODO: Change the autogenerated stub
}
protected function buildData()
{
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
<?php
namespace Payment\Common\Lakala\Data\Cancel;
use Payment\Common\Lakala\Data\LakalaBaseData;
/**
* Class BackCloseData
*
*
* @package Payment\Common\Sw\Data
*
*/
class BackCloseData extends LakalaBaseData
{
public function getData()
{
$this->retData['package'] = [
'result_code' => $this->result_code,//"业务结果,01成功,表示关单成功,此笔订单不能再发起支付;
];
$this->retData['other'] = [
'merchant_no' => $this->merchant_no??'',
'trade_no'=> $this->origin_out_trade_no??'',
'out_trade_no'=> $this->origin_trade_no??'',
'trade_time' => $this->trade_time??'',
];
return parent::getData(); // TODO: Change the autogenerated stub
}
protected function buildData()
{
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
<?php
namespace Payment\Common\Lakala\Data\Cancel;
use Payment\Common\Lakala\Data\LakalaPayData;
/**
* Class CancelData
* 取消订单
*
*/
class CancelData extends LakalaPayData
{
protected function checkDataParam() {}
protected function buildData()
{
$this->retData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'out_trade_no' => $this->trade_no, // 商户消单流水号
'origin_out_trade_no' => $this->origin_trade_no, // 商户支付流水号
'location_info' => parent::locationInfo(),
];
parent::buildData();
}
}
<?php
namespace Payment\Common\Lakala\Data\Cancel;
use Payment\Common\Lakala\Data\LakalaPayData;
use Payment\Utils\ArrayUtil;
/**
* Class CloseData
* 关闭订单
*/
class CloseData extends LakalaPayData
{
protected function checkDataParam()
{
}
protected function buildData()
{
$this->retData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'origin_out_trade_no' => $this->trade_no, // 商户交易流水号
'location_info' => parent::locationInfo(),
];
parent::buildData();
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\PayException;
/**
* Class AliChargeData
* 拉卡拉支付宝支付
*
* @package Payment\Common\Lakala\Data\Charge
*
*/
class AliChargeData extends LiteChargeData
{
protected function checkDataParam()
{
parent::checkDataParam();
/**
* 微信:WECHAT
* 支付宝:ALIPAY
* 银联:UQRCODEPAY
* 翼支付: BESTPAY
* 苏宁易付宝: SUNING
* 拉卡拉支付账户:LKLACC
* 网联小钱包:NUCSPAY
* 京东钱包:JD
*/
$this->account_type = 'ALIPAY';
// 71:微信小程序支付
$this->trans_type = static::JSAPI;
}
protected function buildData()
{
$this->certainSignData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'out_trade_no' => $this->trade_no, // 商户交易流水号
'account_type' => $this->account_type,
'trans_type' => $this->trans_type, // 41:NATIVE(ALIPAY,云闪付支持,京东白条分期)51:JSAPI 61:APP支付 71:微信小程序
'total_amount' => $this->total_amount, // 金额,单位分
'subject' => $this->subject, // 用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
'location_info' => parent::locationInfo(),
'acc_busi_fields' => [
'user_id' => $this->open_id,
'disable_pay_channels' => 'credit_group',
'extend_params' => [
// 'sys_service_provider_id' => '',
]
],
];
$signData = array_merge($this->certainSignData, []);
if (isset($this->notify_url)) {
$signData['notify_url'] = $this->notify_url;
}
if (isset($this->settle_type)) {
$signData['settle_type'] = $this->settle_type; // “0”或者空,常规结算方式, 如需接拉卡拉分账通需传“1”,商户未开通分账之前切记不用上送此参数,如需订单结算需传“2”
}
if (!empty($this->timeout_express)) {
//预下单的订单的有效时间,以分钟为单位。建议不超过15分钟。不传值则默认5分钟。
$signData['acc_busi_fields']['timeout_express'] = $this->timeout_express;
}
if (!empty($this->goods_detail)) {
$signData['acc_busi_fields']['goods_detail'] = $this->goods_detail;
}
if (!empty($this->store_id)) {
// 该字段主要用于商户携带订单的自定义数据。商户定制字段,直接送到账户端
$signData['acc_busi_fields']['store_id'] = $this->store_id;
}
if (!empty($this->min_age)) {
// 该字段主要用于商户携带订单的自定义数据。商户定制字段,直接送到账户端
$signData['acc_busi_fields']['min_age'] = $this->min_age;
}
if (!empty($this->business_params)) {
// 该字段用于上报场景信息,目前支持上报实际门店信息
$signData['acc_busi_fields']['business_params'] = $this->business_params;
}
$this->retData = $signData;
parent::buildData();
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\Lakala\Data\LakalaBaseData;
/**
* Class BackAliChargeData
*
*
* @package Payment\Common\Lakala\Data
*
*/
class BackAliChargeData extends LakalaBaseData
{
public function getData()
{
$this->retData['qr_code'] = $this->acc_resp_fields['code'] ?? '';//二维码码串
if ($this->acc_resp_fields['prepay_id'] ?? '') {
$this->retData['jspackage'] = [
'prepay_id' => $this->acc_resp_fields['prepay_id'] ?? '',
'sub_mch_id' => $this->acc_resp_fields['sub_mch_id'] ?? '',
];
}
$this->retData['other'] = [
'merchant_no' => $this->merchant_no,
'settle_merchant_no' => $this->settle_merchant_no,
'term_no' => $this->term_no,
'settle_term_no' => $this->settle_term_no,
'trade_no' => $this->out_trade_no,
'out_trade_no' => $this->trade_no,
];
return parent::getData(); // TODO: Change the autogenerated stub
}
protected function buildData()
{
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\PayException;
/**
* Class BackLiteChargeData
*/
class BackLiteChargeData extends LakalaBaseData
{
public function getData()
{
$this->retData['jspackage'] = [
'timeStamp' => $this->acc_resp_fields['time_stamp'],
'nonceStr' => $this->acc_resp_fields['nonce_str'],
'package' => $this->acc_resp_fields['package'],
'signType' => $this->acc_resp_fields['sign_type'], // 签名算法,暂支持MD5
'paySign' => $this->acc_resp_fields['pay_sign']
];
$this->retData['other'] = [
'merchant_no' => $this->merchant_no,
'settle_merchant_no' => $this->settle_merchant_no,
'term_no' => $this->term_no,
'settle_term_no' => $this->settle_term_no,
'trade_no' => $this->out_trade_no,
'out_trade_no' => $this->trade_no,
];
return parent::getData();
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
/**
* 构建用于支付的签名相关数据
* @return array
*/
protected function buildData()
{
// TODO: Implement buildData() method.
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\Lakala\Data\Charge\BackLiteChargeData;
/**
* Class BackPubChargeData
* 小程序数据也在这里处理
* @property string $device_info 设备号
* @property string $trade_type 交易类型
* @property string $prepay_id 预支付交易会话标识
*
* @package Payment\Common\Lakala\Data
*
*/
class BackPubChargeData extends BackLiteChargeData
{
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\PayException;
/**
* Class BackScanChargeData
*
*
* @package Payment\Common\Lakala\Data
*
*/
class BackScanChargeData extends LakalaBaseData
{
public function getData()
{
$this->retData['qr_code'] = $this->qr_code;//二维码码串
$this->retData['other'] = [
'merchant_no' => $this->merchant_no,
'settle_merchant_no' => $this->settle_merchant_no,
'term_no' => $this->term_no,
'settle_term_no' => $this->settle_term_no,
'trade_no' => $this->out_trade_no,
'out_trade_no' => $this->trade_no,
];
return parent::getData(); // TODO: Change the autogenerated stub
}
protected function buildData()
{
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\PayException;
use Payment\Common\Lakala\Data\LakalaPayData;
use Payment\Common\LakalaConfig;
use Payment\Config;
/**
* Class ChargeBaseData
*
*
* @package Payment\Common\Lakala\Data\Charge
*/
abstract class ChargeBaseData extends LakalaPayData
{
const NATIVE = 41;
const JSAPI = 51;
const APP = 61;
const WXAPP = 71;
/**
* 检查传入的支付信息是否正确
*/
protected function checkDataParam()
{
// 检查订单号是否合法
if (empty($this->out_trade_no) || mb_strlen($this->out_trade_no) > 32) {
throw new PayException('商户系统的订单号不能为空且长度不能超过32位');
}
// 检查金额不能低于0.01
if ($this->total_amount < 1) {
throw new PayException('支付金额不能低于 ' . Config::PAY_MIN_FEE . ' 元');
}
// 检查 商品名称 与 商品描述
if (empty($this->term_no) || empty($this->merchant_no)) {
throw new PayException('必须提供终端号与商户号');
}
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
/**
* Class LiteChargeData
* 拉卡拉微信小程序支付
*
* @package Payment\Common\Lakala\Data\Charge
*
*/
class LiteChargeData extends ChargeBaseData
{
protected function checkDataParam()
{
parent::checkDataParam();
if (empty($this->sub_appid) || empty($this->open_id)) {
throw new PayException('小程序支付时需要小程序appid和open_id');
}
/**
* 微信:WECHAT
* 支付宝:ALIPAY
* 银联:UQRCODEPAY
* 翼支付: BESTPAY
* 苏宁易付宝: SUNING
* 拉卡拉支付账户:LKLACC
* 网联小钱包:NUCSPAY
* 京东钱包:JD
*/
$this->account_type = 'WECHAT';
// 71:微信小程序支付
$this->trans_type = static::WXAPP;
}
protected function buildData()
{
$this->certainSignData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'out_trade_no' => $this->trade_no ?? $this->out_trade_no, // 商户交易流水号
'account_type' => $this->account_type,
'trans_type' => $this->trans_type, // 41:NATIVE(ALIPAY,云闪付支持,京东白条分期)51:JSAPI 61:APP支付 71:微信小程序
'total_amount' => $this->total_amount, // 金额,单位分
'subject' => $this->subject, // 用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
'location_info' => parent::locationInfo(),
'acc_busi_fields' => [
'sub_appid' => $this->sub_appid,
'user_id' => $this->open_id,
],
];
$signData = array_merge($this->certainSignData, []);
if (isset($this->notify_url)) {
$signData['notify_url'] = $this->notify_url;
}
if (isset($this->settle_type)) {
$signData['settle_type'] = $this->settle_type; // “0”或者空,常规结算方式, 如需接拉卡拉分账通需传“1”,商户未开通分账之前切记不用上送此参数,如需订单结算需传“2”
}
if (!empty($this->timeout_express)) {
//预下单的订单的有效时间,以分钟为单位。建议不超过15分钟。不传值则默认5分钟。
$signData['acc_busi_fields']['timeout_express'] = $this->timeout_express;
}
if (!empty($this->goods_tag)) {
// 订单优惠标记,微信平台配置的商品标记,用于优惠券或者满减使用,accountType为WECHAT时,可选填此字段
$signData['acc_busi_fields']['goods_tag'] = $this->goods_tag;
}
if (!empty($this->goods_detail)) {
$signData['acc_busi_fields']['detail'] = $this->goods_detail;
}
if (!empty($this->attach)) {
// 该字段主要用于商户携带订单的自定义数据。商户定制字段,直接送到账户端
$signData['acc_busi_fields']['attach'] = $this->attach;
}
if (!empty($this->scene_info)) {
// 该字段用于上报场景信息,目前支持上报实际门店信息
$signData['acc_busi_fields']['scene_info'] = $this->scene_info;
}
$this->retData = $signData;
parent::buildData();
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
/**
* Class PubChargeData
* 拉卡拉微信公众号支付
*
* @package Payment\Common\Lakala\Data\Charge
*
*/
class PubChargeData extends LiteChargeData
{
protected function checkDataParam()
{
parent::checkDataParam();
$this->service_id = static::JSAPI;
}
}
<?php
namespace Payment\Common\Lakala\Data\Charge;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
/**
* Class ScanChargeData
*
* @inheritdoc
* @property string $auth_code 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
*
* @package Payment\Common\Lakala\Data\Charge
*/
class ScanChargeData extends ChargeBaseData
{
protected function checkDataParam()
{
parent::checkDataParam(); // TODO: Change the autogenerated stub
// 公众号支付,必须设置openid
$payType = $this->pay_type; //010微信,020支付宝,060qq钱包,090口碑,100翼支付
if ($payType == '010') {
if (empty($this->sub_appid))
throw new PayException('公众号appid,支付时使用的appid');
}
$this->service_id = '011';
}
/**
* 生成下单的数据
*/
protected function buildData()
{
$this->certainSignData = [
// 基本数据
'pay_ver' => trim($this->pay_ver),
'pay_type' => trim($this->pay_type),
'service_id' => $this->service_id,
'merchant_no' => $this->merchant_no,
'terminal_id' => $this->terminal_id,
'terminal_trace' => $this->terminal_trace,
'terminal_time' => $this->terminal_time,
'total_fee' => $this->total_fee, // 金额,单位分
// 'time_expire' => $this->timeout_express,
];
$signData = array_merge($this->certainSignData, []);
if (isset($this->sub_appid)) {
$signData['sub_appid'] = $this->sub_appid;
}
if (isset($this->order_body)) {
$signData['order_body'] = $this->order_body;
}
if (isset($this->notify_url)) {
$signData['notify_url'] = $this->notify_url;
}
if (isset($this->attach)) {
$signData['attach'] = $this->attach;
}
if (isset($this->goods_detail)) {
$signData['goods_detail'] = $this->goods_detail;
//goods_Id String N 商品编号
//goods_name String N 商品名称
//quantity String N 商品数量
//price String N 商品单价,单位为分
}
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
}
<?php
namespace Payment\Common\Lakala\Data;
use Payment\Common\BaseData;
use Payment\Common\PayException;
use Payment\Utils\LakalaCardBin;
use Payment\Utils\LakalaUpload;
/**
* Class BaseData
*
* @property null|string signType
*/
abstract class LakalaBaseData extends BaseData
{
/** 请求成功code 各业务可能不同 */
protected $succ_code;
/**
* 签名算法实现
* @param string $signStr
* @return string
*/
protected function makeSign($signStr)
{
$randomString = time() . sprintf('%02X', rand(0, 255));
$timestamp = time();
$data = $this->appid . "\n"
. $this->serial_no . "\n"
. $timestamp . "\n"
. $randomString . "\n"
. $signStr . "\n";
$sign = $this->rsaSign($data);
$authorization = sprintf(
'LKLAPI-SHA256withRSA appid="%s",serial_no="%s",timestamp="%d",nonce_str="%s",signature="%s"',
$this->appid,
$this->serial_no,
$timestamp,
$randomString,
$sign
);
return $authorization;
}
/**
* 生成 sha256WithRSA 签名
*/
private function rsaSign($content)
{
$privateKey = \openssl_pkey_get_private($this->private_key);
if (!$privateKey) {
throw new PayException('获取私钥失败');
}
$res = \openssl_sign($content, $sign, $privateKey, \OPENSSL_ALGO_SHA256);
if (\function_exists('openssl_free_key')) {
\openssl_free_key($privateKey);
}
if (!$res) {
throw new PayException('[10004] 拉卡拉字符串签名失败');
}
return \base64_encode($sign);
}
/**
* 获取业务成功code 各业务不同
* @return array
*/
public function getResponse($response)
{
if ($response['retCode'] != '000000') {
throw new PayException('拉卡拉返回错误提示:' . $response['retMsg']);
}
return $response['respData'];
}
protected function locationInfo()
{
return [
'request_ip' => $this->ip ?? '', //请求方的IP地址
// 'base_station' => '', // 客户端设备的基站信息(主扫时基站信息使用该字段)
// 'location' => '', // 商户终端的地理位置,银联二维码交易必填
];
}
/**
* 拉卡拉获取银行卡信息
*
* @param string $acct_no
*/
public function bankInfo($acct_no)
{
$cardBin = new LakalaCardBin($this->data);
return $cardBin->handle([
'card_no' => $acct_no,
]);
}
/**
* 拉卡拉获取银行卡信息
*
* @param string $att_type 图片类型
* @param string $pic_url 图片地址
* @return string 图片地址
*/
public function upload($att_type, $pic_url)
{
$cardBin = new LakalaUpload($this->data);
return $cardBin->handle(compact('att_type', 'pic_url'))['att_file_id'];
}
}
<?php
namespace Payment\Common\Lakala\Data;
use Payment\Common\PayException;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\LakalaConfig;
use Payment\Config;
/**
* Class ChargeBaseData
*
*
* @package Payment\Common\Lakala\Data\Charge
*/
abstract class LakalaPayData extends LakalaBaseData
{
protected $succ_code = 'BBS00000';
/**
* @inheritDoc
*/
protected function buildData()
{
$this->retData = [
'req_time' => date('YmdHis'),
'req_data' => $this->retData,
'version' => LakalaConfig::VERSION,
];
}
public function getResponse($response)
{
if ($response['code'] != $this->succ_code) {
throw new PayException('拉卡拉返回错误提示:' . ($response['message'] ?? $response['msg']));
}
return $response['resp_data'];
}
}
<?php
namespace Payment\Common\Lakala\Data;
use Payment\Common\PayException;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\LakalaConfig;
use Payment\Config;
/**
* Class ChargeBaseData
*
*
* @package Payment\Common\Lakala\Data\Charge
*/
abstract class LakalaV2Data extends LakalaBaseData
{
const VERSION = '1.0';
/**
* @inheritDoc
*/
protected function buildData()
{
$this->retData = [
'reqTime' => date('YmdHis'),
'reqData' => $this->retData,
'version' => static::VERSION,
'reqId' => md5(time()),
];
}
/**
* @inheritDoc
*/
public function getResponse($response)
{
if ($response['retCode'] != '000000') {
throw new PayException('拉卡拉返回错误提示:' . $response['retMsg']);
}
return $response['respData'];
}
}
<?php
namespace Payment\Common\Lakala\Data\Other;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackCardBinData extends LakalaBaseData
{
public function getData()
{
$this->retData = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'card_no' => $this->cardNo,
'card_name' => $this->cardName,
'card_type' => $this->cardType,
'bank_name' => $this->bankName,
'bank_code' => $this->bankCode,
'clear_bank_code' => $this->clearingBankCode,
];
return parent::getData();
}
protected function checkDataParam()
{
}
protected function buildData()
{
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Other;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackUploadData extends LakalaBaseData
{
public function getData()
{
$this->retData = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'org_code' => $this->orgCode,
'att_type' => $this->attType,
'att_file_id' => $this->attFileId,
];
return parent::getData();
}
protected function checkDataParam()
{
}
protected function buildData()
{
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Other;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\LakalaConfig;
use Payment\Common\PayException;
class CardBinData extends LakalaBaseData
{
/**
* @inheritDoc
*/
protected function checkDataParam()
{
if (empty($this->org_code)) {
throw new PayException('必须提供拉卡拉机构代码');
}
if (empty($this->card_no)) {
throw new PayException('必须提供卡号');
}
}
protected function buildData()
{
$this->retData = [
'timestamp' => time() . rand(100, 999),
'ver' => '1.0.0',
'reqId' => md5(time()),
'reqData' => [
'version' => '1.0',
'orderNo' => date('YmdHis') . rand(10000000, 99999999),
'orgCode' => $this->org_code,
'cardNo' => $this->card_no,
],
];
}
}
<?php
namespace Payment\Common\Lakala\Data\Other;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\LakalaConfig;
use Payment\Common\PayException;
class UploadData extends LakalaBaseData
{
/**
* @inheritDoc
*/
protected function checkDataParam()
{
if (empty($this->org_code)) {
throw new PayException('必须提供拉卡拉机构代码');
}
if (empty($this->att_type)) {
throw new PayException('必须提供附件类型');
}
if (empty($this->pic_url)) {
throw new PayException('必须提供图片地址');
}
}
protected function buildData()
{
$this->retData = [
'timestamp' => time() . rand(100, 999),
'ver' => '1.0.0',
'reqId' => md5(time()),
'reqData' => [
'version' => '1.0',
'orderNo' => date('YmdHis') . rand(10000000, 99999999),
'orgCode' => $this->org_code,
'attType' => $this->att_type,
'attExtName' => pathinfo($this->pic_url, \PATHINFO_EXTENSION),
'attContext' => base64_encode(@file_get_contents($this->pic_url)),
],
];
}
}
<?php
namespace Payment\Common\Lakala\Data\Query;
use Payment\Common\Lakala\Data\LakalaBaseData;
/**
* 查询交易的数据结构
* Class BackChargeQueryData
*
*
* @package Payment\Common\Lakala\Data\Query
*/
class BackChargeQueryData extends LakalaBaseData
{
protected function buildData()
{
$this->retData['package'] = [
'trade_state' => $this->trade_state ?? '',//交易订单状态 INIT-初始化 CREATE-下单成功 SUCCESS-交易成功 FAIL-交易失败 DEAL-交易处理中 UNKNOWN-未知状态 CLOSE-订单关闭 PART_REFUND-部分退款 REFUND-全部退款(或订单被撤销)
'user_id' => $this->user_id1 ?? $this->user_id2 ?? '',//付款方用户id,“微信openid”、“支付宝账户”、“qq号”等,返回时不参与签名
'pay_trace' => $this->trade_no,//当前支付终端流水号
'pay_time' => $this->trade_time,//当前支付终端交易时间
'log_no' => $this->log_no ?? '',
'total_fee' => $this->total_amount,
'end_time' => $this->end_time ?? '',
];
$this->retData['other'] = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'trade_main_type'=> $this->trade_main_type,
'split_attr' => $this->split_attr,
'split_info' => $this->split_info,
'acc_trade_no' => $this->acc_trade_no??'',
'out_trade_no' => $this->out_trade_no??'',//订单号
'trade_state_desc' => $this->trade_state_desc ?? '',
'acc_settle_amount' => $this->acc_settle_amount ?? '',
'acc_mdiscount_amount' => $this->acc_mdiscount_amount ?? '',
'acc_discount_amount' => $this->acc_discount_amount ?? '',
'acc_other_discount_amount' => $this->acc_other_discount_amount ?? '',
];
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Query;
use Payment\Common\PayException;
use Payment\Common\Lakala\Data\LakalaPayData;
use Payment\Utils\ArrayUtil;
/**
* 查询交易的数据结构
* Class ChargeQueryData
*
*
* @package Payment\Common\Lakala\Data\Query
*/
class ChargeQueryData extends LakalaPayData
{
protected function checkDataParam()
{
// 二者不能同时为空
if (empty($this->merchant_no) && empty($this->term_no)) {
throw new PayException('商户号、终端号都不能为空');
}
if (empty($this->trade_no)) {//订单号,查询凭据,可填利楚订单号、微信订单号、支付宝订单号、银行卡订单号任意一个
throw new PayException('交易订单号不能为空');
}
}
protected function buildData()
{
$this->retData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'out_trade_no' => $this->trade_no, // 商户交易流水号
];
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Refund;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackRefundData extends LakalaBaseData
{
public function getData()
{
$this->retData['package'] = [
'refund_amount' => $this->refund_amount, //退款金额,单位分
'payer_amount' => $this->payer_amount, //实际退款金额,单位分
'refund_no' => $this->out_trade_no, // 系统退款单号
'out_refund_no' => $this->trade_no, //第三方退款单号
'trade_no' => $this->origin_trade_no, // 原支付单号
'trade_time' => $this->trade_time, //退款完成时间,yyyyMMddHHmmss,全局统一时间格式
];
$this->retData['other'] = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'log_no' => $this->log_no,
'acc_trade_no' => $this->acc_trade_no,
'account_type' => $this->account_type,
'total_amount' => $this->total_amount,
];
return parent::getData();
}
protected function buildData()
{
;
}
protected function checkDataParam()
{
// 对于返回数据不做检查检查
}
}
<?php
namespace Payment\Common\Lakala\Data\Refund;
use Payment\Common\Lakala\Data\LakalaPayData;
use Payment\Common\PayException;
/**
* 退款
* Class RefundData
* @package Payment\Common\Hsq\Data
*/
class RefundData extends LakalaPayData
{
protected $succ_code = '00000';
protected function checkDataParam()
{
if (empty($this->order_no) || mb_strlen($this->order_no) > 32) throw new PayException('商户系统订单号不能为空且长度不能超过32位');
if (empty($this->refund_no) || mb_strlen($this->refund_no) > 32) throw new PayException('商户系统退款单号不能为空且长度不能超过32位');
$totalFee = intval($this->total_fee ?? 0); //订单总金额
$refundFee = intval($this->refund_amount ?? 0); //退款总金额
if (empty($totalFee) || empty($refundFee)) throw new PayException('订单总金额或退款金额有误');
if (bccomp($refundFee, $totalFee) === 1) throw new PayException('退款金额不能大于订单总金额');
}
protected function buildData()
{
$this->retData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'term_no' => $this->term_no, // 拉卡拉分配的业务终端号
'out_trade_no' => $this->refund_no, // 商户交易流水号
'origin_out_trade_no' => $this->order_no, // 下单时的商户请求流水号
'refund_amount' => $this->refund_amount,// 退款金额单位分
'refund_reason' => $this->refund_reason ?? '退款',
'refund_acc_mode' => '00', // 00退货账户余额 05商户余额 06终端余额 30终点账户
'refund_amt_sts' => '00', // 00 分账前,01 分账后;
'notify_url' => $this->notify_url ?? '',
'location_info' => parent::locationInfo(),
];
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\PayException;
class ApplyBindData extends LakalaLedgerData
{
protected function checkDataParam()
{
parent::checkDataParam();
if (empty($this->merchant_no)) {
throw new PayException('必须提供拉卡拉分账商户号');
}
if (empty($this->recv_no)) {
throw new PayException('必须提供拉卡拉分账接收方账号');
}
if (empty($this->entrust_file)) {
throw new PayException('必须提供合作协议文件');
}
if (empty($this->notify_url)) {
throw new PayException('必须提供回调地址');
}
}
protected function buildData()
{
$this->retData = [
// 基本数据
'version' => $this->version,
'orderNo' => $this->order_no, // 订单编号
'orgCode' => $this->org_code, // 机构代码
'merCupNo' => $this->merchant_no, // 分账商户商户号
'receiverNo' => $this->recv_no, // 分账接收方编号
'entrustFileName' => '合作协议.jpg',
'entrustFilePath' => $this->upload('SPLIT_COOPERATION_FILE', $this->entrust_file),
'retUrl' => $this->notify_url,
];
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\PayException;
class ApplyReciverData extends LakalaLedgerData
{
protected $succ_code = '000000';
protected function checkDataParam()
{
parent::checkDataParam();
$this->acct_type = $this->acct_type ?? '58';
if (empty($this->acct_name)) {
throw new PayException('必须提供收款账户名称');
}
if (empty($this->mobile)) {
throw new PayException('必须提供收联系手机号');
}
if (empty($this->bank_card_no)) {
throw new PayException('必须提供收款账户卡号');
}
if (empty($this->id_card_no)) {
throw new PayException('必须提供收款账户证件号');
}
if (empty($this->id_card_A_pic)) {
throw new PayException('必须提供收款账户证件正面');
}
if (empty($this->id_card_B_pic)) {
throw new PayException('必须提供收款账户证件反面');
}
if (empty($this->bank_card_pic)) {
throw new PayException('必须提供收款银行卡附件');
}
if ($this->acct_type == '57') {
if (empty($this->license_no)) {
throw new PayException('对公必须提供营业执照号码');
}
if (empty($this->license_name)) {
throw new PayException('对公必须提供营业执照名称');
}
if (empty($this->license_pic)) {
throw new PayException('对公必须提供营业执照附件');
}
if (empty($this->legal_name)) {
throw new PayException('对公必须提供法人名称');
}
}
}
protected function buildData()
{
$bankInfo = $this->bankInfo($this->bank_card_no);
$this->retData = [
// 基本数据
'version' => $this->version,
'orderNo' => $this->order_no, // 订单编号
'orgCode' => $this->org_code,
'acctTypeCode' => $this->acct_type, // 账户类型 57:对公 58:对私
'receiverName' => $this->acct_name,
'contactMobile' => $this->mobile,
'acctName' => $this->acct_name,
'acctNo' => $this->bank_card_no,
'acctCertificateType' => 17,
'acctCertificateNo' => $this->id_card_no,
'acctOpenBankCode' => $bankInfo['bank_code'],
'acctOpenBankName' => $bankInfo['bank_name'],
'acctClearBankCode' => $bankInfo['clear_bank_code'],
'attachList' => [
[
'attachType' => 'BANK_CARD',
'attachName' => '银行卡',
'attachStorePath' => $this->upload('BANK_CARD', $this->bank_card_pic),
]
],
'settleType' => '03', // 提款类型 01:主动提款 03:交易自动结算
];
if ($this->acct_type == '57') {
$this->retData['licenseNo'] = $this->license_no;
$this->retData['licenseName'] = $this->license_name;
$this->retData['legalPersonName'] = $this->legal_name;
$this->retData['legalPersonCertificateType'] = '17';
$this->retData['legalPersonCertificateNo'] = $this->id_card_no;
$this->retData['attachList'][] = [
'attachType' => 'FR_ID_CARD_FRONT',
'attachName' => '法人身份证正面',
'attachStorePath' => $this->upload('FR_ID_CARD_FRONT', $this->id_card_A_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'FR_ID_CARD_BEHIND',
'attachName' => '法人身份证反面',
'attachStorePath' => $this->upload('FR_ID_CARD_BEHIND', $this->id_card_B_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'BUSINESS_LICENCE',
'attachName' => '营业执照',
'attachStorePath' => $this->upload('BUSINESS_LICENCE', $this->license_pic),
];
} else {
$this->retData['attachList'][] = [
'attachType' => 'ID_CARD_FRONT',
'attachName' => '身份证正面',
'attachStorePath' => $this->upload('ID_CARD_FRONT', $this->id_card_A_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'ID_CARD_BEHIND',
'attachName' => '身份证反面',
'attachStorePath' => $this->upload('ID_CARD_BEHIND', $this->id_card_B_pic),
];
}
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackApplyBindData extends LakalaBaseData
{
public function getData()
{
$this->retData = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'order_no' => $this->orderNo,
'org_code' => $this->orgCode,
'apply_id' => $this->applyId,
];
return parent::getData();
}
protected function checkDataParam()
{
}
protected function buildData()
{
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackApplyReciverData extends LakalaBaseData
{
public function getData()
{
$this->retData = [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'order_no' => $this->orderNo,
'org_code' => $this->orgCode,
'org_id' => $this->orgId,
'org_name' => $this->orgName,
'receiver_no' => $this->receiverNo,
];
return parent::getData();
}
protected function checkDataParam()
{
}
protected function buildData()
{
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\Lakala\Data\LakalaBaseData;
class BackTransferData extends LakalaBaseData
{
public function getData()
{
$this->retData = [
'response' => [
'merchant_no' => $this->merchant_no,
'term_no' => $this->term_no,
'trans_no' => $this->out_separate_no,
'out_trade_no' => $this->separate_no,
'status' => $this->status,
'total_amt' => $this->total_amt,
],
'is_success' => 'T',
];
return parent::getData();
}
protected function checkDataParam()
{
}
protected function buildData()
{
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\Lakala\Data\LakalaV2Data;
use Payment\Common\PayException;
abstract class LakalaLedgerData extends LakalaV2Data
{
const VERSION = '2.0';
protected function checkDataParam()
{
$this->version = $this->version ?? '1.0';
$this->order_no = $this->order_no ?? date('YmdHis') . rand(10000000, 99999999);
if (empty($this->org_code)) {
throw new PayException('必须提供机构代码');
}
}
}
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\PayException;
class ModifyReciverData extends LakalaLedgerData
{
protected function checkDataParam()
{
parent::checkDataParam();
$this->acct_type = $this->acct_type ?? '58';
if (empty($this->recv_no)) {
throw new PayException('必须提供分账接收方编号');
}
if (empty($this->acct_name)) {
throw new PayException('必须提供收款账户名称');
}
if (empty($this->mobile)) {
throw new PayException('必须提供收联系手机号');
}
if (empty($this->bank_card_no)) {
throw new PayException('必须提供收款账户卡号');
}
if (empty($this->id_card_no)) {
throw new PayException('必须提供收款账户证件号');
}
if (empty($this->id_card_A_pic)) {
throw new PayException('必须提供收款账户证件正面');
}
if (empty($this->id_card_B_pic)) {
throw new PayException('必须提供收款账户证件反面');
}
if (empty($this->bank_card_pic)) {
throw new PayException('必须提供收款银行卡附件');
}
if ($this->acct_type == '57') {
if (empty($this->license_no)) {
throw new PayException('对公必须提供营业执照号码');
}
if (empty($this->license_name)) {
throw new PayException('对公必须提供营业执照名称');
}
if (empty($this->license_pic)) {
throw new PayException('对公必须提供营业执照附件');
}
if (empty($this->legal_name)) {
throw new PayException('对公必须提供法人名称');
}
}
}
protected function buildData()
{
$bankInfo = $this->bankInfo($this->bank_card_no);
$this->retData = [
// 基本数据
'version' => $this->version,
'orderNo' => $this->order_no, // 订单编号
'acctTypeCode' => $this->acct_type, // 账户类型 57:对公 58:对私
'orgCode' => $this->org_code,
'receiverNo' => $this->recv_no,
'receiverName' => $this->acct_name,
'contactMobile' => $this->mobile,
'acctName' => $this->acct_name,
'acctNo' => $this->bank_card_no,
'acctCertificateType' => 17,
'acctCertificateNo' => $this->id_card_no,
'acctOpenBankCode' => $bankInfo['bank_code'],
'acctOpenBankName' => $bankInfo['bank_name'],
'acctClearBankCode' => $bankInfo['clear_bank_code'],
'attachList' => [
[
'attachType' => 'BANK_CARD',
'attachName' => '银行卡',
'attachStorePath' => $this->upload('BANK_CARD', $this->bank_card_pic),
]
],
'status' => 'VALID', // 接收方状态 有效:VALID 无效:INVALID
];
if ($this->acct_type == '57') {
$this->retData['licenseNo'] = $this->license_no;
$this->retData['licenseName'] = $this->license_name;
$this->retData['legalPersonName'] = $this->legal_name;
$this->retData['legalPersonCertificateType'] = '17';
$this->retData['legalPersonCertificateNo'] = $this->id_card_no;
$this->retData['attachList'][] = [
'attachType' => 'FR_ID_CARD_FRONT',
'attachName' => '法人身份证正面',
'attachStorePath' => $this->upload('FR_ID_CARD_FRONT', $this->id_card_A_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'FR_ID_CARD_BEHIND',
'attachName' => '法人身份证反面',
'attachStorePath' => $this->upload('FR_ID_CARD_BEHIND', $this->id_card_B_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'BUSINESS_LICENCE',
'attachName' => '营业执照',
'attachStorePath' => $this->upload('BUSINESS_LICENCE', $this->license_pic),
];
} else {
$this->retData['attachList'][] = [
'attachType' => 'ID_CARD_FRONT',
'attachName' => '身份证正面',
'attachStorePath' => $this->upload('ID_CARD_FRONT', $this->id_card_A_pic),
];
$this->retData['attachList'][] = [
'attachType' => 'ID_CARD_BEHIND',
'attachName' => '身份证反面',
'attachStorePath' => $this->upload('ID_CARD_BEHIND', $this->id_card_B_pic),
];
}
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala\Data\Transfer;
use Payment\Common\Lakala\Data\LakalaPayData;
use Payment\Common\PayException;
class TransferData extends LakalaPayData
{
protected $succ_code = 'SACS0000';
protected function checkDataParam()
{
if (empty($this->trans_no)) {
throw new PayException('必须提供商户订单号');
}
if (empty($this->merchant_no)) {
throw new PayException('必须提供拉卡拉分账商户号');
}
if (empty($this->recv_no)) {
throw new PayException('必须提供拉卡拉分账接收方账号');
}
if (empty($this->amount) || $this->amount < 0){
throw new PayException('必须提供转账金额');
}
}
protected function buildData()
{
$this->retData = [
// 基本数据
'merchant_no' => $this->merchant_no, // 拉卡拉分配的商户号
'out_separate_no' => $this->trans_no, // 商户交易流水号
'total_amt' => round($this->amount / 90 * 100 * 100), // 交易金额 单位分
'cal_type' => 1, // 分账计算类型 0- 按照指定金额,1- 按照指定比例。默认 0
'recv_datas' => [
[
'recv_no' => $this->merchant_no,
'separate_value' => 0.1, // 10%
],
[
'recv_no' => $this->recv_no,
'separate_value' => 0.9, // 90%
]
],
];
$this->notify_url AND $this->retData['notify_url'] = $this->notify_url;
parent::buildData();
}
}
\ No newline at end of file
<?php
namespace Payment\Common\Lakala;
use Payment\Common\BaseData;
use Payment\Common\BaseStrategy;
use Payment\Common\Lakala\Data\LakalaBaseData;
use Payment\Common\PayException;
use Payment\Common\LakalaConfig;
use Payment\Utils\ArrayUtil;
use Payment\Utils\Curl;
abstract class LakalaBaseStrategy implements BaseStrategy
{
/** @var LakalaConfig */
protected $config;
/**
* 支付数据
* @var LakalaBaseData $reqData
*/
protected $reqData;
/**
* LakalaBaseStrategy constructor.
* @param array $config
* @throws PayException
*/
public function __construct(array $config)
{
try {
$this->config = new LakalaConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 发送完了请求
* @param array $body
* @return mixed
* @throws PayException
*/
protected function sendReq($body)
{
$url = $this->getReqUrl();
if (is_null($url)) {
throw new PayException('目前不支持该接口。请联系开发者添加');
}
$responseTxt = $this->curlPost($body, $url);
payLogs('lakala-req-response:' . json_encode($responseTxt));
if ($responseTxt['error']) {
// throw new PayException('网络发生错误,请稍后再试curl返回码:' . $responseTxt['message']);
}
// 格式化为数组
$retData = json_decode($responseTxt['body'], true);
return $this->reqData->getResponse($retData);
}
protected function curlPost($body, $url)
{
payLogs('lakala-req-url:' . $url);
$curl = new Curl();
$this_header = [
'Content-Type: application/json',
'Accept: application/json',
'Authorization: ' . $body['sign'],
];
payLogs('lakala-req-body:' . json_encode($body));
unset($body['sign']);
return $curl->set([
'CURLOPT_HEADER' => 0,
'CURLOPT_HTTPHEADER' => $this_header
])->post($body, $url)->submit($url, false, true);
}
/**
* 获取需要的url 默认返回下单的url,根据实际情况,需要被覆写
* 默认是h5支付
*
* @param null $url
* @return null|string
*/
protected function getReqUrl($url = null)
{
if (isset($this->config->base_url) && !empty($this->config->base_url)) {
$_pre = $this->config->base_url;
} else {
$_pre = LakalaConfig::BASE_URL;
}
return $_pre . ($url ?? LakalaConfig::UNIFIED_URL);
}
/**
* @param array $data
*
* @throws PayException
* @return array|string
*/
public function handle(array $data)
{
$buildClass = $this->getBuildDataClass();
try {
$this->reqData = new $buildClass($this->config, $data);
} catch (PayException $e) {
throw $e;
}
$this->reqData->setSign();
$body = $this->reqData->getData();
$ret = $this->sendReq($body);
// 检查返回的数据是否被篡改
$flag = true; // $this->verifySign($ret);
if (!$flag) {
throw new PayException('返回数据被篡改。请检查网络是否安全!');
}
return $this->retData($ret);
}
/**
* 处理微信的返回值并返回给客户端
* @param array $ret
* @return mixed
*
*/
protected function retData(array $ret)
{
return $ret;
}
/**
* 检查微信返回的数据是否被篡改过
* @param array $retData
* @return boolean
*
*/
protected function verifySign(array $retData)
{
$retSign = $retData['sign'];
$values = ArrayUtil::removeKeys($retData, ['sign', 'sign_type']);
$values = ArrayUtil::paraFilter($values);
$values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values);
$signStr .= '&key=';
switch ($this->config->signType) {
case 'MD5':
$sign = md5($signStr);
break;
case 'HMAC-SHA256':
$sign = hash_hmac('sha256', $signStr, '');
break;
default:
$sign = '';
}
return strtoupper($sign) === $retSign;
}
}
<?php
namespace Payment\Common\Lakala;
class LakalaSM4
{
/** @var static */
private static $instance;
const SM4_CK = [
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
];
const SM4_SBOX = [
0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,
0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,
0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,
0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,
0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,
0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,
0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,
0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,
0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,
0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,
0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,
0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,
0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,
0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,
0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
];
const SM4_FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
public $_rk = [];
public $_block_size = 16;
public static function instance()
{
static::$instance = static::$instance ?? new static;
return static::$instance;
}
/**
* sm4加密(ecb)
* @param $key 16位十六进制的字符,比如asw34a5ses5w81wf
* @param $data 原始数据
* @return string
*/
public function encrypt($key, $data)
{
$this->sm4KeySchedule($key);
$bytes = $this->pad($data, $this->_block_size);
$chunks = array_chunk($bytes, $this->_block_size);
$ciphertext = "";
foreach ($chunks as $chunk) {
$ciphertext .= $this->sm4Encrypt($chunk);
}
return base64_encode($ciphertext);
}
/**
* sm4解密
* @param $key
* @param $data
* @return bool|string
*/
public function decrypt($key, $data)
{
$data = base64_decode($data);
if (strlen($data) < 0 || strlen($data) % $this->_block_size != 0) {
return false;
}
$this->sm4KeySchedule($key);
$bytes = unpack("C*", $data);
$chunks = array_chunk($bytes, $this->_block_size);
$plaintext = "";
foreach ($chunks as $chunk) {
$plaintext .= substr($this->sm4Decrypt($chunk), 0, 16);
}
$plaintext = $this->unPad($plaintext);
return $plaintext;
}
private function sm4Decrypt($cipherText)
{
$x = [];
for ($j=0; $j<4; $j++) {
$x[$j]=($cipherText[$j*4]<<24) |($cipherText[$j*4+1]<<16)| ($cipherText[$j*4+2]<<8)|($cipherText[$j*4+3]);
}
for ($i=0; $i<32; $i++) {
$tmp = $x[$i+1]^$x[$i+2]^$x[$i+3]^$this->_rk[31-$i];
$buf= (self::SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 |(self::SM4_SBOX[($tmp >> 16) & 0xFF]) << 16 |(self::SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 |(self::SM4_SBOX[$tmp & 0xFF]);
$x[$i+4]=$x[$i]^($buf^$this->sm4Rotl32(($buf), 2)^ $this->sm4Rotl32(($buf), 10) ^ $this->sm4Rotl32(($buf), 18)^ $this->sm4Rotl32(($buf), 24));
}
$plainText = [];
for ($k=0; $k<4; $k++) {
$plainText[4*$k]=($x[35-$k]>> 24)& 0xFF;
$plainText[4*$k+1]=($x[35-$k]>> 16)& 0xFF;
$plainText[4*$k+2]=($x[35-$k]>> 8)& 0xFF;
$plainText[4*$k+3]=($x[35-$k])& 0xFF;
}
return $this->bytesToString($plainText);
}
private function sm4Encrypt($plainText)
{
$x = [];
for ($j=0; $j<4; $j++) {
$x[$j]=($plainText[$j*4]<<24) |($plainText[$j*4+1]<<16)| ($plainText[$j*4+2]<<8)|($plainText[$j*4+3]);
}
for ($i=0; $i<32; $i++) {
$tmp = $x[$i+1]^$x[$i+2]^$x[$i+3]^$this->_rk[$i];
$buf= (self::SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 |(self::SM4_SBOX[($tmp >> 16) & 0xFF]) << 16 |(self::SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 |(self::SM4_SBOX[$tmp & 0xFF]);
$x[$i+4]=$x[$i]^($buf^$this->sm4Rotl32(($buf), 2)^ $this->sm4Rotl32(($buf), 10) ^ $this->sm4Rotl32(($buf), 18)^ $this->sm4Rotl32(($buf), 24));
}
$cipherText = [];
for ($k=0; $k<4; $k++) {
$cipherText[4*$k]=($x[35-$k]>> 24)& 0xFF;
$cipherText[4*$k+1]=($x[35-$k]>> 16)& 0xFF;
$cipherText[4*$k+2]=($x[35-$k]>> 8)& 0xFF;
$cipherText[4*$k+3]=($x[35-$k])& 0xFF;
}
return $this->bytesToString($cipherText);
}
private function stringToBytes($string)
{
return unpack('C*', $string);
}
private function bytesToString($bytes)
{
return vsprintf(str_repeat('%c', count($bytes)), $bytes);
}
private function pad($data)
{
$bytes = $this->stringToBytes($data);
$rem = $this->_block_size - count($bytes) % $this->_block_size;
for ($i = 0; $i < $rem; $i++) {
array_push($bytes, $rem);
}
return $bytes;
}
private function unPad($data)
{
$bytes = $this->stringToBytes($data);
$rem = $bytes[count($bytes)];
$bytes = array_slice($bytes, 0, count($bytes) - $rem);
return $this->bytesToString($bytes);
}
private function sm4Rotl32($buf, $n)
{
return (($buf << $n) & 0xffffffff) | ($buf >> (32-$n));
}
private function sm4KeySchedule($key)
{
$this->_rk = [];
$key = array_values(unpack("C*", $key));
$k = [];
for ($i=0; $i<4; $i++) {
$k[$i] = self::SM4_FK[$i]^(($key[4*$i]<<24) | ($key[4*$i+1]<<16) |($key[4*$i+2]<<8) | ($key[4*$i+3]));
}
for ($j=0; $j<32; $j++) {
$tmp = $k[$j+1]^$k[$j+2]^$k[$j+3]^ self::SM4_CK[$j];
$buf = (self::SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 |(self::SM4_SBOX[($tmp >> 16) & 0xFF]) << 16 |(self::SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 |(self::SM4_SBOX[$tmp & 0xFF]);
$k[$j+4]=$k[$j]^(($buf)^($this->sm4Rotl32(($buf), 13))^($this->sm4Rotl32(($buf), 23)));
$this->_rk[$j]=$k[$j+4];
}
}
}
<?php
namespace Payment\Common;
use Payment\Utils\ArrayUtil;
final class LakalaConfig extends ConfigInterface
{
public $base_url;
public $appid; // appid
public $merchant_no;//商户号
public $term_no;//终端号
public $serial_no; // 证书序列号
public $org_code; // 机构代码
public $private_key; // 私钥
public $mer_inner_no; // 分账商户号
public $entrust_file; // 合作协议
public $sub_appid;// 微信分配的公众账号ID,公众号支付时使用的appid(若传入,则open_id需要保持一致)
public $certainSignData = null;//专门用于签名的数组
public $sign_sort = false;//签名是否需要字典排序
// 指定回调页面
public $notify_url;
const VERSION = 3; //版本号
const VERSION_1 = 1.0; //版本号
const BASE_URL = 'https://s2.lakala.com'; //'https://test.wsmsd.cn/sit';
const UNIFIED_URL = '/api/v3/labs/trans/preorder'; // 主扫支付
const SCANPAY_URL = '/api/v3/labs/trans/micropay'; // 被扫支付(预支付)
const FACEPAY_URL = '/pay/110/facepay';//自助收银
const BARCODE_URL = '/pay/100/barcodepay';//刷卡(条码)支付
const FACEPAY_ACCESSTOKEN_URL = '/pay/110/faceinfo';//自助收银SDK调用凭证获取接口
const AUTH_OPENID = '/wx/jsapi/authopenid';//用于服务商通道获取微信openid,Method:GET
const AUTHCODE_TO_OPENID_URL = '/pay/110/authcodetoopenid';//授权码查询 OPENID 接口
const CHARGE_QUERY_URL = '/api/v3/labs/query/tradequery'; // 支付查询url
const REFUND_URL = '/api/v3/rfd/refund_front/refund'; // 申请退款url
const CANCEL_URL = '/api/v3/labs/relation/revoked'; //撤销交易(只针对刷卡支付)
const CLOSE_URL = '/api/v3/labs/relation/close'; //关闭订单(仅限服务商模式商户且为微信支付时可用)
const TRANSFER_URL = '/api/v3/sacs/balanceSeparate'; //余额分账
const APPLY_RECEVER_URL = '/api/v2/mms/openApi/ledger/applyLedgerReceiver';
const MODIFY_RECEVER_URL = '/api/v2/mms/openApi/ledger/modifyLedgerReceiver';
const APPLY_BIND_URL = '/api/v2/mms/openApi/ledger/applyBind';
const CARD_BIN = '/api/v2/mms/openApi/cardBin';
const UPLOAD_FILE = '/api/v2/mms/openApi/uploadFile';
/**
* 初始化微信配置文件
* WxConfig constructor.
* @param array $config
* @throws PayException
*/
public function __construct(array $config)
{
try {
$this->initConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 初始化配置文件参数
* @param array $config
* @throws PayException
*/
private function initConfig(array $config)
{
$config = ArrayUtil::paraFilter($config);
if (key_exists('appid', $config) && !empty($config['appid'])) {
$this->appid = $config['appid'];
} else {
throw new PayException('必须提供拉卡拉APPID');
}
if (key_exists('merchant_no', $config) && !empty($config['merchant_no'])) {
$this->merchant_no = $config['merchant_no'];
} else {
throw new PayException('必须提供SW商户号');
}
if (key_exists('term_no', $config) && !empty($config['term_no'])) {
$this->term_no = $config['term_no'];
} else {
throw new PayException('必须提供SW终端号');
}
if (key_exists('serial_no', $config) && !empty($config['serial_no'])) {
$this->serial_no = $config['serial_no'];
} else {
throw new PayException('必须提供证书序列号');
}
if (key_exists('org_code', $config) && !empty($config['org_code'])) {
$this->org_code = $config['org_code'];
} else {
throw new PayException('必须提供机构代码');
}
if (key_exists('private_key', $config) && !empty($config['private_key'])) {
$this->private_key = $config['private_key'];
} else {
throw new PayException('必须提供私钥证书');
}
if (key_exists('sub_appid', $config) && !empty($config['sub_appid'])) {
$this->sub_appid = $config['sub_appid'];
}
if (key_exists('mer_inner_no', $config) && !empty($config['mer_inner_no'])) {
$this->mer_inner_no = trim($config['mer_inner_no']);
}
if (key_exists('entrust_file', $config) && !empty($config['entrust_file'])) {
$this->entrust_file = trim($config['entrust_file']);
}
// 检查 异步通知的url
if (key_exists('notify_url', $config) && !empty($config['notify_url'])) {
$this->notify_url = trim($config['notify_url']);
}
if (key_exists('base_url', $config)) {
$this->base_url = trim($config['base_url']);
}
}
}
...@@ -44,6 +44,8 @@ final class Config{ ...@@ -44,6 +44,8 @@ final class Config{
const BAOFOO_PAY = 'baofoopay'; //宝付代付 const BAOFOO_PAY = 'baofoopay'; //宝付代付
const LAKALA_PAY = 'lakala'; // 拉卡拉
//========================= 金额问题设置 =======================// //========================= 金额问题设置 =======================//
const PAY_MIN_FEE = '0.01';// 支付的最小金额 const PAY_MIN_FEE = '0.01';// 支付的最小金额
...@@ -301,9 +303,26 @@ final class Config{ ...@@ -301,9 +303,26 @@ final class Config{
const HSQ_QUERY_TRANSFER = 'hsq_query_transfer'; //宝付代付交易状态查证接口 const HSQ_QUERY_TRANSFER = 'hsq_query_transfer'; //宝付代付交易状态查证接口
//========================= 拉卡拉相关 ==========================//
// https://o.lakala.com/open/document/
const LAKALA_CHANNEL_PUB = 'lkl_pub';// 微信公众号h5支付
const LAKALA_CHANNEL_LITE = 'lkl_lite';// 小程序支付
const LAKALA_CHANNEL_ALI = 'lkl_ali';// 支付宝
const LAKALA_CHANNEL_SCAN = 'lkl_scan';// 扫码支付
const LAKALA_CHARGE = 'lkl_charge';// 统一下单
const LAKALA_REFUND = 'lkl_refund';// 退款
const LAKALA_CANCEL = 'lkl_cancel';// 交易撤销,只能撤销当天的交易,全额退款,实时返回退款结果
const LAKALA_CLOSE = 'lkl_close'; // 关单
const LAKALA_QUERY = 'lkl_query'; // 查询接口
const LAKALA_TRANSFER = 'lkl_transfer'; // 拉卡拉转账交易
} }
<?php
namespace Payment\Notify;
use Payment\Common\PayException;
use Payment\Common\LakalaConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;
class LakalaNotifty extends NotifyStrategy
{
public function __construct(array $config)
{
parent::__construct($config);
try {
$this->config = new LakalaConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 获取返回的异步通知数据
* @return array|bool
* @author yeran
*/
public function getNotifyData()
{
//支持直接读取input流
$data = file_get_contents('php://input');
if (empty($data)) { //如果参数为空,则不进行处理
return false;
}
return json_decode($data, true);
}
/**
* 检查异步通知的数据是否正确
* @param array $data
*/
public function checkNotifyData(array $data)
{
// 检查返回数据签名是否正确
return $this->verifySign($data);
}
/**
* 检查微信返回的数据是否被篡改过
* @param array $retData
*/
protected function verifySign(array $retData)
{
return true;
if (empty($this->config->key)) return false;
if (empty($this->config->publicKey)) return false;
$key = $this->config->key;
$publicKey = $this->config->publicKey;
if (is_file($publicKey)) {
$publicKey = openssl_get_publickey(file_get_contents($publicKey));
} else {
$publicKey = $this->config->publicKey;
}
if (empty($publicKey)) return false;
$sign = $retData['sign'];
//固定格式拼接后
$signArr = [
'method' => $retData['method'],
'version' => $retData['version'],
'format' => $retData['format'],
'merchantNo' => $retData['merchantNo'],
'signType' => $retData['signType'],
'signContent' => $retData['signContent'],
'key' => $key,
];
$signStr = ArrayUtil::createLinkstring($signArr);
//验签
$result = openssl_verify($signStr, hex2bin($sign), $publicKey, OPENSSL_ALGO_SHA256);
if ($result) {
return true; //验签成功
} else {
return false;
}
}
/**
* 封装回调函数需要的数据格式
*
* @param array $data
*/
protected function getRetData(array $data)
{
$retData = [
'openid' => $data['user_id1'] ?: $data['user_id2'] ?: '',
'order_no' => $data['out_trade_no'], // 商户交易流水号
'transaction_id' => $data['out_trade_no'], // 商户交易流水号
'amount' => $data['total_amount'], // 订单金额
'trade_status' => $data['trade_status'], // 交易状态INIT-初始化 CREATE-下单成功 SUCCESS-交易成功 FAIL-交易失败 DEAL-交易处理中 UNKNOWN-未知状态 CLOSE-订单关闭 PART_REFUND-部分退款 REFUND-全部退款 REVOKED-订单撤销
'pay_time' => $data['trade_time'],
'outtrxid' => $data['trade_no'], // 拉卡拉交易流水号
'chnltrxid' => $data['acc_trade_no'], // 账户端交易订单号
'bank_type' => $data['bank_type'] ?? '',
'channel' => Config::LAKALA_CHARGE,
];
return $retData;
}
/**
* 处理完后返回的数据格式
* @param bool $flag
* @param string $msg 通知信息,错误原因
* @author yeran
* @return string
*/
protected function replyNotify($flag, $message = 'OK')
{
// 默认为成功
$code = 'SUCCESS';
if (!$flag) {
$code = 'FAIL';
}
return compact('code', 'message');
}
}
<?php
namespace Payment\Notify;
use Payment\Common\PayException;
use Payment\Common\LakalaConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;
class LakalaTransferNotifty extends NotifyStrategy
{
public function __construct(array $config)
{
parent::__construct($config);
try {
$this->config = new LakalaConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 获取返回的异步通知数据
* @return array|bool
* @author yeran
*/
public function getNotifyData()
{
//支持直接读取input流
$data = file_get_contents('php://input');
if (empty($data)) { //如果参数为空,则不进行处理
return false;
}
return json_decode($data, true);
}
/**
* 检查异步通知的数据是否正确
* @param array $data
*/
public function checkNotifyData(array $data)
{
// 检查返回数据签名是否正确
return $this->verifySign($data);
}
/**
* 检查微信返回的数据是否被篡改过
* @param array $retData
*/
protected function verifySign(array $retData)
{
return true;
if (empty($this->config->key)) return false;
if (empty($this->config->publicKey)) return false;
$key = $this->config->key;
$publicKey = $this->config->publicKey;
if (is_file($publicKey)) {
$publicKey = openssl_get_publickey(file_get_contents($publicKey));
} else {
$publicKey = $this->config->publicKey;
}
if (empty($publicKey)) return false;
$sign = $retData['sign'];
//固定格式拼接后
$signArr = [
'method' => $retData['method'],
'version' => $retData['version'],
'format' => $retData['format'],
'merchantNo' => $retData['merchantNo'],
'signType' => $retData['signType'],
'signContent' => $retData['signContent'],
'key' => $key,
];
$signStr = ArrayUtil::createLinkstring($signArr);
//验签
$result = openssl_verify($signStr, hex2bin($sign), $publicKey, OPENSSL_ALGO_SHA256);
if ($result) {
return true; //验签成功
} else {
return false;
}
}
/**
* 封装回调函数需要的数据格式
*
* @param array $data
*/
protected function getRetData(array $data)
{
$retData = [
'trans_no' => $data['out_separate_no'], // 商户交易流水号
'out_trans_no' => $data['separate_no'], // 拉卡拉交易流水号
'amount' => $data['detail_datas'][1]['amt'], // 转账金额
'state' => $data['status'] == 'SUCCESS' ? 1 : ($data['status'] == 'FAIL' ? 2 : -1), // SUCCESS:成功,FAIL:失败
'trans_remark' => $data['result_desc'], // 拉卡拉交易流水号
'channel' => Config::LAKALA_TRANSFER,
];
return $retData;
}
/**
* 处理完后返回的数据格式
* @param bool $flag
* @param string $msg 通知信息,错误原因
* @author yeran
* @return string
*/
protected function replyNotify($flag, $message = 'OK')
{
// 默认为成功
$code = 'SUCCESS';
if (!$flag) {
$code = 'FAIL';
}
return compact('code', 'message');
}
}
...@@ -23,6 +23,8 @@ use Payment\Notify\YSNotify; ...@@ -23,6 +23,8 @@ use Payment\Notify\YSNotify;
use Payment\Notify\YSENotify; use Payment\Notify\YSENotify;
use Payment\Notify\HsqNotify; use Payment\Notify\HsqNotify;
use Payment\Notify\HsqTransferNotify; use Payment\Notify\HsqTransferNotify;
use Payment\Notify\LakalaNotifty;
use Payment\Notify\LakalaTransferNotifty;
class NotifyContext class NotifyContext
{ {
...@@ -85,9 +87,14 @@ class NotifyContext ...@@ -85,9 +87,14 @@ class NotifyContext
case Config::HSQ_TRANSFER: case Config::HSQ_TRANSFER:
$this->notify = new HsqTransferNotify($config); $this->notify = new HsqTransferNotify($config);
break; break;
case Config::LAKALA_CHARGE:
$this->notify = new LakalaNotifty($config);
break;
case Config::LAKALA_TRANSFER:
$this->notify = new LakalaTransferNotifty($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE TL_CHARGE MI_CHARGE SW_CHARGE FU_CHARGE HSQ_CHARGE '); throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE TL_CHARGE MI_CHARGE SW_CHARGE FU_CHARGE HSQ_CHARGE LAKALA_TRANSFER');
} }
} catch (PayException $e) { } catch (PayException $e) {
throw $e; throw $e;
......
<?php
namespace Payment\Query\Sw;
use Payment\Common\Lakala\Data\Query\BackChargeQueryData;
use Payment\Common\Lakala\Data\Query\ChargeQueryData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaChargeQuery extends LakalaBaseStrategy
{
/**
* 返回查询订单的数据
*
*/
public function getBuildDataClass()
{
return ChargeQueryData::class;
}
/**
* 返回微信查询的url
* @param null $url
* @return string
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::CHARGE_QUERY_URL);
}
/**
* 处理通知的返回数据
* @param array $ret
* @return mixed
*
*/
protected function retData(array $ret)
{
$back = new BackChargeQueryData($this->config, $ret);
$backData = $back->getData();
// 移除sign
unset($backData['sign']);
return $backData;
}
}
...@@ -33,6 +33,7 @@ use Payment\Query\WNF\WNFChargeQuery; ...@@ -33,6 +33,7 @@ use Payment\Query\WNF\WNFChargeQuery;
use Payment\Query\Hsq\HsqChargeQuery; use Payment\Query\Hsq\HsqChargeQuery;
use Payment\Query\Hsq\HsqRefundQuery; use Payment\Query\Hsq\HsqRefundQuery;
use Payment\Query\Hsq\HsqTransferQuery; use Payment\Query\Hsq\HsqTransferQuery;
use Payment\Query\Sw\LakalaChargeQuery;
class QueryContext class QueryContext
{ {
...@@ -59,17 +60,16 @@ class QueryContext ...@@ -59,17 +60,16 @@ class QueryContext
case Config::ALI_CHARGE: case Config::ALI_CHARGE:
$this->query = new AliChargeQuery($config); $this->query = new AliChargeQuery($config);
break; break;
case Config::ALI_REFUND:// 支付宝退款订单查询 case Config::ALI_REFUND: // 支付宝退款订单查询
$this->query = new AliRefundQuery($config); $this->query = new AliRefundQuery($config);
break; break;
case Config::ALI_TRANSFER: case Config::ALI_TRANSFER:
$this->query = new AliTransferQuery($config); $this->query = new AliTransferQuery($config);
break; break;
case Config::WX_CHARGE: // 微信支付订单查询
case Config::WX_CHARGE:// 微信支付订单查询
$this->query = new WxChargeQuery($config); $this->query = new WxChargeQuery($config);
break; break;
case Config::WX_REFUND:// 微信退款订单查询 case Config::WX_REFUND: // 微信退款订单查询
$this->query = new WxRefundQuery($config); $this->query = new WxRefundQuery($config);
break; break;
case Config::WX_TRANSFER: //微信企业付款到零钱订单查询 case Config::WX_TRANSFER: //微信企业付款到零钱订单查询
...@@ -78,24 +78,22 @@ class QueryContext ...@@ -78,24 +78,22 @@ class QueryContext
case Config::WX_PAY_BANK: //微信企业付款到银行卡订单查询 case Config::WX_PAY_BANK: //微信企业付款到银行卡订单查询
$this->query = new WxPayBankQuery($config); $this->query = new WxPayBankQuery($config);
break; break;
case Config::CMB_CHARGE: // 招商支付查询
case Config::CMB_CHARGE:// 招商支付查询
$this->query = new CmbChargeQuery($config); $this->query = new CmbChargeQuery($config);
break; break;
case Config::CMB_REFUND:// 招商退款查询 case Config::CMB_REFUND: // 招商退款查询
$this->query = new CmbRefundQuery($config); $this->query = new CmbRefundQuery($config);
break; break;
case Config::TL_QUERY:// 通联查询 case Config::TL_QUERY: // 通联查询
$this->query = new TLQuery($config); $this->query = new TLQuery($config);
break; break;
case Config::MI_QUERY:// Mi付查询 case Config::MI_QUERY: // Mi付查询
$this->query = new MiQuery($config); $this->query = new MiQuery($config);
break; break;
case Config::SW_QUERY: // 扫呗查询
case Config::SW_QUERY:// 扫呗查询
$this->query = new SwChargeQuery($config); $this->query = new SwChargeQuery($config);
break; break;
case Config::SW_T_QUERY:// 扫呗(3.0)查询 case Config::SW_T_QUERY: // 扫呗(3.0)查询
$this->query = new SwChargeThreeQuery($config); $this->query = new SwChargeThreeQuery($config);
break; break;
case Config::FU_CHARGE: case Config::FU_CHARGE:
...@@ -104,31 +102,33 @@ class QueryContext ...@@ -104,31 +102,33 @@ class QueryContext
case Config::FU_REFUND: case Config::FU_REFUND:
$this->query = new FuRefundQuery($config); $this->query = new FuRefundQuery($config);
break; break;
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->query=new LTFChargeQuery($config); $this->query = new LTFChargeQuery($config);
break; break;
case Config::LTF_REFUND: case Config::LTF_REFUND:
$this->query=new LTFRefundQuery($config); $this->query = new LTFRefundQuery($config);
break; break;
case Config::YS_QUERY: //易生支付
case Config::YS_QUERY://易生支付
$this->query = new YSChargeQuery($config); $this->query = new YSChargeQuery($config);
break; break;
case Config::YSE_QUERY://银盛支付 case Config::YSE_QUERY: //银盛支付
$this->query = new YSEChargeQuery($config); $this->query = new YSEChargeQuery($config);
break; break;
case Config::WNF_QUERY://微诺付 case Config::WNF_QUERY: //微诺付
$this->query = new WNFChargeQuery($config); $this->query = new WNFChargeQuery($config);
break; break;
case Config::HSQ_QUERY://慧收钱 case Config::HSQ_QUERY: //慧收钱
$this->query = new HsqChargeQuery($config); $this->query = new HsqChargeQuery($config);
break; break;
case Config::HSQ_QUERY_REFUND://慧收钱退款查询 case Config::HSQ_QUERY_REFUND: //慧收钱退款查询
$this->query = new HsqRefundQuery($config); $this->query = new HsqRefundQuery($config);
break; break;
case Config::HSQ_QUERY_TRANSFER: //宝付代付交易状态查证接口 case Config::HSQ_QUERY_TRANSFER: //宝付代付交易状态查证接口
$this->query = new HsqTransferQuery($config); $this->query = new HsqTransferQuery($config);
break; break;
case Config::LAKALA_QUERY: // 拉卡拉
$this->query = new LakalaChargeQuery($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_CHARGE ALI_REFUND WX_CHARGE WX_REFUND WX_TRANSFER WX_PAY_BANK CMB_CHARGE CMB_REFUND TLPAY MI_QUERY SW_QUERY FU_CHARGE FU_REFUND WNF_QUERY HSQ_QUERY HSQ_QUERY_REFUND HSQ_QUERY_TRANSFER '); throw new PayException('当前仅支持:ALI_CHARGE ALI_REFUND WX_CHARGE WX_REFUND WX_TRANSFER WX_PAY_BANK CMB_CHARGE CMB_REFUND TLPAY MI_QUERY SW_QUERY FU_CHARGE FU_REFUND WNF_QUERY HSQ_QUERY HSQ_QUERY_REFUND HSQ_QUERY_TRANSFER ');
} }
......
<?php
namespace Payment\Refund;
use Payment\Common\Lakala\Data\Refund\BackRefundData;
use Payment\Common\Lakala\Data\Refund\RefundData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
/**
* 需要商户当前账户内有大于退款金额的余额,否则会造成余额不足,退款失败;
* 限支付30天内退款,超过30天,不能进行退款操作(具体退款限制时间由通道决定)。
*
* Class SwRefund
* @package Payment\Refund\Sw
*/
class LakalaRefund extends LakalaBaseStrategy
{
/**
* 返回查询订单的数据
*
*/
public function getBuildDataClass()
{
return RefundData::class;
}
/**
* 返回微信查询的url
* @param null $url
* @return string
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::REFUND_URL);
}
/**
* 处理通知的返回数据
* @param array $ret
* @return mixed
*
*/
protected function retData(array $ret)
{
$back = new BackRefundData($this->config, $ret);
$backData = $back->getData();
return $backData;
}
}
...@@ -23,6 +23,7 @@ use Payment\Refund\WxRefund; ...@@ -23,6 +23,7 @@ use Payment\Refund\WxRefund;
use Payment\Refund\YSRefund; use Payment\Refund\YSRefund;
use Payment\Refund\YSERefund; use Payment\Refund\YSERefund;
use Payment\Refund\HsqRefund; use Payment\Refund\HsqRefund;
use Payment\Refund\LakalaRefund;
class RefundContext class RefundContext
{ {
...@@ -85,6 +86,9 @@ class RefundContext ...@@ -85,6 +86,9 @@ class RefundContext
case Config::HSQ_REFUND: case Config::HSQ_REFUND:
$this->refund = new HsqRefund($config); $this->refund = new HsqRefund($config);
break; break;
case Config::LAKALA_REFUND:
$this->refund = new LakalaRefund($config);
break;
default: default:
throw new PayException('当前仅支持:ALI WEIXIN CMB TL MI SW FU WNF HSQ'); throw new PayException('当前仅支持:ALI WEIXIN CMB TL MI SW FU WNF HSQ');
} }
......
<?php
namespace Payment\Trans;
use Payment\Common\Lakala\Data\Transfer\ApplyBindData;
use Payment\Common\Lakala\Data\Transfer\BackApplyBindData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaApplyBind extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return ApplyBindData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::APPLY_BIND_URL);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackApplyBindData($this->config, $ret);
return $back->getData();
}
}
<?php
namespace Payment\Trans;
use Payment\Common\Lakala\Data\Transfer\ApplyReciverData;
use Payment\Common\Lakala\Data\Transfer\BackApplyReciverData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaApplyRecever extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return ApplyReciverData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::APPLY_RECEVER_URL);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackApplyReciverData($this->config, $ret);
return $back->getData();
}
}
<?php
namespace Payment\Trans;
use Payment\Common\Lakala\Data\Transfer\ApplyReciverData;
use Payment\Common\Lakala\Data\Transfer\BackApplyReciverData;
use Payment\Common\Lakala\Data\Transfer\ModifyReciverData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaModifyRecever extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return ModifyReciverData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::MODIFY_RECEVER_URL);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackApplyReciverData($this->config, $ret);
return $back->getData();
}
}
<?php
namespace Payment\Trans;
use Payment\Common\Lakala\Data\Transfer\BackTransferData;
use Payment\Common\Lakala\Data\Transfer\TransferData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
use Payment\Config;
use Payment\Utils\Curl;
class LakalaTransfer extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return TransferData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::TRANSFER_URL);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackTransferData($this->config, $ret);
return $back->getData();
}
}
...@@ -13,6 +13,7 @@ use Payment\Trans\AliTransfer; ...@@ -13,6 +13,7 @@ use Payment\Trans\AliTransfer;
use Payment\Trans\WxPayBank; use Payment\Trans\WxPayBank;
use Payment\Trans\WxTransfer; use Payment\Trans\WxTransfer;
use Payment\Trans\HsqTransfer; use Payment\Trans\HsqTransfer;
use Payment\Trans\LakalaTransfer;
class TransferContext class TransferContext
{ {
...@@ -47,8 +48,11 @@ class TransferContext ...@@ -47,8 +48,11 @@ class TransferContext
case Config::HSQ_TRANSFER: case Config::HSQ_TRANSFER:
$this->transfer = new HsqTransfer($config); $this->transfer = new HsqTransfer($config);
break; break;
case Config::LAKALA_TRANSFER:
$this->transfer = new LakalaTransfer($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_TRANSFER、WX_TRANSFER、WX_PAY_BANK、HSQ_TRANSFER'); throw new PayException('当前仅支持:ALI_TRANSFER、WX_TRANSFER、WX_PAY_BANK、HSQ_TRANSFER、LAKALA_TRANSFER');
} }
} catch (PayException $e) { } catch (PayException $e) {
throw $e; throw $e;
......
<?php
namespace Payment\Utils;
use Payment\Common\Lakala\Data\Other\BackCardBinData;
use Payment\Common\Lakala\Data\Other\CardBinData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
use Payment\Config;
use Payment\Utils\Curl;
class LakalaCardBin extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return CardBinData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::CARD_BIN);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackCardBinData($this->config, $ret);
return $back->getData();
}
}
<?php
namespace Payment\Utils;
use Payment\Common\Lakala\Data\Other\BackUploadData;
use Payment\Common\Lakala\Data\Other\UploadData;
use Payment\Common\Lakala\LakalaBaseStrategy;
use Payment\Common\LakalaConfig;
class LakalaUpload extends LakalaBaseStrategy
{
public function getBuildDataClass()
{
return UploadData::class;
}
/*
* 返回转款的url
*/
protected function getReqUrl($url = null)
{
return parent::getReqUrl($url ?? LakalaConfig::UPLOAD_FILE);
}
/**
* 转款的返回数据
* @param array $ret
* @return mixed
*/
protected function retData(array $ret)
{
$back = new BackUploadData($this->config, $ret);
return $back->getData();
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!