4337 lines
185 KiB
Plaintext
4337 lines
185 KiB
Plaintext
<?php
|
||
header("Access-Control-Allow-Origin: *");
|
||
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE");
|
||
header("Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With");
|
||
header("Access-Control-Allow-Credentials: true");
|
||
header("Content-Type: text/html; charset=utf-8");
|
||
|
||
|
||
use phprs\util\Verify;
|
||
use phprs\util\exceptions\Forbidden;
|
||
use phprs\util\Logger;
|
||
use phprs\util\exceptions\NotFound;
|
||
use phprs\ezsql\Sql;
|
||
use phprs\util\exceptions\BadRequest;
|
||
|
||
require_once 'apiBase.php';
|
||
require_once '../../payment/wechat/lib/WxPay.Api.php';
|
||
require_once '../../payment/wechat/WxPay.JsApiPay.php';
|
||
require_once '../../payment/wechat/WxPay.NativePay.php';
|
||
require_once '../../payment/wechat/WxPay.AppPay.php';
|
||
require_once '../../payment/wechat/log.php';
|
||
require_once '../../payment/wechat/notify.php';
|
||
|
||
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/wappay/service/AlipayTradeService.php';
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/wappay/buildermodel/AlipayTradeWapPayContentBuilder.php';
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/wappay/buildermodel/alipaytraderefundcontentbuilder.php';
|
||
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/f2fpay/service/AlipayTradeService.php';
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/f2fpay/model/builder/AlipayTradePrecreateContentBuilder.php';
|
||
require_once dirname(dirname(__DIR__)) . '/payment/alipay/f2fpay/model/builder/alipaytraderefundcontentbuilder.php';
|
||
//require_once dirname(dirname(__DIR__)) . '/payment/alipay/aop/aopclient.php';
|
||
|
||
|
||
require_once '../../payment/swiftpass/utils.class.php';
|
||
require_once '../../payment/swiftpass/class/RequestHandler.class.php';
|
||
require_once '../../payment/swiftpass/class/ClientResponseHandler.class.php';
|
||
require_once '../../payment/swiftpass/class/PayHttpClient.class.php';
|
||
|
||
/// 未知的支付方式(线上网页支付)
|
||
define('PAYCODE_ONLINE_UNKNOWN', 0);
|
||
/// 微信支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_WECHAT', 1);
|
||
/// 支付宝支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_ALIPAY', 2);
|
||
/// 威富通微信支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_SWIFTPASS_WECHAT', 3);
|
||
/// 威富通支付宝支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_SWIFTPASS_ALIPAY', 4);
|
||
/// 汇付宝微信支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_HEEPAY_WECHAT', 5);
|
||
/// 汇付宝支付宝支付(线上网页支付)
|
||
define('PAYCODE_ONLINE_HEEPAY_ALIPAY', 6);
|
||
/// 微信支付(线上网页支付)(非微信环境)
|
||
define('PAYCODE_ONLINE_WECHATWITHBROWSER', 7);
|
||
/// 汇付宝微信支付(线上网页支付)(非微信环境)
|
||
define('PAYCODE_ONLINE_HEEPAY_WECHATWITHBROWSER', 8);
|
||
|
||
|
||
/// 未知的支付方式(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_UNKNOWN', 100);
|
||
/// 微信支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_WECHAT', 101);
|
||
/// 支付宝支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_ALIPAY', 102);
|
||
/// 威富通微信支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_SWIFTPASS_WECHAT', 103);
|
||
/// 威富通支付宝支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_SWIFTPASS_ALIPAY', 104);
|
||
/// 汇付宝微信支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_HEEPAY_WECHAT', 105);
|
||
/// 汇付宝支付宝支付(线下扫码支付)
|
||
define('PAYCODE_OFFLINE_HEEPAY_ALIPAY', 106);
|
||
|
||
|
||
/// 未知的支付方式(移动平台支付)
|
||
define('PAYCODE_MOBILE_UNKNOWN', 200);
|
||
/// 微信支付(移动平台支付)
|
||
define('PAYCODE_MOBILE_WECHAT', 201);
|
||
/// 支付宝支付(移动平台支付)
|
||
define('PAYCODE_MOBILE_ALIPAY', 202);
|
||
/// 威富通微信支付(移动平台支付)
|
||
define('PAYCODE_MOBILE_SWIFTPASS_WECHAT', 203);
|
||
/// 威富通支付宝支付(移动平台支付)
|
||
define('PAYCODE_MOBILE_SWIFTPASS_ALIPAY', 204);
|
||
|
||
|
||
/// 微信支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_WECHAT', 'wechat_online');
|
||
/// 支付宝支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_ALIPAY', 'alipay_online');
|
||
/// 威富通微信支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_SWIFTPASS_WECHAT', 'swiftpass_wechat_online');
|
||
/// 威富通支付宝支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_SWIFTPASS_ALIPAY', 'swiftpass_alipay_online');
|
||
/// 汇付宝微信支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_HEEPAY_WECHAT', 'heepay_wechat_online');
|
||
/// 汇付宝支付宝支付(线上网页支付)
|
||
define('PAYTYPE_ONLINE_HEEPAY_ALIPAY', 'heepay_alipay_online');
|
||
/// 微信支付(线上网页支付)(非微信环境)
|
||
define('PAYTYPE_ONLINE_WECHATWITHBROWSER', 'wechat_browser_online');
|
||
/// 汇付宝微信支付(线上网页支付)(非微信环境)
|
||
define('PAYTYPE_ONLINE_HEEPAY_WECHATWITHBROWSER', 'heepay_browser_online');
|
||
|
||
|
||
/// 微信支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_WECHAT', 'wechat_offline');
|
||
/// 支付宝支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_ALIPAY', 'alipay_offline');
|
||
/// 威富通微信支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_SWIFTPASS_WECHAT', 'swiftpass_wechat_offline');
|
||
/// 威富通支付宝支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_SWIFTPASS_ALIPAY', 'swiftpass_alipay_offline');
|
||
/// 汇付宝微信支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_HEEPAY_WECHAT', 'heepay_wechat_offline');
|
||
/// 汇付宝支付宝支付(线下扫码支付)
|
||
define('PAYTYPE_OFFLINE_HEEPAY_ALIPAY', 'heepay_alipay_offline');
|
||
|
||
|
||
/// 微信支付(移动平台支付)
|
||
define('PAYTYPE_MOBILE_WECHAT', 'wechat_mobile');
|
||
/// 支付宝支付(移动平台支付)
|
||
define('PAYTYPE_MOBILE_ALIPAY', 'alipay_mobile');
|
||
/// 威富通微信支付(移动平台支付)
|
||
define('PAYTYPE_MOBILE_SWIFTPASS_WECHAT', 'swiftpass_wechat_mobile');
|
||
/// 威富通支付宝支付(移动平台支付)
|
||
define('PAYTYPE_MOBILE_SWIFTPASS_ALIPAY', 'swiftpass_alipay_mobile');
|
||
|
||
|
||
/// 支付状态(未支付)
|
||
define('PAYSTATUS_NORMAL', 0);
|
||
/// 支付状态(已支付)
|
||
define('PAYSTATUS_PAY', 1);
|
||
/// 支付状态(已退款)
|
||
define('PAYSTATUS_REFUND', -1);
|
||
|
||
|
||
|
||
/// 通知结果(成功)
|
||
define('NOTIFYSTATUS_SUCCESS', 'success');
|
||
define('NOTIFYSTATUS_ERROR', 'error');
|
||
define('NOTIFYSTATUS_FAIL', 'fail');
|
||
|
||
|
||
/**
|
||
*
|
||
* 支付管理
|
||
* @path("/newpay")
|
||
*/
|
||
class newpay extends apiBase
|
||
{
|
||
/**
|
||
* 支付完成回调到客户端(同步回调页面)
|
||
* @route({"GET","/test"})
|
||
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
|
||
*/
|
||
public function test()
|
||
{
|
||
echo $this->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;
|
||
}
|
||
else
|
||
{
|
||
$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);
|
||
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_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 = array(
|
||
'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 = array(
|
||
'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 = array(
|
||
'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 = array(
|
||
'status' => PAYSTATUS_PAY,
|
||
'transaction_id' => $trade_no,
|
||
///'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))
|
||
{
|
||
/// 获取附带的参数
|
||
$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 = array(
|
||
'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;
|
||
}
|
||
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, '找不到的商户信息。');
|
||
|
||
$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}!");
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 微信支付 异步回调用页面
|
||
* @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;
|
||
$sign_str = '';
|
||
if (isset($param['sign']))
|
||
{
|
||
unset($param['sign']);
|
||
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
|
||
}
|
||
|
||
if ($sign_str != $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(array('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;
|
||
$sign_str = '';
|
||
if (isset($param['sign']))
|
||
{
|
||
unset($param['sign']);
|
||
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
|
||
}
|
||
|
||
if ($sign_str != $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(array('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;
|
||
$sign_str = '';
|
||
if (isset($param['sign']))
|
||
{
|
||
unset($param['sign']);
|
||
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
|
||
}
|
||
|
||
if ($sign_str != $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(array('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;
|
||
$sign_str = '';
|
||
if (isset($param['sign']))
|
||
{
|
||
unset($param['sign']);
|
||
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
|
||
}
|
||
if ($sign_str != $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']);
|
||
$refund_safe_domain1 = $refund_safe_domain->refund_safe_domain1;
|
||
$refund_safe_domain2 = $refund_safe_domain->refund_safe_domain2;
|
||
$refund_safe_domain3 = $refund_safe_domain->refund_safe_domain3;
|
||
|
||
$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 ($refund_safe_domain1 != $referer_domain && $refund_safe_domain2 != $referer_domain && $refund_safe_domain3 != $referer_domain && $local_domain != $referer_domain)
|
||
return new returnObject(500, 13006, '不是安全的域名。', $referer_domain);
|
||
}
|
||
|
||
$attach = GetAttachParameters(array('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 = array();
|
||
$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 = array();
|
||
$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 = array();
|
||
$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(array('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'], '<br>';
|
||
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', array('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 = <<<EOF
|
||
<script type="text/javascript">
|
||
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();
|
||
}
|
||
</script>
|
||
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(array('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(array('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, array('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 = <<<EOF
|
||
<script type="text/javascript">
|
||
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();
|
||
}
|
||
</script>
|
||
EOF;
|
||
*/
|
||
$htmlContent = <<<EOF
|
||
<script>
|
||
window.location.href="https://pay.swiftpass.cn/pay/jspay?token_id={$resHandler->getParameter('token_id')}&showwxtitle=1";
|
||
</script>
|
||
EOF;
|
||
die($htmlContent);
|
||
//return new returnObject(0, 0, '', array('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(array('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(array('id' => $pay_log['plid'], 'ver' => 1,)) : $attach['remark']; ///
|
||
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
|
||
$meta_option = JsonObjectToJsonString(array('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
|
||
<form style="display:none;" id='frmpay' method='post' name='frmpay' action='https://pay.Heepay.com/Payment/Index.aspx'>
|
||
<input type='hidden' name='version' value='{$version}' />
|
||
<input type='hidden' name='agent_id' value='{$agent_id}' />
|
||
<input type='hidden' name='agent_bill_id' value='{$agent_bill_id}' />
|
||
<input type='hidden' name='agent_bill_time' value='{$agent_bill_time}' />
|
||
<input type='hidden' name='pay_type' value='{$pay_type}' />
|
||
<input type='hidden' name='pay_code' value='{$pay_code}' />
|
||
<input type='hidden' name='pay_amt' value='{$pay_amt}' />
|
||
<input type='hidden' name='notify_url' value='{$notify_url}' />
|
||
<input type='hidden' name='return_url' value='{$return_url}' />
|
||
<input type='hidden' name='user_ip' value='{$user_ip}' />
|
||
<input type='hidden' name='goods_name' value='{$goods_name}' />
|
||
<input type='hidden' name='goods_num' value='{$goods_num}' />
|
||
<input type='hidden' name='goods_note' value='{$goods_note}' />
|
||
<input type='hidden' name='meta_option' value='{$meta_option}' />
|
||
<input type='hidden' name='remark' value='{$remark}' />
|
||
<input type='hidden' name='is_phone' value='{$is_phone}' />
|
||
<input type='hidden' name='is_frame' value='{$is_frame}' />
|
||
<input type='hidden' name='sign' value='{$sign}' />
|
||
</form>
|
||
|
||
<script>
|
||
document.frmpay.submit();
|
||
</script>
|
||
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(array('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(array('id' => $pay_log['plid'], 'ver' => 1,)), 'GBK')) : $attach['remark']; ///
|
||
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
|
||
//$meta_option = JsonObjectToJsonString(array('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
|
||
<form style="display:none;" id='frmpay' method='post' name='frmpay' action='https://pay.Heepay.com/Payment/Index.aspx'>
|
||
<input type='hidden' name='version' value='{$version}' />
|
||
<input type='hidden' name='agent_id' value='{$agent_id}' />
|
||
<input type='hidden' name='agent_bill_id' value='{$agent_bill_id}' />
|
||
<input type='hidden' name='agent_bill_time' value='{$agent_bill_time}' />
|
||
<input type='hidden' name='pay_type' value='{$pay_type}' />
|
||
<input type='hidden' name='pay_amt' value='{$pay_amt}' />
|
||
<input type='hidden' name='notify_url' value='{$notify_url}' />
|
||
<input type='hidden' name='return_url' value='{$return_url}' />
|
||
<input type='hidden' name='user_ip' value='{$user_ip}' />
|
||
<input type='hidden' name='goods_name' value='{$goods_name}' />
|
||
<input type='hidden' name='goods_num' value='{$goods_num}' />
|
||
<input type='hidden' name='goods_note' value='{$goods_note}' />
|
||
<input type='hidden' name='remark' value='{$remark}' />
|
||
<input type='hidden' name='is_phone' value='{$is_phone}' />
|
||
<input type='hidden' name='sign' value='{$sign}' />
|
||
</form>
|
||
|
||
<script>
|
||
document.frmpay.submit();
|
||
</script>
|
||
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 = array();
|
||
$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(array('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(
|
||
array(
|
||
'h5_info' => array(
|
||
'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'], '<br>';
|
||
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', array('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 = <<<EOF
|
||
//<script type="text/javascript">
|
||
// 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();
|
||
// }
|
||
//</script>
|
||
//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 = <<<EOL
|
||
<script type="text/javascript">
|
||
window.location.href="{$order['mweb_url']}";
|
||
</script>
|
||
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(array('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(array('id' => $pay_log['plid'], 'ver' => 1,)), 'GBK')) : $attach['remark']; ///
|
||
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
|
||
$meta_option = JsonObjectToJsonString(array('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
|
||
<form style="display:none;" id='frmpay' method='post' name='frmpay' action='https://pay.Heepay.com/Payment/Index.aspx'>
|
||
<input type='hidden' name='version' value='{$version}' />
|
||
<input type='hidden' name='agent_id' value='{$agent_id}' />
|
||
<input type='hidden' name='agent_bill_id' value='{$agent_bill_id}' />
|
||
<input type='hidden' name='agent_bill_time' value='{$agent_bill_time}' />
|
||
<input type='hidden' name='pay_type' value='{$pay_type}' />
|
||
<input type='hidden' name='pay_code' value='{$pay_code}' />
|
||
<input type='hidden' name='pay_amt' value='{$pay_amt}' />
|
||
<input type='hidden' name='notify_url' value='{$notify_url}' />
|
||
<input type='hidden' name='return_url' value='{$return_url}' />
|
||
<input type='hidden' name='user_ip' value='{$user_ip}' />
|
||
<input type='hidden' name='goods_name' value='{$goods_name}' />
|
||
<input type='hidden' name='goods_num' value='{$goods_num}' />
|
||
<input type='hidden' name='goods_note' value='{$goods_note}' />
|
||
<input type='hidden' name='meta_option' value='{$meta_option}' />
|
||
<input type='hidden' name='remark' value='{$remark}' />
|
||
<input type='hidden' name='is_phone' value='{$is_phone}' />
|
||
<input type='hidden' name='is_frame' value='{$is_frame}' />
|
||
<input type='hidden' name='sign' value='{$sign}' />
|
||
</form>
|
||
|
||
<script>
|
||
document.frmpay.submit();
|
||
</script>
|
||
EOL;
|
||
exit($html);
|
||
*/
|
||
$Params = array(
|
||
'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 .= "<input type='hidden' name='{$Key}' value='{$Value}' />\r\n";
|
||
$LinkParam .= "{$Key}={$Value}&";
|
||
}
|
||
|
||
$LinkParam = substr($LinkParam, 0, strlen($LinkParam) - strlen('&'));
|
||
|
||
$Form = <<<EOL
|
||
<form style="display:none;" id='frmpay' method='post' name='frmpay' action='https://pay.Heepay.com/Payment/Index.aspx'>
|
||
{$FormParam}
|
||
</form>
|
||
EOL;
|
||
|
||
$Link = <<<EOL
|
||
https://pay.Heepay.com/Payment/Index.aspx?{$LinkParam}
|
||
EOL;
|
||
|
||
$Html = <<<EOL
|
||
{$Form}
|
||
|
||
<script>
|
||
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();
|
||
}
|
||
}
|
||
</script>
|
||
EOL;
|
||
|
||
//$Html = "<script language='JavaScript'>\r\n window.location.href='{$Link}';\r\n</script>";
|
||
exit($Html);
|
||
//return new returnObject(0, 0);
|
||
}
|
||
|
||
|
||
/**
|
||
* 微信支付-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '',
|
||
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_WECHAT);
|
||
if (!$pay_log)
|
||
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
/// 附加参数
|
||
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
|
||
/// 异步通知地址
|
||
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/wechatpay');
|
||
|
||
$wechat = array(
|
||
'appid' => $this->marketInfo['weixin_appid'], /// 微信公众号APPID
|
||
'secret' => $this->marketInfo['weixin_secret_appid'],
|
||
'mchid' => $this->marketInfo['weixin_mchid'], /// 微信公众号商户号
|
||
'signkey' => $this->marketInfo['weixin_paykey'], /// 支付秘钥
|
||
);
|
||
|
||
/**
|
||
* 流程:
|
||
* 1、调用统一下单,取得code_url,生成二维码
|
||
* 2、用户扫描二维码,进行支付
|
||
* 3、支付完成之后,微信服务器会通知支付成功
|
||
* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
|
||
*/
|
||
$notify = new NativePay();
|
||
$input = new WxPayUnifiedOrder();
|
||
$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('NATIVE'); /// 交易类型
|
||
$input->SetProduct_id($title); /// 商品ID(trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。)
|
||
$result = $notify->GetPayUrl($input, $wechat);
|
||
///$url2 = $result['code_url'];
|
||
|
||
return new returnObject(0, 0, '', array(
|
||
'code_img_url' => 'http://paysdk.weixin.qq.com/example/qrcode.php?data=' . rawurlencode($result['code_url']),
|
||
'code_url' => rawurlencode($result['code_url']),
|
||
));
|
||
}
|
||
|
||
|
||
/**
|
||
* 支付宝支付-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_ali_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '',
|
||
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_ALIPAY);
|
||
if (!$pay_log)
|
||
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
$alipay_appid = $this->marketInfo['alipay_appid'];
|
||
|
||
/// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),系统商开发使用,详情请咨询支付宝技术支持
|
||
$providerId = ''; //系统商pid,作为系统商返佣数据提取的依据
|
||
$extendParams = new ExtendParams();
|
||
$extendParams->setSysServiceProviderId($providerId);
|
||
$extendParamsArr = $extendParams->getExtendParams();
|
||
|
||
// 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail
|
||
$goods1 = new GoodsDetail();
|
||
$goods1->setGoodsId("apple-01");
|
||
$goods1->setGoodsName("iphone");
|
||
$goods1->setPrice(3000);
|
||
$goods1->setQuantity(1);
|
||
//得到商品1明细数组
|
||
$goods1Arr = $goods1->getGoodsDetail();
|
||
|
||
/// 继续创建并添加第一条商品信息,用户购买的产品为“xx牙刷”,单价为5.05元,购买了两件
|
||
$goods2 = new GoodsDetail();
|
||
$goods2->setGoodsId("apple-02");
|
||
$goods2->setGoodsName("ipad");
|
||
$goods2->setPrice(1000);
|
||
$goods2->setQuantity(1);
|
||
/// 得到商品1明细数组
|
||
$goods2Arr = $goods2->getGoodsDetail();
|
||
|
||
/// 商品明细列表,需填写购买商品详细信息,
|
||
$goodsDetailList = array($goods1Arr,$goods2Arr);
|
||
|
||
/// 附加参数
|
||
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
|
||
/// 异步通知地址
|
||
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/alipay');
|
||
|
||
/// 创建请求builder,设置请求参数
|
||
$qrPayRequestBuilder = new AlipayTradePrecreateContentBuilder();
|
||
$qrPayRequestBuilder->setOutTradeNo($pay_log['out_trade_no']); /// (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
|
||
$qrPayRequestBuilder->setTotalAmount($fee / 100); /// (必填) 订单总金额,单位为元,不能超过1亿元。如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
|
||
$qrPayRequestBuilder->setTimeExpress('5m'); /// 支付超时,线下扫码交易定义为5分钟
|
||
$qrPayRequestBuilder->setSubject($title); /// (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
|
||
$qrPayRequestBuilder->setBody($attach); /// 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
|
||
//$qrPayRequestBuilder->setUndiscountableAmount(0); /// (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段。如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
|
||
//$qrPayRequestBuilder->setDiscountableAmount(0); /// (不推荐使用) 订单可打折金额,可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折。如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
|
||
//$qrPayRequestBuilder->setExtendParams($extendParamsArr); /// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),系统商开发使用,详情请咨询支付宝技术支持
|
||
//$qrPayRequestBuilder->setGoodsDetailList($goodsDetailList); /// 商品明细列表,需填写购买商品详细信息,
|
||
//$qrPayRequestBuilder->setStoreId(''); /// (可选) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
|
||
//$qrPayRequestBuilder->setOperatorId(''); /// 商户操作员编号,添加此参数可以为商户操作员做销售统计
|
||
//$qrPayRequestBuilder->setAlipayStoreId($alipayStoreId); /// 支付宝的店铺编号
|
||
//$qrPayRequestBuilder->setAppAuthToken($appAuthToken); /// 第三方应用授权令牌,商户授权系统商开发模式下使用
|
||
$qrPayRequestBuilder->setNotifyUrl($notify_url); /// 异步通知地址
|
||
|
||
$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, /// 异步通知地址
|
||
'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', /// 支付宝公钥文件名
|
||
'MaxQueryRetry' => "10", /// 最大查询重试次数
|
||
'QueryDuration' => "3", /// 查询间隔
|
||
);
|
||
|
||
/// 调用qrPay方法获取当面付应答
|
||
$qrPay = new AlipayTradeService_f2fpay($config);
|
||
$qrPayResult = $qrPay->qrPay($qrPayRequestBuilder);
|
||
$response = $qrPayResult->getResponse();
|
||
|
||
// 根据状态值进行业务处理
|
||
switch ($qrPayResult->getTradeStatus())
|
||
{
|
||
case "SUCCESS":
|
||
$qrcode = $qrPay->create_erweima($response->qr_code);
|
||
return new returnObject(0, 0, '', array('code_img_url' => $qrcode, 'code_url' => rawurlencode($response->qr_code),));
|
||
case "FAILED":
|
||
return new returnObject(1, $response->sub_code, $response->sub_msg);
|
||
case "UNKNOWN":
|
||
return new returnObject(1, $response->code, $response->msg);
|
||
default:
|
||
return new returnObject(1, 500, '不支持的返回状态,创建订单二维码返回异常!!!');
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 威富通聚合支付--微信-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
|
||
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_SWIFTPASS_WECHAT);
|
||
if (!$pay_log)
|
||
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
$mch_id = $this->marketInfo['swiftpass_mchid'];
|
||
$secret_key = $this->marketInfo['swiftpass_paykey'];
|
||
$attach = json_encode(array('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/offline/swiftpasswechatpay', true); /// 异步通知地址
|
||
|
||
/// service 是 String(32) 接口类型:pay.weixin.native
|
||
/// version 否 String(8) 版本号,version默认值是2.0
|
||
/// charset 否 String(8) 可选值 UTF-8 ,默认为 UTF-8
|
||
/// sign_type 否 String(8) 签名类型,取值:MD5默认:MD5
|
||
/// mch_id 是 String(32) 商户号,由平台分配
|
||
/// out_trade_no 是 String(32) 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
|
||
/// device_info 否 String(32) 终端设备号
|
||
/// body 是 String(127) 商品描述
|
||
/// 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,确保平台能通过互联网访问该地址
|
||
/// 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。该时间取自商户服务器
|
||
/// op_user_id 否 String(32) 操作员帐号,默认为商户号
|
||
/// goods_tag 否 String(32) 商品标记,微信平台配置的商品标记,用于优惠券或者满减使用
|
||
/// product_id 否 String(32) 预留字段此 id 为静态可打印的二维码中包含的商品 ID,商户自行维护。
|
||
/// nonce_str 是 String(32) 随机字符串,不长于 32 位
|
||
/// limit_credit_pay 否 String(32) 限定用户使用微信支付时能否使用信用卡,值为1,禁用信用卡;值为0或者不传此参数则不禁用
|
||
/// sign 是 String(32) MD5签名结果,详见“安全规范”
|
||
|
||
//$reqHandler->setReqParams($_POST, array('method'));
|
||
$reqHandler->setParameter('service', 'pay.weixin.native'); /// 接口类型
|
||
$reqHandler->setParameter('mch_id', $mch_id); /// 商户号,由平台分配
|
||
$reqHandler->setParameter('version', '2.0'); /// 版本号,version默认值是2.0
|
||
$reqHandler->setParameter('out_trade_no', $pay_log['out_trade_no']); /// 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
|
||
$reqHandler->setParameter('body', $title); /// 商品描述
|
||
$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('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());
|
||
//echo '<pre>';
|
||
//var_dump($resHandler);
|
||
if ($resHandler->isTenpaySign())
|
||
{
|
||
//var_dump($resHandler->getAllParameters());
|
||
/// 当返回状态与业务结果都为0时才返回,其它结果请查看接口文档
|
||
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
|
||
{
|
||
return new returnObject(0, 0, '', array(
|
||
'code_img_url' => $resHandler->getParameter('code_img_url'),
|
||
'code_url' => $resHandler->getParameter('code_url'),
|
||
///'code_status' => $resHandler->getParameter('code_status'),
|
||
));
|
||
}
|
||
else
|
||
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'), null);
|
||
}
|
||
else
|
||
return new returnObject(502, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
|
||
}
|
||
else
|
||
return new returnObject(501, $pay->getResponseCode(), $pay->getErrInfo(), null);
|
||
}
|
||
|
||
|
||
/**
|
||
* 威富通聚合支付--支付宝-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
}
|
||
|
||
|
||
/**
|
||
* 汇付宝聚合支付--微信-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_heepay_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
|
||
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_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(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1));
|
||
|
||
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/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 = 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 = 'https://'; /// 必填 (同步回调)支付后返回的商户显示页面,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 = JsonObjectToJsonString(array('id' => $pay_log['plid'], 'ver' => 1,)); ///
|
||
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
|
||
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
|
||
$pay_code = ''; //char型,空字符串
|
||
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
|
||
|
||
/*************创建签名***************/
|
||
$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); /// 签名值
|
||
|
||
$param = array(
|
||
'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,
|
||
'remark' => $remark,
|
||
'sign' => $sign,
|
||
);
|
||
$result = Characet(SendPost('https://pay.heepay.com/Payment/Index.aspx', $param));
|
||
|
||
//{"code":"0000","message":"success","qr_code_url":"https://pay.swiftpass.cn/pay/qrcode?uuid=weixin%3A%2F%2Fwxpay%2Fbizpayurl%3Fpr%3Dl1zcih6"}
|
||
$object = json_decode($result);
|
||
if (is_null($object))
|
||
return new returnObject(1, 500, $result);
|
||
|
||
if ('0000' == $object->code)
|
||
return new returnObject(0, 0, '', array(
|
||
'code_img_url' => $object->qr_code_url,
|
||
'code_url' => substr(strstr($object->qr_code_url, 'uuid='), strlen('uuid=')),
|
||
///'code_status' => $resHandler->getParameter('code_status'),
|
||
));
|
||
else
|
||
return new returnObject(1, $object->code, $object->message);
|
||
}
|
||
|
||
|
||
/**
|
||
* 汇付宝聚合支付--支付宝-线下
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_offline_heepay_ali_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
|
||
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_HEEPAY_ALIPAY);
|
||
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(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1));
|
||
|
||
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/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 = 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 = 'https://'; /// 必填 (同步回调)支付后返回的商户显示页面,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($title); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
|
||
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
|
||
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
|
||
$remark = JsonObjectToJsonString(array('id' => $pay_log['plid'], 'ver' => 1,)); ///
|
||
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
|
||
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
|
||
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
|
||
|
||
/*************创建签名***************/
|
||
$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); /// 签名值
|
||
|
||
$param = array(
|
||
'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_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,
|
||
'remark' => $remark,
|
||
'sign' => $sign,
|
||
);
|
||
$result = Characet(SendPost('https://pay.heepay.com/Payment/Index.aspx', $param));
|
||
|
||
//{"code":"0000","message":"success","qr_code_url":"https://pay.swiftpass.cn/pay/qrcode?uuid=weixin%3A%2F%2Fwxpay%2Fbizpayurl%3Fpr%3Dl1zcih6"}
|
||
$object = json_decode($result);
|
||
if (empty($object))
|
||
return new returnObject(1, 500, $result);
|
||
|
||
if ('0000' == $object->code)
|
||
return new returnObject(0, 0, '', array(
|
||
'code_img_url' => $object->qr_code_url,
|
||
'code_url' => substr(strstr($object->qr_code_url, 'uuid='), strlen('uuid=')),
|
||
///'code_status' => $resHandler->getParameter('code_status'),
|
||
));
|
||
else
|
||
return new returnObject(1, $object->code, $object->message);
|
||
}
|
||
|
||
|
||
/**
|
||
* 微信支付-移动
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _pay_mobile_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
/// 保存支付记录
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '', $orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_MOBILE_WECHAT);
|
||
if (!$pay_log)
|
||
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
$notify_url = $this->getFullUrl('/api/newpay/notify/mobile/wechatpay'); /// 异步通知地址
|
||
|
||
load()->model('payment');
|
||
$wechat = array();
|
||
$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(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1,), JSON_UNESCAPED_UNICODE);
|
||
|
||
///$tools = new AppPay();
|
||
$input = new WxPayUnifiedOrder();
|
||
$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($title); ///
|
||
$input->SetNotify_url($notify_url); /// 通知地址
|
||
$input->SetTrade_type('APP'); /// 交易类型
|
||
$input->SetProduct_id($title); /// 商品ID(trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。)
|
||
$order = WxPayApi::unifiedOrder($input, 6, $wechat); /// 获得订单的基本信息,包括prepayid
|
||
//print_r($order);
|
||
|
||
///var_dump($order);
|
||
/// 在return_code和result_code都为SUCCESS的时候有返回
|
||
if ('SUCCESS' == $order['result_code'] && 'SUCCESS' == $order['return_code'])
|
||
{
|
||
///$appApiParameters = $tools->GetAppApiParameters($order, $wechat); /// 生成提交给app的一些参数
|
||
return new returnObject(0, 0, '', array(
|
||
'prepay_id' => $order['prepay_id'],
|
||
'nonce_str' => $order['nonce_str'],
|
||
'sign' => $order['sign'],
|
||
));
|
||
}
|
||
elseif ('SUCCESS' == $order['return_code'])
|
||
return new returnObject(500, $order['err_code'], $order['err_code_des']);
|
||
else
|
||
return new returnObject(500, $order['return_code'], $order['return_msg']);
|
||
}
|
||
|
||
|
||
/**
|
||
* 支付宝支付-移动
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _pay_mobile_ali_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
}
|
||
|
||
|
||
/**
|
||
* 威富通聚合支付--微信-移动
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _pay_mobile_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
/// 保存支付记录
|
||
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '', $orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_MOBILE_SWIFTPASS_WECHAT);
|
||
if (!$pay_log)
|
||
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
$mch_id = $this->marketInfo['swiftpass_mchid'];
|
||
$secret_key = $this->marketInfo['swiftpass_paykey'];
|
||
$attach = json_encode(array('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/offline/swiftpasswechatpay', true); /// 异步通知地址
|
||
|
||
///$reqHandler->setReqParams($_POST, array('method'));
|
||
$reqHandler->setParameter('service', 'unified.trade.pay'); /// 接口类型
|
||
$reqHandler->setParameter('mch_id', $mch_id); /// 商户号,由平台分配
|
||
$reqHandler->setParameter('version', '2.0'); /// 版本号,version默认值是2.0
|
||
$reqHandler->setParameter('out_trade_no', $pay_log['out_trade_no']); /// 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
|
||
$reqHandler->setParameter('body', $title); /// 商品描述
|
||
$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('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
|
||
$reqHandler->createSign(); /// 创建签名
|
||
|
||
$data = Utils::toXml($reqHandler->getAllParameters());
|
||
//var_dump($data);
|
||
|
||
$pay->setReqContent($reqHandler->getGateURL(), $data);
|
||
if ($pay->call())
|
||
{
|
||
$resHandler->setContent($pay->getResContent());
|
||
$resHandler->setKey($reqHandler->getKey());
|
||
if ($resHandler->isTenpaySign())
|
||
{
|
||
/// 当返回状态与业务结果都为0时才返回,其它结果请查看接口文档
|
||
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
|
||
{
|
||
///$resHandler->getParameter('services')
|
||
return new returnObject(0, 0, '', array('prepay_id' => $resHandler->getParameter('token_id'),));
|
||
}
|
||
else
|
||
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'), null);
|
||
}
|
||
else
|
||
return new returnObject(502, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
|
||
}
|
||
else
|
||
return new returnObject(501, $pay->getResponseCode(), $pay->getErrInfo(), null);
|
||
}
|
||
|
||
|
||
/**
|
||
* 威富通聚合支付--支付宝-移动
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 支付金额(单位分)
|
||
* @param string $title 支付标题
|
||
* @param string $notice_url 回调地址(异步)
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _pay_mobile_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach)
|
||
{
|
||
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
$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']; /// 支付秘钥
|
||
|
||
$input = new WxPayRefund();
|
||
if (!empty($transaction_id))
|
||
$input->SetTransaction_id($transaction_id);
|
||
elseif (!empty($out_trade_no))
|
||
$input->SetOut_trade_no($out_trade_no);
|
||
else
|
||
return new returnObject(500, 13002, 'transaction_id和out_trade_no参数必须有一个不为空。', null);
|
||
|
||
$input->SetTotal_fee($total_fee);
|
||
$input->SetRefund_fee($refund_fee);
|
||
$input->SetOut_refund_no($wechat['mchid'] . date('YmdHis') . random(8, 1));
|
||
$input->SetOp_user_id($wechat['mchid']);
|
||
$refund_result = WxPayApi::refund($input, 6, $wechat, $this->db);
|
||
if (!empty($refund_result) && count($refund_result) > 0)
|
||
{
|
||
if (strcasecmp($refund_result['return_code'], 'SUCCESS') == 0)
|
||
{
|
||
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
|
||
return new returnObject(0, 0, '申请退款成功。', $attach);
|
||
else
|
||
return new returnObject(500, 1, '退款失败!');
|
||
}
|
||
else
|
||
return new returnObject(500, 13001, $refund_result);
|
||
}
|
||
else
|
||
return new returnObject(500, 13000, '申请退款返回消息为空。');
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_wechat_with_browser_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
if (empty($trade_no) && empty($out_trade_no))
|
||
return new returnObject(1, 13002, '至少传入一个订单号。', null);
|
||
|
||
$alipay_appid = $this->marketInfo['alipay_appid']; /// 支付宝appid
|
||
$sign_key = $this->marketInfo['signkey']; /// 签名key
|
||
|
||
$RequestBuilder = new AlipayTradeRefundContentBuilder_wappay();
|
||
/// 商户订单号和支付宝交易号不能同时为空。 trade_no、 out_trade_no如果同时存在优先取trade_no
|
||
$RequestBuilder->setTradeNo($trade_no); /// 支付宝交易号,和商户订单号二选一
|
||
$RequestBuilder->setOutTradeNo($out_trade_no); /// 商户订单号,和支付宝交易号二选一
|
||
$RequestBuilder->setRefundAmount($refund_fee / 100); /// 退款金额,不能大于订单总金额
|
||
$RequestBuilder->setRefundReason('申请退款'); /// 退款的原因说明
|
||
$RequestBuilder->setOutRequestNo($order_id); /// 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
|
||
|
||
$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', /// 支付宝公钥文件名
|
||
);
|
||
$Response = new AlipayTradeService_wappay($config);
|
||
$result = $Response->Refund($RequestBuilder);
|
||
|
||
if (10000 == $result->code)
|
||
{
|
||
if ($this->_notify_alipay_order_status_v1($this->appid, $this->market_key, $out_trade_no, $trade_no, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
|
||
return new returnObject(0, 0, '申请退款成功。', $attach);
|
||
else
|
||
return new returnObject(1, 1, '退款失败!');
|
||
}
|
||
else
|
||
return new returnObject(1, $result->code, $result->msg);
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
$resHandler = new ClientResponseHandler();
|
||
$reqHandler = new RequestHandler();
|
||
$pay = new PayHttpClient();
|
||
|
||
//$reqHandler->setReqParams($_POST,array('method'));
|
||
//$reqParam = $reqHandler->getAllParameters();
|
||
if (empty($transaction_id) && empty($out_trade_no))
|
||
{
|
||
return new returnObject(500, 501, '请输入商户订单号或平台订单号!');
|
||
}
|
||
|
||
$mch_id = $this->marketInfo['swiftpass_mchid'];
|
||
$secret_key = $this->marketInfo['swiftpass_paykey'];
|
||
|
||
$reqHandler->setGateUrl('https://pay.swiftpass.cn/pay/gateway');
|
||
$reqHandler->setKey($secret_key);
|
||
|
||
$reqHandler->setParameter('version', '2.0');
|
||
$reqHandler->setParameter('service', 'unified.trade.refund'); /// 接口类型
|
||
$reqHandler->setParameter('mch_id', $mch_id); /// 必填项,商户号,由平台分配
|
||
$reqHandler->setParameter('out_trade_no', $out_trade_no); /// 商户订单号
|
||
$reqHandler->setParameter('transaction_id', $transaction_id); /// 微信订单号
|
||
$reqHandler->setParameter('out_refund_no', $order_id); /// 商户退款单号,32个字符内、可包含字母,确保在商户系统唯一。同个退款单号多次请求,平台当一个单处理,只会退一次款。如果出现退款不成功,请采用原退款单号重新发起,避免出现重复退款。
|
||
$reqHandler->setParameter('total_fee', $total_fee); /// 总金额
|
||
$reqHandler->setParameter('refund_fee', $refund_fee); /// 退款金额
|
||
$reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
|
||
$reqHandler->setParameter('op_user_id', $mch_id); /// 必填项,操作员帐号,默认为商户号
|
||
|
||
$reqHandler->createSign(); /// 创建签名
|
||
|
||
$data = Utils::toXml($reqHandler->getAllParameters()); /// 将提交参数转为xml,目前接口参数也只支持XML方式
|
||
|
||
$pay->setReqContent($reqHandler->getGateURL(), $data);
|
||
if ($pay->call())
|
||
{
|
||
$resHandler->setContent($pay->getResContent());
|
||
$resHandler->setKey($reqHandler->getKey());
|
||
|
||
if ($resHandler->isTenpaySign())
|
||
{
|
||
//当返回状态与业务结果都为0时才返,其它结果请查看接口文档
|
||
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
|
||
{
|
||
/*
|
||
$res = array('transaction_id'=>$resHandler->getParameter('transaction_id'),
|
||
'out_trade_no'=>$resHandler->getParameter('out_trade_no'),
|
||
'out_refund_no'=>$resHandler->getParameter('out_refund_no'),
|
||
'refund_id'=>$resHandler->getParameter('refund_id'),
|
||
'refund_channel'=>$resHandler->getParameter('refund_channel'),
|
||
'refund_fee'=>$resHandler->getParameter('refund_fee'),
|
||
'coupon_refund_fee'=>$resHandler->getParameter('coupon_refund_fee'));
|
||
*/
|
||
$res = $resHandler->getAllParameters();
|
||
///Utils::dataRecodes('提交退款', $res);
|
||
///echo json_encode(array('status'=>200,'msg'=>'退款成功,请查看result.txt文件!','data'=>$res));
|
||
///exit();
|
||
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
|
||
return new returnObject(0, 0, '申请退款成功。', $attach);
|
||
else
|
||
return new returnObject(500, 1, '退款失败!');
|
||
}
|
||
else
|
||
{
|
||
//echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$resHandler->getParameter('err_code').' Error Message:'.$resHandler->getParameter('err_msg')));
|
||
//exit();
|
||
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$resHandler->getParameter('status').' Error Message:'.$resHandler->getParameter('message')));
|
||
return new returnObject(500, $resHandler->getParameter('status'), $resHandler->getParameter('message'));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//echo json_encode(array('status'=>500,'msg'=>'Response Code:'.$pay->getResponseCode().' Error Info:'.$pay->getErrInfo()));
|
||
return new returnObject(500, $pay->getResponseCode(), $pay->getErrInfo());
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_swiftpass_ali_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $XmlData
|
||
* @return array
|
||
*/
|
||
private function XmlToArray($XmlData)
|
||
{
|
||
$Parser = xml_parser_create();
|
||
xml_parse_into_struct($Parser, $XmlData, $Values, $Indexs);
|
||
xml_parser_free($Parser);
|
||
|
||
$Result = null;
|
||
foreach ($Indexs as $Key => $Value)
|
||
{
|
||
foreach ($Value as $Index)
|
||
{
|
||
if (isset($Values[$Index]['value']))
|
||
$Result[strtolower($Key)] = $Values[$Index]['value'];
|
||
}
|
||
}
|
||
|
||
return $Result;
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
if (empty($out_trade_no))
|
||
return new returnObject(500, 501, '请输入商户订单号或平台订单号!');
|
||
|
||
$refund = $refund_fee / 100;
|
||
|
||
$mch_id = $this->marketInfo['heepay_mchid'];
|
||
$secret_key = $this->marketInfo['heepay_refundkey'];
|
||
|
||
//$agent_bill_id = $out_trade_no; /// 选填 商户系统内部的支付订单号(要保证唯一)
|
||
$agent_id = $mch_id; /// 必填 商户编号如1234567(汇付宝商户编号:七位整数数字)
|
||
//$pay_type = 20; /// 必填 支付类型20,(数据类型:int)
|
||
$notify_url = 'https://'; /// 必填 接收异步通知退款结果的页面
|
||
$version = 1; /// 当前接口版本号1
|
||
$refund_details = "{$out_trade_no},{$refund},t{$out_trade_no}"; /// 商户系统内部的定单号(要保证唯一), 商户退款单号可为空,如果传了要保证唯一, 支持批量退款和部分退款, 商户原支付单号,金额,商户退款单号“|”商户原支付单号,金额,商户退款单号 分割最多支持50笔 注意:金额传0或为空默认做全额退款 样例(63548281250,0.01,5232112“|”6358281251,0,5232113)
|
||
$signstr = strtolower("agent_id={$agent_id}&key={$secret_key}¬ify_url={$notify_url}&refund_details={$refund_details}&version={$version}"); /// 必填 签名结果
|
||
$sign = strtolower(md5($signstr));
|
||
|
||
$param = array(
|
||
'version' => $version,
|
||
'agent_id' => $agent_id,
|
||
//'agent_bill_id' => $agent_bill_id,
|
||
//'pay_type' => $pay_type,
|
||
'refund_details' => $refund_details,
|
||
'notify_url' => $notify_url,
|
||
'sign' => $sign,
|
||
);
|
||
|
||
$result = SendPost('https://pay.heepay.com/API/Payment/PaymentRefund.aspx', $param);
|
||
$result = $this->XmlToArray(Characet($result));
|
||
///libxml_disable_entity_loader(true);
|
||
///$result = json_decode(json_encode(simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
|
||
if (strcmp($result->ret_code, '0000') == 0)
|
||
{
|
||
$sign = "agent_id={$result['agent_id']}&key={$secret_key}&ret_code={$result['ret_code']}&ret_msg={$result['ret_msg']}";
|
||
if ($sign != $result->sign)
|
||
return new returnObject(1, 500, '返回数据签名错误!', null);
|
||
else
|
||
{
|
||
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
|
||
return new returnObject(0, 0, '申请退款成功。', $attach);
|
||
else
|
||
return new returnObject(500, 1, '退款失败!');
|
||
}
|
||
}
|
||
else
|
||
return new returnObject(1, intval($result['ret_code']), $result['ret_msg']);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_heepay_ali_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_online_heepay_wechat_with_browser_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
$alipay_appid = $this->marketInfo['alipay_appid']; /// 支付宝appid
|
||
$sign_key = $this->marketInfo['signkey']; /// 签名key
|
||
|
||
/// 第三方应用授权令牌,商户授权系统商开发模式下使用
|
||
$appAuthToken = ""; /// 根据真实值填写
|
||
|
||
/// 创建退款请求builder,设置参数
|
||
$refundRequestBuilder = new AlipayTradeRefundContentBuilder_f2fpay();
|
||
$refundRequestBuilder->setTradeNo($trade_no); /// 支付宝交易号,和商户订单号不能同时为空
|
||
$refundRequestBuilder->setOutTradeNo($out_trade_no); /// 订单支付时传入的商户订单号,不能和 trade_no同时为空。
|
||
$refundRequestBuilder->setRefundAmount($refund_fee / 100); /// 需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数
|
||
$refundRequestBuilder->setOutRequestNo($order_id); /// 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
|
||
$refundRequestBuilder->setAppAuthToken($appAuthToken); /// 第三方应用授权令牌,商户授权系统商开发模式下使用
|
||
|
||
$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', /// 支付宝公钥文件名
|
||
);
|
||
/// 初始化类对象,调用refund获取退款应答
|
||
$refundResponse = new AlipayTradeService_f2fpay($config);
|
||
$refundResult = $refundResponse->refund($refundRequestBuilder);
|
||
$response = $refundResult->getResponse();
|
||
/// 根据交易状态进行处理
|
||
switch ($refundResult->getTradeStatus())
|
||
{
|
||
case "SUCCESS":
|
||
if ($this->_notify_alipay_order_status_v1($this->appid, $this->market_key, $out_trade_no, $trade_no, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
|
||
return new returnObject(0, 0, '申请退款成功。', $attach);
|
||
else
|
||
return new returnObject(1, 1, '退款失败!');
|
||
|
||
case "FAILED":
|
||
return new returnObject(1, $response->sub_code, $response->sub_msg);
|
||
case "UNKNOWN":
|
||
return new returnObject(1, $response->code, $response->msg);
|
||
default:
|
||
return new returnObject(1, 500, '不支持的返回状态,申请退款返回异常!!!');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_offline_heepay_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_heepay_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_mobile_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_mobile_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $transaction_id 微信订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_mobile_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
/**
|
||
* @param string $trade_no 支付宝订单号
|
||
* @param string $out_trade_no 平台订单号
|
||
* @param string $order_id 订单号
|
||
* @param int $total_fee 订单总金额
|
||
* @param int $refund_fee 退款金额
|
||
* @param array $attach 其他参数
|
||
* @return returnObject
|
||
*/
|
||
private function _refund_mobile_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
|
||
{
|
||
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
|
||
return $this->_refund_online_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $appid 应用id
|
||
* @param string $devkey 开发者id
|
||
* @param string $sid sid
|
||
* @param string $scode scode
|
||
* @param string $orderid 订单号
|
||
* @param int $fee 红包金额(单位分)
|
||
* @param string $wishing 红包祝福语
|
||
* @param string $act_name 活动名称
|
||
* @param string $remark 备注
|
||
* @param string $sign 签名
|
||
* @return array|returnObject
|
||
*/
|
||
private function verify_send_red_pack_v1($appid = '', $devkey = '', $sid = '', $scode = '', $orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $sign = '')
|
||
{
|
||
/// 验证公共参数是否合法
|
||
parent::init($appid, $devkey, $sid, $scode);
|
||
$verify_result = parent::verify();
|
||
if (!is_error_api($verify_result))
|
||
{
|
||
/// 校验签名
|
||
$param = $_REQUEST;
|
||
$sign_str = '';
|
||
if (isset($param['sign']))
|
||
{
|
||
unset($param['sign']);
|
||
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
|
||
}
|
||
if ($sign_str != $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($wishing))
|
||
return new returnObject(500, 500, '请指定红包祝福语!', null);
|
||
if (empty($act_name))
|
||
return new returnObject(500, 500, '请指定活动名称!', null);
|
||
if (empty($remark))
|
||
return new returnObject(500, 500, '请指定备注信息!', null);
|
||
|
||
/// 获取附加的参数
|
||
$attach = GetAttachParameters(array('appid', 'devkey', 'sid', 'scode', 'orderid', 'fee', 'wishing', 'act_name', 'remark', 'send_type', '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 $app_id 支付应用(int)
|
||
* @param string $market_key 门店key
|
||
* @param string $to_user 领取用户
|
||
* @param string $orderid 订单ID
|
||
* @param integer $fee 红包金额(单位分)
|
||
* @param string $wishing 红包祝福语
|
||
* @param string $act_name 活动名称
|
||
* @param string $remark 备注信息
|
||
* @param array $attach 支付附加参数
|
||
* @param string $type 发送方式
|
||
* @return mixed
|
||
**/
|
||
private function saved_redpack_info_v1($app_id, $market_key, $to_user, $orderid, $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = null, $type = '')
|
||
{
|
||
$tag = array();
|
||
$tag['wishing'] = $wishing; /// 红包祝福语
|
||
$tag['act_name'] = $act_name; /// 活动名称
|
||
$tag['client_ip'] = CLIENT_IP; /// 客户端ip
|
||
$tag['remark'] = $remark; /// 备注信息
|
||
$tag['attach'] = json_encode($attach, JSON_UNESCAPED_UNICODE);
|
||
$tag = json_encode($tag, JSON_UNESCAPED_UNICODE);
|
||
|
||
$record = array();
|
||
$record['type'] = $type; /// 支付方式
|
||
$record['app_key'] = $app_id; /// 支付应用(int)
|
||
$record['market_key'] = $market_key; /// 支付商家(int)
|
||
$record['user_id'] = $to_user; /// 领取用户
|
||
$record['order_id'] = $orderid; /// 订单编号
|
||
$record['fee'] = $fee; /// 红包金额(单位分)
|
||
$record['tag'] = $tag; /// 其他附加内容
|
||
$record['state'] = 0; /// 状态(0:创建;1:已成功)
|
||
$record['createtime'] = TIMESTAMP; /// 创建时间戳
|
||
//$record['out_trade_no'] = md5(date('YmdHis') . '_' . $app_id . '_' . $market_key . '_' . random(8, 1)); /// 支付唯一ID
|
||
$record['out_trade_no'] = substr(md5($market_key . TIMESTAMP . random(8, 1)), 0, 28); /// 支付唯一ID
|
||
|
||
$pdo = $this->db;
|
||
try
|
||
{
|
||
$pdo->beginTransaction();
|
||
/// 插入一条支付记录
|
||
$id = Sql::replaceInto('syweb_core_redpacklog')->values($record)->exec($pdo)->lastInsertId();
|
||
$pdo->commit();
|
||
|
||
$record['id'] = $id;
|
||
return $record;
|
||
}
|
||
catch(Exception $e)
|
||
{
|
||
$pdo->rollBack();
|
||
echo $e->getMessage();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 微信红包
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 红包金额(单位分)
|
||
* @param string $wishing 红包祝福语
|
||
* @param string $act_name 活动名称
|
||
* @param string $remark 备注信息
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _send_red_pack_wechat_v1($orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = array())
|
||
{
|
||
/// 验证用户登陆方式
|
||
if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
|
||
return new returnObject(500, 500, '请使用微信登录再领取红包!', null);
|
||
|
||
/// 保存支付记录
|
||
$redpack_log = $this->saved_redpack_info_v1($this->appid, $this->market_key, $this->userInfo['openid'],
|
||
$orderid, $fee, $wishing, $act_name, $remark, $attach, PAYTYPE_ONLINE_WECHAT);
|
||
if (!$redpack_log)
|
||
return new returnObject(500, 500, '写入红包信息失败, 请联系管理员或稍候再试!', null);
|
||
|
||
$wechat = array('appid' => $this->marketInfo['weixin_appid'], /// 微信公众号APPID
|
||
'secret' => $this->marketInfo['weixin_secret_appid'],
|
||
'mchid' => $this->marketInfo['weixin_mchid'], /// 微信公众号商户号
|
||
'signkey' => $this->marketInfo['weixin_paykey'], /// 支付秘钥
|
||
);
|
||
|
||
$input = new WxPaySendredpack();
|
||
$input->SetMch_billno($redpack_log['out_trade_no']); /// 商户订单号
|
||
$input->SetSend_name($this->marketInfo['market_name']); /// 商户名称
|
||
$input->SetRe_openid($redpack_log['user_id']); /// 接受红包的用户的openid
|
||
$input->SetTotal_amount($redpack_log['fee']); /// 红包金额(单位分)
|
||
$input->SetTotal_num(1); /// 红包发放总人数
|
||
$input->SetWishing($wishing); /// 红包祝福语
|
||
$input->SetClient_ip(CLIENT_IP); /// 调用接口的机器Ip地址
|
||
$input->SetAct_name($act_name); /// 活动名称
|
||
$input->SetRemark($remark); /// 备注信息
|
||
|
||
$result = WxPayApi::sendredpack($input, 6, $wechat);
|
||
if (!empty($result) && count($result) > 0)
|
||
{
|
||
if ($result['return_code'] == 'SUCCESS')
|
||
{
|
||
if ($result['result_code'] == 'SUCCESS')
|
||
{
|
||
$this->db->beginTransaction();
|
||
Sql::update('syweb_core_redpacklog')->setArgs(array('state' => 1, 'transaction_id' => $result['send_listid'],))->where('id = ?', $redpack_log['id'])->exec($this->db);
|
||
$this->db->commit();
|
||
|
||
return new returnObject(0, 0, '申请红包发送成功!');
|
||
}
|
||
else
|
||
return new returnObject(1, $result['err_code'], $result['err_code_des']);
|
||
}
|
||
else
|
||
return new returnObject(1, $result['return_code'], $result['return_msg']);
|
||
}
|
||
else
|
||
return new returnObject(1, 14019, '申请发送红包返回消息为空。');
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 支付宝红包
|
||
* @param string $orderid 订单号
|
||
* @param integer $fee 红包金额(单位分)
|
||
* @param string $wishing 红包祝福语
|
||
* @param string $act_name 活动名称
|
||
* @param string $remark 备注信息
|
||
* @param array|mixed $attach 附带的其他参数
|
||
* @return boolean
|
||
*/
|
||
private function _send_red_pack_ali_v1($orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = array())
|
||
{
|
||
return new returnObject(500, 500, '还没有实现该功能, 请关注平台后续更新!', null);
|
||
}
|
||
|
||
|
||
/**
|
||
* @property({"default":"@db"})
|
||
* @var PDO
|
||
*/
|
||
public $db;
|
||
} |