Commit e4475be6 by yeran

add new channel : MiPay by yeran

1 parent a64a86c0
<?php
/**
* @author: helei
* @createTime: 2016-08-01 11:37
* @description: 微信配置文件
*/
return [
'app_id' => 'mf0cvupxsxnvoaykq6jd27hc1c9u1n0h', // 开发appid
'sub_merchant_id' => '201810301001',// 商户id
'sign_type' => 'RSA2',// MD5 HMAC-SHA256
'method' => 'trade.wxpay.unifiedorder',
'notify_url' => 'http://172.16.2.46:8080/vo-apidemo/OrderServlet',
];
//测试账号
//商户号:55079104816PJXP
//交易密码:Zyzswz1234
// 登录密码:Zyzs123456
//appid00020281 交易密钥:55079104816PJXP04
\ No newline at end of file
<?php
require_once __DIR__ . '/../../autoload.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
date_default_timezone_set('Asia/Shanghai');
$miConfig = require_once 'MiConfig.php';
$orderNo = 12345678;//time() . rand(1000, 9999);
// 订单信息
$data = [
'out_refund_sn' => '1231321',
'out_trade_sn' => '1213456798',
'meepay_trade_no' => 'LD0118103116581749379',
'refund_amount'=>1
];
try {
$ret = \Payment\Client\Cancel::run(Config::MI_CHANNEL_LITE, $miConfig, $data);
} catch (PayException $e) {
echo $e->errorMessage();
exit;
}
echo json_encode($ret, JSON_UNESCAPED_UNICODE);
\ No newline at end of file
<?php
require_once __DIR__ . '/../../autoload.php';
use Payment\Common\PayException;
use Payment\Client\Charge;
use Payment\Config;
date_default_timezone_set('Asia/Shanghai');
$miConfig = require_once 'MiConfig.php';
$orderNo = 1213456798;//time() . rand(1000, 9999);
// 订单信息
$payData = [
'body' => '商品名称',
'out_trade_sn' => $orderNo, //自定义订单号
'sub_appid' => 'wx03b4aeb839cc8d85',//小程序appid
'sub_openid'=>'oUlAM0Wp1K1rJEGJ0t__Ls5-qFKE',
'spbill_create_ip'=>'',
// 'timeout_express' => time() + 600,// 表示必须 600s 内付款
'trxamt' => '1',// 微信沙箱模式,需要金额固定为3.01
'attach' => '备注信息',
// 如果是服务商,请提供以下参数
// 'sub_store_id' => 6,//微信分配的子商户公众账号ID
'limit_pay' => 'no_credit',
'total_amount' =>1
];
try {
$ret = Charge::run(Config::MI_CHANNEL_LITE, $miConfig, $payData);
} catch (PayException $e) {
echo $e->errorMessage();
exit;
}
echo '--result---'.json_encode($ret, JSON_UNESCAPED_UNICODE);
\ No newline at end of file
header("Content-type: text/html; charset=gb2312");
<?php
require_once __DIR__ . '/../../autoload.php';
use Payment\Common\PayException;
use Payment\Client\Notify;
use Payment\Config;
date_default_timezone_set('Asia/Shanghai');
$miConfig = require_once 'MiConfig.php';
try{
Notify::run(Config::MI_CHARGE,$miConfig,new TestNotify());
}catch (Exception $exception){
}
?>
<?php
/**
* 退款处理 金额必须是 3.01
* Created by PhpStorm.
* User: helei
* Date: 2017/4/30
* Time: 下午3:51
*/
require_once __DIR__ . '/../../autoload.php';
use Payment\Common\PayException;
use Payment\Client\Refund;
use Payment\Config;
date_default_timezone_set('Asia/Shanghai');
$wxConfig = require_once 'MiConfig.php';
$data = [
'out_refund_sn' => '1231321',
'out_trade_sn' => '1213456798',
'meepay_trade_no' => 'LD0118103116581749379',
'refund_amount'=>1
];
try {
$ret = Refund::run(Config::MI_REFUND, $wxConfig, $data);
} catch (PayException $e) {
echo $e->errorMessage();
exit;
}
echo json_encode($ret, JSON_UNESCAPED_UNICODE);
\ No newline at end of file
...@@ -19,9 +19,10 @@ $aliConfig = require_once __DIR__ . '/aliconfig.php'; ...@@ -19,9 +19,10 @@ $aliConfig = require_once __DIR__ . '/aliconfig.php';
$wxConfig = require_once __DIR__ . '/wxconfig.php'; $wxConfig = require_once __DIR__ . '/wxconfig.php';
$cmbConfig = require_once __DIR__ . '/cmbconfig.php'; $cmbConfig = require_once __DIR__ . '/cmbconfig.php';
$tlConfig = require_once __DIR__ . '/TLConfig.php'; $tlConfig = require_once __DIR__ . '/TLConfig.php';
$miConfig = require_once __DIR__ . '/mipay/MiConfig.php';
$callback = new TestNotify(); $callback = new TestNotify();
$type = 'tl_charge';// xx_charge $type = 'mi_charge';// xx_charge
if (stripos($type, 'ali') !== false) { if (stripos($type, 'ali') !== false) {
$config = $aliConfig; $config = $aliConfig;
...@@ -31,14 +32,26 @@ if (stripos($type, 'ali') !== false) { ...@@ -31,14 +32,26 @@ if (stripos($type, 'ali') !== false) {
$config = $cmbConfig; $config = $cmbConfig;
}elseif (stripos($type, 'tl') !== false){ }elseif (stripos($type, 'tl') !== false){
$config = $tlConfig; $config = $tlConfig;
}elseif (stripos($type, 'mi') !== false){
$config = $miConfig;
} }
try { try {
if (!empty($config)){ if (!empty($config)){
// $retData = Notify::getNotifyData($type, $config);// 获取第三方的原始数据,未进行签名检查 // $retData = Notify::getNotifyData($type, $config);// 获取第三方的原始数据,未进行签名检查
$retData = "{\"acct\":\"odNM242ffm2FaJlLIpkcwM1O3YsE\",\"appid\":\"00020281\",\"chnltrxid\":\"4200000135201805042268978922\",\"cusid\":\"55079104816PJXP\",\"cusorderid\":\"20180504091414288930545254561086\",\"outtrxid\":\"20180504091414288930545254561086\",\"paytime\":\"20180504091423\",\"sign\":\"AD9FB6CD0E1455574C690F8AFE26F2A1\",\"termauthno\":\"CFT\",\"termrefnum\":\"4200000135201805042268978922\",\"termtraceno\":\"0\",\"trxamt\":\"1\",\"trxcode\":\"VSP501\",\"trxdate\":\"20180504\",\"trxid\":\"111817080000227489\",\"trxreserved\":\"通联支付测试备注信息\",\"trxstatus\":\"0000\"}"; // $retData = "{\"acct\":\"odNM242ffm2FaJlLIpkcwM1O3YsE\",\"appid\":\"00020281\",\"chnltrxid\":\"4200000135201805042268978922\",\"cusid\":\"55079104816PJXP\",\"cusorderid\":\"20180504091414288930545254561086\",\"outtrxid\":\"20180504091414288930545254561086\",\"paytime\":\"20180504091423\",\"sign\":\"AD9FB6CD0E1455574C690F8AFE26F2A1\",\"termauthno\":\"CFT\",\"termrefnum\":\"4200000135201805042268978922\",\"termtraceno\":\"0\",\"trxamt\":\"1\",\"trxcode\":\"VSP501\",\"trxdate\":\"20180504\",\"trxid\":\"111817080000227489\",\"trxreserved\":\"通联支付测试备注信息\",\"trxstatus\":\"0000\"}";
$ret = ArrayUtil::ValidSign(json_decode($retData,true), $tlConfig['md5_key']); //
// $ret = ArrayUtil::ValidSign(json_decode($retData,true), $tlConfig['md5_key']);
// $basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR;
// $publicKeyPath = "{$basePath}mipay".DIRECTORY_SEPARATOR."meepay_public_key.pem";
$publicKeyPath = "/project/ldy/payment/src/CacertFile/mipay/meepay_public_key.pem";
$retData = "{\"result_code\":\"SUCCESS\",\"out_trade_sn\":\"SN20181031020706\",\"meepay_trade_no\":\"MF0118103102070684504\",\"transaction_id\":\"4200000203201810316768166604\",\"sub_merchant_id\":\"10002\",\"sub_appid\":\"wx03b4aeb839cc8d85\",\"sub_openid\":\"oUlAM0fD5RsWs9CvOCCMU_nYEDSY\",\"total_amount\":\"1\",\"trade_type\":\"NATIVE\",\"nonce_str\":\"af7rhpf50cjqjadyzthu82hyl7rzdkgk\",\"fee_type\":\"CNY\",\"cash_fee\":\"1\",\"attach\":\"1233\",\"sign_type\":\"RSA2\",\"sign\":\"d0AsaPytw9by+gfD9DLBHp9s1U+aQt9qVd1DYjPP4xvp+7umDU/bLsuxER+0XPF5M0vwdcks/Tge+KCWX3wWdMIOnltVKfDRFfsf7HOznwr4sE5zUxb0nkfCayLMZ/m/kcgqy9QryAl+SY/+MmLlmnxEI6eyjtnX0rf8qZyZDGI=\"}";
$ret = ArrayUtil::SignVerify(json_decode($retData,true),$publicKeyPath);
echo $ret; echo $ret;
} }
} catch (PayException $e) { } catch (PayException $e) {
......
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCxzOUE1Fz484RYGIZCQj32NFe9GqzG6t6v2l1W3SU+6drxFZIC
BmGCC/VLgh4PQYVslkfbWWEoxaCE74BcnRH9W6fIQOLyN6l2n55QAfVxs0Ft4jc1
PB/ppQukg3feEU3GTRqjrR9IOoKlJmZxe6a8XpWA2m9BXhs4uln0HiBncwIDAQAB
AoGBAKm11Ggut+ucrRdVmVlHV1NZFOJYwtA/wX0DJpLSFUoe96+kkjBCnPH/rgx7
z2tqdAt4ym/RuY6sTJJ29QPxnQesFyN16UBCiI0tZd6og3UJkVCcLGUN8clYd4Dk
ojnoGDy7HTJ3Wll46wQpI5IxwxD3oQkKYBmlmX18zSIKaWx5AkEA1yi56EKbS4r3
M2CU0OzdZ9Cx266gxND+LbwAFbEJRWjLjZ07v7eDxSPWSdOZDSAUw0BXFyfXYX+7
ZhYVIJ+4jQJBANOMybItaG0pUsVXNMd7XV3NMHCjGhLDRhAC6qIjcKRSA5P1lca+
xcRW4GzxOAhsddtSR4NLMf7rRUEA9gMIn/8CQQDHHkamfvXPPKU3o/s1OvBQAmCH
aR4Z5zxEQQdnC7cDyE8RGOFRtNk62caX/j5XWkg8xk+S+2klLxvUBz24OniFAkAg
H+EBDaQt73iCPxvkrvcep2oTsLDk6IJbLBY1SOxyB4JDlaeI5q9hgU/TO04m+VFs
XLI/XcvZyiBaHqs9CrJBAkEAzXeJESzXcy3ANdqH5C6MMfvCgNSyHXs29xheuM6g
S5xz6HzoHlo+fq1SJjk7axvtGWrLftwWMJ0g0q4fm7M69A==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDsmPri2HHumfboEpjrg7tAM1fS
i8nfqVMMb6CwbF0Hweg6Z54/7bFX3LFGib530hkZla7loCm87kuLaRAgvUOu16OS
y0OTfu8OfvMRb384xxp5Hhm5wIgriozhBRebq1MGF+GfkGb1SkYyD0uM/o64+HO4
c8vcJqoUaiBGmXv4owIDAQAB
-----END PUBLIC KEY-----
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace Payment; namespace Payment;
use Payment\Charge\MiPay\MiCancel;
use Payment\Charge\TLpay\TLCancel; use Payment\Charge\TLpay\TLCancel;
use Payment\Common\BaseStrategy; use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
...@@ -42,6 +43,9 @@ class CancelContext ...@@ -42,6 +43,9 @@ class CancelContext
case Config::TL_CHANNEL_LITE: case Config::TL_CHANNEL_LITE:
$this->cancelHandler = new TLCancel($config); $this->cancelHandler = new TLCancel($config);
break; break;
case Config::MI_CHANNEL_LITE:
$this->cancelHandler = new MiCancel($config);
break;
default: default:
throw new PayException('当前仅支持:通联支付平台'); throw new PayException('当前仅支持:通联支付平台');
} }
......
<?php
/**
* Created by IntelliJ IDEA.
* User: yeran
* Date: 2018/4/23
* Time: 下午5:44
*/
namespace Payment\Charge\MiPay;
use Payment\Common\MiConfig;
use Payment\Common\MiPay\Data\Cancel\MiCancelData;
use Payment\Common\MiPay\MiBaseStrategy;
/**
* Class MiCancel
* @package Payment\Charge\MiPay
*/
class MiCancel extends MiBaseStrategy{
/**
* 交易撤销 的url
* @return null|string
* @author helei
*/
protected function getReqUrl()
{
return MiConfig::GATEWAY_URL;
}
/**
* 获取交易退款对应的数据完成类
* @return MiCancelData
* @author helei
*/
public function getBuildDataClass()
{
// TODO: Implement getBuildDataClass() method.
$this->config->paytype = 'W06';
return MiCancelData::class;
}
}
\ No newline at end of file
<?php
/**
* @author: yeran
* @createTime: 2018-10-30 11:13
* @description: 米付支付发起支付接口
*/
namespace Payment\Charge\MiPay;
use Payment\Common\MiPay\Data\Charge\MiChargeData;
use Payment\Common\MiPay\MiBaseStrategy;
/**
* Class MiLiteCharge
*
* 米付-微信小程序支付
*
* @package Payment\Charge\MiPay
*/
class MiLiteCharge extends MiBaseStrategy
{
public function getBuildDataClass()
{
return MiChargeData::class;
}
/**
* 处理返回值。直接返回与微信小程序文档对应的字段
* @param array $ret
*
* @return array $backData 包含以下键
*
* ```php
* $backData = [
* 'appId' => '', // 小程序id
* 'package' => '', // 订单详情扩展字符串 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
* 'nonceStr' => '', // 随机字符串
* 'timeStamp' => '', // 时间戳
* 'signType' => '', // 签名算法,暂支持MD5
* 'paySign' => '', // 签名
* ];
* ```
* @author helei
*/
protected function retData(array $ret)
{
return $ret['jspackage'];
}
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
namespace Payment\Charge\TLpay; namespace Payment\Charge\TLpay;
use Payment\Common\TLConfig; use Payment\Common\TLConfig;
use Payment\Common\TLpay\Data\Cancel\TLCancelData; use Payment\Common\TLpay\Data\Cancel\MiCancelData;
use Payment\Common\TLpay\TLBaseStrategy; use Payment\Common\TLpay\TLBaseStrategy;
/** /**
...@@ -30,7 +30,7 @@ class TLCancel extends TLBaseStrategy{ ...@@ -30,7 +30,7 @@ class TLCancel extends TLBaseStrategy{
/** /**
* 获取交易退款对应的数据完成类 * 获取交易退款对应的数据完成类
* @return TLCancelData * @return MiCancelData
* @author helei * @author helei
*/ */
public function getBuildDataClass() public function getBuildDataClass()
...@@ -38,7 +38,7 @@ class TLCancel extends TLBaseStrategy{ ...@@ -38,7 +38,7 @@ class TLCancel extends TLBaseStrategy{
// TODO: Implement getBuildDataClass() method. // TODO: Implement getBuildDataClass() method.
$this->config->paytype = 'W06'; $this->config->paytype = 'W06';
return TLCancelData::class; return MiCancelData::class;
} }
......
...@@ -16,6 +16,7 @@ use Payment\Charge\Ali\AliWebCharge; ...@@ -16,6 +16,7 @@ use Payment\Charge\Ali\AliWebCharge;
use Payment\Charge\Ali\AliQrCharge; use Payment\Charge\Ali\AliQrCharge;
use Payment\Charge\Cmb\CmbCharge; use Payment\Charge\Cmb\CmbCharge;
use Payment\Charge\MiPay\MiLiteCharge;
use Payment\Charge\TLpay\TLLiteCharge; use Payment\Charge\TLpay\TLLiteCharge;
use Payment\Charge\Wx\WxAppCharge; use Payment\Charge\Wx\WxAppCharge;
use Payment\Charge\Wx\WxBarCharge; use Payment\Charge\Wx\WxBarCharge;
...@@ -87,16 +88,20 @@ class ChargeContext ...@@ -87,16 +88,20 @@ class ChargeContext
case Config::WX_CHANNEL_BAR: case Config::WX_CHANNEL_BAR:
$this->channel = new WxBarCharge($config); $this->channel = new WxBarCharge($config);
break; break;
case Config::CMB_CHANNEL_WAP: case Config::CMB_CHANNEL_WAP:
case Config::CMB_CHANNEL_APP: case Config::CMB_CHANNEL_APP:
$this->channel = new CmbCharge($config); $this->channel = new CmbCharge($config);
break; break;
case Config::TL_CHANNEL_LITE: case Config::TL_CHANNEL_LITE: //通联支付
$this->channel = new TLLiteCharge($config); $this->channel = new TLLiteCharge($config);
break; break;
case Config::MI_CHANNEL_LITE: //米付小程序通道
$this->channel = new MiLiteCharge($config);
break;
default: default:
throw new PayException('当前支持:支付宝 微信 招商一网通 通联支付'); throw new PayException('当前支持:支付宝 微信 招商一网通 通联支付 米付');
} }
} catch (PayException $e) { } catch (PayException $e) {
throw $e; throw $e;
......
<?php <?php
/** /**
* Created by PhpStorm. * @author yeran
* User: helei * @createTime 2018-10-30
* Date: 2017/3/4 *
* Time: 下午5:40 * @desc 撤单处理类
*/ */
namespace Payment\Client; namespace Payment\Client;
...@@ -32,7 +33,9 @@ class Cancel ...@@ -32,7 +33,9 @@ class Cancel
Config::CMB_CHANNEL_APP,// 招行一网通 Config::CMB_CHANNEL_APP,// 招行一网通
'applepay_upacp',// Apple Pay 'applepay_upacp',// Apple Pay
Config::TL_CHANNEL_LITE, Config::TL_CHANNEL_LITE,//通联支付
Config::MI_CHANNEL_LITE, //米付
]; ];
/** /**
......
<?php <?php
/**
* Created by PhpStorm.
* User: helei
* Date: 2017/3/4
* Time: 下午5:40
*/
namespace Payment\Client; namespace Payment\Client;
...@@ -32,7 +27,10 @@ class Charge ...@@ -32,7 +27,10 @@ class Charge
Config::CMB_CHANNEL_APP,// 招行一网通 Config::CMB_CHANNEL_APP,// 招行一网通
'applepay_upacp',// Apple Pay 'applepay_upacp',// Apple Pay
Config::TL_CHANNEL_LITE, Config::TL_CHANNEL_LITE, // 通联支付
Config::MI_CHANNEL_LITE,//米付小程序通道
]; ];
/** /**
......
<?php <?php
/**
* Created by PhpStorm.
* User: helei
* Date: 2017/3/7
* Time: 下午6:29
*/
namespace Payment\Client; namespace Payment\Client;
...@@ -24,7 +19,9 @@ class Notify ...@@ -24,7 +19,9 @@ class Notify
Config::CMB_CHARGE,// 招行一网通 Config::CMB_CHARGE,// 招行一网通
'applepay_upacp',// Apple Pay 'applepay_upacp',// Apple Pay
Config::TL_CHARGE Config::TL_CHARGE,//通联支付
Config::MI_CHARGE,//米付
]; ];
/** /**
......
<?php <?php
/** /**
* Created by PhpStorm. * @author yeran
* User: helei * @time 2018-10-30 11:29
* Date: 2017/3/6 * @desc 交易查询
* Time: 下午9:08
*/ */
namespace Payment\Client; namespace Payment\Client;
...@@ -33,7 +33,9 @@ class Query ...@@ -33,7 +33,9 @@ class Query
Config::CMB_CHARGE, Config::CMB_CHARGE,
Config::CMB_REFUND, Config::CMB_REFUND,
Config::TL_QUERY Config::TL_QUERY,//通联支付
Config::MI_QUERY,//米付
]; ];
/** /**
......
<?php <?php
/** /**
* Created by PhpStorm. * @author yeran
* User: helei * @time 2018-10-30 11:34
* Date: 2017/3/7 * @desc 退款
* Time: 上午10:50 *
*/ */
namespace Payment\Client; namespace Payment\Client;
...@@ -28,7 +29,8 @@ class Refund ...@@ -28,7 +29,8 @@ class Refund
'applepay_upacp',// Apple Pay 'applepay_upacp',// Apple Pay
Config::TL_REFUND Config::TL_REFUND,//通联支付
Config::MI_REFUND,//米付
]; ];
/** /**
......
...@@ -58,6 +58,8 @@ abstract class BaseData ...@@ -58,6 +58,8 @@ abstract class BaseData
$this->channel = Config::CMB_PAY; $this->channel = Config::CMB_PAY;
}elseif ($config instanceof TLConfig) { }elseif ($config instanceof TLConfig) {
$this->channel = Config::TL_PAY; $this->channel = Config::TL_PAY;
} elseif ($config instanceof MiConfig) {
$this->channel = Config::MI_PAY;
} }
$this->data = array_merge($config->toArray(), $reqData);//配置信息合并 $this->data = array_merge($config->toArray(), $reqData);//配置信息合并
...@@ -116,18 +118,20 @@ abstract class BaseData ...@@ -116,18 +118,20 @@ abstract class BaseData
$data = $this->retData; $data = $this->retData;
} }
if($this->channel === Config::TL_PAY){ if($this->channel === Config::TL_PAY){
$this->retData['sign'] = ArrayUtil::SignArray($data,$this->md5Key);//签名 $this->retData['sign'] = ArrayUtil::SignArray($data,$this->md5Key);//签名
}else { }else if ($this->channel === Config::MI_PAY){
$values = ArrayUtil::removeKeys($data, ['sign']);
$values = ArrayUtil::arraySort($values); $basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR;
$this->cacertPath = "{$basePath}mipay".DIRECTORY_SEPARATOR."ldy_private_key.pem";
$this->retData['sign'] = ArrayUtil::SignRSA($data,$this->cacertPath);//签名
} else{
$values = ArrayUtil::removeKeys($data, ['sign']);
$values = ArrayUtil::arraySort($values);
$signStr = ArrayUtil::createLinkstring($values); $signStr = ArrayUtil::createLinkstring($values);
$this->retData['sign'] = $this->makeSign($signStr); $this->retData['sign'] = $this->makeSign($signStr);
} }
} }
......
<?php
namespace Payment\Common;
use Payment\Utils\ArrayUtil;
use Payment\Utils\StrUtil;
final class MiConfig extends ConfigInterface
{
// 应用ID
public $appId;
// 平台分配的商户号
public $sub_merchant_id;
// 随机字符串,不长于32位
public $nonce_str;
public $trade_type;
public $method;
public $sign_type = 'RSA2';
public $limit_pay;
public $publicKeyPath;//公钥路径
// 指定回调页面
public $returnUrl;
public $version = 'v1';//接口版本号
const GATEWAY_URL = 'https://openapi.meepay.net/pay/gateway';
// 统一下单url
const UNIFIED_URL = 'https://openapi.meepay.net/pay/trade/wxpay_unifiedorder';
// 撤销交易url
const ORDER_CANCEL_URL = 'https://vsp.allinpay.com/apiweb/unitorder/cancel';
// 申请退款url
const REFUND_URL = 'https://vsp.allinpay.com/apiweb/unitorder/refund';
// 支付查询url
const CHARGE_QUERY_URL = 'https://vsp.allinpay.com/apiweb/unitorder/query';
// 退款账户
const REFUND_UNSETTLED = 'REFUND_SOURCE_UNSETTLED_FUNDS';// 未结算资金退款(默认使用未结算资金退款)
const REFUND_RECHARGE = 'REFUND_SOURCE_RECHARGE_FUNDS';// 可用余额退款(限非当日交易订单的退款)
const PLATFORM_APPID = '00032161'; // 平台appId
const orgid = '55079104816UGBA'; // 代为发起交易的机构商户号
/**
* 初始化配置文件
* TLConfig 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);
// 检查 分配的公众账号ID
if (key_exists('app_id', $config) && !empty($config['app_id'])) {
$this->appId = $config['app_id'];
if(self::PLATFORM_APPID == $this->appId){
$this->orgid = self::orgid;
}else{
$this->orgid = null;
}
} else {
throw new PayException('必须提供支付平台分配的公众账号ID');
}
// 检查 method
if (key_exists('method', $config) && !empty($config['method'])) {
$this->method = $config['method'];
} else {
throw new PayException('必须提供method');
}
// 检查 平台支付分配的商户号
if (key_exists('sub_merchant_id', $config) && !empty($config['sub_merchant_id'])) {
$this->sub_merchant_id = $config['sub_merchant_id'];
} else {
throw new PayException('必须提供支付平台分配的子商户号');
}
if (key_exists('trade_type', $config) && !empty($config['trade_type'])) {
$this->trade_type = $config['trade_type'];
} else {
$this->trade_type = 'MINIAPP'; // 默认是小程序支付
}
// 检查 异步通知的url
if (key_exists('notify_url', $config) && !empty($config['notify_url'])) {
$this->notifyUrl = trim($config['notify_url']);
} else {
throw new PayException('异步通知的url必须提供.');
}
// 设置禁止使用的支付方式
if (key_exists('limit_pay', $config) && !empty($config['limit_pay']) && $config['limit_pay'][0] === 'no_credit') {
$this->limitPay = $config['limit_pay'][0];
}
// 生成随机字符串
$this->nonce_str = StrUtil::getNonceStr();
}
}
<?php
namespace Payment\Common\MiPay\Data\Cancel;
use Payment\Common\MiPay\Data\MiBaseData;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
/**
* Class MiCancelData
* 通联支付
*
* @package Payment\Common\MiPay\Data\Charge
* @author yeran
*/
class MiCancelData extends MiBaseData
{
protected function checkDataParam()
{
$reqsn = $this->out_refund_sn;// 商户退款单号
$oldreqsn = $this->out_trade_sn;//服务商自定义单号
$oldtrxid = $this->meepay_trade_no; //米付订单号
if ((empty($oldreqsn) && empty($oldtrxid)) || empty($reqsn)) {
throw new PayException('单号数据缺失');
}
}
/**
* 组装数据,用于计算sign,以及与支付平台对接
*
* 交易撤销数据
*
*/
protected function buildData()
{
$signData = [
// 基本数据
'appid' => $this->appId,
'method' => 'trade.reverse',
'nonce_str' => $this->nonce_str,
'version' => $this->version,
'sign_type' => $this->sign_type,
'out_refund_sn' => $this->out_refund_sn,
'out_trade_sn' => $this->out_trade_sn,
'meepay_trade_no' => $this->meepay_trade_no,
'refund_amount' => $this->refund_amount,
];
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
/**
* 处理支付平台的返回值并返回给客户端
* @param array $ret
* @return mixed
* @author yeran
*/
protected function retData(array $ret){
return $ret;
}
}
<?php
namespace Payment\Common\MiPay\Data\Cancel;
use Payment\Common\PayException;
use Payment\Common\MiPay\Data\MiBaseData;
use Payment\Utils\ArrayUtil;
/**
* 用户退款
* Class RefundData
*
* @package Payment\Common\MiPay\Data\Cancel
* @author yeran
*/
class RefundData extends MiBaseData
{
/**
* 退款数据封装
*/
protected function buildData()
{
$this->retData = [
'appid' => $this->appId,
'method' => 'trade.refund',
'nonce_str' => $this->nonce_str,
'version' => $this->version,
'sign_type' => $this->sign_type,
'out_refund_sn' => $this->out_refund_sn,
'out_trade_sn' => $this->out_trade_sn,
'meepay_trade_no' => $this->meepay_trade_no,
'refund_amount' => $this->refund_amount,
// 'trxamt' => $this->trxamt,// 退款金额,分
// 'reqsn' => $this->reqsn,// 商户退款单号
// 'oldreqsn' => $this->oldreqsn,//原交易的商户订单号
// 'oldtrxid' => $this->oldtrxid,//原交易的收银宝平台流水
// 'remark' => $this->remark,// 备注
];
$this->retData = ArrayUtil::paraFilter($this->retData);
}
/**
* 检查参数
* @author yeran
*/
protected function checkDataParam()
{
$reqsn = $this->out_refund_sn;// 商户退款单号
$oldreqsn = $this->out_trade_sn;
$oldtrxid = $this->meepay_trade_no;
// $trxamt = $this->trxamt;
if (empty($reqsn)) {
throw new PayException('请设置退款单号 refund_no');
}
// 二者不能同时为空
if (empty($oldreqsn) && empty($oldtrxid)) {
throw new PayException('必须提供米付支付交易号或平台唯一订单号。');
}
// if ($trxamt<1) {
// throw new PayException('退款金额异常');
// }
}
}
<?php
namespace Payment\Common\MiPay\Data;
class BackMiChargeData extends MiBaseData
{
protected function buildData()
{
$this->retData = [
'appId' => $this->appid,
'timeStamp' => time() . '',
'nonceStr' => $this->randomstr,
'package' => 'prepay_id=' . $this->chnltrxid,
'signType' => 'MD5',// 签名算法,暂支持MD5
];
}
protected function checkDataParam()
{
// 不进行检查
}
}
<?php
namespace Payment\Common\MiPay\Data\Charge;
use Payment\Common\PayException;
use Payment\Common\MiPay\Data\MiBaseData;
use Payment\Config;
/**
* Class ChargeBaseData
*
* @inheritdoc
*
* @property string $reqsn
* @property string $trxamt
* @property string $client_ip 用户端实际ip
* @property string $body
* @property string $return_param 附加数据,在查询API和支付通知中原样返回
* @property integer $validtime 订单有效时间,默认为5分钟,最长60分钟
*
* @package Payment\Common\TLpay\Data\Charge
*/
abstract class ChargeBaseData extends MiBaseData
{
/**
* 检查传入的支付信息是否正确
*/
protected function checkDataParam()
{
$out_trade_sn = $this->out_trade_sn;
$trxamt = $this->total_amount;//分
$body = $this->body;
// 检查订单号是否合法
if (empty($out_trade_sn) || mb_strlen($out_trade_sn) > 64) {
throw new PayException('订单号不能为空,并且长度不能超过64位');
}
// 检查金额不能低于0.01
if (bccomp($trxamt, 100 * Config::PAY_MIN_FEE, 2) === -1) {
throw new PayException('支付金额不能低于 ' . Config::PAY_MIN_FEE . ' 元');
}
// 检查 商品名称 与 商品描述
if (empty($body)) {
throw new PayException('必须提供订单商品名称');
}
// 订单有效时间,以分为单位,不填默认为5分钟,最大60分钟
// if(!$this->validtime)
// $this->validtime = 5;
//
// if ($this->validtime >60) {
// throw new PayException('订单有效时间最大60分钟');
// }
// 设置ip地址
$clientIp = $this->spbill_create_ip;
if (empty($clientIp)) {
$this->spbill_create_ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
}
}
}
<?php
namespace Payment\Common\MiPay\Data\Charge;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;
/**
* Class TLChargeData
* 通联支付
*
* @property string $openid trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
* @property string $sub_appid 微信分配的子商户公众账号ID
* @property string $sub_mch_id 微信支付分配的子商户号
* @property string $sub_openid 用户在子商户appid下的唯一标识
*
* @package Payment\Common\Weixin\Data\Charge
* anthor yeran
*/
class MiChargeData extends ChargeBaseData
{
protected function checkDataParam()
{
parent::checkDataParam(); // TODO: Change the autogenerated stub
// 小程序支付,必须设置openid
$acct = $this->openid || $this->sub_openid;
if (empty($acct)) {
throw new PayException('用户唯一标识,必须携带');
}
}
/**
* 组装数据,用于计算sign,以及与支付平台对接
*/
protected function buildData()
{
$signData = [
// 基本数据
'appid' => trim($this->appId),
'sub_merchant_id'=> $this->sub_merchant_id,
'sub_appid' => trim($this->sub_appid),
'version' => $this->version,
'nonce_str' => $this->nonce_str,
'trade_type' => $this->trade_type,
'notify_url' => $this->notifyUrl,
'limit_pay' => $this->limitPay, // 指定不使用信用卡
'method' => $this->method,
'out_trade_sn'=>$this->out_trade_sn,
'sign_type' => $this->sign_type,
'body' => trim($this->body),
'attach' => trim($this->attach),
'sub_openid' => trim($this->sub_openid),
'total_amount' => $this->total_amount,//单位分
'spbill_create_ip' => $this->spbill_create_ip
];
// 移除数组中的空值
$this->retData = ArrayUtil::paraFilter($signData);
}
}
<?php
namespace Payment\Common\MiPay\Data;
use Payment\Common\BaseData;
use Payment\Utils\StrUtil;
/**
* Class BaseData
*
*
* @package Payment\Common\MiPay\Data
*/
abstract class MiBaseData extends BaseData
{
/**
* 签名算法实现 通联支付sign生成算法:sign = md5(string.getbyte("utf-8")).toUpperCase();
* @param string $signStr
* @return string
*/
protected function makeSign($signStr){
return strtoupper(md5(StrUtil::getBytes($signStr)));
}
}
<?php
namespace Payment\Common\MiPay\Data\Query;
use Payment\Common\PayException;
use Payment\Common\MiPay\Data\MiBaseData;
use Payment\Utils\ArrayUtil;
/**
* 查询交易的数据结构
* Class TLQueryData
*
*
* @package Payment\Common\MiPay\Data\Query
*/
class MiQueryData extends MiBaseData
{
protected function buildData()
{
$this->retData = [
'appid' => $this->appId,
'cusid' => $this->cusid,
'version' => $this->version,
'randomstr' => $this->randomstr,
'reqsn' => $this->reqsn,//商户的交易订单号
'trxid' => $this->trxid,//支付的收银宝平台流水
];
$this->retData = ArrayUtil::paraFilter($this->retData);
}
protected function checkDataParam()
{
$trxid = $this->trxid;// 支付的收银宝平台流水
$reqsn = $this->reqsn;// 商户订单号,查询效率低,不建议使用
// 二者不能同时为空
if (empty($trxid) && empty($reqsn)) {
throw new PayException('必须提供通联支付交易号或商户网站唯一订单号。建议使用通联支付交易号');
}
}
}
\ No newline at end of file
<?php
namespace Payment\Common\MiPay;
use Payment\Common\BaseData;
use Payment\Common\BaseStrategy;
use Payment\Common\PayException;
use Payment\Common\MiConfig;
use Payment\Utils\ArrayUtil;
use Payment\Utils\Curl;
/**
* Created by IntelliJ IDEA.
* User: yeran
* Date: 2018/4/21
* Time: 下午11:39
*/
abstract class MiBaseStrategy implements BaseStrategy{
/**
* 通联支付的配置文件
* @var MiConfig $config
*/
protected $config;
/**
* 支付数据
* @var BaseData $reqData
*/
protected $reqData;
/**
* WxBaseStrategy constructor.
* @param array $config
* @throws PayException
*/
public function __construct(array $config)
{
/* 设置内部字符编码为 UTF-8 */
mb_internal_encoding("UTF-8");
try {
$this->config = new MiConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 发送完了请求
* @param array $body
* @return mixed
* @throws PayException
* @author helei
*/
protected function sendReq($body)
{
$url = $this->getReqUrl();
if (is_null($url)) {
throw new PayException('目前不支持该接口。请联系开发者添加');
}
$responseTxt = $this->curlPost($body, $url);
if ($responseTxt['error'] != 0) { //通信标识
throw new PayException('支付平台返回错误提示0:' . $responseTxt['message']);
}
// 格式化为数组
$retData = (json_decode($responseTxt['body'],true));
if ($retData['return_code'] != 'SUCCESS') { //通信标识
throw new PayException('支付平台返回错误提示1:' . $retData['errmsg']);
}
if ($retData['result_code'] != 'SUCCESS') {//交易标识
$msg = $retData['errmsg']?:'交易失败-系统繁忙';
throw new PayException('支付平台返回错误提示2:' . $msg);
}
return $retData;
}
/**
* 父类仅提供基础的post请求,子类可根据需要进行重写
* @param array $body
* @param string $url
* @return mixed
* @author helei
*/
protected function curlPost($body, $url)
{
$curl = new Curl();
// $paramsStr = ArrayUtil::ToUrlParams($body);
// die(json_encode($body));
return $curl->set([
'CURLOPT_HEADER' => 0,
])->post($body, $url)->submit($url,true);
}
/**
* 获取需要的url 默认返回下单的url
* @author helei
* @return string|null
*/
protected function getReqUrl()
{
return MiConfig::GATEWAY_URL;
}
/**
* @param array $data
* @author helei
* @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();//计算sign,整理数据格式
$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
* @author helei
*/
protected function retData(array $ret)
{
return $ret;
}
/**
* 检查支付平台返回的数据是否被篡改过:sign=md5(string.getbyte("utf-8")).toUpperCase()
* @param array $retData
* @return boolean
* @author helei
*/
protected function verifySign(array $retData)
{
$retSign = $retData['sign'];
$values = ArrayUtil::removeKeys($retData, ['sign', 'sign_type']);
$values = ArrayUtil::paraFilter($values);
$signStr = ArrayUtil::SignArray($values,$this->config->md5Key);
return strtoupper($signStr) === $retSign;
}
}
\ No newline at end of file
...@@ -7,13 +7,35 @@ ...@@ -7,13 +7,35 @@
* @link https://helei112g.github.io/ * @link https://helei112g.github.io/
* *
* @version 2.6.1 * @version 2.6.1
* @version 3.0.0 by yeran 2018-10-30
*/ */
namespace Payment; namespace Payment;
final class Config final class Config
{ {
const VERSION = '3.1.1-dev'; const VERSION = '3.0.0';
//======================= 账户类型 ======================//
const WECHAT_PAY = 'wechat';
const ALI_PAY = 'ali';
const CMB_PAY = 'cmb';
const TL_PAY ='tl'; // 通联支付
const MI_PAY = 'mipay'; // 米付
//========================= 金额问题设置 =======================//
const PAY_MIN_FEE = '0.01';// 支付的最小金额
const TRANS_FEE = '50000';// 转账达到这个金额,需要添加额外信息
//======================= 交易状态常量定义 ======================//
const TRADE_STATUS_SUCC = 'success';// 交易成功
const TRADE_STATUS_FAILD = 'not_pay';// 交易未完成
//========================= ali相关接口 =======================// //========================= ali相关接口 =======================//
// 支付相关常量 // 支付相关常量
...@@ -95,25 +117,30 @@ final class Config ...@@ -95,25 +117,30 @@ final class Config
const TL_QUERY = 'tl_query'; const TL_QUERY = 'tl_query';
const TL_PAY ='tl';
//========================= 金额问题设置 =======================//
const PAY_MIN_FEE = '0.01';// 支付的最小金额
const TRANS_FEE = '50000';// 转账达到这个金额,需要添加额外信息 //========================= 米付相关接口 =======================//
// 支付常量
const MI_CHANNEL_APP = 'mi_pub';// 米付微信公众号h5支付
const MI_CHANNEL_LITE = 'mi_lite';// 米付小程序支付
const MI_BIND = 'mi_bind';// 签约API
const MI_PUB_KEY = 'mi_pub_key';// 查询公钥
const MI_CHARGE = 'mi_charge';// 米付支付-统一下单
const MI_REFUND = 'mi_refund';// 米付退款
const MI_CANCEL = 'mi_cancel';// 米付交易撤销,只能撤销当天的交易,全额退款,实时返回退款结果
const MI_QUERY = 'mi_query'; // 米付查询接口
//======================= 交易状态常量定义 ======================//
const TRADE_STATUS_SUCC = 'success';// 交易成功
const TRADE_STATUS_FAILD = 'not_pay';// 交易未完成
//======================= 账户类型 ======================//
const WECHAT_PAY = 'wechat';
const ALI_PAY = 'ali';
const CMB_PAY = 'cmb';
} }
<?php
namespace Payment\Notify;
use Payment\Common\PayException;
use Payment\Common\MiConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;
use Payment\Utils\StrUtil;
/**
* Class MiNotify
* 微信回调处理
* @package Payment\Notify
* @anthor yeran
*/
class MiNotify extends NotifyStrategy
{
/**
* MiNotify constructor.
* @param array $config
* @throws PayException
*/
public function __construct(array $config)
{
parent::__construct($config);
try {
$this->config = new MiConfig($config);
} catch (PayException $e) {
throw $e;
}
}
/**
* 获取返回的异步通知数据
* @return array|bool
* @author yeran
*/
public function getNotifyData()
{
$params = array();
foreach($_POST as $key=>$val) {//动态遍历获取所有收到的参数,此步非常关键
$params[$key] = $val;
}
if(count($params)<1){//如果参数为空,则不进行处理
return false;
}
if(!$this->checkNotifyData($params)){
return false;
}
return $params;
}
/**
* 检查异步通知的数据是否正确
* @param array $data
*
* @author yeran
* @return boolean
*/
public function checkNotifyData(array $data)
{
// 检查返回数据签名是否正确
return $this->verifySign($data);
}
/**
* 检查微信返回的数据是否被篡改过
* @param array $retData
* @return boolean
* @author yeran
*/
protected function verifySign(array $retData)
{
$basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR;
$this->config->publicKeyPath = "{$basePath}mipay".DIRECTORY_SEPARATOR."meepay_public_key.pem";
if(ArrayUtil::SignVerify($retData, $this->config->publicKeyPath)){//验签成功
//此处进行业务逻辑处理
return true;
}
else{
return false;
}
}
/**
*
* 封装回调函数需要的数据格式
*
* @param array $data
*
* @return array
* @author yeran
*/
protected function getRetData(array $data)
{
if ($this->config->returnRaw) {
$data['channel'] = Config::MI_CHARGE;
return $data;
}
$retData = [
// 'bank_type' => $data['bank_type'],
'cash_fee' => $data['cash_fee'],
// 'device_info' => $data['device_info'],
'fee_type' => $data['fee_type'],
// 'is_subscribe' => $data['is_subscribe'],
'appid' => $data['sub_appid'],
'sub_merchant_id' => $data['sub_merchant_id'],
'buyer_id' => $data['sub_openid'],
'order_no' => $data['out_trade_sn'],//平台
'meepay_trade_no' => $data['meepay_trade_no'],//米付
// 'pay_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),// 支付完成时间
'amount' => $data['total_amount'],
'trade_type' => $data['trade_type'],
'transaction_id' => $data['transaction_id'],//微信
'trade_state' => strtolower($data['result_code']),
'channel' => Config::MI_CHARGE,
];
// 检查是否存在用户自定义参数
if (isset($data['attach']) && ! empty($data['attach'])) {
$retData['return_param'] = $data['attach'];
}
return $retData;
}
/**
* 处理完后返回的数据格式
* @param bool $flag
* @param string $msg 通知信息,错误原因
* @author yeran
* @return string
*/
protected function replyNotify($flag, $msg = 'OK')
{
// 默认为成功
$return_code ='SUCCESS';
if (! $flag) {
$return_code ='FAIL';
}
return $return_code;
}
}
<?php <?php
/** /**
* @author: helei * @author: yeran
* @createTime: 2016-07-14 17:42 * @createTime: 2018-10-30 11:26
* @description: 暴露给客户端调用的接口 * @description: 支付异步回调
* @link https://github.com/helei112g/payment/tree/paymentv2
* @link https://helei112g.github.io/
*/ */
namespace Payment; namespace Payment;
use Payment\Notify\AliNotify; use Payment\Notify\AliNotify;
use Payment\Notify\CmbNotify; use Payment\Notify\CmbNotify;
use Payment\Notify\MiNotify;
use Payment\Notify\NotifyStrategy; use Payment\Notify\NotifyStrategy;
use Payment\Notify\PayNotifyInterface; use Payment\Notify\PayNotifyInterface;
use Payment\Notify\TLNotify; use Payment\Notify\TLNotify;
...@@ -51,6 +50,9 @@ class NotifyContext ...@@ -51,6 +50,9 @@ class NotifyContext
case Config::TL_CHARGE: case Config::TL_CHARGE:
$this->notify = new TLNotify($config); $this->notify = new TLNotify($config);
break; break;
case Config::MI_CHARGE:
$this->notify = new MiNotify($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE 常量'); throw new PayException('当前仅支持:ALI_CHARGE WX_CHARGE CMB_CHARGE 常量');
} }
...@@ -78,7 +80,7 @@ class NotifyContext ...@@ -78,7 +80,7 @@ class NotifyContext
*/ */
public function notify(PayNotifyInterface $notify) public function notify(PayNotifyInterface $notify)
{ {
if (! $this->notify instanceof NotifyStrategy) { if (!$this->notify instanceof NotifyStrategy) {
throw new PayException('请检查初始化是否正确'); throw new PayException('请检查初始化是否正确');
} }
......
<?php
/**
* Created by IntelliJ IDEA.
* User: yeran
* Date: 2018/4/23
* Time: 下午7:07
*/
namespace Payment\Query\MiPay;
use Payment\Common\BaseData;
use Payment\Common\MiConfig;
use Payment\Common\MiPay\Data\Query\MiQueryData;
use Payment\Common\MiPay\MiBaseStrategy;
class MiQuery extends MiBaseStrategy {
/**
* 获取支付对应的数据完成类
* @return BaseData
* @author yeran
*/
public function getBuildDataClass()
{
// TODO: Implement getBuildDataClass() method.
return MiQueryData::class;
}
/**
* 返回查询的url
* @return string
* @author helei
*/
protected function getReqUrl()
{
return MiConfig::CHARGE_QUERY_URL;
}
public function retData(array $ret)
{
//cusid 商户号 平台分配的商户号 否 15
//appid 应用ID 平台分配的APPID 否 8
//trxid 交易单号 平台的交易流水号 否 20
//chnltrxid 支付渠道交易单号 如支付宝,微信平台的交易单号 是 50
//reqsn 商户订单号 商户的交易订单号 否 32
//trxcode 交易类型 交易类型 否 8 见3.2
//trxamt 交易金额 单位为分 否 16
//trxstatus 交易状态 交易的状态 是 4 如果trxstatus为空,则交易正在处理中,尚未完成
//acct 支付平台用户标识 "JS支付时使用 微信支付-用户的微信openid 支付宝支付-用户user_id " 是 32 如果为空,则默认填000000
//fintime 交易完成时间 yyyyMMddHHmmss 是 14
//randomstr 随机字符串 随机生成的字符串 否 32
//errmsg 错误原因 失败的原因说明 是 100
//sign 签名 否 32 详见1.5
return $ret;
}
}
\ No newline at end of file
...@@ -11,7 +11,7 @@ namespace Payment\Query\TLpay; ...@@ -11,7 +11,7 @@ namespace Payment\Query\TLpay;
use Payment\Common\BaseData; use Payment\Common\BaseData;
use Payment\Common\TLConfig; use Payment\Common\TLConfig;
use Payment\Common\TLpay\Data\Query\TLQueryData; use Payment\Common\TLpay\Data\Query\MiQueryData;
use Payment\Common\TLpay\TLBaseStrategy; use Payment\Common\TLpay\TLBaseStrategy;
...@@ -25,7 +25,7 @@ class TLQuery extends TLBaseStrategy { ...@@ -25,7 +25,7 @@ class TLQuery extends TLBaseStrategy {
public function getBuildDataClass() public function getBuildDataClass()
{ {
// TODO: Implement getBuildDataClass() method. // TODO: Implement getBuildDataClass() method.
return TLQueryData::class; return MiQueryData::class;
} }
/** /**
......
<?php <?php
/** /**
* @author: helei * @author: yeran
* @createTime: 2016-07-28 17:24 * @createTime: 2018-10-30 11:30
* @description: * @description: 查询实例化
*/ */
namespace Payment; namespace Payment;
...@@ -14,6 +14,7 @@ use Payment\Query\Ali\AliRefundQuery; ...@@ -14,6 +14,7 @@ use Payment\Query\Ali\AliRefundQuery;
use Payment\Query\Ali\AliTransferQuery; use Payment\Query\Ali\AliTransferQuery;
use Payment\Query\Cmb\CmbChargeQuery; use Payment\Query\Cmb\CmbChargeQuery;
use Payment\Query\Cmb\CmbRefundQuery; use Payment\Query\Cmb\CmbRefundQuery;
use Payment\Query\MiPay\MiQuery;
use Payment\Query\TLpay\TLQuery; use Payment\Query\TLpay\TLQuery;
use Payment\Query\Wx\WxChargeQuery; use Payment\Query\Wx\WxChargeQuery;
use Payment\Query\Wx\WxRefundQuery; use Payment\Query\Wx\WxRefundQuery;
...@@ -70,6 +71,9 @@ class QueryContext ...@@ -70,6 +71,9 @@ class QueryContext
case Config::TL_QUERY:// 通联退款查询 case Config::TL_QUERY:// 通联退款查询
$this->query = new TLQuery($config); $this->query = new TLQuery($config);
break; break;
case Config::MI_QUERY:// 通联退款查询
$this->query = new MiQuery($config);
break;
default: default:
throw new PayException('当前仅支持:ALI_CHARGE ALI_REFUND WX_CHARGE WX_REFUND WX_TRANSFER CMB_CHARGE CMB_REFUND TLPAY'); throw new PayException('当前仅支持:ALI_CHARGE ALI_REFUND WX_CHARGE WX_REFUND WX_TRANSFER CMB_CHARGE CMB_REFUND TLPAY');
} }
......
<?php
/**
* @author: yeran
* @createTime: 2018-04-22 19:01
* @description:
*/
namespace Payment\Refund;
use Payment\Common\MiConfig;
use Payment\Common\MiPay\Data\Cancel\RefundData;
use Payment\Common\MiPay\MiBaseStrategy;
/**
* Class MiRefund
* 微信退款操作
* @package Payment\Refund
* @author yeran
*/
class MiRefund extends MiBaseStrategy
{
public function getBuildDataClass()
{
return RefundData::class;
}
/**
* 返回退款的url
* @return null|string
* @author helei
*/
protected function getReqUrl()
{
return MiConfig::GATEWAY_URL;
}
protected function retData(array $ret)
{
//返回数组结构
return $ret;
}
}
<?php <?php
/** /**
* @author: helei * @author: yeran
* @createTime: 2016-07-27 17:42 * @createTime: 2018-10-30 11:35
* @description: 退款统一接口 * @description: 退款统一接口
* @link https://github.com/helei112g/payment/tree/paymentv2
* @link https://helei112g.github.io/
*/ */
namespace Payment; namespace Payment;
...@@ -13,6 +11,7 @@ use Payment\Common\BaseStrategy; ...@@ -13,6 +11,7 @@ use Payment\Common\BaseStrategy;
use Payment\Common\PayException; use Payment\Common\PayException;
use Payment\Refund\AliRefund; use Payment\Refund\AliRefund;
use Payment\Refund\CmbRefund; use Payment\Refund\CmbRefund;
use Payment\Refund\MiRefund;
use Payment\Refund\TLRefund; use Payment\Refund\TLRefund;
use Payment\Refund\WxRefund; use Payment\Refund\WxRefund;
...@@ -50,6 +49,9 @@ class RefundContext ...@@ -50,6 +49,9 @@ class RefundContext
case Config::TL_REFUND: case Config::TL_REFUND:
$this->refund = new TLRefund($config); $this->refund = new TLRefund($config);
break; break;
case Config::MI_REFUND:
$this->refund = new MiRefund($config);
break;
default: default:
throw new PayException('当前仅支持:ALI WEIXIN CMB'); throw new PayException('当前仅支持:ALI WEIXIN CMB');
} }
......
...@@ -24,7 +24,7 @@ class ArrayUtil ...@@ -24,7 +24,7 @@ class ArrayUtil
if ($val === '' || $val === null) { if ($val === '' || $val === null) {
continue; continue;
} else { } else {
if (! is_array($para[$key])) { if (!is_array($para[$key])) {
$para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]); $para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]);
} }
...@@ -43,11 +43,11 @@ class ArrayUtil ...@@ -43,11 +43,11 @@ class ArrayUtil
*/ */
public static function removeKeys(array $inputs, $keys) public static function removeKeys(array $inputs, $keys)
{ {
if (! is_array($keys)) {// 如果不是数组,需要进行转换 if (!is_array($keys)) {// 如果不是数组,需要进行转换
$keys = explode(',', $keys); $keys = explode(',', $keys);
} }
if (empty($keys) || ! is_array($keys)) { if (empty($keys) || !is_array($keys)) {
return $inputs; return $inputs;
} }
...@@ -61,7 +61,7 @@ class ArrayUtil ...@@ -61,7 +61,7 @@ class ArrayUtil
} }
} }
if (! $flag) { if (!$flag) {
$inputs = array_values($inputs); $inputs = array_values($inputs);
} }
return $inputs; return $inputs;
...@@ -89,7 +89,7 @@ class ArrayUtil ...@@ -89,7 +89,7 @@ class ArrayUtil
*/ */
public static function createLinkstring($para) public static function createLinkstring($para)
{ {
if (! is_array($para)) { if (!is_array($para)) {
throw new \Exception('必须传入数组参数'); throw new \Exception('必须传入数组参数');
} }
...@@ -100,7 +100,7 @@ class ArrayUtil ...@@ -100,7 +100,7 @@ class ArrayUtil
continue; continue;
} }
$arg.=$key.'='.urldecode($val).'&'; $arg .= $key . '=' . urldecode($val) . '&';
} }
//去掉最后一个&字符 //去掉最后一个&字符
$arg && $arg = substr($arg, 0, -1); $arg && $arg = substr($arg, 0, -1);
...@@ -117,7 +117,8 @@ class ArrayUtil ...@@ -117,7 +117,8 @@ class ArrayUtil
/** /**
* 将参数数组签名 * 将参数数组签名
*/ */
public static function SignArray(array $array,$appkey){ public static function SignArray(array $array, $appkey)
{
$array['key'] = $appkey;// 将key放到数组中一起进行排序和组装 $array['key'] = $appkey;// 将key放到数组中一起进行排序和组装
ksort($array); ksort($array);
$blankStr = self::ToUrlParams($array); $blankStr = self::ToUrlParams($array);
...@@ -128,9 +129,8 @@ class ArrayUtil ...@@ -128,9 +129,8 @@ class ArrayUtil
public static function ToUrlParams(array $array) public static function ToUrlParams(array $array)
{ {
$buff = ""; $buff = "";
foreach ($array as $k => $v) foreach ($array as $k => $v) {
{ if ($v != "" && !is_array($v)) {
if($v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&"; $buff .= $k . "=" . $v . "&";
} }
} }
...@@ -141,15 +141,85 @@ class ArrayUtil ...@@ -141,15 +141,85 @@ class ArrayUtil
/** /**
* 校验签名 * 校验签名
* @param array|参数 $array * @param array
* @param array 参数 * @param $appkey
* @return bool * @return bool
*/ */
public static function ValidSign(array $array,$appkey){ public static function ValidSign(array $array, $appkey)
{
$sign = $array['sign']; $sign = $array['sign'];
unset($array['sign']); unset($array['sign']);
$array['key'] = $appkey; $array['key'] = $appkey;
$mySign = self::SignArray($array, $appkey); $mySign = self::SignArray($array, $appkey);
return strtolower($sign) == strtolower($mySign); return strtolower($sign) == strtolower($mySign);
} }
public static function SignRSA($param, $keyPath)
{
ksort($param);
$str = '';
foreach ($param as $key => $value) {
if (!empty($str)) {
$str .= '&' . $key . '=' . $value;
} else {
$str .= $key . '=' . $value;
}
}
$private_key = file_get_contents($keyPath);
if (empty($private_key)) {
echo "Private Key error!";
exit;
}
$pkeyid = openssl_get_privatekey($private_key);
if (empty($pkeyid)) {
echo "private key resource identifier False!";
exit;
}
$str = urlencode($str);
$verify = openssl_sign($str, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
openssl_free_key($pkeyid);
return base64_encode($signature);
}
/**
* 米付签名校验
*
* @param $param
* @param $keyPath
* @return bool|int
*/
public static function SignVerify($param, $keyPath)
{
$signature = base64_decode($param['sign']);
unset($param['sign']);
ksort($param);
$str = '';
foreach ($param as $key => $value) {
if (!empty($str)) {
$str .= '&' . $key . '=' . $value;
} else {
$str .= $key . '=' . $value;
}
}
$public_key = file_get_contents($keyPath);
if (empty($public_key)) {
echo "public Key error!";
exit;
}
$pkeyid = openssl_get_publickey($public_key);
if (empty($pkeyid)) {
echo "public key resource identifier False!";
exit;
}
$str = urlencode($str);
$verify = openssl_verify($str, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
return $verify;
}
} }
...@@ -16,6 +16,7 @@ class Curl ...@@ -16,6 +16,7 @@ class Curl
private $option; private $option;
private $default; private $default;
private $download; private $download;
private $isJsonStr=false;
private static $instance; private static $instance;
public function __construct() public function __construct()
...@@ -121,7 +122,7 @@ class Curl ...@@ -121,7 +122,7 @@ class Curl
* @param string $url * @param string $url
* @return array * @return array
*/ */
public function submit($url) public function submit($url,$isJsonStr= false)
{ {
if (! $this->post) { if (! $this->post) {
return array( return array(
...@@ -129,6 +130,7 @@ class Curl ...@@ -129,6 +130,7 @@ class Curl
'message' => '未设置POST信息' 'message' => '未设置POST信息'
); );
} }
$this->isJsonStr = $isJsonStr;
return $this->set('CURLOPT_URL', $url)->exec(); return $this->set('CURLOPT_URL', $url)->exec();
} }
...@@ -216,9 +218,14 @@ class Curl ...@@ -216,9 +218,14 @@ class Curl
// POST选项 // POST选项
if ($this->post) { if ($this->post) {
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POST, true);
if($this->isJsonStr){
curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($this->postFieldsBuild($this->post)));
}else{
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postFieldsBuild($this->post)); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postFieldsBuild($this->post));
} }
}
// 运行句柄 // 运行句柄
$body = curl_exec($ch); $body = curl_exec($ch);
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!