getLocaleUrl(true);
}
/**
* 获取门店付款方式列表
* @route({"POST","/querylist"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"paytype","$._POST.paytype"}) 支付类型
* @param({"level","$._POST.level"}) 类型(1: 线上支付; 2: 线下扫码支付; 3: 移动app支付)
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject|mixed
*/
public function getPayList($appid = '', $devkey = '', $market_key = '', $paytype = 0, $level = 0, $version = null, $sign = null)
{
/// 验证公共参数是否合法
$this->init($appid, $devkey);
$verify_result = $this->verify_admin($market_key);
if (is_error_api($verify_result))
{
if ($verify_result instanceof returnObject)
return $verify_result;
$return = new returnObject();
$return->from_array((array)$verify_result);
return $verify_result;
}
switch ($version)
{
case 1:
{
if (empty($market_key))
{
$condition = 'is_enabled = 1';
if (!empty($level))
$condition .= sprintf(' and type_level = %d', intval($level));
if (!empty($paytype))
$condition .= sprintf(' and type_id = %d', intval($paytype));
$data = Sql::Select('type_id, type_key, type_name, image, url, is_third, third_flag, type_level')
->from('syweb_paytype_base')
->where($condition)
->get($this->db);
return new returnObject(0, 0, '', $data);
}
else
{
$condition = 'a.type_key = b.type_key and a.is_enabled = 1 and b.is_enabled = 1 and b.market_key = ?';
if (!empty($level))
$condition .= sprintf(' and a.type_level = %d', intval($level));
if (!empty($paytype))
$condition .= sprintf(' and a.type_id = %d', intval($paytype));
$data = Sql::Select('a.type_id, a.type_key, a.type_name, a.image, a.url, a.is_third, a.third_flag, a.type_level')
->from('syweb_paytype_base a, syweb_paytype_market b')
->where($condition, $market_key)
->get($this->db);
return new returnObject(0, 0, '', $data);
}
break;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 聚合支付-线上
* @route({"POST","/pay/online"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"return_url","$._POST.return_url"}) 回调地址(同步)
*
* @param({"paytype","$._POST.paytype"}) 支付类型(1: 微信支付; 2: 支付宝支付; 3: 威富通聚合支付(微信); 4: 威富通聚合支付(支付宝))
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_online($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $paytype, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
/// 支付前校验
$attach = $this->verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign);
if ($attach instanceof returnObject)
return $attach;
switch ($paytype)
{
case PAYCODE_ONLINE_WECHAT: /// 微信支付
return $this->_pay_online_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_ALIPAY: /// 支付宝支付
return $this->_pay_online_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_SWIFTPASS_WECHAT: /// 威富通聚合支付-微信
return $this->_pay_online_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_SWIFTPASS_ALIPAY: /// 威富通聚合支付-支付
return $this->_pay_online_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_HEEPAY_WECHAT: /// 汇付宝微信支付(线上网页支付)
return $this->_pay_online_heepay_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_HEEPAY_ALIPAY: /// 汇付宝支付宝支付(线上网页支付)
return $this->_pay_online_heepay_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_WECHATWITHBROWSER: /// /// 微信支付(线上网页支付)(非微信环境)
return $this->_pay_online_wechat_with_browser_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_HEEPAY_WECHATWITHBROWSER: /// 汇付宝微信支付(线上网页支付)(非微信环境)
return $this->_pay_online_heepay_wechat_with_browser_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_HEEPAY_UNIONPAY: /// 汇付宝银联支付
return $this->_pay_online_heepay_unionpay_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_IPAY_PC: /// 爱呗支付(pc网页)
return $this->_pay_online_ipay_pc_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_IPAY_H5: /// 爱呗支付(h5网页)
return $this->_pay_online_ipay_h5_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
case PAYCODE_ONLINE_TDY: /// 躺倒鸭
return $this->_pay_online_tdy_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
default:
echo sprintf('未知的支付类型: %d' . PHP_EOL . '支付类型(%d: 微信支付; %d: 支付宝支付; %d: 威富通聚合支付(微信); %d: 威富通聚合支付(支付宝))',
$paytype, PAYCODE_ONLINE_WECHAT, PAYCODE_ONLINE_ALIPAY, PAYCODE_ONLINE_SWIFTPASS_WECHAT, PAYCODE_ONLINE_SWIFTPASS_ALIPAY);
return -1;
}
break;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 微信支付
* @route({"POST","/pay/online/wechat"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"return_url","$._POST.return_url"}) 回调地址(同步)
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_online_wechat($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
$attach = $this->verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign);
if ($attach instanceof returnObject)
return $attach;
return $this->_pay_online_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 支付宝支付
* @route({"POST","/pay/online/ali"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"return_url","$._POST.return_url"}) 回调地址(同步)
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_online_ali($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
$attach = $this->verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign);
if ($attach instanceof returnObject)
return $attach;
return $this->_pay_online_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 威富通聚合支付--微信
* @route({"POST","/pay/online/swiftpasswechat"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"return_url","$._POST.return_url"}) 回调地址(同步)
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_online_swiftpass_wechat($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
$attach = $this->verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign);
if ($attach instanceof returnObject)
return $attach;
return $this->_pay_online_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 威富通聚合支付--支付宝
* @route({"POST","/pay/online/swiftpassali"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"return_url","$._POST.return_url"}) 回调地址(同步)
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_online_swiftpass_ali($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
$attach = $this->verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign);
if ($attach instanceof returnObject)
return $attach;
return $this->_pay_online_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach);
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 聚合支付-线下
* @route({"POST","/pay/offline"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"paytype","$._POST.paytype"}) 支付类型(1: 微信支付; 2: 支付宝支付; 3: 威富通聚合支付(微信); 4: 威富通聚合支付(支付宝))
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_offline($appid, $devkey, $market_key, $orderid, $fee, $title, $notice_url, $paytype, $version = null, $sign = null)
{
switch ($version)
{
case 1:
{
/// 支付前校验
$attach = $this->verify_pay_offline_v1($appid, $devkey, $market_key, $orderid, $fee, $title, $notice_url, $sign);
if ($attach instanceof returnObject)
{
return $attach;
}
switch ($paytype)
{
case PAYCODE_OFFLINE_WECHAT: /// 微信支付
return $this->_pay_offline_wechat_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_OFFLINE_ALIPAY: /// 支付宝支付
return $this->_pay_offline_ali_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_OFFLINE_SWIFTPASS_WECHAT: /// 威富通聚合支付-微信
return $this->_pay_offline_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_OFFLINE_SWIFTPASS_ALIPAY: /// 威富通聚合支付-支付宝
return $this->_pay_offline_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_OFFLINE_HEEPAY_WECHAT: /// 汇付宝微信支付(线下扫码支付)
return $this->_pay_offline_heepay_wechat_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_OFFLINE_HEEPAY_ALIPAY: /// 汇付宝支付宝支付(线下扫码支付)
return $this->_pay_offline_heepay_ali_v1($orderid, $fee, $title, $notice_url, $attach);
default:
echo sprintf('未知的支付类型: %d' . PHP_EOL . '支付类型(%d: 微信支付; %d: 支付宝支付; %d: 威富通聚合支付(微信); %d: 威富通聚合支付(支付宝)); %d: 汇付宝聚合支付(微信); %d: 汇付宝聚合支付(支付宝));',
$paytype, PAYCODE_OFFLINE_WECHAT, PAYCODE_OFFLINE_ALIPAY, PAYCODE_OFFLINE_SWIFTPASS_WECHAT, PAYCODE_OFFLINE_SWIFTPASS_ALIPAY, PAYCODE_OFFLINE_HEEPAY_WECHAT, PAYCODE_OFFLINE_HEEPAY_ALIPAY);
return -1;
}
}
default:
{
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
}
/**
* 聚合支付-移动端
* @route({"POST","/pay/mobile"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"from_user","$._POST.from_user"}) 要支付的用户标志(openid或userid)
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 支付总价
* @param({"title","$._POST.title"}) 支付主题
*
* @param({"notice_url","$._POST.notice_url"}) 回调地址(异步)
* @param({"paytype","$._POST.paytype"}) 支付类型(1: 微信支付; 2: 支付宝支付; 3: 威富通聚合支付(微信); 4: 威富通聚合支付(支付宝))
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function pay_mobile($appid, $devkey, $sid, $scode, $market_key, $from_user, $orderid, $fee, $title, $notice_url, $paytype, $version, $sign)
{
switch ($version)
{
case 1:
{
/// 支付前校验
$attach = $this->verify_pay_mobile_v1($appid, $devkey, $market_key, $from_user, $orderid, $fee, $title, $notice_url, $sign);
if ($attach instanceof returnObject)
return $attach;
switch ($paytype)
{
case PAYCODE_MOBILE_WECHAT: /// 微信支付
return $this->_pay_mobile_wechat_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_MOBILE_ALIPAY: /// 支付宝支付
return $this->_pay_mobile_ali_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_MOBILE_SWIFTPASS_WECHAT: /// 威富通聚合支付-微信
return $this->_pay_mobile_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach);
case PAYCODE_MOBILE_SWIFTPASS_ALIPAY: /// 威富通聚合支付-支付宝
return $this->_pay_mobile_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach);
default:
echo sprintf('未知的支付类型: %d' . PHP_EOL . '支付类型(%d: 微信支付; %d: 支付宝支付; %d: 威富通聚合支付(微信); %d: 威富通聚合支付(支付宝))',
$paytype, PAYCODE_MOBILE_WECHAT, PAYCODE_MOBILE_ALIPAY, PAYCODE_MOBILE_SWIFTPASS_WECHAT, PAYCODE_MOBILE_SWIFTPASS_ALIPAY);
return -1;
}
}
default:
{
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
}
/**
* 退款(错误码:13000-13050)
* @route({"POST","/refund"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"transaction_id","$._POST.transaction_id"}) 微信订单号
* @param({"out_trade_no","$._POST.out_trade_no"}) 商户单号
* @param({"refund_fee","$._POST.refund_fee"}) 退款金额(单位分)
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function refund($appid, $devkey, $sid, $scode, $transaction_id, $out_trade_no, $refund_fee, $version, $sign)
{
switch ($version)
{
case 1:
{
/// 腿款前校验
$attach = $this->verify_refund_v1($appid, $devkey, $sid, $scode, $transaction_id, $out_trade_no, $refund_fee, $sign);
if ($attach instanceof returnObject)
return $attach;
if (!empty($out_trade_no) && !empty($transaction_id))
{
$pay_log = Sql::Select('*')
->from('syweb_core_paylog a')
->where('out_trade_no = ? and transaction_id = ? and app_key = ? and market_key = ?', $out_trade_no, $transaction_id, $this->appid, $this->market_key)
->get($this->db, null);
}
elseif (!empty($out_trade_no))
{
$pay_log = Sql::Select('*')
->from('syweb_core_paylog a')
->where('out_trade_no = ? and app_key = ? and market_key = ?', $out_trade_no, $this->appid, $this->market_key)
->get($this->db, null);
}
elseif (!empty($transaction_id))
{
$pay_log = Sql::Select('*')
->from('syweb_core_paylog a')
->where('transaction_id = ? and app_key = ? and market_key = ?', $transaction_id, $this->appid, $this->market_key)
->get($this->db, null);
}
else
$pay_log = null;
if (!empty($pay_log) && count($pay_log) > 0)
{
$pay_log = $pay_log[0];
switch ($pay_log['status'])
{
case PAYSTATUS_NORMAL:
return new returnObject(500, 1, '该订单尚未付款, 申请退款失败!');
case PAYSTATUS_REFUND:
case PAYSTATUS_PAY:
$total_fee = intval($pay_log['pay_fee']) - intval($pay_log['refund_fee']);
if ($refund_fee > $total_fee)
return new returnObject(500, 2, '超过订单最大可退金额!');
break;
default:
return new returnObject(500, 3, sprintf('未知的订单状态 %d, 申请退款失败!', $pay_log['status']));
}
}
else
return new returnObject(500, 4, '找不到对应的支付记录,请核实后再试!');
switch ($pay_log['type'])
{
case PAYTYPE_ONLINE_WECHAT: /// 微信在线支付
return $this->_refund_online_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_ALIPAY: /// 支付宝在线支付
return $this->_refund_online_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_SWIFTPASS_WECHAT: /// 威富通微信在线支付
return $this->_refund_online_swiftpass_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_SWIFTPASS_ALIPAY: /// 威富通支付宝在线支付
return $this->_refund_online_swiftpass_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_HEEPAY_WECHAT: /// 汇付宝微信支付(线上网页支付)
return $this->_refund_online_heepay_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_HEEPAY_ALIPAY: /// 汇付宝支付宝支付(线上网页支付)
return $this->_refund_online_heepay_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_WECHATWITHBROWSER: /// 微信支付(线上网页支付)(非微信环境)
return $this->_refund_online_wechat_with_browser_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_HEEPAY_WECHATWITHBROWSER: /// 汇付宝微信支付(线上网页支付)(非微信环境)
return $this->_refund_online_heepay_wechat_with_browser_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_ONLINE_HEEPAY_UNIONPAY: /// 汇付宝银联支付
return $this->_refund_online_heepay_unionpay_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_WECHAT: /// 微信扫码支付
return $this->_refund_offline_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_ALIPAY: /// 支付宝扫码支付
return $this->_refund_offline_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_SWIFTPASS_WECHAT: /// 威富通微信扫码支付
return $this->_refund_offline_swiftpass_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_SWIFTPASS_ALIPAY: /// 威富通支付宝扫码支付
return $this->_refund_offline_swiftpass_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_HEEPAY_WECHAT: /// 汇付宝微信支付(线下扫码支付)
return $this->_refund_offline_heepay_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_OFFLINE_HEEPAY_ALIPAY: /// 汇付宝支付宝支付(线下扫码支付)
return $this->_refund_offline_heepay_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_MOBILE_WECHAT: /// 微信支付(移动平台支付)
return $this->_refund_mobile_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_MOBILE_ALIPAY: /// 支付宝支付(移动平台支付)
return $this->_refund_mobile_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_MOBILE_SWIFTPASS_WECHAT: /// 威富通微信支付(移动平台支付)
return $this->_refund_mobile_swiftpass_wechat_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
case PAYTYPE_MOBILE_SWIFTPASS_ALIPAY: /// 威富通支付宝支付(移动平台支付)
return $this->_refund_mobile_swiftpass_ali_v1($pay_log['transaction_id'], $pay_log['out_trade_no'], $pay_log['order_id'], $pay_log['pay_fee'], $refund_fee, $attach);
default:
return new returnObject(500, -1, '不正确的支付信息, 请联系管理员!!');
}
}
default:
{
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
}
/**
* 检测支付是否成功(错误代码:12000-12050)
* @route({"POST","/querystatus"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"transaction_id","$._POST.transaction_id"}) 微信订单号
* @param({"out_trade_no","$._POST.out_trade_no"}) 商户单号
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject|mixed
*/
public function query_pay_status($appid, $devkey, $sid, $scode, $transaction_id, $out_trade_no, $version, $sign)
{
switch ($version)
{
case 1:
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, $sid, $scode);
$verify_result = parent::verify();
if (is_error_api($verify_result))
return json_encode($verify_result, JSON_UNESCAPED_UNICODE);
if (empty($orderid))
return new returnObject(1, 12001, '请指定订单编号');
/// 根据order_id查询指定支付纪录的状态
if (!empty($out_trade_no) && !empty($transaction_id))
{
$payLog = Sql::Select('*')
->from('syweb_core_paylog a')
->where('out_trade_no = ? and transaction_id = ? and app_key = ? and market_key = ?', $out_trade_no, $transaction_id, $this->appInfo['id'], $this->market_key)
->get($this->db, null);
}
elseif (!empty($out_trade_no))
{
$payLog = Sql::Select('*')
->from('syweb_core_paylog a')
->where('out_trade_no = ? and app_key = ? and market_key = ?', $out_trade_no, $this->appInfo['id'], $this->market_key)
->get($this->db, null);
}
elseif (!empty($transaction_id))
{
$payLog = Sql::Select('*')
->from('syweb_core_paylog a')
->where('transaction_id = ? and app_key = ? and market_key = ?', $transaction_id, $this->appInfo['id'], $this->market_key)
->get($this->db, null);
}
else
{
$payLog = null;
}
if (!empty($payLog) && count($payLog) > 0)
$payLog['tag'] = json_decode($payLog['tag']);
return new returnObject(0, 0, '', $payLog);
}
default:
{
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
}
/**
* @note 通知微信订单状态.
* @param string $app_id appid
* @param string $market_key 门店id
* @param string $out_trade_no 订单号
* @param string $transaction_id 微信订单号
* @param string $from_user 来源用户(用户openid)
* @param int $pay_fee 支付金额
* @param int $refund_fee 退款金额(单位分)
* @param string $sign_key 签名key
* @param int $status 通知订单状态(0: 正常; 1: 已付款; -1: 已退款)
* @return bool
*/
private function _notify_wechat_order_status_v1($app_id, $market_key, $out_trade_no, $transaction_id, $from_user, $pay_fee, $refund_fee, $status, $sign_key)
{
switch ($status)
{
case PAYSTATUS_NORMAL: /// 普通状态
break;
case PAYSTATUS_PAY: /// 已支付
{
$log = Sql::select('syweb_core_paylog.*')
->from('syweb_core_paylog')
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->get($this->db, null);
if (!empty($log) && count($log) > 0)
{
$log = $log[0];
}
if (!empty($log) && !empty($log['plid']) && is_numeric($log['status']) && $log['status'] != '0')
{
///exit('订单已经付款');
return true;
}
$log['tag'] = json_decode($log['tag']);
$log['tag']->transaction_id = $transaction_id;
$log['tag']->total_fee = $pay_fee;
/// 提前设置为已经支付成功状态
$recordTemp = [
'status' => PAYSTATUS_PAY,
'transaction_id' => $transaction_id,
///'openid' => $open_id,
'tag' => json_encode($log['tag'], JSON_UNESCAPED_UNICODE),
];
try
{
$db = $this->db;
$db->beginTransaction();
Sql::update('syweb_core_paylog')->setArgs($recordTemp)->where('plid = ?', $log['plid'])->exec($db);
$db->commit();
}
catch (PDOException $e)
{
var_dump($e);
}
$notice_url = $log['tag']->notice_url; /// 回调地址
//$param_mask = $log['tag']->param_mask; /// 回调参数格式
/// 验证客户端逻辑处理
if (!empty($notice_url))
{
// if (!empty($param_mask))
// {
// $callback_data = str_replace("%orderNo%", $log['order_id'], $param_mask);
// $callback_data = str_replace("%money%", $log["fee"], $callback_data);
//
// $callback_data = str_replace("%outtradeNo%", $log['out_trade_no'], $callback_data);
// $callback_data = str_replace("%transactionid%", $log['tag']->transaction_id, $callback_data);
// $callback_data = str_replace("%signkey%", $sign_key, $callback_data);
//
// $callback_response = ihttp_request($notice_url . "?" . $callback_data, "", false);
// $callback_response = mb_convert_encoding($callback_response, "UTF-8");
//
// $begin_position = strstr($callback_response, "\r\n");
// if ($begin_position >= 0)
// {
// $callback_response = substr($callback_response, $begin_position + 17);
// }
// else
// {
// $callback_response = "";
// }
//
// if (!empty($callback_response) && !is_null(json_decode($callback_response)))
// {
// $callback_result = @json_decode($callback_response, true);
// if ($callback_result['error'] != '0')
// {
// /// 假如客户端返回非0,则表示逻辑处理失败,则将再次发起
// //$msg = "订单处理出错。";
// return false;
// }
// }
// else
// {
// /// 假如客户端返回非0,则表示支付失败
// //$msg = "订单处理出错。";
// return false;
// }
// }
// else
{
/// 获取附带的参数
$attach = $log['tag']->attach;
if (is_string($attach))
$attach = json_decode($attach);
$callback_data = (array)$attach;
$callback_data['order_no'] = $log['order_id']; /// 订单号
$callback_data['out_trade_no'] = $log['out_trade_no']; /// 商家订单号
$callback_data['transaction_id'] = $transaction_id; /// 微信订单号
$callback_data['total_fee'] = $log['tag']->total_fee; /// 支付金额(单位分)
$callback_data['version'] = 1; /// 版本号
$callback_data['sign'] = SignParameter($callback_data, $sign_key); /// 生成签名
//$callback_data = json_encode($callback_data, JSON_UNESCAPED_UNICODE);
//$callback_response = ihttp_request($notice_url, $callback_data, false);
try
{
/// 发送post请求
$callback_response = @SendPost($notice_url, $callback_data);
/// 返回success表示成功, 否则表示失败.
return strcasecmp(NOTIFYSTATUS_SUCCESS, $callback_response) == 0;
}
catch (Exception $e)
{
return false;
}
}
}
}
break;
case PAYSTATUS_REFUND: /// 已退款
{
try
{
$db = $this->db;
if (!empty($transaction_id))
{
$pay_log = Sql::Select('*')
->from('syweb_core_paylog')
->where('`app_key` = ? and `market_key` = ? and `transaction_id` = ?', $app_id, $market_key, $transaction_id)
->get($db);
$refund_fee += intval((empty($pay_log) || count($pay_log) == 0) ? 0 : $pay_log[0]['refund_fee']);
$recordTemp = [
'status' => PAYSTATUS_REFUND,
'refund_fee' => $refund_fee,
];
$db->beginTransaction();
Sql::update('syweb_core_paylog')
->setArgs($recordTemp)
->where('`app_key` = ? and `market_key` = ? and `transaction_id` = ?', $app_id, $market_key, $transaction_id)
->exec($db);
$db->commit();
}
elseif (!empty($out_trade_no))
{
$pay_log = Sql::Select('*')
->from('syweb_core_paylog')
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->get($db);
$refund_fee += intval((empty($pay_log) || count($pay_log) == 0) ? 0 : $pay_log[0]['refund_fee']);
$recordTemp = [
'status' => PAYSTATUS_REFUND,
'refund_fee' => $refund_fee,
];
$db->beginTransaction();
Sql::update('syweb_core_paylog')
->setArgs($recordTemp)
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->exec($db);
$db->commit();
return true;
}
else
return false;
}
catch (PDOException $e)
{
//var_dump($e);
return false;
}
}
break;
}
return true;
}
/**
* @note 通知支付宝订单状态.
* @param string $app_id appid
* @param string $market_key 门店id
* @param string $out_trade_no 订单号
* @param string $trade_no 支付宝交易订单号
* @param string $from_user 来源用户(用户openid)
* @param int $pay_fee 支付金额
* @param int $refund_fee 退款金额(单位分)
* @param string $sign_key 签名key
* @param int $status 通知订单状态(0: 正常; 1: 已付款; -1: 已退款)
* @return bool
*/
private function _notify_alipay_order_status_v1($app_id = '', $market_key = '', $out_trade_no = '', $trade_no = '', $from_user = '', $pay_fee = 0, $refund_fee = 0, $status = PAYSTATUS_REFUND, $sign_key = '')
{
switch ($status)
{
case PAYSTATUS_NORMAL: /// 普通状态
break;
case PAYSTATUS_PAY: /// 已支付
{
$log = Sql::select('syweb_core_paylog.*')
->from('syweb_core_paylog')
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->get($this->db, null);
if (!empty($log) && count($log) > 0)
$log = $log[0];
if (!empty($log) && !empty($log['plid']) && is_numeric($log['status']) && $log['status'] != '0')
return true;
$log['tag'] = json_decode($log['tag']);
$log['tag']->transaction_id = $trade_no;
$log['tag']->total_fee = $pay_fee;
/// 提前设置为已经支付成功状态
$recordTemp = [
'status' => PAYSTATUS_PAY,
'transaction_id' => $trade_no,
///'openid' => $open_id,
'tag' => json_encode($log['tag'], JSON_UNESCAPED_UNICODE),
'pay_time' => time(),
];
try
{
$db = $this->db;
$db->beginTransaction();
Sql::update('syweb_core_paylog')->setArgs($recordTemp)->where('plid = ?', $log['plid'])->exec($db);
$db->commit();
}
catch (PDOException $e)
{
var_dump($e);
}
$notice_url = $log['tag']->notice_url; /// 回调地址
//$param_mask = $log['tag']->param_mask; /// 回调参数格式
/// 验证客户端逻辑处理
if (!empty($notice_url))
{
/// 获取附带的参数
$attach = $log['tag']->attach;
if (is_string($attach))
$attach = json_decode($attach);
$callback_data = (array)$attach;
$callback_data['order_no'] = $log['order_id']; /// 订单号(用户)
$callback_data['out_trade_no'] = $log['out_trade_no']; /// 商户订单号(平台)
$callback_data['transaction_id'] = $trade_no; /// 支付宝交易订单号
$callback_data['total_fee'] = $log['tag']->total_fee; /// 支付金额(单位分)
$callback_data['version'] = 1; /// 版本号
$callback_data['sign'] = SignParameter($callback_data, $sign_key); /// 生成签名
//$callback_data = json_encode($callback_data, JSON_UNESCAPED_UNICODE);
//$callback_response = ihttp_request($notice_url, $callback_data, false);
try
{
/// 发送post请求
$callback_response = @SendPost($notice_url, $callback_data);
/// 返回success表示成功, 否则表示失败.
return strcasecmp(NOTIFYSTATUS_SUCCESS, $callback_response) == 0;
}
catch (Exception $e)
{
return false;
}
}
break;
}
case PAYSTATUS_REFUND: /// 已退款
{
try
{
$db = $this->db;
$pay_log = Sql::Select('*')
->from('syweb_core_paylog')
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->get($db);
$refund_fee += intval((empty($pay_log) || count($pay_log) == 0) ? 0 : $pay_log[0]['refund_fee']);
$recordTemp = [
'status' => PAYSTATUS_REFUND,
'refund_fee' => $refund_fee,
'refund_time' => time(),
];
$db->beginTransaction();
Sql::update('syweb_core_paylog')
->setArgs($recordTemp)
->where('`app_key` = ? and `market_key` = ? and `out_trade_no` = ?', $app_id, $market_key, $out_trade_no)
->exec($db);
$db->commit();
return true;
}
catch (PDOException $e)
{
var_dump($e);
return false;
}
break;
}
}
return true;
}
/**
* 支付完成回调到客户端(同步回调页面)
* @route({"GET","/callback/v1"})
* @param({"plid","$._GET.plid"}) 订单编号
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return null
*/
public function online_callback_v1($plid)
{
$log = Sql::select('a.*, b.signkey')
->from('syweb_core_paylog a')
->leftJoin('syweb_market b')
->on('a.market_key = b.market_key')
->where('a.plid = ?', $plid)
->get($this->db, null);
if (!empty($log))
{
$log = $log[0];
/// 判断支付订单号(内部)
$log['tag'] = json_decode($log['tag']);
$returnUrl = $log['tag']->return_url; /// 客户端回调地址
$attach = (array)json_decode($log['tag']->attach); /// 客户端传回的参数
$order_no = $log['order_id']; /// 订单号
$out_trade_no = $log['out_trade_no']; /// 商家订单号
$transaction_id = $log['transaction_id']; /// 微信订单号
//$total_fee = $log['tag']->total_fee; /// 支付金额(单位分)
/// tag中的支付金额为实际回调的支付金额,这里需要判断一下是因为有可能在执行同步回调的时候,异步回调还没有通知,所以这里需要做一个判断
$total_fee = empty($log['tag']->total_fee) ? $log['pay_fee'] : $log['tag']->total_fee; /// 支付金额(单位分)
$signkey = $log['signkey']; /// 签名key
/// 这里生成参数的签名
$param = $attach;
$param['order_no'] = $order_no; /// 订单号
$param['out_trade_no'] = $out_trade_no; /// 商家订单号
$param['transaction_id'] = $transaction_id; /// 微信订单号
$param['total_fee'] = $total_fee; /// 支付金额(单位分)
$sign = SignParameter($param, $signkey);
$param = '';
foreach ($attach as $k => $v)
{
$param .= "&{$k}={$v}";
}
if (!empty($returnUrl))
{
$p = strstr($returnUrl, '?');
if (empty($p))
$returnUrl .= "?order_no={$order_no}&out_trade_no={$out_trade_no}&transaction_id={$transaction_id}&total_fee={$total_fee}{$param}&sign={$sign}";
elseif ('?' == $p)
$returnUrl .= "order_no={$order_no}&out_trade_no={$out_trade_no}&transaction_id={$transaction_id}&total_fee={$total_fee}{$param}&sign={$sign}";
else
$returnUrl .= "&order_no={$order_no}&out_trade_no={$out_trade_no}&transaction_id={$transaction_id}&total_fee={$total_fee}{$param}&sign={$sign}";
header('location: ' . $returnUrl);
}
else
header('location: ' . $this->getLocaleUrl());
}
else
echo '无效的支付信息!';
}
/**
* 支付完成回调到客户端(同步回调页面)
* @route({"GET","/callback"})
* @param({"plid","$._GET.plid"}) 订单编号
* @param({"version","$._GET.version"}) 版本号
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return null
*/
public function online_callback($plid = 0, $version = 1)
{
switch ($version)
{
case 1:
$this->online_callback_v1($plid);
break;
default:
echo JsonObjectToJsonString('不正确的支付信息, 请联系管理员!!');
}
}
/**
* 微信支付 异步回调用页面
* @route({"POST","/notify/online/wechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_wechat_notify()
{
$content = file_get_contents('php://input');
$resultObj = new WxPayResults();
$resultObj->FromXml($content, 2);
if (!array_key_exists('attach', $resultObj->GetValues()))
return new returnObject(1, 10001, '回调参数缺少attach参数。');
$attach = json_decode($resultObj->GetValues()['attach']);
if (empty($attach))
return new returnObject(1, 10002, '回调参数attach不能为空。');
$app_id = $attach->app_id;
$market_key = $attach->market_key;
$version = $attach->version;
switch ($version)
{
case 1:
{
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10004, '找不到的商户信息。');
$wechatInfo["appid"] = $marketList[0]['weixin_appid'];
$wechatInfo["secret"] = $marketList[0]['weixin_secret_appid'];
$wechatInfo["mchid"] = $marketList[0]['weixin_mchid'];
$wechatInfo["signkey"] = $marketList[0]['weixin_paykey'];
$sign_key = $marketList[0]['signkey']; /// 签名key
$resultObj->CheckSign($wechatInfo);
$values = $resultObj->GetValues();
/// 订单号
$tradeno = $values['out_trade_no'];
/// 支付订单号(微信)
$out_transaction_id = $values['transaction_id'];
/// 支付金额(单位分)
$total_fee = $values['total_fee'];
/// 用户openid
$open_id = $values['openid'];
/// 此处可以在添加相关处理业务,校验通知参数中的商户订单号out_trade_no和金额total_fee是否和商户业务系统的单号和金额是否一致,一致后方可更新数据库表中的记录。
/// 更改订单状态
if ($this->_notify_wechat_order_status_v1($app_id, $market_key, $tradeno, $out_transaction_id, $open_id, $total_fee, 0, PAYSTATUS_PAY, $sign_key))
echo NOTIFYSTATUS_SUCCESS;
else
echo NOTIFYSTATUS_ERROR;
exit;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 支付宝支付 异步回调用页面
* @route({"POST","/notify/online/alipay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_alipay_notify()
{
//$content = (array)JsonStringToJsonObject(rawurldecode(file_get_contents('php://input')));
$content = $_POST;
if (!array_key_exists('passback_params', $content))
//return new returnObject(1, 10001, '回调参数缺少passback_params参数。');
die(NOTIFYSTATUS_FAIL);
if (is_string($content['passback_params']))
$attach = (array)json_decode($content['passback_params']);
else
$attach = (array)$content['passback_params'];
if (empty($attach))
//return new returnObject(1, 10002, '回调参数passback_params不能为空。');
die(NOTIFYSTATUS_FAIL);
$app_id = $attach['app_id'];
$market_key = $attach['market_key'];
$version = $attach['version'];
switch ($version)
{
case 1:
{
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0) {
//return new returnObject(1, 10004, '找不到的商户信息。');
die(NOTIFYSTATUS_FAIL);
}
$alipay_appid = $marketList[0]['alipay_appid']; /// 支付宝appid
$sign_key = $marketList[0]['signkey']; /// 签名key
//==============
$aop = new AopClient();
$aop->alipayPublicKey = dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem';
$result = $aop->rsaCheckV1($content, $aop->alipayPublicKey, 'RSA2');
if (!$result) {
//file_put_contents('d:/signerror.txt', JsonObjectToJsonString($content));
die(NOTIFYSTATUS_FAIL);
}
//==============
// 验证成功
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//$seller_id = isset($content['seller_id']) ? $content['seller_id'] : ''; /// seller_id卖家支付宝用户号
$out_trade_no = $content['out_trade_no']; /// 商户订单号
$trade_no = $content['trade_no']; /// 支付宝交易号
$trade_status = $content['trade_status']; /// 交易状态
$buyer_id = isset($content['buyer_id']) ? $content['buyer_id'] : ''; /// 买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字
//$buyer_logon_id = isset($content['buyer_logon_id']) ? $content['buyer_logon_id'] : ''; /// 买家支付宝账号
//$total_amount = intval(isset($content['total_amount']) ? floatval($content['total_amount']) * 100 : 0); /// 订单金额
$receipt_amount = intval(isset($content['receipt_amount']) ? floatval($content['receipt_amount']) * 100 : 0); /// 实收金额
//$invoice_amount = intval(isset($content['invoice_amount']) ? floatval($content['invoice_amount']) * 100 : 0); /// 开票金额
//$buyer_pay_amount = intval(isset($content['buyer_pay_amount']) ? floatval($content['buyer_pay_amount']) * 100 : 0); /// 用户在交易中支付的金额
//$point_amount = intval(isset($content['point_amount']) ? floatval($content['point_amount']) : 0); /// 使用集分宝支付的金额
//$refund_fee = intval(isset($content['refund_fee']) ? floatval($content['refund_fee']) : 0); /// 退款通知中,返回总退款金额,单位为元,支持两位小数
if ('TRADE_FINISHED' == $trade_status)
{
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 如果有做过处理,不执行商户的业务程序
// 注意:
// 退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
// 调试用,写文本函数记录程序运行情况是否正常
// logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
elseif ('TRADE_SUCCESS' == $trade_status)
{
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 如果有做过处理,不执行商户的业务程序
// 注意:
// 付款完成后,支付宝系统发送该交易状态通知
// 调试用,写文本函数记录程序运行情况是否正常
// logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
/// 更改订单状态
if ($this->_notify_alipay_order_status_v1($app_id, $market_key, $out_trade_no, $trade_no, $buyer_id, $receipt_amount, 0, PAYSTATUS_PAY, $sign_key))
die(NOTIFYSTATUS_SUCCESS);
else
die(NOTIFYSTATUS_FAIL);
}
default:
//return new returnObject(500, -1, "不支持的接口版本:{$version}!");
die(NOTIFYSTATUS_FAIL);
}
}
/**
* 威富通聚合支付-微信支付 异步回调用页面
* @route({"POST","/notify/online/swiftpasswechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_swiftpass_wechat_notify()
{
$xml = file_get_contents('php://input');
$resHandler = new ClientResponseHandler();
$resHandler->setContent($xml);
$attach = $resHandler->getParameter('attach');
/// {"app_id":"14936872341446","market_key":"0000"}
$attach = json_decode($attach);
if (!is_object($attach))
return new returnObject(1, 10002, '回调参数attach不能为空。');
$app_id = $attach->app_id;
$market_key = $attach->market_key;
$version = $attach->version;
switch($version)
{
case 1:
{
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10003, '找不到的商户信息。');
$mchid = $marketList[0]['swiftpass_mchid']; /// 商户号
$secret_key = $marketList[0]['swiftpass_paykey']; /// 签名key
$sign_key = $marketList[0]['signkey']; /// 签名key
$resHandler->setKey($secret_key);
if (!$resHandler->isTenpaySign()) /// 验签
return new returnObject(1, 10004, 'bad signature.');
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
{
/// 订单号
$tradeno = $resHandler->getParameter('out_trade_no');
/// 支付订单号(威富通平台)
$transaction_id = $resHandler->getParameter('transaction_id');
/// 支付订单号(微信)
$out_transaction_id = $resHandler->getParameter('out_transaction_id');
/// 支付金额(单位分)
$total_fee = $resHandler->getParameter('total_fee');
/// 用户openid
$open_id = $resHandler->getParameter('sub_openid');
/// 此处可以在添加相关处理业务,校验通知参数中的商户订单号out_trade_no和金额total_fee是否和商户业务系统的单号和金额是否一致,一致后方可更新数据库表中的记录。
/// 更改订单状态
if ($this->_notify_wechat_order_status_v1($app_id, $market_key, $tradeno, $out_transaction_id, $open_id, $total_fee, 0, PAYSTATUS_PAY, $sign_key))
echo NOTIFYSTATUS_SUCCESS;
else
echo NOTIFYSTATUS_ERROR;
exit;
}
elseif (0 != $resHandler->getParameter('status'))
return new returnObject(500, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
elseif (0 != $resHandler->getParameter('result_code'))
return new returnObject(500, $resHandler->getParameter('result_code'), $resHandler->getParameter('err_msg'), null);
else
return new returnObject(500, -1, $resHandler->getAllParameters());
break;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 汇付宝聚合支付-微信支付 异步回调用页面
* @route({"GET","/notify/online/heepaywechatpay"})
* @route({"POST","/notify/online/heepaywechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_heepay_wechat_notify()
{
$result = $_REQUEST['result']; /// 必填 支付结果,1=成功 其它为未知
$pay_message = $_REQUEST['pay_message']; /// 选填 支付结果信息,支付成功时为空
$agent_id = $_REQUEST['agent_id']; /// 必填 商户编号 如1234567
$jnet_bill_no = $_REQUEST['jnet_bill_no']; /// 必填 汇付宝交易号(订单号)
$agent_bill_id = $_REQUEST['agent_bill_id']; /// 必填 商户系统内部的订单号
$pay_type = $_REQUEST['pay_type']; /// 必填 支付类型
$pay_amt = $_REQUEST['pay_amt']; /// 必填 订单实际支付金额(注意:此金额是用户的实付金额)
$remark = $_REQUEST['remark']; /// 必填 商家数据包,原样返回
$return_sign = $_REQUEST['sign']; /// 必填 MD5签名结果
$remark = iconv("GB2312","UTF-8//IGNORE", urldecode($remark)); /// 签名验证中的中文采用UTF-8编码;
/*
$attach = json_decode($remark);
if (!is_object($attach))
return new returnObject(1, 10002, '回调参数attach不能为空。');
$id = $attach->id;
$version = $attach->ver;
*/
$record = Sql::select('a.plid, a.app_key, a.market_key, b.heepay_paykey, b.signkey, a.version')
->from('syweb_core_paylog a, syweb_market b')
->where('a.market_key = b.market_key and a.out_trade_no = ?', $agent_bill_id)
->get($this->db, null);
if (empty($record) || count($record) <= 0)
return new returnObject(1, 10003, '找不到对应的支付信息。');
$version = $record[0]['version']; /// 版本号
switch($version)
{
case 1:
{
/*
$record = Sql::select('a.plid, a.app_key, a.market_key, b.heepay_paykey, b.signkey, a.version')
->from('syweb_core_paylog a, syweb_market b')
->where('a.market_key = b.market_key and a.plid = ?', $id)
->get($this->db, null);
if (empty($record) || count($record) <= 0)
return new returnObject(1, 10003, '找不到对应的支付信息。');
*/
$key = $record[0]['heepay_paykey']; /// 商户签名密钥
$Params = "result={$result}&agent_id={$agent_id}&jnet_bill_no={$jnet_bill_no}&agent_bill_id={$agent_bill_id}&pay_type={$pay_type}&pay_amt={$pay_amt}&remark={$remark}&key={$key}";
$Sign = md5($Params);
if($Sign == $return_sign) { /// 比较签名密钥结果是否一致,一致则保证了数据的一致性
/// 商户自行处理自己的业务逻辑
/// 订单号
$tradeno = $agent_bill_id;
/// 支付订单号(汇付宝平台)
$transaction_id = $jnet_bill_no;
/// 支付订单号(微信)
//$out_transaction_id = '';
/// 支付金额(单位分)
$total_fee = intval($pay_amt * 100);
/// 用户openid
$open_id = '';
/// 此处可以在添加相关处理业务,校验通知参数中的商户订单号out_trade_no和金额total_fee是否和商户业务系统的单号和金额是否一致,一致后方可更新数据库表中的记录。
/// 更改订单状态
if ($this->_notify_wechat_order_status_v1($record[0]['app_key'], $record[0]['market_key'], $tradeno, $transaction_id, $open_id, $total_fee, 0, PAYSTATUS_PAY, $record[0]['signkey']))
//echo NOTIFYSTATUS_SUCCESS;
echo 'ok';
else
echo NOTIFYSTATUS_ERROR;
exit;
} else {
//echo NOTIFYSTATUS_ERROR;
echo 'error';
/// 商户自行处理,可通过查询接口更新订单状态,也可以通过商户后台自行补发通知,或者反馈运营人工补发
return new returnObject(1, 10004, 'bad signature.');
}
break;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 爱贝pc网页支付 异步回调用页面
* @route({"GET","/notify/online/ipaypcpay"})
* @route({"POST","/notify/online/ipaypcpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_ipay_pc_notify()
{
//file_put_contents('c:/1.txt', file_get_contents('php://input'));
$param = $_REQUEST;
$transdata = $param['transdata'];
if (stripos("%22", $transdata)) /// 判断接收到的数据是否做过 Urldecode处理,如果没有处理则对数据进行Urldecode处理
$param = array_map('urldecode', $param);
$obj = json_decode($param['transdata']);
if (is_null($obj))
return new returnObject(1, 500, '错误的参数格式');
$appid = $obj->appid;
/// 平台公钥
//$platpkey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIouv++6h+CL/kGDxldXMqb92a3/tszmPzGZ4DkwZhNAkOxLuOTWkYaw5+TGktxnNsjU6YJvC88vH3pYsnmHvCheJnEmj3GNamjig5c7QrzeCgBG974SbIrF7iY/tsdE6YQPfw+Q0oVf+sfFk61wPToQPcQgsJw7tYQrFC+jqe9QIDAQAB';
$platpkey = file_get_contents(dirname(dirname(__DIR__)) . "/payment/ipay/key/{$appid}/public.txt");
/// 把数据组装成验签函数要求的参数格式
$resp = 'transdata=' . $param['transdata'] . '&sign=' . $param['sign'] . '&signtype=' . $param['signtype'];
/// 验签函数parseResp() 中 只接受明文数据。数据如:transdata={"appid":"3003686553","appuserid":"10123059","cporderid":"1234qwedfq2as123sdf3f1231234r","cpprivate":"11qwe123r23q232111","currency":"RMB","feetype":0,"money":0.12,"paytype":403,"result":0,"transid":"32011601231456558678","transtime":"2016-01-23 14:57:15","transtype":0,"waresid":1}&sign=jeSp7L6GtZaO/KiP5XSA4vvq5yxBpq4PFqXyEoktkPqkE5b8jS7aeHlgV5zDLIeyqfVJKKuypNUdrpMLbSQhC8G4pDwdpTs/GTbDw/stxFXBGgrt9zugWRcpL56k9XEXM5ao95fTu9PO8jMNfIV9mMMyTRLT3lCAJGrKL17xXv4=&signtype=RSA
//echo "进入了2" . $resp;
if (!parseResp($resp, $platpkey, $json)) { /// 验签失败
//echo NOTIFYSTATUS_ERROR;
echo 'error';
/// 商户自行处理,可通过查询接口更新订单状态,也可以通过商户后台自行补发通知,或者反馈运营人工补发
return new returnObject(1, 10004, 'bad signature.');
}
/// 以下是 验签通过之后 对数据的解析。
$transdata = $param['transdata'];
$obj = json_decode($transdata);
$appid = @$obj->appid; /// 平台为商户应用分配的唯一代码
$appuserid = @$obj->appuserid; /// 用户在商户应用的唯一标识
$cporderid = @$obj->cporderid; /// 商户订单号
$cpprivate = @$obj->cpprivate; /// 商户私有信息
$currency = @$obj->currency; /// 货币类型以及单位:RMB – 人民币(单位:元)
$feetype = @$obj->feetype; /// 计费方式,具体定义见简介及注意事项
$money = @$obj->money; /// 本次交易的金额(请务必严格校验商品金额与交易的金额是否一致)
$paytype = @$obj->paytype; /// 支付方式,具体定义见简介及注意事项
$result = @$obj->result; /// 交易结果:0–交易成功; 1–交易失败;
$transid = @$obj->transid; /// 计费支付平台的交易流水号
$transtime = @$obj->transtime; /// 交易时间格式:yyyy-mm-dd hh24:mi:ss
$transtype = @$obj->transtype; /// 交易类型:0–支付交易;1–支付冲正(暂未启用);2–契约退订;3–自动续费
$waresid = @$obj->waresid; /// 平台为应用内需计费商品分配的编码
if (0 != $result) {
echo NOTIFYSTATUS_ERROR;
/// 商户自行处理,可通过查询接口更新订单状态,也可以通过商户后台自行补发通知,或者反馈运营人工补发
return new returnObject(1, 10004, 'failed with pay.');
}
$record = Sql::select('a.plid, a.app_key, a.market_key, b.ipay_mchid, b.signkey, a.version')
->from('syweb_core_paylog a, syweb_market b')
->where('a.market_key = b.market_key and a.out_trade_no = ?', $cporderid)
->get($this->db, null);
if (empty($record) || count($record) <= 0)
return new returnObject(1, 10003, '找不到对应的支付信息。');
elseif (intval($cpprivate) != $record[0]['plid'])
return new returnObject(1, 10004, '不正确的支付信息。');
$version = $record[0]['version']; /// 版本号
switch($version)
{
case 1:
{
/// 订单号
$tradeno = $cporderid;
/// 支付订单号(爱贝平台)
$transaction_id = $transid;
/// 支付订单号(微信)
//$out_transaction_id = '';
/// 支付金额(单位分)
$total_fee = intval($money * 100);
/// 用户openid
$open_id = '';
/// 此处可以在添加相关处理业务,校验通知参数中的商户订单号out_trade_no和金额total_fee是否和商户业务系统的单号和金额是否一致,一致后方可更新数据库表中的记录。
/// 更改订单状态
if ($this->_notify_wechat_order_status_v1($record[0]['app_key'], $record[0]['market_key'], $tradeno, $transaction_id, $open_id, $total_fee, 0, PAYSTATUS_PAY, $record[0]['signkey'])) {
echo NOTIFYSTATUS_SUCCESS;
//file_put_contents('c:/1.txt', PHP_EOL.'ok', FILE_APPEND);
} else {
echo NOTIFYSTATUS_ERROR;
//file_put_contents('c:/1.txt', PHP_EOL.'error', FILE_APPEND);
}
exit;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* 躺倒鸭异步回调用页面
* @route({"GET","/notify/online/tdypay"})
* @route({"POST","/notify/online/tdypay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return string|returnObject
*/
public function online_tdy_notify()
{
//$app_id = @$_REQUEST['appid']; /// 由躺倒鸭分配的应用ID
$prepay_id = @$_REQUEST['prepay_id']; /// 预下单号
$order_id = @$_REQUEST['order_id']; /// CP/SP侧生成的订单ID
$ts = @$_REQUEST['ts']; /// 时间戳,精确到毫秒
$sign = @$_REQUEST['sign']; /// 签名字符串,32位小写md5,参见《附录2:交易参数签名方 式》
$trade_status = @$_REQUEST['trade_status']; /// 交易状态。ORDER_NOT_EXIST 订单不存在;NON_PAYMENT 未支付;SUCCESS 支付成功;FAILURE 支付失败
$trade_time = @$_REQUEST['trade_time']; /// 交易时间,时间戳,精确到毫秒
$trade_amount = @$_REQUEST['trade_amount']; /// 交易金额,单位分
$data = @$_REQUEST['data']; /// CP/SP自定义的订单附加信息。躺倒鸭回调时原样返回
$attach = (array)json_decode($data);
if (empty($attach))
//return new returnObject(1, 10002, '回调参数passback_params不能为空。');
die('FAIL');
$app_id = $attach['app_id'];
$market_key = $attach['market_key'];
$buyer_id = $attach['buyer_id'];
$version = $attach['version'];
switch ($version)
{
case 1:
{
/// 查询商户信息
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0) {
//return new returnObject(1, 10004, '找不到的商户信息。');
die('FAIL');
}
$tdy_app_id = $marketList[0]['tdy_app_id']; /// 躺倒鸭appid
$tdy_app_key = $marketList[0]['tdy_app_key']; /// 躺倒鸭appkey
$sign_key = $marketList[0]['signkey']; /// 签名key
/// 校验appid
if (0 != strcmp($tdy_app_id, @$_REQUEST['appid'])) {
//return new returnObject(1, 10004, 'appid不匹配!');
die('FAIL');
}
/// 校验签名
$this_sign = mb_strtolower(md5("{$tdy_app_id}{$order_id}{$ts}{$tdy_app_key}"), USEDCHARSET);
if (0 != strcmp($sign, $this_sign)) {
//return new returnObject(1, 10004, '签名错误!');
die('FAIL');
}
/// 判断支付状态
if (0 == strcasecmp($trade_status, 'SUCCESS')) { /// 支付成功
/// 更改订单状态
if ($this->_notify_alipay_order_status_v1($app_id, $market_key, $order_id, $prepay_id, $buyer_id, $trade_amount, 0, PAYSTATUS_PAY, $sign_key)) {
die('SUCCESS');
} else {
die('SUCCESS');
}
} else {
die('FAIL');
}
}
default:
//return new returnObject(500, -1, "不支持的接口版本:{$version}!");
die('FAIL');
}
}
/**
* 微信支付 异步回调用页面
* @route({"POST","/notify/offline/wechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function offline_wechat_notify()
{
return $this->online_wechat_notify();
}
/**
* 支付宝支付 异步回调用页面
* @route({"POST","/notify/offline/alipay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function offline_alipay_notify()
{
$content = $_POST;
if (!array_key_exists('body', $content))
//return new returnObject(1, 10001, '回调参数缺少body参数。');
die(NOTIFYSTATUS_FAIL);
if (is_string($content['body']))
$attach = (array)json_decode($content['body']);
else
$attach = (array)$content['body'];
if (empty($attach))
//return new returnObject(1, 10002, '回调参数body不能为空。');
die(NOTIFYSTATUS_FAIL);
$app_id = $attach['app_id'];
$market_key = $attach['market_key'];
$version = $attach['version'];
switch ($version)
{
case 1:
{
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10004, '找不到的商户信息。');
$alipay_appid = $marketList[0]['alipay_appid']; /// 支付宝appid
$sign_key = $marketList[0]['signkey']; /// 签名key
//==============
$aop = new AopClient();
$aop->alipayPublicKey = dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem';
$result = $aop->rsaCheckV1($content, $aop->alipayPublicKey, 'RSA2');
if (!$result)
{
file_put_contents('d:/signerror.txt', JsonObjectToJsonString($content));
die(NOTIFYSTATUS_FAIL);
}
//==============
// 验证成功
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//$seller_id = isset($content['seller_id']) ? $content['seller_id'] : ''; /// seller_id卖家支付宝用户号
$out_trade_no = $content['out_trade_no']; /// 商户订单号
$trade_no = $content['trade_no']; /// 支付宝交易号
$trade_status = $content['trade_status']; /// 交易状态
$buyer_id = isset($content['buyer_id']) ? $content['buyer_id'] : ''; /// 买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字
//$buyer_logon_id = isset($content['buyer_logon_id']) ? $content['buyer_logon_id'] : ''; /// 买家支付宝账号
//$total_amount = intval(isset($content['total_amount']) ? floatval($content['total_amount']) * 100 : 0); /// 订单金额
$receipt_amount = intval(isset($content['receipt_amount']) ? floatval($content['receipt_amount']) * 100 : 0); /// 实收金额
//$invoice_amount = intval(isset($content['invoice_amount']) ? floatval($content['invoice_amount']) * 100 : 0); /// 开票金额
//$buyer_pay_amount = intval(isset($content['buyer_pay_amount']) ? floatval($content['buyer_pay_amount']) * 100 : 0); /// 用户在交易中支付的金额
//$point_amount = intval(isset($content['point_amount']) ? floatval($content['point_amount']) : 0); /// 使用集分宝支付的金额
//$refund_fee = intval(isset($content['refund_fee']) ? floatval($content['refund_fee']) : 0); /// 退款通知中,返回总退款金额,单位为元,支持两位小数
if ('TRADE_FINISHED' == $trade_status)
{
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 如果有做过处理,不执行商户的业务程序
// 注意:
// 退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
// 调试用,写文本函数记录程序运行情况是否正常
// logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
elseif ('TRADE_SUCCESS' == $trade_status)
{
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 如果有做过处理,不执行商户的业务程序
// 注意:
// 付款完成后,支付宝系统发送该交易状态通知
// 调试用,写文本函数记录程序运行情况是否正常
// logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
/// 更改订单状态
if ($this->_notify_alipay_order_status_v1($app_id, $market_key, $out_trade_no, $trade_no, $buyer_id, $receipt_amount, 0, PAYSTATUS_PAY, $sign_key))
die(NOTIFYSTATUS_SUCCESS);
else
die(NOTIFYSTATUS_FAIL);
}
default:
//return new returnObject(500, -1, "不支持的接口版本:{$version}!");
die(NOTIFYSTATUS_FAIL);
}
}
/**
* 威富通聚合支付-微信支付 异步回调用页面
* @route({"POST","/notify/offline/swiftpasswechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function offline_swiftpass_wechat_notify()
{
return $this->online_swiftpass_wechat_notify();
}
/**
* 汇付宝聚合支付-微信支付 异步回调用页面
* @route({"POST","/notify/offline/heepaywechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function offline_heepay_wechat_notify()
{
return $this->offline_heepay_wechat_notify();
}
/**
* 微信支付 异步回调用页面
* @route({"POST","/notify/mobile/wechatpay"})
* @return returnObject|string
*/
public function mobile_wechat_notify()
{
return $this->online_wechat_notify();
}
/**
* 威富通聚合支付-微信支付 异步回调用页面
* @route({"POST","/notify/mobile/swiftpasswechatpay"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function mobile_swiftpass_wechat_notify()
{
return $this->online_swiftpass_wechat_notify();
}
/**
* 发红包
* @route({"GET","/sendredpack"})
* @route({"POST","/sendredpack"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"sid","$._POST.sid"}) sid
* @param({"scode","$._POST.scode"}) scode
* @param({"orderid","$._POST.orderid"}) 订单编号
* @param({"fee","$._POST.fee"}) 红包金额(单位分)
* @param({"wishing","$._POST.wishing"}) 红包祝福语
* @param({"act_name","$._POST.act_name"}) 活动名称
* @param({"remark","$._POST.remark"}) 备注
*
* @param({"send_type","$._POST.send_type"}) 支付类型(1: 微信支付; 2: 支付宝支付)
*
* @param({"version","$._POST.version"}) 版本号
* @param({"sign","$._POST.sign"}) 签名
*
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return returnObject
*/
public function send_red_pack($appid, $devkey, $sid, $scode, $orderid, $fee, $wishing, $act_name, $remark, $send_type = 1, $version = 1, $sign = '')
{
switch ($version)
{
case 1:
{
/// 发送前校验
$attach = $this->verify_send_red_pack_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $wishing, $act_name, $remark, $sign);
if ($attach instanceof returnObject)
return $attach;
switch ($send_type)
{
case PAYCODE_ONLINE_WECHAT: /// 微信红包
return $this->_send_red_pack_wechat_v1($orderid, $fee, $wishing, $act_name, $remark, $attach);
case PAYCODE_ONLINE_ALIPAY: /// 支付宝红包
return $this->_send_red_pack_ali_v1($orderid, $fee, $wishing, $act_name, $remark, $attach);
default:
echo sprintf('未知的红包类型: %d' . PHP_EOL . '支付类型(%d: 微信红包; %d: 支付宝红包; %d)',
$send_type, PAYCODE_ONLINE_WECHAT, PAYCODE_ONLINE_ALIPAY);
return -1;
}
break;
}
default:
return new returnObject(500, -1, "不支持的接口版本:{$version}!");
}
}
/**
* @note 在线支付前校验
* @param string $appid 应用id
* @param string $devkey 开发者key
* @param string $sid sid
* @param string $scode scode
* @param string $orderid 订单号
* @param int $fee 支付金额(分)
* @param string $title 支付标题
* @param string $notice_url 异步通知地址
* @param string $return_url 同步通知地址
* @param string $sign 签名
* @return array|returnObject
*/
private function verify_pay_online_v1($appid, $devkey, $sid, $scode, $orderid, $fee, $title, $notice_url, $return_url, $sign)
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, $sid, $scode);
$verify_result = parent::verify();
if (!is_error_api($verify_result))
{
if (false)
{
/// 校验签名
$param = $_REQUEST;
if (isset($param['sign']))
{
$raw_sign = $param['sign'];
unset($param['sign']);
}
else
$raw_sign = $sign;
$own_sign = SignParameter($param, $this->marketInfo['signkey']);
if ($own_sign != $raw_sign)
return new returnObject(500, -1, '签名错误', null);
}
if (empty($orderid))
return new returnObject(500, 500, '请指定订单编号!', null);
if (!is_numeric($fee))
return new returnObject(500, 500, '请正确指定订单价格!', null);
if (empty($title))
return new returnObject(500, 500, '请指定title!', null);
if (empty($notice_url) && empty($return_url))
return new returnObject(500, 500, '请至少指定一个支付回调通知页面!', null);
/// 获取附加的参数
$attach = GetAttachParameters(['appid', 'devkey', 'sid', 'scode', 'orderid', 'fee', 'title', 'notice_url', 'return_url', 'paytype', 'version', 'sign',]);
$attach['paytime'] = time();
return $attach;
}
elseif ($verify_result instanceof returnObject)
{
return $verify_result;
}
else
{
$return = new returnObject();
$return->from_array((array)$verify_result);
return $verify_result;
}
}
/**
* @note 扫码支付前校验
* @param string $appid 应用id
* @param string $devkey 开发者key
* @param string $market_key 门店key
* @param string $orderid 订单号
* @param int $fee 支付金额(分)
* @param string $title 支付标题
* @param string $notice_url 异步通知地址
* @param string $sign 签名
* @return array|returnObject
*/
private function verify_pay_offline_v1($appid, $devkey, $market_key, $orderid, $fee, $title, $notice_url, $sign)
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, '', '');
$verify_result = parent::verify_admin($market_key);
if (!is_error_api($verify_result))
{
if (false)
{
/// 校验签名
$param = $_REQUEST;
if (isset($param['sign']))
{
$raw_sign = $param['sign'];
unset($param['sign']);
}
else
$raw_sign = $sign;
$own_sign = SignParameter($param, $this->marketInfo['signkey']);
if ($own_sign != $raw_sign)
return new returnObject(500, -1, '签名错误', null);
}
if (empty($orderid))
return new returnObject(500, 500, '请指定订单编号!', null);
if (!is_numeric($fee))
return new returnObject(500, 500, '请正确指定订单价格!', null);
if (empty($title))
return new returnObject(500, 500, '请指定title!', null);
if (empty($notice_url))
return new returnObject(500, 500, '请指定一个支付回调通知页面!', null);
/// 获取附加的参数
$attach = GetAttachParameters(['appid', 'devkey', 'market_key', 'orderid', 'fee', 'title', 'notice_url', 'paytype', 'version', 'sign',]);
$attach['paytime'] = time();
return $attach;
}
elseif ($verify_result instanceof returnObject)
{
return $verify_result;
}
else
{
$return = new returnObject();
$return->from_array((array)$verify_result);
return $verify_result;
}
}
/**
* @param string $appid 应用id
* @param string $devkey 开发者id
* @param string $market_key 门店key
* @param string $from_user 支付用户
* @param string $orderid 订单号
* @param int $fee 支付总价
* @param string $title 支付主题
* @param string $notice_url 回调地址(异步)
* @param string $sign 签名
* @return array|null|returnObject
*/
private function verify_pay_mobile_v1($appid, $devkey, $market_key, $from_user, $orderid, $fee, $title, $notice_url, $sign)
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, '', '');
$verify_result = parent::verify_admin($market_key);
if (!is_error_api($verify_result))
{
if (false)
{
/// 校验签名
$param = $_REQUEST;
if (isset($param['sign']))
{
$raw_sign = $param['sign'];
unset($param['sign']);
}
else
$raw_sign = $sign;
$own_sign = SignParameter($param, $this->marketInfo['signkey']);
if ($own_sign != $raw_sign)
return new returnObject(500, -1, '签名错误', null);
}
if (empty($orderid))
return new returnObject(500, 500, '请指定订单编号!', null);
if (!is_numeric($fee))
return new returnObject(500, 500, '请正确指定订单价格!', null);
if (empty($title))
return new returnObject(500, 500, '请指定title!', null);
if (empty($notice_url))
return new returnObject(500, 500, '请指定一个支付回调通知页面!', null);
/// 获取附加的参数
$attach = GetAttachParameters(['appid', 'devkey', 'sid', 'scode', 'market_key', 'from_user', 'orderid', 'fee', 'title', 'notice_url', 'paytype', 'version', 'sign',]);
$attach['paytime'] = time();
return $attach;
}
elseif ($verify_result instanceof returnObject)
{
return $verify_result;
}
else
{
$return = new returnObject();
$return->from_array((array)$verify_result);
return $verify_result;
}
}
/**
* @note 退款校验
* @param string $appid 应用id
* @param string $devkey 开发者key
* @param string $sid sid
* @param string $scode scode
* @param string $transaction_id 三方订单号(微信等)
* @param string $out_trade_no 平台订单号
* @param int $refund_fee 退款金额
* @param string $sign 签名
* @return array|returnObject
*/
private function verify_refund_v1($appid, $devkey, $sid, $scode, $transaction_id, $out_trade_no, $refund_fee, $sign)
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, $sid, $scode);
$verify_result = parent::verify();
if (!is_error_api($verify_result))
{
/// 校验签名
$param = $_REQUEST;
if (isset($param['sign']))
{
$raw_sign = $param['sign'];
unset($param['sign']);
}
else
$raw_sign = $sign;
$own_sign = SignParameter($param, $this->marketInfo['signkey']);
if ($own_sign != $raw_sign)
return new returnObject(500, -1, '签名错误', null);
if (!isset($transaction_id) && !isset($out_trade_no))
return new returnObject(500, 13001, 'transaction_id和out_trade_no参数必须至少传入一个。', null);
if (empty($transaction_id) && empty($out_trade_no))
return new returnObject(500, 13002, 'transaction_id和out_trade_no参数必须有一个不为空。', null);
if (empty($refund_fee) || (!is_numeric($refund_fee) && !is_float($refund_fee)))
return new returnObject(500, 13004, 'refund_fee不能为空,并且需要为数字。', null);
$refererUrl = $_SERVER['HTTP_REFERER']; /// 当前调用退款的域名
$localUrl = $this->getLocaleUrl(); /// 本地域名
/// 退款安全域名
$refund_safe_domain = json_decode($this->marketInfo['refund_safe_domain']);
$referer_paths = parse_url($refererUrl);
$local_paths = parse_url($localUrl);
if (!empty($referer_paths) && count($referer_paths) > 0)
{
$referer_domain = $referer_paths['host'];
$local_domain = $local_paths['host'];
if (!in_array($referer_domain, $refund_safe_domain) && $local_domain != $referer_domain)
return new returnObject(500, 13006, '不是安全的域名。', $referer_domain);
}
$attach = GetAttachParameters(['appid', 'devkey', 'sid', 'scode', 'transaction_id', 'out_trade_no', 'total_fee', 'refund_fee', 'version', 'sign',]);
return $attach;
}
else
{
$return = new returnObject();
$return->from_array((array)$verify_result);
return $return;
}
}
/**
* @note 保存支付信息
* @param string $app_id 支付应用(int)
* @param string $market_key 门店key
* @param string $fromUser 支付用户
* @param string $orderid 订单ID
* @param integer $fee 支付价格
* @param string $title 支付主题
* @param string $notice_url 支付成功回调地址
* @param string $return_url 支付回调地址
* @param array $attach 支付附加参数
// * @param string $param_mask 自定义的参数格式(回调通知时使用)
* @param string $type 支付方式
* @return mixed
**/
private function saved_payinfo_v1($app_id, $market_key, $fromUser, $orderid, $fee, $title, $notice_url, $return_url, $attach, $type)
{
$log = Sql::select('syweb_core_paylog.*')
->from('syweb_core_paylog')
->where('app_key = ? and market_key = ? and `order_id` = ?', $app_id, $market_key, $orderid)
->get($this->db, null);
if (!empty($log) && count($log) > 0)
$log = $log[0];
if (!empty($log) && !empty($log['plid']) && is_numeric($log['status']))
{
switch ($log['status'])
{
case PAYSTATUS_PAY:
echo '订单已经付款';
return false;
case PAYSTATUS_REFUND:
echo '订单已经退款';
return false;
case PAYSTATUS_NORMAL:
break;
default:
break;
}
}
/// 重置支付记录
if (!empty($log))
$log = null;
if (empty($log))
{
$tag = [];
$tag['return_url'] = $return_url; /// 支付完成页面跳转地址
$tag['notice_url'] = $notice_url; /// 支付回调页面请求地址
//$tag['param_mask'] = $param_mask; /// 支付回复参数格式
$tag['total_fee'] = $fee; /// 支付金额
$tag['attach'] = json_encode($attach, JSON_UNESCAPED_UNICODE);
$tag = json_encode($tag, JSON_UNESCAPED_UNICODE);
$record = [];
$record['type'] = $type; /// 支付方式
$record['app_key'] = $app_id; /// 支付应用(int)
$record['market_key'] = $market_key; /// 支付商家(int)
$record['openid'] = $fromUser; /// 支付来源用户
$record['order_id'] = $orderid; /// 订单编号
$record['pay_fee'] = $fee; /// 支付金额
$record['refund_fee'] = 0; /// 退款金额
$record['tag'] = $tag; /// 其他附加内容
$record['title'] = $title; /// 支付主题
$record['status'] = PAYSTATUS_NORMAL; /// 支付状态
$record['encrypt_code'] = ''; /// 编码
$record['createtime'] = TIMESTAMP; /// 支付创建时间戳
$record['out_trade_no'] = md5(date('YmdHis') . '_' . $app_id . '_' . $market_key . '_' . random(8, 1)); /// 支付唯一ID
$record['version'] = 1; /// 版本号
$pdo = $this->db;
try
{
$pdo->beginTransaction();
/// 插入一条支付记录
$plid = Sql::insertInto('syweb_core_paylog')->values($record)->exec($pdo)->lastInsertId();
$pdo->commit();
$record['plid'] = $plid;
return $record;
}
catch(Exception $e)
{
$pdo->rollBack();
echo $e->getMessage();
return false;
}
}
return true;
}
/**
* 微信支付-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
//* @param string $param_mask
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
/// 验证用户登陆方式
if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
return new returnObject(500, 500, '请使用微信登录再进行支付!', null);
/// 保存支付记录
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/wechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
load()->model('payment');
$wechat = [];
$wechat['appid'] = $this->marketInfo['weixin_appid']; /// 微信公众号APPID
$wechat['secret'] = $this->marketInfo['weixin_secret_appid'];
$wechat['mchid'] = $this->marketInfo['weixin_mchid']; /// 微信公众号商户号
$wechat['signkey'] = $this->marketInfo['weixin_paykey']; /// 支付秘钥
//$openid = $this->userInfo['openid'];
$attach = json_encode(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1,], JSON_UNESCAPED_UNICODE);
$tools = new JsApiPay();
/// ②、实例化统一下单对象
$input = new WxPayUnifiedOrder();
$input->SetAppid($wechat['appid']); /// 公众号APPID
$input->SetMch_id($wechat['mchid']); /// 公众号商户ID
//$input->SetPayKey($wechat['signkey']); /// 公众号APPID
//$input->SetSecretId($wechat['secret']); /// 公众号商户ID
$input->SetBody($title); /// 本次支付主题
$input->SetAttach($attach); /// 支付回传的值
$input->SetOut_trade_no($pay_log['out_trade_no']);
$input->SetTotal_fee($fee); /// 微信支付单位为分
$input->SetTime_start(date("YmdHis")); /// 支付发起时间戳
$input->SetTime_expire(date("YmdHis", time() + 600));/// 支付有效期
$input->SetGoods_tag("");
$input->SetNotify_url($notify_url);
$input->SetTrade_type("JSAPI");
$input->SetOpenid($pay_log['openid']);
try
{
$order = WxPayApi::unifiedOrder($input, 6, $wechat); /// 提交统一订单
}
catch (Exception $e)
{
if (isset($order['return_msg']))
echo $order['return_msg'], '
';
exit($e->getMessage());
}
/// $wOpt = wechat_build($params, $wechat);
$jsApiParameters = $tools->GetJsApiParameters($order, $wechat);
if (is_error($jsApiParameters))
{
/*
if ($jsApiParameters['message'] == 'invalid out_trade_no' || $jsApiParameters['message'] == 'OUT_TRADE_NO_USED')
{
$id = date('YmdH');
pdo_update('syweb_core_paylog', ['plid' => $id, ], ['plid' => $log['plid'], ]);
pdo_query("ALTER TABLE " . tablename('syweb_core_paylog') . " auto_increment = " . ($id + 1) . ";");
exit('抱歉,发起支付失败,系统已经修复此问题,请重新尝试支付。');
}
*/
exit("抱歉,发起支付失败,具体原因为:“{$jsApiParameters['errno']}:{$jsApiParameters['message']}”。请及时联系站点管理员。");
}
$htmlContent = <<
function jsApiCall() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{$jsApiParameters},
function(res) {
if ('get_brand_wcpay_request:ok' == res.err_msg) { /// 支付成功
window.location.href="{$callback_url}";
} else if ('get_brand_wcpay_request:cancel' == res.err_msg) { /// 用户取消
//alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
history.go(-1);
} else { /// 其他错误
//alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
history.go(-1);
}
}
);
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
} else {
jsApiCall();
}
EOF;
exit($htmlContent);
}
/**
* 支付宝支付-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_online_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
/// 保存支付记录
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, @$this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_ALIPAY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$alipay_appid = $this->marketInfo['alipay_appid'];
$attach = json_encode(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ], JSON_UNESCAPED_UNICODE);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/alipay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
$payRequestBuilder = new AlipayTradeWapPayContentBuilder();
$payRequestBuilder->setBody($title); /// 商品描述,可空
$payRequestBuilder->setSubject($title); /// 订单名称,必填
$payRequestBuilder->setOutTradeNo($pay_log['out_trade_no']); /// 商户订单号,商户网站订单系统中唯一订单号,必填
$payRequestBuilder->setTotalAmount($fee / 100); /// 付款金额,必填
$payRequestBuilder->setTimeExpress('1m');
$payRequestBuilder->setPassbackParams($attach); /// 回传参数
$config = array (
'app_id' => $alipay_appid, /// 应用id
//'merchant_private_key' => '', /// 商户私钥,您的原始格式RSA私钥
'merchant_private_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/rsa_private_key.pem', /// 商户私钥文件名
'notify_url' => $notify_url, /// 异步通知地址
'return_url' => $callback_url, /// 同步通知地址
'charset' => 'utf-8', /// 编码格式
'sign_type' => 'RSA2', /// 签名方式
'gatewayUrl' => 'https://openapi.alipay.com/gateway.do', /// 支付宝网关
//'alipay_public_key' => '', /// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem', /// 支付宝公钥文件名
);
$payResponse = new AlipayTradeService_wappay($config);
$result = $payResponse->wapPay($payRequestBuilder, $config['return_url'], $config['notify_url']);
exit($result);
}
/**
* 威富通聚合支付--微信-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
{
return new returnObject(500, 500, '请使用微信登录再进行支付!', null);
}
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_SWIFTPASS_WECHAT);
if (!$pay_log)
{
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
}
$openid = $this->userInfo['openid'];
$mch_id = $this->marketInfo['swiftpass_mchid'];
$secret_key = $this->marketInfo['swiftpass_paykey'];
$attach = json_encode(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ], JSON_UNESCAPED_UNICODE);
$resHandler = new ClientResponseHandler();
$reqHandler = new RequestHandler();
$pay = new PayHttpClient();
$reqHandler->setGateUrl('https://pay.swiftpass.cn/pay/gateway');
$reqHandler->setKey($secret_key);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/swiftpasswechatpay', true); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/*
service 是 String(32) 接口类型:pay.weixin.jspay
version 否 String(8) 版本号,version默认值是2.0
charset 否 String(8) 可选值 UTF-8 ,默认为 UTF-8
sign_type 否 String(8) 签名类型,取值:MD5默认:MD5
mch_id 是 String(32) 商户号,由平台分配
is_raw 否 String(1) 是否原生态 值为1:是;值为0:否;不传默认是0
is_minipg 否 String(1) 值为1,表示小程序支付;不传或值不为1,表示公众账号内支付
out_trade_no 是 String(32) 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
device_info 否 String(32) 终端设备号
body 是 String(127) 商品描述
sub_openid 是 String(128) 微信用户关注商家公众号的openid(注:使用测试号时此参数置空,即不要传这个参数,使用正式商户号时才传入,参数名是sub_openid,具体请看文档最后注意事项第7点)
sub_appid 否 String(32) 微信公众平台基本配置中的AppID(应用ID)
attach 否 String(128) 商户附加信息,可做扩展参数,255字符内
total_fee 是 Int 总金额,以分为单位,不允许包含任何字、符号
mch_create_ip 是 String(16) 订单生成的机器 IP
notify_url 是 String(255) 接收平台通知的URL,需给绝对路径,255字符内格式如:http://wap.tenpay.com/tenpay.asp,确保平台能通过互联网访问该地址
callback_url 否 String(255) 交易完成后跳转的URL,需给绝对路径,255字符内格式如:http://wap.tenpay.com/callback.asp注:该地址只作为前端页面的一个跳转,需使用notify_url通知结果作为支付最终结果。
time_start 否 String(14) 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。时区为GMT+8 beijing。该时间取自商户服务器
time_expire 否 String(14) 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自商户服务器
goods_tag 否 String(32) 商品标记,微信平台配置的商品标记,用于优惠券或者满减使用
nonce_str 是 String(32) 随机字符串,不长于 32 位
limit_credit_pay 否 String(32) 限定用户使用微信支付时能否使用信用卡,值为1,禁用信用卡;值为0或者不传此参数则不禁用
sign 是 String(32) MD5签名结果,详见“安全规范”
*/
//$reqHandler->setReqParams($_POST, ['method',]);
$reqHandler->setParameter('service', 'pay.weixin.jspay'); /// 接口类型
$reqHandler->setParameter('mch_id', $mch_id); /// 商户号,由平台分配
$reqHandler->setParameter('version', '2.0'); /// 版本号,version默认值是2.0
$reqHandler->setParameter('is_raw', '1'); /// 是否原生态 值为1:是;值为0:否;不传默认是0
$reqHandler->setParameter('out_trade_no', $pay_log['out_trade_no']); /// 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
$reqHandler->setParameter('body', $title); /// 商品描述
$reqHandler->setParameter('sub_openid', $openid); /// 微信用户关注商家公众号的openid(注:使用测试号时此参数置空,即不要传这个参数,使用正式商户号时才传入,参数名是sub_openid,具体请看文档最后注意事项第7点)
$reqHandler->setParameter('attach', $attach); /// 商户附加信息,可做扩展参数,255字符内
$reqHandler->setParameter('total_fee', $fee); /// 总金额,以分为单位,不允许包含任何字、符号
$reqHandler->setParameter('mch_create_ip', $_SERVER['REMOTE_ADDR']); /// 订单生成的机器 IP
$reqHandler->setParameter('notify_url', $notify_url); /// 异步通知地址
$reqHandler->setParameter('callback_url', $callback_url); /// 同步通知地址
$reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
$reqHandler->createSign(); /// 创建签名
$data = Utils::toXml($reqHandler->getAllParameters());
//var_dump($data);
//var_dump($pay->getResContent());
$pay->setReqContent($reqHandler->getGateURL(), $data);
if ($pay->call())
{
$resHandler->setContent($pay->getResContent());
$resHandler->setKey($reqHandler->getKey());
//var_dump($resHandler->getAllParameters());
if ($resHandler->isTenpaySign())
{
//var_dump($resHandler->getAllParameters());
/// 当返回状态与业务结果都为0时才返回,其它结果请查看接口文档
$status_code = $resHandler->getParameter('status');
$result_code = $resHandler->getParameter('result_code');
if (0 == $status_code && 0 == $result_code)
{
/*
$payInfo = json_decode($resHandler->getParameter('pay_info'));
$htmlContent = <<
function jsApiCall() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": "{$payInfo->appId}", /// 公众号名称,由商户传入
"timeStamp": "{$payInfo->timeStamp}", /// 时间戳,自1970 年以来的秒数
"nonceStr": "{$payInfo->nonceStr}", /// 随机串
"package": "{$payInfo->package}",
"signType": "{$payInfo->signType}", /// 微信签名方式:
"paySign": "{$payInfo->paySign}" /// 微信签名,
}, function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
/// 此处可以使用此方式判断前端返回,微信团队郑重提示:res.err_msg 将在用户支付成功后返回ok,但并不保证它绝对可靠。
window.location.href="{$callback_url}";
} else {
//alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
history.go(-1);
}
}
);
}
if (typeof WeixinJSBridge == "undefined") {
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
EOF;
*/
$htmlContent = <<
window.location.href="https://pay.swiftpass.cn/pay/jspay?token_id={$resHandler->getParameter('token_id')}&showwxtitle=1";
EOF;
die($htmlContent);
//return new returnObject(0, 0, '', ['token_id' => $resHandler->getParameter('token_id'), 'pay_info' => $resHandler->getParameter('pay_info'),]);
}
elseif (0 != $status_code)
return new returnObject(500, $status_code, $resHandler->getParameter('message'), null);
elseif (0 != $result_code)
return new returnObject(500, $result_code, $resHandler->getParameter('err_msg'), null);
else
return new returnObject(500, 500, '未知错误!');
}
else
{
if (0 != $resHandler->getParameter('status'))
return new returnObject(502, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
elseif (0 != $resHandler->getParameter('result_code'))
return new returnObject(502, $resHandler->getParameter('result_code'), $resHandler->getParameter('err_msg'), null);
else
return new returnObject(502, 502, '签名错误');
}
}
else
return new returnObject(501, $pay->getResponseCode(), $pay->getErrInfo(), null);
}
/**
* 威富通聚合支付--支付宝-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
}
/**
* 汇付宝聚合支付--微信-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_heepay_wechat_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
return new returnObject(500, 500, '请使用微信登录再进行支付!', null);
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_HEEPAY_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
//$openid = $this->userInfo['openid'];
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ]);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/heepaywechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$is_phone = 1; /// 必填 是否使用手机触屏版,1=是(不参加签名)
$is_frame = 1; /// 必填 =0代表在除了微信浏览器之外的浏览器支付(不参加签名)
$pay_type = 30; /// 必填 支付类型30,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = $callback_url; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
/// 微信支付不涉及同步返回,此处可填写任意URL,没有实际使用
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode($title); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = empty(@$attach['remark']) ? JsonObjectToJsonString(['id' => $pay_log['plid'], 'ver' => 1, ]) : $attach['remark']; ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
$meta_option = JsonObjectToJsonString(['s' => 'WAP', 'n' => $this->marketInfo['market_name'], 'id' => $this->getLocaleUrl(), ]); /// 必填 {“s”:”WAP”,”n”:”WAP网站名”,”id”:”WAP网站的首页URL”}(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$pay_code = ''; //char型,空字符串
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
$meta_option = rawurlencode(base64_encode(Characet($meta_option, 'GBK'))); ///
/*************创建签名***************/
$sign_str = '';
$sign_str = $sign_str . 'version=' . $version;
$sign_str = $sign_str . '&agent_id=' . $agent_id;
$sign_str = $sign_str . '&agent_bill_id=' . $agent_bill_id;
$sign_str = $sign_str . '&agent_bill_time=' . $agent_bill_time;
$sign_str = $sign_str . '&pay_type=' . $pay_type;
$sign_str = $sign_str . '&pay_amt=' . $pay_amt;
$sign_str = $sign_str . '¬ify_url=' . $notify_url;
$sign_str = $sign_str . '&return_url=' . $return_url;
$sign_str = $sign_str . '&user_ip=' . $user_ip;
$sign_str = $sign_str . '&key=' . $sign_key;
$sign = md5($sign_str); /// 签名值
$html = <<
EOL;
exit($html);
//return new returnObject(0, 0);
}
/**
* 汇付宝聚合支付--支付宝-线上
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_heepay_ali_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_HEEPAY_ALIPAY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ]);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/heepaywechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$is_phone = 1; /// 必填 是否使用手机触屏版,1=是(不参加签名)
$pay_type = 22; /// 必填 支付类型22,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = $callback_url; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode(Characet($title, 'GBK')); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = empty(@$attach['remark']) ? rawurlencode(Characet(JsonObjectToJsonString(['id' => $pay_log['plid'], 'ver' => 1, ]), 'GBK')) : $attach['remark']; ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
//$meta_option = JsonObjectToJsonString(['s' => 'WAP', 'n' => $this->marketInfo['market_name'], 'id' => $this->getLocaleUrl(), ]); /// 必填 {“s”:”WAP”,”n”:”WAP网站名”,”id”:”WAP网站的首页URL”}(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
//$meta_option = rawurlencode(base64_encode(Characet($meta_option, 'GBK'))); ///
/*************创建签名***************/
//sign=MD5(version=1&agent_id=1234567&agent_bill_id=123456789&agent_bill_time=20170527102250&pay_type=22&pay_amt=0.1¬ify_url=http://xxxxx/test/notify.aspx&return_url=http://xxxxx/test/return.aspx&user_ip=192.168.1.1&key=1234567890)
$sign = "version={$version}&agent_id={$agent_id}&agent_bill_id={$agent_bill_id}&agent_bill_time={$agent_bill_time}&pay_type={$pay_type}&pay_amt={$pay_amt}¬ify_url={$notify_url}&return_url={$return_url}&user_ip={$user_ip}&key={$sign_key}";
$sign = md5($sign); /// 签名值
$html = <<
EOL;
exit($html);
}
/**
* 微信网页支付(非微信环境)
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_wechat_with_browser_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
/// 验证用户登陆方式
//if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
// return new returnObject(500, 500, '请使用微信登录再进行支付!', null);
/// 保存支付记录
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, @$this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_WECHATWITHBROWSER);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/wechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
load()->model('payment');
$wechat = [];
$wechat['appid'] = $this->marketInfo['weixin_appid']; /// 微信公众号APPID
$wechat['secret'] = $this->marketInfo['weixin_secret_appid'];
$wechat['mchid'] = $this->marketInfo['weixin_mchid']; /// 微信公众号商户号
$wechat['signkey'] = $this->marketInfo['weixin_paykey']; /// 支付秘钥
//$openid = $this->userInfo['openid'];
$attach = json_encode(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ], JSON_UNESCAPED_UNICODE);
$tools = new JsApiPay();
/// ②、实例化统一下单对象
$input = new WxPayUnifiedOrder();
$input->SetAppid($wechat['appid']); /// 公众号APPID
$input->SetMch_id($wechat['mchid']); /// 公众号商户ID
//$input->SetPayKey($wechat['signkey']); /// 公众号APPID
//$input->SetSecretId($wechat['secret']); /// 公众号商户ID
$input->SetBody($title); /// 本次支付主题
$input->SetAttach($attach); /// 支付回传的值
$input->SetOut_trade_no($pay_log['out_trade_no']);
$input->SetTotal_fee($fee); /// 微信支付单位为分
$input->SetTime_start(date("YmdHis")); /// 支付发起时间戳
$input->SetTime_expire(date("YmdHis", time() + 600));/// 支付有效期
$input->SetGoods_tag("");
$input->SetNotify_url($notify_url);
//$input->SetTrade_type("JSAPI");
$input->SetTrade_type("MWEB"); /// H5支付的交易类型为MWEB
//$input->SetOpenid($pay_log['openid']); /// 这里要注释掉
$input->SetSceneInfo(
JsonObjectToJsonString(
[
'h5_info' => [
'type' => 'Wap', /// 场景类型
//'wap_url' => $this->getLocaleUrl(), /// WAP网站URL地址
'wap_url' => $callback_url,
'wap_name' => '商娱支付', /// WAP 网站名
],
]
)
);
try
{
$order = WxPayApi::unifiedOrder($input, 6, $wechat); /// 提交统一订单
}
catch (Exception $e)
{
if (isset($order['return_msg']))
echo $order['return_msg'], '
';
exit($e->getMessage());
}
/// $wOpt = wechat_build($params, $wechat);
// $jsApiParameters = $tools->GetJsApiParameters($order, $wechat);
//
// if (is_error($jsApiParameters))
// {
// /*
// if ($jsApiParameters['message'] == 'invalid out_trade_no' || $jsApiParameters['message'] == 'OUT_TRADE_NO_USED')
// {
// $id = date('YmdH');
// pdo_update('syweb_core_paylog', ['plid' => $id), array('plid' => $log['plid'], ]);
// pdo_query("ALTER TABLE " . tablename('syweb_core_paylog') . " auto_increment = " . ($id + 1) . ";");
// exit('抱歉,发起支付失败,系统已经修复此问题,请重新尝试支付。');
// }
// */
// exit("抱歉,发起支付失败,具体原因为:“{$jsApiParameters['errno']}:{$jsApiParameters['message']}”。请及时联系站点管理员。");
// }
//
// $htmlContent = <<
// function jsApiCall() {
// WeixinJSBridge.invoke(
// 'getBrandWCPayRequest',
// {$jsApiParameters},
// function(res) {
// if ('get_brand_wcpay_request:ok' == res.err_msg) { /// 支付成功
// window.location.href="{$callback_url}";
// } else if ('get_brand_wcpay_request:cancel' == res.err_msg) { /// 用户取消
// //alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
// history.go(-1);
// } else { /// 其他错误
// //alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
// history.go(-1);
// }
// }
// );
// }
//
// if (typeof WeixinJSBridge == "undefined") {
// if (document.addEventListener) {
// document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
// } else if (document.attachEvent) {
// document.attachEvent('WeixinJSBridgeReady', jsApiCall);
// document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
// }
// } else {
// jsApiCall();
// }
//
//EOF;
// exit($htmlContent);
if (strcasecmp($order['return_code'], NOTIFYSTATUS_SUCCESS))
die($order['return_msg']);
elseif(strcasecmp($order['result_code'], NOTIFYSTATUS_SUCCESS))
die($order['err_code_des']);
else
{
$htmlContent = <<
window.location.href="{$order['mweb_url']}";
EOL;
die($htmlContent);
}
}
/**
* 汇付宝聚合支付--微信-线上(非微信环境)
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_heepay_wechat_with_browser_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_HEEPAY_WECHATWITHBROWSER);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ]);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/heepaywechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$is_phone = 1; /// 必填 是否使用手机触屏版,1=是(不参加签名)
$is_frame = 0; /// 必填 =0代表在除了微信浏览器之外的浏览器支付(不参加签名)
$pay_type = 30; /// 必填 支付类型30,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = $callback_url; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
/// 微信支付不涉及同步返回,此处可填写任意URL,没有实际使用
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode(Characet($title, 'GBK')); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = empty(@$attach['remark']) ? rawurlencode(Characet(JsonObjectToJsonString(['id' => $pay_log['plid'], 'ver' => 1, ]), 'GBK')) : $attach['remark']; ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
$meta_option = JsonObjectToJsonString(['s' => 'WAP', 'n' => $this->marketInfo['market_name'], 'id' => $this->getLocaleUrl(), ]); /// 必填 {“s”:”WAP”,”n”:”WAP网站名”,”id”:”WAP网站的首页URL”}(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$pay_code = ''; //char型,空字符串
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
$meta_option = rawurlencode(base64_encode(Characet($meta_option, 'GBK'))); ///
/*************创建签名***************/
$sign_str = '';
$sign_str = $sign_str . 'version=' . $version;
$sign_str = $sign_str . '&agent_id=' . $agent_id;
$sign_str = $sign_str . '&agent_bill_id=' . $agent_bill_id;
$sign_str = $sign_str . '&agent_bill_time=' . $agent_bill_time;
$sign_str = $sign_str . '&pay_type=' . $pay_type;
$sign_str = $sign_str . '&pay_amt=' . $pay_amt;
$sign_str = $sign_str . '¬ify_url=' . $notify_url;
$sign_str = $sign_str . '&return_url=' . $return_url;
$sign_str = $sign_str . '&user_ip=' . $user_ip;
$sign_str = $sign_str . '&key=' . $sign_key;
$sign = md5($sign_str); /// 签名值
/*
$html = <<
EOL;
exit($html);
*/
$Params = [
'version' => $version,
'agent_id' => $agent_id,
'agent_bill_id' => $agent_bill_id,
'agent_bill_time' => $agent_bill_time,
'pay_type' => $pay_type,
'pay_code' => $pay_code,
'pay_amt' => $pay_amt,
'notify_url' => $notify_url,
'return_url' => $return_url,
'user_ip' => $user_ip,
'goods_name' => $goods_name,
'goods_num' => $goods_num,
'goods_note' => $goods_note,
'meta_option' => $meta_option,
'remark' => $remark,
'is_phone' => $is_phone,
'is_frame' => $is_frame,
'sign' => $sign,
];
$FormParam = '';
$LinkParam = '';
foreach ($Params as $Key => $Value)
{
$FormParam .= "\r\n";
$LinkParam .= "{$Key}={$Value}&";
}
$LinkParam = substr($LinkParam, 0, strlen($LinkParam) - strlen('&'));
$Form = <<
{$FormParam}
EOL;
$Link = <<
window.onload = function() {
try {
if ('undefined' != typeof window.settings)
window.settings.loadurl('{$Link}');
else
document.frmpay.submit();
} catch(err) {
//alert(err.message);
document.frmpay.submit();
}
}
EOL;
//$Html = "";
exit($Html);
//return new returnObject(0, 0);
}
/**
* 汇付宝聚合支付--银联支付
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_heepay_unionpay_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_HEEPAY_UNIONPAY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(['app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1, ]);
$notify_url = $this->getFullUrl('/api/newpay/notify/online/heepaywechatpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$pay_type = 19; /// 必填 支付类型19,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = $callback_url; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
/// 微信支付不涉及同步返回,此处可填写任意URL,没有实际使用
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode(Characet($title, 'GBK')); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = empty(@$attach['remark']) ? rawurlencode(Characet(JsonObjectToJsonString(['id' => $pay_log['plid'], 'ver' => 1, ]), 'GBK')) : $attach['remark']; ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
$meta_option = JsonObjectToJsonString(['s' => 'WAP', 'n' => $this->marketInfo['market_name'], 'id' => $this->getLocaleUrl(), ]); /// 必填 {“s”:”WAP”,”n”:”WAP网站名”,”id”:”WAP网站的首页URL”}(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$pay_code = ''; //char型,空字符串
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
$meta_option = rawurlencode(base64_encode(Characet($meta_option, 'GBK'))); ///
/*************创建签名***************/
$sign_str = '';
$sign_str = $sign_str . 'version=' . $version;
$sign_str = $sign_str . '&agent_id=' . $agent_id;
$sign_str = $sign_str . '&agent_bill_id=' . $agent_bill_id;
$sign_str = $sign_str . '&agent_bill_time=' . $agent_bill_time;
$sign_str = $sign_str . '&pay_type=' . $pay_type;
$sign_str = $sign_str . '&pay_amt=' . $pay_amt;
$sign_str = $sign_str . '¬ify_url=' . $notify_url;
$sign_str = $sign_str . '&return_url=' . $return_url;
$sign_str = $sign_str . '&user_ip=' . $user_ip;
$sign_str = $sign_str . '&key=' . $sign_key;
$sign = md5($sign_str); /// 签名值
$html = <<
EOL;
exit($html);
// $Params = [
// 'version' => $version,
// 'agent_id' => $agent_id,
// 'agent_bill_id' => $agent_bill_id,
// 'agent_bill_time' => $agent_bill_time,
// 'pay_type' => $pay_type,
// 'pay_code' => $pay_code,
// 'pay_amt' => $pay_amt,
// 'notify_url' => $notify_url,
// 'return_url' => $return_url,
// 'user_ip' => $user_ip,
// 'goods_name' => $goods_name,
// 'goods_num' => $goods_num,
// 'goods_note' => $goods_note,
// 'meta_option' => $meta_option,
// 'remark' => $remark,
// 'sign' => $sign,
// ];
//
// $FormParam = '';
// $LinkParam = '';
// foreach ($Params as $Key => $Value)
// {
// $FormParam .= "\r\n";
// $LinkParam .= "{$Key}={$Value}&";
// }
//
// $LinkParam = substr($LinkParam, 0, strlen($LinkParam) - strlen('&'));
//
// $Form = <<
//{$FormParam}
//
//EOL;
//
// $Link = <<
// window.onload = function() {
// try {
// if ('undefined' != typeof window.settings)
// window.settings.loadurl('{$Link}');
// else
// document.frmpay.submit();
// } catch(err) {
// //alert(err.message);
// document.frmpay.submit();
// }
// }
//
//EOL;
// exit($html);
}
/**
* 爱呗支付--pc网页
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_ipay_pc_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_IPAY_PC);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
/// 应用编号
//$appid = '3019229652';
$appid = $this->marketInfo['ipay_mchid'];
/// 应用私钥
//$appkey = 'MIICXQIBAAKBgQCi4cy1Xqt8aOPLANjeY2jFPHMNJP0PNns9X662Oye8I4ApOlLC16b30aRBaKpCwIiWlbREBsVsmIEK8n50wc+49CrHXV6P8btA0fKvd/EDmRP8AdHk6F9ze/iwHQM2+Yj0BqsWgUCwOwKdIWtEQqPqavH7/lPdxaJXri3zl6rMXwIDAQABAoGAI+GD++xH8JcWnzCnlY3mlZR0b8/XI1PIIEQEs8YiQbK8V9iuRJfHA06eVX5eC2hobmu6E0Y+lWae/q9epg/P1z7MdFUEwdW2OoDorl7Yf4xtLe2t1LcIZ+9Zvx/49mPNVpVmNEzR73glH5jMQ2tvvGHe3EOn4xkxZFPW/32IuZkCQQDo0kW/s6V7z7JXTqrWCFxo9KbQCKmZNRFKEVTeoUrowrGMrhPWabaMbN5NbvfqVn8fbdt0VcMptOmWPTSlIIbNAkEAsxkKVzK/SsbLOim/4BSNEdu7Nd5lnue6jxMO0qPYFeLa2qaAEbM9YdRTtYqzqHwX8Vx5uRGmMhfIeHN6ywdn2wJBAKXxEWOkcIOBstRFrr/kr7DjB25pbjBTwaHwHnSbs5+Y/SGPBXaiXElUY1H/kNZGlk7ZZzxQ0EyOtJqvvzEesNUCQF6+yneiwwvd6rkUSQtUE+T0py8yPfQ4hrsVy+um/bNmVX0CRBIZDknot3f8rlpde5UV5NcA/TjW2BjQjo9Fla0CQQDUqVtXDDt/10s/8mWDKkZIVwDdsYHBC1E+FEw2CQMB/yOT4ve/cmPzbH26ysbqnZoaZelbetwLVe5avYeL0Nh5';
$appkey = file_get_contents(dirname(dirname(__DIR__)) . "/payment/ipay/key/{$appid}/private.txt");
/// 平台公钥
//$platpkey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIouv++6h+CL/kGDxldXMqb92a3/tszmPzGZ4DkwZhNAkOxLuOTWkYaw5+TGktxnNsjU6YJvC88vH3pYsnmHvCheJnEmj3GNamjig5c7QrzeCgBG974SbIrF7iY/tsdE6YQPfw+Q0oVf+sfFk61wPToQPcQgsJw7tYQrFC+jqe9QIDAQAB';
$platpkey = file_get_contents(dirname(dirname(__DIR__)) . "/payment/ipay/key/{$appid}/public.txt");
/// 订单提交地址
$order_url = 'https://cp.iapppay.com/payapi/order';
//$order_url = 'http://ipay.iapppay.com:9999/payapi/order';
$notify_url = $this->getFullUrl('/api/newpay/notify/online/ipaypcpay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
$order_info = [
'appid' => $appid, /// 平台分配的应用编号
'waresid' => 1, /// 应用中的商品编号
'waresname' => $title, /// 商品名称,对于消费型_应用传入价格的计费方式有效,如果不传则展示后台设置的商品名称
'cporderid' => $pay_log['out_trade_no'], /// 商户生成的订单号,需要保证系统唯一
'price' => $fee / 100, /// 支付金额,对于消费型_应用传入价格的计费方式有效,其它计费方式不需要传入本参数
'currency' => 'RMB', /// 货币类型以及单位:RMB – 人民币(单位:元)
'appuserid' => $this->sid, /// 用户在商户应用的唯一标识,建议为用户帐号。对于游戏,需要区分到不同区服,#号分隔;比如游戏帐号abc在01区,则传入“abc#01”
'cpprivateinfo' => $pay_log['plid'], /// 商户私有信息,支付完成后发送支付结果通知时会透传给商户
'notifyurl' => $notify_url, /// 商户服务端接收支付结果通知的地址
];
/// 组装请求报文,对数据签名
$data = composeReq($order_info, $appkey);
//echo $data, '
', PHP_EOL;
/// 发送到爱贝服务后台请求下单
$resp = request_by_curl($order_url, $data, 'send order');
//echo $resp, '
', PHP_EOL;
/// 验签数据并且解析返回报文
if (!parseResp($resp, $platpkey, $json)) {
if (isset($json->code))
return new returnObject(1, @$json->code, @$json->errmsg, null);
else
return new returnObject(1, 500, 'failed');
}
$transid = $json->transid; /// 交易单号
$order_info = [
'tid' => $transid, /// 向收银台服务端下单获取的交易流水号(transid)
'app' => $appid, /// 应用编号,商户在收银台注册的应用编号。可在商户自服务平台查询
///'acid' => '', /// 分销商渠道编号,字符长度<=16。非自定义,需后台申请(https://www.iapppay.com/g-chafunc.html);不使用爱贝分渠道功能则不填。
'url_r' => $callback_url, /// 用户支付完成后的网页端跳转地址。带有支付结果通知数据。最大长度512
'url_h' => $_SERVER['HTTP_REFERER'], /// 用户放弃支付后网页端跳转地址。最大长度512
];
/// 组装请求报文,对数据签名
$data = h5composeReq($order_info, $appkey);
$url = 'https://web.iapppay.com/pay/gateway?' . $data;
$html = <<
window.location.href = "$url";
EOL;
die($html);
}
/**
* 躺倒鸭在线支付
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param string $return_url 回调地址(同步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_online_tdy_v1($orderid, $fee, $title, $notice_url, $return_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, $return_url, $attach, PAYTYPE_ONLINE_TDY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$app_id = $this->marketInfo['tdy_app_id']; /// appid
$app_key = $this->marketInfo['tdy_app_key']; /// appkey
$tdy_id = @$attach['tdyid']; /// 躺倒鸭侧用户唯一ID
$tdy_token = @$attach['tdytoken']; /// 躺倒鸭会话ID
$url = 'https://youxiapi.tangdaoya.com/exchange/v1/trade/prepayment'; /// 接口地址
$notify_url = $this->getFullUrl('/api/newpay/notify/online/tdypay'); /// 异步通知地址
$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
//https://api.tscce.cn/api/newpay/notify/online/tdypay
//https://api.tscce.cn/api/newpay/callback/v1?plid=48856
//echo $notify_url,'
', $callback_url, '
';
/// 获取微秒
list($m, $s) = explode(' ', microtime());
/// 转成浮点数
$m = floatval($m);
$s = floatval($s);
$ts = round(($s + $m) * 1000); /// 毫秒
$order_id = $pay_log['out_trade_no']; /// 订单号
$sign = mb_strtolower(md5("{$app_id}{$order_id}{$ts}{$app_key}"), USEDCHARSET);
$attach = json_encode(
[
'app_id' => $this->appid,
'market_key' => $this->market_key,
'buyer_id' => $tdy_id,
'version' => 1,
],
JSON_UNESCAPED_UNICODE);
$data = [
'appid' => $app_id, /// 躺倒鸭分配给CP/SP的应用ID
'tdyid' => $tdy_id, /// 躺倒鸭侧用户唯一ID
'tdytoken' => $tdy_token, /// 躺倒鸭会话ID
'order_id' => $order_id, /// CP/SP侧生成的订单ID,必须唯一
'order_name' => $title, /// 订单名称,将显示给用户(不要包含游戏名称,躺倒鸭会显示游戏 名称及logo,正确举例如下:“充值100元宝”)
'amount' => $fee, /// 订单价格,单位分,必须大于0
'ts' => $ts, /// 时间戳,精确到毫秒,躺倒鸭会校验有效性,5分钟内有效
'sign' => $sign, /// 签名字符串,32位小写md5,参见《附录2:交易参数签名方式》
'data' => $attach, /// CP/SP自定义的订单附加信息。躺倒鸭回调时会原样返回
];
$ret = SendPost($url, $data);
if (is_string($ret)) {
$ret = JsonStringToJsonObject($ret);
}
if (!isset($ret->code)) {
return new returnObject(1, 500, '预下单出错!', [
'result' => false,
'message' => '预下单出错!',
]);
} elseif (0 != strcmp('0', $ret->code)) {
return new returnObject(1, $ret->code, @$ret->msg, [
'result' => false,
'message' => @$ret->msg,
]);
} elseif (empty(@$ret->prepay_id)) {
return new returnObject(1, $ret->code, '未知错误!', [
'result' => false,
'message' => '未知错误!',
]);
} else {
return new returnObject(0, 0, 'success', [
'result' => true,
'prepay_id' => $ret->prepay_id,
]);
// $html = <<
//
//
//
//
//