Commit 5105f24a by 赵凯(PHP)

update

1 parent b01d0be6
<?php
date_default_timezone_set('Asia/Shanghai');
require_once __DIR__.'/../../autoload.php';
//require_once __DIR__.'/common.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
$config = [
'channelid' => '860010010210008',
'key' => 'fkdkldvkij5dfd24dl24dk2dddflaaf2',
'merid' => '880210010215460',
'termid' => '10006468',
];
$payData = [
'tradetrace' => '11620210303155407146230',
'oritradetrace' => '2019062017085196425851101913',
];
try{
$ret = \Payment\Client\Cancel::run(Config::YS_CHARGE, $config, $payData);
}catch(PayException $e){
exit($e->errorMessage());
}
echo json_encode($ret, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
<?php
date_default_timezone_set('Asia/Shanghai');
require_once __DIR__.'/../../autoload.php';
//require_once __DIR__.'/common.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
$config = [
'channelid' => '860010010210008',
'key' => 'fkdkldvkij5dfd24dl24dk2dddflaaf2',
'merid' => '880210010215460',
'termid' => '10006468',
];
$payData = [
'tradetrace' => '11620210304155042147189',
// 'oritradetrace' => '2019062017085196425851101913',
];
try{
$ret = \Payment\Client\Close::run(Config::YS_CHARGE, $config, $payData);
}catch(PayException $e){
exit($e->errorMessage());
}
echo json_encode($ret, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
<?php
date_default_timezone_set('Asia/Shanghai');
require_once __DIR__.'/../../autoload.php';
//require_once __DIR__.'/common.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
$config = [
'channelid' => '860010010210008',
'key' => 'fkdkldvkij5dfd24dl24dk2dddflaaf2',
'merid' => '880210010215460',
'termid' => '10006468'
];
$payData = [
'notifyurl' => 'https://www.test.com/test/test.t',
'tradetrace' => '2019062017085196425851101915',
// 'openid' =>'oDqg_5Za0tc23LhTkUR6PfFZ8O2g',
'openid' =>'ohWpr5L1oy5SK4LMyoazVG4BJVGY',
'tradeamt'=>1
];
// $payData = [
// "out_trade_no" => "2019062017085196425851101915",
// "total_fee" => 1,
// "body" => 'hello 你好呀',
// "extra_param" => '',
// 'open_id' => "oDqg_5Za0tc23LhTkUR6PfFZ8O2g"
// ];
try{
$ret = Charge::run(Config::YS_CHANNEL_LITE, $config, $payData);
}catch(PayException $e){
exit($e->errorMessage());
}
echo json_encode($ret, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
<?php
date_default_timezone_set('Asia/Shanghai');
require_once __DIR__.'/../../autoload.php';
//require_once __DIR__.'/common.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
$config = [
'channelid' => '860010010210008',
'key' => 'fkdkldvkij5dfd24dl24dk2dddflaaf2',
'merid' => '880210010215460',
'termid' => '10006468',
];
$payData = [
'notifyurl' => 'https://www.test.com/test/test.t',
'tradetrace' => '2019062017085196425851101912',
'openid' =>'oDqg_5Za0tc23LhTkUR6PfFZ8O2g',
'tradeamt'=>1
];
try{
$ret = Charge::run(Config::YS_CHANNEL_PUB, $config, $payData);
}catch(PayException $e){
exit($e->errorMessage());
}
echo json_encode($ret, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
<?php
date_default_timezone_set('Asia/Shanghai');
require_once __DIR__.'/../../autoload.php';
//require_once __DIR__.'/common.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
$config = [
'channelid' => '860010010210008',
'key' => 'fkdkldvkij5dfd24dl24dk2dddflaaf2',
'merid' => '880210010215460',
'termid' => '10006468',
];
$payData = [
// 'notifyurl' => 'https://www.test.com/test/test.t',
// 'tradetrace' => '2019062017085196425851101913',
'tradetrace' => '2019062017085196425851101915',
// 'openid' =>'oDqg_5Za0tc23LhTkUR6PfFZ8O2g',
// 'tradeamt'=>1
];
try{
$ret = \Payment\Client\Query::run(Config::YS_QUERY, $config, $payData);
}catch(PayException $e){
exit($e->errorMessage());
}
echo json_encode($ret, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
...@@ -12,6 +12,7 @@ use Payment\Charge\LTF\LTFCancel; ...@@ -12,6 +12,7 @@ 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;
use Payment\Charge\TLpay\TLCancel; use Payment\Charge\TLpay\TLCancel;
use Payment\Charge\YS\YSCancel;
use Payment\Common\BaseStrategy; use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
...@@ -56,6 +57,9 @@ class CancelContext{ ...@@ -56,6 +57,9 @@ class CancelContext{
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->cancelHandler = new LTFCancel($config); $this->cancelHandler = new LTFCancel($config);
break; break;
case Config::YS_CHARGE:
$this->cancelHandler = new YSCancel($config);
break;
default: default:
throw new PayException('当前仅支持:通联支付平台'); throw new PayException('当前仅支持:通联支付平台');
} }
......
<?php
namespace Payment\Charge\YS;
use Payment\Common\BaseData;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Cancel\CancelData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSCancel extends YSBaseStrategy{
/**
* 获取支付对应的数据完成类
*
* @return BaseData
*/
public function getBuildDataClass(){
// TODO: Implement getBuildDataClass() method.
return CancelData::class;
}
protected function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
<?php
namespace Payment\Charge\YS;
use Payment\Common\BaseData;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Cancel\CloseData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSClose extends YSBaseStrategy{
/**
* 获取支付对应的数据完成类
*
* @return BaseData
*/
public function getBuildDataClass(){
// TODO: Implement getBuildDataClass() method.
return CloseData::class;
}
protected function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
<?php
namespace Payment\Charge\YS;
use Payment\Common\BaseData;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Charge\NatChargeData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSNatCharge extends YSBaseStrategy{
/**
* 获取支付对应的数据完成类
*
* @return BaseData
*/
public function getBuildDataClass(){
// TODO: Implement getBuildDataClass() method.
return NatChargeData::class;
}
protected function getReqUrl($url = null){
return parent::getReqUrl($url??LTFConfig::SCANPAY_URL); // TODO: Change the autogenerated stub
}
}
<?php
namespace Payment\Charge\YS;
use Payment\Common\BaseData;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Charge\PubChargeData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSPubCharge extends YSBaseStrategy{
/**
* 获取支付对应的数据完成类
*
* @return BaseData
*/
public function getBuildDataClass(){
// TODO: Implement getBuildDataClass() method.
return PubChargeData::class;
}
protected function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
<?php
namespace Payment\Charge\YS;
use Payment\Common\BaseData;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Charge\ScanChargeData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSScanCharge extends YSBaseStrategy{
/**
* 获取支付对应的数据完成类
*
* @return BaseData
*/
public function getBuildDataClass(){
// TODO: Implement getBuildDataClass() method.
return ScanChargeData::class;
}
protected function getReqUrl($url = null){
return parent::getReqUrl($url??LTFConfig::SCANPAY_URL); // TODO: Change the autogenerated stub
}
}
...@@ -36,6 +36,9 @@ use Payment\Charge\Wx\WxBarCharge; ...@@ -36,6 +36,9 @@ use Payment\Charge\Wx\WxBarCharge;
use Payment\Charge\Wx\WxPubCharge; use Payment\Charge\Wx\WxPubCharge;
use Payment\Charge\Wx\WxQrCharge; use Payment\Charge\Wx\WxQrCharge;
use Payment\Charge\Wx\WxWapCharge; use Payment\Charge\Wx\WxWapCharge;
use Payment\Charge\YS\YSNatCharge;
use Payment\Charge\YS\YSPubCharge;
use Payment\Charge\YS\YSScanCharge;
use Payment\Common\BaseStrategy; use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
...@@ -165,8 +168,20 @@ class ChargeContext ...@@ -165,8 +168,20 @@ class ChargeContext
case Config::LTF_CHANNEL_PAY: case Config::LTF_CHANNEL_PAY:
$this->channel=new LTFPayCharge($config); $this->channel=new LTFPayCharge($config);
break; break;
//易生支付
case Config::YS_CHANNEL_PUB:
case Config::YS_CHANNEL_LITE: //小程序、公众号
$this->channel = new YSPubCharge($config);
break;
case Config::YS_CHANNEL_SCAN: //被扫
$this->channel = new YSScanCharge($config);
break;
case Config::YS_CHANNEL_NATIVE: //主扫
$this->channel = new YSNatCharge($config);
break;
default: default:
throw new PayException('当前支持:支付宝、微信、招商一网通、通联支付、米付支付、扫呗支付、富友支付、联拓富。'); throw new PayException('当前支持:支付宝、微信、招商一网通、通联支付、米付支付、扫呗支付、富友支付、联拓富、易生支付。');
} }
} catch (PayException $e) { } catch (PayException $e) {
throw $e; throw $e;
......
...@@ -42,6 +42,8 @@ class Cancel ...@@ -42,6 +42,8 @@ class Cancel
Config::FU_CHARGE, //富友 Config::FU_CHARGE, //富友
Config::LTF_CHARGE, Config::LTF_CHARGE,
Config::YS_CHARGE,//易生支付
]; ];
/** /**
......
...@@ -48,6 +48,12 @@ class Charge ...@@ -48,6 +48,12 @@ class Charge
Config::LTF_CHANNEL_BAR, Config::LTF_CHANNEL_BAR,
Config::LTF_CHANNEL_PAY, Config::LTF_CHANNEL_PAY,
//易生支付
Config::YS_CHANNEL_PUB,
Config::YS_CHANNEL_LITE,
Config::YS_CHANNEL_SCAN,
Config::YS_CHANNEL_NATIVE,
// Config::YS_CHANNEL_BAR
]; ];
/** /**
......
...@@ -18,6 +18,7 @@ class Close { ...@@ -18,6 +18,7 @@ class Close {
Config::SW_CHARGE, //扫呗支付关闭订单 Config::SW_CHARGE, //扫呗支付关闭订单
Config::FU_CHARGE, //富友支付关闭订单 Config::FU_CHARGE, //富友支付关闭订单
Config::LTF_CHARGE,//联拓富支付关闭订单 Config::LTF_CHARGE,//联拓富支付关闭订单
Config::YS_CHARGE,//易生支付关闭订单
]; ];
/** /**
......
...@@ -29,6 +29,8 @@ class Notify ...@@ -29,6 +29,8 @@ class Notify
Config::FU_CHARGE, //富友 Config::FU_CHARGE, //富友
Config::LTF_CHARGE, //联拓富 Config::LTF_CHARGE, //联拓富
Config::YS_CHARGE, //易生
]; ];
/** /**
......
...@@ -44,6 +44,8 @@ class Query ...@@ -44,6 +44,8 @@ class Query
Config::FU_REFUND, Config::FU_REFUND,
Config::LTF_CHARGE, Config::LTF_CHARGE,
Config::LTF_REFUND, Config::LTF_REFUND,
Config::YS_QUERY,//易生
]; ];
/** /**
......
...@@ -36,6 +36,8 @@ class Refund ...@@ -36,6 +36,8 @@ class Refund
Config::FU_REFUND, //富友 Config::FU_REFUND, //富友
Config::LTF_REFUND, Config::LTF_REFUND,
Config::YS_REFUND,//易生支付
]; ];
/** /**
......
...@@ -5,6 +5,7 @@ namespace Payment; ...@@ -5,6 +5,7 @@ namespace Payment;
use Payment\Charge\Fu\FuClose; use Payment\Charge\Fu\FuClose;
use Payment\Charge\LTF\LTFClose; use Payment\Charge\LTF\LTFClose;
use Payment\Charge\Sw\SwClose; use Payment\Charge\Sw\SwClose;
use Payment\Charge\YS\YSClose;
use Payment\Common\BaseStrategy; use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
...@@ -43,6 +44,9 @@ class CloseContext{ ...@@ -43,6 +44,9 @@ class CloseContext{
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->closeHandler = new LTFClose($config); $this->closeHandler = new LTFClose($config);
break; break;
case Config::YS_CHARGE: //易生支付
$this->closeHandler = new YSClose($config);
break;
default: default:
throw new PayException('当前仅支持:SW_CHARGE、FU_CHARGE、LTF_CHARGE'); throw new PayException('当前仅支持:SW_CHARGE、FU_CHARGE、LTF_CHARGE');
} }
......
...@@ -61,7 +61,9 @@ abstract class BaseData ...@@ -61,7 +61,9 @@ abstract class BaseData
$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) {
$this->channel = Config::YS_PAY;
}
$this->data = array_merge($config->toArray(), $reqData);//配置信息合并 $this->data = array_merge($config->toArray(), $reqData);//配置信息合并
try { try {
...@@ -151,6 +153,12 @@ abstract class BaseData ...@@ -151,6 +153,12 @@ abstract class BaseData
$signStr = ArrayUtil::createLinkstring($values); $signStr = ArrayUtil::createLinkstring($values);
$this->makeSign($signStr); $this->makeSign($signStr);
break; break;
case Config::YS_PAY:
$values = ArrayUtil::removeKeys($data, ['sign']);
$values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values);
$this->makeSign($signStr);
break;
default: default:
$values = ArrayUtil::removeKeys($data, ['sign']); $values = ArrayUtil::removeKeys($data, ['sign']);
$values = ArrayUtil::arraySort($values); $values = ArrayUtil::arraySort($values);
......
...@@ -17,7 +17,7 @@ abstract class LTFBaseData extends BaseData{ ...@@ -17,7 +17,7 @@ abstract class LTFBaseData extends BaseData{
switch ($this->signType) { switch ($this->signType) {
case 'MD5': case 'MD5':
$signStr .= '&key=' . $this->key; $signStr .= '&key=' . $this->key;
$sign = md5($signStr); $sign = strtoupper(md5($signStr));
break; break;
default: default:
......
<?php
namespace Payment\Common;
use Payment\Utils\ArrayUtil;
use Payment\Utils\StrUtil;
final class YSConfig extends ConfigInterface{
public const REQUEST_URL = 'https://notify-test.eycard.cn:7443/WorthTech_Access_AppPaySystemV2/apppayacc';
public $request_url = 'https://notify-test.eycard.cn:7443/WorthTech_Access_AppPaySystemV2/apppayacc';
public $signType = 'MD5';
// public $notifyurl;
public $channelid;//渠道编号
public $merid;//门店编号
public $termid; //终端编号
public $key; //签名密钥
// public $tradetrace; //订单号
//
// public $tradeamt; //订单号
//
// public $openid; //订单号
/**
* FuConfig 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
*/
/**
* 初始化配置文件参数
* @param array $config
* @throws PayException
*/
private function initConfig(array $config)
{
$config = ArrayUtil::paraFilter($config);
if (key_exists('channelid', $config) && !empty($config['channelid'])) $this->channelid = $config['channelid'];else throw new PayException('必须提供渠道号标识');
if (key_exists('merid', $config) && !empty($config['merid'])) $this->merid = $config['merid']; else throw new PayException('必须提供商户编号');
if (key_exists('termid', $config) && !empty($config['termid'])) $this->termid = $config['termid'];
if (key_exists('key', $config) && !empty($config['key'])) $this->key = $config['key'];
// if (key_exists('out_trade_no', $config) && !empty($config['out_trade_no'])) $this->tradetrace = $config['out_trade_no'];
//
// if (key_exists('total_fee', $config) && !empty($config['total_fee'])) $this->tradeamt = $config['total_fee'];
//
// if (key_exists('open_id', $config) && !empty($config['open_id'])) $this->openid = $config['open_id'];
}
}
<?php
namespace Payment\Common\YSpay\Data\Cancel;
use Payment\Common\YSpay\Data\YSBaseData;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class CancelData extends YSBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return array
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "cancel", //操作类型(“cancel”)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //原交易流水(建议使用易生流水号查询:wtorderid)
// 'oritradetrace' => $this->oritradetrace, //原交易流水; 与 oriwtorderid 字段可以二选一上送,如果都上送,以 本节点为准。
// 'oriwtorderid' => $this->oriwtorderid, //原交易的系统订单号;与 oritradetrace 字段可以二选一上送,如果都 上送,以 oritradetrace 节点为准
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->version)){
$signData['version'] = $this->version; //填写的值为 2 时,交易成功后返回优惠信息
}
if(isset($this->oritradetrace)){
$signData['oritradetrace'] = $this->oritradetrace; //退货金额,以分为单位,不大于原交易金额与已成功退货金额之差
}else{
if(isset($this->oriwtorderid)){
$signData['oriwtorderid'] = $this->oriwtorderid; //退货金额,以分为单位,不大于原交易金额与已成功退货金额之差
}
}
$this->retData = ArrayUtil::paraFilter($signData);
}
/**
* 检查传入的参数. $reqData是否正确.
*
* @return mixed
* @throws PayException
*/
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
parent::checkDataParam();
}
}
<?php
namespace Payment\Common\YSpay\Data\Cancel;
use Payment\Common\YSpay\Data\YSBaseData;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class CloseData extends YSBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return array
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "close", //操作类型(“close”)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //原交易流水(建议使用易生流水号查询:wtorderid)
];
$signData = array_merge($this->certainSignData, []);
$this->retData = ArrayUtil::paraFilter($signData);
}
/**
* 检查传入的参数. $reqData是否正确.
*
* @return mixed
* @throws PayException
*/
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
parent::checkDataParam();
}
}
<?php
namespace Payment\Common\YSpay\Data\Charge;
use Payment\Common\YSpay\Data\YSBaseData;
use Payment\Common\PayException;
use Payment\Config;
abstract class ChargeBaseData extends YSBaseData{
/**
* 检查传入的参数. $reqData是否正确.
*
* @return mixed
* @throws \Payment\Common\PayException
*/
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
// 检查金额不能低于0.01
if ($this->tradeamt < 1) {
throw new PayException('支付金额不能低于 ' . Config::PAY_MIN_FEE . ' 元');
}
}
}
<?php
namespace Payment\Common\YSpay\Data\Charge;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class NatChargeData extends ChargeBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return void
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "apPreOrder", //操作类型(“apPreOrder”:支付宝;“upPreOrder”:银联)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //商户订单号(控制在 50 位长度以内,确保在请求接口的系统中全局 唯一;可以包含数字与字母;不能包含其他特殊字符)
'tradeamt' => $this->tradeamt, //交易金额(单位:分)
'tradetype' => $this->tradetype ?? "NATIVE", //支付方式
'notifyurl' => $this->notifyurl, //客户端接收支付成功通知的地址
'body' => $this->body ?? "乐店云支付", //商品或支付单简要描述
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->openid)){ //支付宝(买家支付宝用户ID),上送支付宝用户ID时,当前订单仅当前支付宝用户支付
$signData['openid'] = $this->openid;
}
if(isset($this->instalment)){ //支付宝花呗分期
$signData['instalment'] = $this->instalment;
}
if(isset($this->handingfee)){
$signData['handingfee'] = $this->handingfee; //手续费(以分为单位,第一位是 D 或 C,表示借、贷)
}
if(isset($this->version)){
$signData['version'] = $this->version; //填写的值为 2 时,交易成功后返回优惠信息
}
if(isset($this->identity)){
$signData['identity'] = $this->identity; //JSON 格式指定付款人信息(格式繁琐,不推荐使用)
}
if(isset($this->patnersettleflag)){
$signData['patnersettleflag'] = $this->patnersettleflag;//资金结算秒到标识(取值:1、2) 1:本次交易正常T1结算,2:本次交易秒到(前提条件:代理需开通白名单、商户需要开通秒到功能)
}
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
protected function checkDataParam(){
parent::checkDataParam(); // TODO: Change the autogenerated stub
if(empty($this->notifyurl)){
throw new PayException('支付通知地址不能为空');
}
}
}
<?php
namespace Payment\Common\YSpay\Data\Charge;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class PubChargeData extends ChargeBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return void
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "wxPreOrder", //操作类型(“wxPreOrder”:微信;“apPreOrder”:支付宝)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //商户订单号(控制在 50 位长度以内,确保在请求接口的系统中全局 唯一;可以包含数字与字母;不能包含其他特殊字符)
'tradeamt' => $this->tradeamt, //交易金额(单位:分)
'tradetype' => $this->tradetype ?? "JSAPI", //支付方式
'notifyurl' => $this->notifyurl, //客户端接收支付成功通知的地址
'openid' => $this->openid, //支付宝(买家支付宝用户ID);微信(用户在商户sub_appid下的唯一标识)
'body' => $this->body ?? "乐店云支付", //商品或支付单简要描述
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->handingfee)){
$signData['handingfee'] = $this->handingfee; //手续费(以分为单位,第一位是 D 或 C,表示借、贷)
}
if(isset($this->version)){
$signData['version'] = $this->version; //填写的值为 2 时,交易成功后返回优惠信息
}
if(isset($this->identity)){
$signData['identity'] = $this->identity; //JSON 格式指定付款人信息(格式繁琐,不推荐使用)
}
if(isset($this->patnersettleflag)){
$signData['patnersettleflag'] = $this->patnersettleflag;//资金结算秒到标识(取值:1、2) 1:本次交易正常T1结算,2:本次交易秒到(前提条件:代理需开通白名单、商户需要开通秒到功能)
}
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
protected function checkDataParam(){
parent::checkDataParam(); // TODO: Change the autogenerated stub
if(empty($this->notifyurl)){
throw new PayException('支付通知地址不能为空');
}
if(empty($this->openid)){
throw new PayException('用户OPENID 不能为空');
}
}
}
<?php
namespace Payment\Common\YSpay\Data\Charge;
use Payment\Common\YSpay\Data\YSBaseData;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class ScanChargeData extends YSBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return void
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "scanPay", //操作类型(“scanPay”)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //商户订单号(控制在 50 位长度以内,确保在请求接口的系统中全局 唯一;可以包含数字与字母;不能包含其他特殊字符)
'tradeamt' => $this->tradeamt, //交易金额(单位:分)
'authcode' => $this->authcode, //扫码支付授权码,设备读取用户微信、支付宝、银联钱包中的条码或 者二维码信息
'body' => $this->body ?? "乐店云支付", //商品或支付单简要描述
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->maintradetype)){ //刷脸类型填写(faceScanPay)
$signData['maintradetype'] = $this->maintradetype;
}
if(isset($this->instalment)){ //支付宝花呗分期
$signData['instalment'] = $this->instalment;
}
if(isset($this->handingfee)){
$signData['handingfee'] = $this->handingfee; //手续费(以分为单位,第一位是 D 或 C,表示借、贷)
}
if(isset($this->version)){
$signData['version'] = $this->version; //填写的值为 2 时,交易成功后返回优惠信息
}
if(isset($this->identity)){
$signData['identity'] = $this->identity; //JSON 格式指定付款人信息(格式繁琐,不推荐使用)
}
if(isset($this->patnersettleflag)){
$signData['patnersettleflag'] = $this->patnersettleflag;//资金结算秒到标识(取值:1、2) 1:本次交易正常T1结算,2:本次交易秒到(前提条件:代理需开通白名单、商户需要开通秒到功能)
}
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
protected function checkDataParam(){
parent::checkDataParam(); // TODO: Change the autogenerated stub
if(empty($this->notifyUrl)){
throw new PayException('支付通知地址不能为空');
}
}
}
<?php
namespace Payment\Common\YSpay\Data\Query;
use Payment\Common\YSpay\Data\YSBaseData;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class ChargeQueryData extends YSBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return array
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "tradeQuery", //操作类型(“tradeQuery”)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //原交易流水(建议使用易生流水号查询:wtorderid)
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->tradetype)){
$signData['tradetype'] = $this->tradetype; //交易类型(“samecardQuery”:同名卡转出查询;其他查询为空)
}
$this->retData = ArrayUtil::paraFilter($signData);
}
/**
* 检查传入的参数. $reqData是否正确.
*
* @return mixed
* @throws PayException
*/
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
parent::checkDataParam();
if(empty($this->tradetrace)){
throw new PayException('第三方订单号不能为空');
}
}
}
<?php
namespace Payment\Common\YSpay\Data;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
class RefundData extends YSBaseData{
/**
* 构建用于支付的签名相关数据
*
* @return array
*/
protected function buildData(){
// TODO: Implement buildData() method.
$this->certainSignData = [
'channelid' => $this->channelid, //渠道编号
'opt' => $this->opt ?? "zwrefund", //操作类型(“zwrefund”)
'merid' => $this->merid, //商戶编号
'termid' => $this->termid, //终端编号
'tradetrace' => $this->tradetrace, //原交易流水(建议使用易生流水号查询:wtorderid)
// 'oritradetrace' => $this->oritradetrace, //原交易流水; 与 oriwtorderid 字段可以二选一上送,如果都上送,以 本节点为准。
// 'oriwtorderid' => $this->oriwtorderid, //原交易的系统订单号;与 oritradetrace 字段可以二选一上送,如果都 上送,以 oritradetrace 节点为准
'tradeamt' => $this->tradeamt, //退货金额,以分为单位,不大于原交易金额与已成功退货金额之差
];
$signData = array_merge($this->certainSignData, []);
if(isset($this->oritradetrace)){
$signData['oritradetrace'] = $this->oritradetrace; //退货金额,以分为单位,不大于原交易金额与已成功退货金额之差
}else{
if(isset($this->oriwtorderid)){
$signData['oriwtorderid'] = $this->oriwtorderid; //退货金额,以分为单位,不大于原交易金额与已成功退货金额之差
}
}
$this->retData = ArrayUtil::paraFilter($signData);
}
/**
* 检查传入的参数. $reqData是否正确.
*
* @return mixed
* @throws PayException
*/
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
parent::checkDataParam();
if(empty($this->oritradetrace)&&empty($this->oriwtorderid)){
throw new PayException('必须提供原交易系统的交易流水或者交易订单号');
}
}
}
<?php
namespace Payment\Common\YSpay\Data;
use Payment\Common\BaseData;
use Payment\Common\PayException;
abstract class YSBaseData extends BaseData{
/**
* 签名算法实现 便于后期扩展微信不同的加密方式
*
* @param string $signStr
* @return string
*/
protected function makeSign($signStr){
if(empty($this->key)) throw new PayException('请检查签名密钥是否正确');
switch ($this->signType) {
case 'MD5':
$signStr .= '&key=' . $this->key;
$sign = strtoupper(md5($signStr));
break;
default:
$sign = '';
}
$this->retData['sign'] = $sign;
return $sign;
// TODO: Implement makeSign() method.
}
protected function checkDataParam(){
// TODO: Implement checkDataParam() method.
// 检查订单号是否合法
if (empty($this->tradetrace) || mb_strlen($this->tradetrace) > 64) {
throw new PayException('商户系统的订单号不能为空且长度不能超过64位');
}
if (empty($this->merid) || empty($this->channelid)) {
throw new PayException('必须提供合作方标识与门店编号');
}
}
}
<?php
namespace Payment\Common\YSpay;
use Payment\Common\BaseData;
use Payment\Common\BaseStrategy;
use Payment\Common\YSConfig;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
use Payment\Utils\Curl;
abstract class YSBaseStrategy implements BaseStrategy
{
protected $config;
/**
* 支付数据
* @var BaseData $reqData
*/
protected $reqData;
/**
* FuBaseStrategy constructor.
* @param array $config
* @throws PayException
*/
public function __construct(array $config)
{
/* 设置内部字符编码为 UTF-8 */
mb_internal_encoding("UTF-8");
try {
$this->config = new YSConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 发送完了请求
* @param $body
* @return mixed
* @throws \Payment\Common\PayException
*/
protected function sendReq($body)
{
$url = $this->getReqUrl();
if (is_null($url)) {
throw new PayException('目前不支持该接口。请联系开发者添加');
}
$responseTxt = $this->curlPost($body, $url);
if ($responseTxt['error']) {
throw new PayException('网络发生错误,请稍后再试curl返回码:' . $responseTxt['message']);
}
// 格式化为数组
$retData = (json_decode($responseTxt['body'], true));
if ($retData['resultcode'] != '00') {
throw new PayException('支付平台返回错误提示:' . $retData['returnmsg']);
}
return $retData;
}
protected function curlPost($body, $url)
{
$curl = new Curl();
return $curl->set([
'CURLOPT_HEADER' => 0
])->post($body, $url)->submit($url);
}
/**
* 处理具体的业务
*
* @param array $data
* @return mixed
* @throws \Payment\Common\PayException
*/
public function handle(array $data)
{
// TODO: Implement handle() method.
$buildClass = $this->getBuildDataClass();
try {
$this->reqData = new $buildClass($this->config, $data);
} catch (PayException $e) {
throw $e;
}
$this->reqData->setSign();
$body = $this->reqData->getData();
echo "<pre>";
var_dump(json_encode($body));
echo "</pre>";
$ret = $this->sendReq($body);
// 检查返回的数据是否被篡改
$flag = true;
// $flag = $this->verifySign($ret);
if (!$flag) {
throw new PayException('返回数据被篡改。请检查网络是否安全!');
}
return $this->retData($ret);
}
/**
* 获取请求地址
* @param null $url
* @return string
*/
protected function getReqUrl($url = null)
{
if (isset($this->config->base_url) && !empty($this->config->base_url)) {
$_pre = $this->config->base_url;
} else {
$_pre = YSConfig::REQUEST_URL;
}
return $_pre;
}
/**
* 处理微信的返回值并返回给客户端
* @param array $ret
* @return mixed
*
*/
protected function retData(array $ret)
{
return $ret;
}
/**
* 检查微信返回的数据是否被篡改过
*
* @param array $retData
* @return boolean
* @throws \Exception
*/
protected function verifySign(array $retData)
{
$retSign = $retData['sign'];
$values = ArrayUtil::removeKeys($retData, ['sign']);
$values = ArrayUtil::paraFilter($values);
$values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values);
$signStr = str_replace(' ', '', $signStr);
$signStr .= '&key=' . $this->config->key;
switch ($this->config->signType) {
case 'MD5':
$sign = md5($signStr);
break;
case 'HMAC-SHA256':
$sign = hash_hmac('sha256', $signStr, $this->config->key);
break;
default:
$sign = '';
}
// echo $retSign;echo"<br>";
// echo strtoupper($sign);die;
return strtoupper($sign) === $retSign;
}
}
...@@ -32,6 +32,8 @@ final class Config{ ...@@ -32,6 +32,8 @@ final class Config{
const LTF_PAY = 'ltfpay'; //富友支付 const LTF_PAY = 'ltfpay'; //富友支付
const YS_PAY = 'yspay'; //易生支付
//========================= 金额问题设置 =======================// //========================= 金额问题设置 =======================//
const PAY_MIN_FEE = '0.01';// 支付的最小金额 const PAY_MIN_FEE = '0.01';// 支付的最小金额
...@@ -203,4 +205,24 @@ final class Config{ ...@@ -203,4 +205,24 @@ final class Config{
const LTF_CANCEL = 'ltf_cancel';// 交易撤销,只能撤销当天的交易,全额退款,实时返回退款结果 const LTF_CANCEL = 'ltf_cancel';// 交易撤销,只能撤销当天的交易,全额退款,实时返回退款结果
const LTF_CHANNEL_PAY = 'ltf_pay';// 聚合支付 const LTF_CHANNEL_PAY = 'ltf_pay';// 聚合支付
//=======================易生支付 相关接口===================//
//支付常量
const YS_CHARGE = 'ys_charge';// 统一下单
const YS_CHANNEL_PUB = 'ys_pub'; // 微信公众号h5支付
const YS_CHANNEL_LITE = 'ys_lite';// 小程序支付
const YS_CHANNEL_SCAN = 'ys_scan';// 付款码支付
// const YS_CHANNEL_BAR = 'ys_bar';// 刷卡(条码)支付 用户被扫模式
const YS_CHANNEL_NATIVE = 'ys_native';//主扫模式
const YS_QUERY = 'ys_query'; // 查询接口
const YS_REFUND = 'ys_refund';// 退款
const YS_CANCEL = 'ys_cancel';// 交易撤销,只能撤销当天的交易,全额退款,实时返回退款结果
} }
<?php
namespace Payment\Notify;
use Payment\Common\YSConfig;
use Payment\Common\PayException;
use Payment\Config;
use Payment\Utils\ArrayUtil;
class YSNotify extends NotifyStrategy{
/**
* SwNotify constructor.
*
* @param array $config
* @throws PayException
*/
public function __construct(array $config){
parent::__construct($config);
try{
$this->config = new YSConfig($config);
}catch(PayException $e){
throw $e;
}
}
/**
* 获取移除通知的数据 并进行简单处理(如:格式化为数组)
* 如果获取数据失败,返回false
*
* @return array|false
*/
public function getNotifyData(){
$params = array();
//支持直接读取input流
$data = @file_get_contents('php://input');
if(!empty($data)){
// $inputArray = json_decode($data, true);
parse_str($data,$inputArray);
$params = array_merge($params, $inputArray);
}
if(count($params) < 1){//如果参数为空,则不进行处理
return false;
}
return $params;
// TODO: Implement getNotifyData() method.
}
/**
* 检查异步通知的数据是否合法
* 如果检查失败,返回false
*
* @param array $data 由 $this->getNotifyData() 返回的数据
* @return boolean
* @throws \Exception
*/
public function checkNotifyData(array $data){
return $this->verifySign($data);
}
/**
* 检查数据是否被篡改过
*
* @param array $retData
* @return bool
* @throws \Exception
*/
protected function verifySign(array $retData){
$retSign = $retData['sign'];//先不验证加密
return true;
$data = ArrayUtil::removeKeys($retData, ['sign']);
$values = [
'return_code' => $data['code'],
'return_msg' => $data['msg'],
'out_trade_no' => $data['outTradeNo'],
'transaction_id' => $data['transactionId'],
'pay_type' => $data['payType'],
'total_fee' => $data['totalAmount'],
'user_id' => $data['buyerId'],
'out_transaction_id' => $data['outTransactionId'],
];
$values = ArrayUtil::paraFilter($values);
// $values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values);
switch($this->config->signType){
case 'MD5':
$sign = md5($signStr);
break;
default:
$sign = '';
}
return strtoupper($sign) === strtoupper($retSign);
}
/**
* 向客户端返回必要的数据
*
* @param array $data
* @return void
*/
protected function getRetData(array $data){
// TODO: Implement getRetData() method.
$retData = [
'order_no' => $data['wtorderid'],
'out_trade_no' => $data['tradetrace'],
'transaction_id' => $data['wxtransactionid'],
'pay_time' => $data['wxtimeend'],
'user_id' => $data['wxopenid'],
'out_transaction_id' => $data['wxtransactionid'],
'channel' => Config::YS_CHARGE,
];
if(isset($data['clearamt'])){
$retData['clear_amt'] = $data['clearamt'];
}
if(isset($data['payamt'])){
$retData['pay_amt'] = $data['payamt'];
}
return $retData;
}
/**
* 根据返回结果,回答支付机构。是否回调通知成功
*
* @param boolean $flag 每次返回的bool值
* @param string $msg 通知信息,错误原因
* @return mixed
*/
protected function replyNotify($flag, $msg = 'OK'){
$return_code ='00';
if (! $flag) {
$return_code ='01';
}
return [
'resultcode' => $return_code
];
}
}
...@@ -18,6 +18,7 @@ use Payment\Notify\SwNotify; ...@@ -18,6 +18,7 @@ use Payment\Notify\SwNotify;
use Payment\Notify\TLNotify; use Payment\Notify\TLNotify;
use Payment\Notify\WxNotify; use Payment\Notify\WxNotify;
use Payment\Common\PayException; use Payment\Common\PayException;
use Payment\Notify\YSNotify;
class NotifyContext class NotifyContext
{ {
...@@ -65,6 +66,9 @@ class NotifyContext ...@@ -65,6 +66,9 @@ class NotifyContext
case Config::LTF_CHARGE: case Config::LTF_CHARGE:
$this->notify = new LTFNotify($config); $this->notify = new LTFNotify($config);
break; break;
case Config::YS_CHARGE:
$this->notify = new YSNotify($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE TL_CHARGE MI_CHARGE SW_CHARGE FU_CHARGE'); throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE TL_CHARGE MI_CHARGE SW_CHARGE FU_CHARGE');
} }
......
<?php
namespace Payment\Query\YS;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Query\ChargeQueryData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSChargeQuery extends YSBaseStrategy{
public function getBuildDataClass(){
return ChargeQueryData::class;
}
/**
* 返回
* @param null $url
* @return string
*/
public function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
<?php
namespace Payment\Query\YS;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\Query\RefundQueryData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSRefundQuery extends YSBaseStrategy{
public function getBuildDataClass(){
return RefundQueryData::class;
}
public function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
...@@ -26,6 +26,7 @@ use Payment\Query\Wx\WxChargeQuery; ...@@ -26,6 +26,7 @@ use Payment\Query\Wx\WxChargeQuery;
use Payment\Query\Wx\WxPayBankQuery; use Payment\Query\Wx\WxPayBankQuery;
use Payment\Query\Wx\WxRefundQuery; use Payment\Query\Wx\WxRefundQuery;
use Payment\Query\Wx\WxTransferQuery; use Payment\Query\Wx\WxTransferQuery;
use Payment\Query\YS\YSChargeQuery;
class QueryContext class QueryContext
{ {
...@@ -101,6 +102,10 @@ class QueryContext ...@@ -101,6 +102,10 @@ class QueryContext
case Config::LTF_REFUND: case Config::LTF_REFUND:
$this->query=new LTFRefundQuery($config); $this->query=new LTFRefundQuery($config);
break; break;
case Config::YS_QUERY://易生支付
$this->query = new YSChargeQuery($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'); 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');
} }
......
<?php
namespace Payment\Refund;
use Payment\Common\YSConfig;
use Payment\Common\YSpay\Data\RefundData;
use Payment\Common\YSpay\YSBaseStrategy;
class YSRefund extends YSBaseStrategy{
public function getBuildDataClass(){
return RefundData::class;
}
public function getReqUrl($url = null){
return parent::getReqUrl($url ?? YSConfig::REQUEST_URL); // TODO: Change the autogenerated stub
}
}
...@@ -18,6 +18,7 @@ use Payment\Refund\MiRefund; ...@@ -18,6 +18,7 @@ use Payment\Refund\MiRefund;
use Payment\Refund\SwRefund; use Payment\Refund\SwRefund;
use Payment\Refund\TLRefund; use Payment\Refund\TLRefund;
use Payment\Refund\WxRefund; use Payment\Refund\WxRefund;
use Payment\Refund\YSRefund;
class RefundContext class RefundContext
{ {
...@@ -65,6 +66,9 @@ class RefundContext ...@@ -65,6 +66,9 @@ class RefundContext
case Config::LTF_REFUND: case Config::LTF_REFUND:
$this->refund= new LTFRefund($config); $this->refund= new LTFRefund($config);
break; break;
case Config::YS_REFUND:
$this->refund = new YSRefund($config);
break;
default: default:
throw new PayException('当前仅支持:ALI WEIXIN CMB TL MI SW FU'); throw new PayException('当前仅支持:ALI WEIXIN CMB TL MI SW FU');
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!