Files
youlegames/codes/agent/game/api/source/apis/newpay.php
2026-03-15 01:27:05 +08:00

4922 lines
212 KiB
PHP
Raw Blame History

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