window.onload = function() {
try {
if ('undefined' != typeof window.settings)
window.settings.loadurl('{$Link}');
else
document.frmpay.submit();
} catch(err) {
//alert(err.message);
document.frmpay.submit();
}
}
EOL;
//$Html = "";
exit($Html);
//return new returnObject(0, 0);
}
/**
* 微信支付-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '',
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
/// 附加参数
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
/// 异步通知地址
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/wechatpay');
$wechat = array(
'appid' => $this->marketInfo['weixin_appid'], /// 微信公众号APPID
'secret' => $this->marketInfo['weixin_secret_appid'],
'mchid' => $this->marketInfo['weixin_mchid'], /// 微信公众号商户号
'signkey' => $this->marketInfo['weixin_paykey'], /// 支付秘钥
);
/**
* 流程:
* 1、调用统一下单,取得code_url,生成二维码
* 2、用户扫描二维码,进行支付
* 3、支付完成之后,微信服务器会通知支付成功
* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
*/
$notify = new NativePay();
$input = new WxPayUnifiedOrder();
$input->SetBody($title); /// 商品描述
$input->SetAttach($attach); /// 附加数据
$input->SetOut_trade_no($pay_log['out_trade_no']); /// 商户订单号
$input->SetTotal_fee($fee); /// 支付金额
$input->SetTime_start(date('YmdHis')); /// 交易起始时间
$input->SetTime_expire(date('YmdHis', time() + 600)); /// 交易结束时间
$input->SetGoods_tag('');
$input->SetNotify_url($notify_url); /// 异步通知地址
$input->SetTrade_type('NATIVE'); /// 交易类型
$input->SetProduct_id($title); /// 商品ID(trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。)
$result = $notify->GetPayUrl($input, $wechat);
///$url2 = $result['code_url'];
return new returnObject(0, 0, '', array(
'code_img_url' => 'http://paysdk.weixin.qq.com/example/qrcode.php?data=' . rawurlencode($result['code_url']),
'code_url' => rawurlencode($result['code_url']),
));
}
/**
* 支付宝支付-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_ali_v1($orderid, $fee, $title, $notice_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '',
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_ALIPAY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$alipay_appid = $this->marketInfo['alipay_appid'];
/// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),系统商开发使用,详情请咨询支付宝技术支持
$providerId = ''; //系统商pid,作为系统商返佣数据提取的依据
$extendParams = new ExtendParams();
$extendParams->setSysServiceProviderId($providerId);
$extendParamsArr = $extendParams->getExtendParams();
// 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail
$goods1 = new GoodsDetail();
$goods1->setGoodsId("apple-01");
$goods1->setGoodsName("iphone");
$goods1->setPrice(3000);
$goods1->setQuantity(1);
//得到商品1明细数组
$goods1Arr = $goods1->getGoodsDetail();
/// 继续创建并添加第一条商品信息,用户购买的产品为“xx牙刷”,单价为5.05元,购买了两件
$goods2 = new GoodsDetail();
$goods2->setGoodsId("apple-02");
$goods2->setGoodsName("ipad");
$goods2->setPrice(1000);
$goods2->setQuantity(1);
/// 得到商品1明细数组
$goods2Arr = $goods2->getGoodsDetail();
/// 商品明细列表,需填写购买商品详细信息,
$goodsDetailList = array($goods1Arr,$goods2Arr);
/// 附加参数
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
/// 异步通知地址
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/alipay');
/// 创建请求builder,设置请求参数
$qrPayRequestBuilder = new AlipayTradePrecreateContentBuilder();
$qrPayRequestBuilder->setOutTradeNo($pay_log['out_trade_no']); /// (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
$qrPayRequestBuilder->setTotalAmount($fee / 100); /// (必填) 订单总金额,单位为元,不能超过1亿元。如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
$qrPayRequestBuilder->setTimeExpress('5m'); /// 支付超时,线下扫码交易定义为5分钟
$qrPayRequestBuilder->setSubject($title); /// (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
$qrPayRequestBuilder->setBody($attach); /// 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
//$qrPayRequestBuilder->setUndiscountableAmount(0); /// (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段。如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
//$qrPayRequestBuilder->setDiscountableAmount(0); /// (不推荐使用) 订单可打折金额,可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折。如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
//$qrPayRequestBuilder->setExtendParams($extendParamsArr); /// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),系统商开发使用,详情请咨询支付宝技术支持
//$qrPayRequestBuilder->setGoodsDetailList($goodsDetailList); /// 商品明细列表,需填写购买商品详细信息,
//$qrPayRequestBuilder->setStoreId(''); /// (可选) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
//$qrPayRequestBuilder->setOperatorId(''); /// 商户操作员编号,添加此参数可以为商户操作员做销售统计
//$qrPayRequestBuilder->setAlipayStoreId($alipayStoreId); /// 支付宝的店铺编号
//$qrPayRequestBuilder->setAppAuthToken($appAuthToken); /// 第三方应用授权令牌,商户授权系统商开发模式下使用
$qrPayRequestBuilder->setNotifyUrl($notify_url); /// 异步通知地址
$config = array(
'app_id' => $alipay_appid, /// 应用id
//'merchant_private_key' => '', /// 商户私钥,您的原始格式RSA私钥
'merchant_private_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/rsa_private_key.pem', /// 商户私钥文件名
'notify_url' => $notify_url, /// 异步通知地址
'charset' => 'utf-8', /// 编码格式
'sign_type' => 'RSA2', /// 签名方式
'gatewayUrl' => 'https://openapi.alipay.com/gateway.do', /// 支付宝网关
//'alipay_public_key' => '', /// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem', /// 支付宝公钥文件名
'MaxQueryRetry' => "10", /// 最大查询重试次数
'QueryDuration' => "3", /// 查询间隔
);
/// 调用qrPay方法获取当面付应答
$qrPay = new AlipayTradeService_f2fpay($config);
$qrPayResult = $qrPay->qrPay($qrPayRequestBuilder);
$response = $qrPayResult->getResponse();
// 根据状态值进行业务处理
switch ($qrPayResult->getTradeStatus())
{
case "SUCCESS":
$qrcode = $qrPay->create_erweima($response->qr_code);
return new returnObject(0, 0, '', array('code_img_url' => $qrcode, 'code_url' => rawurlencode($response->qr_code),));
case "FAILED":
return new returnObject(1, $response->sub_code, $response->sub_msg);
case "UNKNOWN":
return new returnObject(1, $response->code, $response->msg);
default:
return new returnObject(1, 500, '不支持的返回状态,创建订单二维码返回异常!!!');
}
}
/**
* 威富通聚合支付--微信-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_SWIFTPASS_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$mch_id = $this->marketInfo['swiftpass_mchid'];
$secret_key = $this->marketInfo['swiftpass_paykey'];
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
$resHandler = new ClientResponseHandler();
$reqHandler = new RequestHandler();
$pay = new PayHttpClient();
$reqHandler->setGateUrl('https://pay.swiftpass.cn/pay/gateway');
$reqHandler->setKey($secret_key);
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/swiftpasswechatpay', true); /// 异步通知地址
/// service 是 String(32) 接口类型:pay.weixin.native
/// version 否 String(8) 版本号,version默认值是2.0
/// charset 否 String(8) 可选值 UTF-8 ,默认为 UTF-8
/// sign_type 否 String(8) 签名类型,取值:MD5默认:MD5
/// mch_id 是 String(32) 商户号,由平台分配
/// out_trade_no 是 String(32) 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
/// device_info 否 String(32) 终端设备号
/// body 是 String(127) 商品描述
/// attach 否 String(128) 商户附加信息,可做扩展参数,255字符内
/// total_fee 是 Int 总金额,以分为单位,不允许包含任何字、符号
/// mch_create_ip 是 String(16) 订单生成的机器 IP
/// notify_url 是 String(255) 接收平台通知的URL,需给绝对路径,255字符内格式如:http://wap.tenpay.com/tenpay.asp,确保平台能通过互联网访问该地址
/// time_start 否 String(14) 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。时区为GMT+8 beijing。该时间取自商户服务器
/// time_expire 否 String(14) 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自商户服务器
/// op_user_id 否 String(32) 操作员帐号,默认为商户号
/// goods_tag 否 String(32) 商品标记,微信平台配置的商品标记,用于优惠券或者满减使用
/// product_id 否 String(32) 预留字段此 id 为静态可打印的二维码中包含的商品 ID,商户自行维护。
/// nonce_str 是 String(32) 随机字符串,不长于 32 位
/// limit_credit_pay 否 String(32) 限定用户使用微信支付时能否使用信用卡,值为1,禁用信用卡;值为0或者不传此参数则不禁用
/// sign 是 String(32) MD5签名结果,详见“安全规范”
//$reqHandler->setReqParams($_POST, array('method'));
$reqHandler->setParameter('service', 'pay.weixin.native'); /// 接口类型
$reqHandler->setParameter('mch_id', $mch_id); /// 商户号,由平台分配
$reqHandler->setParameter('version', '2.0'); /// 版本号,version默认值是2.0
$reqHandler->setParameter('out_trade_no', $pay_log['out_trade_no']); /// 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
$reqHandler->setParameter('body', $title); /// 商品描述
$reqHandler->setParameter('attach', $attach); /// 商户附加信息,可做扩展参数,255字符内
$reqHandler->setParameter('total_fee', $fee); /// 总金额,以分为单位,不允许包含任何字、符号
$reqHandler->setParameter('mch_create_ip', $_SERVER['REMOTE_ADDR']); /// 订单生成的机器 IP
$reqHandler->setParameter('notify_url', $notify_url); /// 异步通知地址
$reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
$reqHandler->createSign(); /// 创建签名
$data = Utils::toXml($reqHandler->getAllParameters());
//var_dump($data);
//var_dump($pay->getResContent());
$pay->setReqContent($reqHandler->getGateURL(), $data);
if ($pay->call())
{
$resHandler->setContent($pay->getResContent());
$resHandler->setKey($reqHandler->getKey());
//echo '';
//var_dump($resHandler);
if ($resHandler->isTenpaySign())
{
//var_dump($resHandler->getAllParameters());
/// 当返回状态与业务结果都为0时才返回,其它结果请查看接口文档
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
{
return new returnObject(0, 0, '', array(
'code_img_url' => $resHandler->getParameter('code_img_url'),
'code_url' => $resHandler->getParameter('code_url'),
///'code_status' => $resHandler->getParameter('code_status'),
));
}
else
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'), null);
}
else
return new returnObject(502, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
}
else
return new returnObject(501, $pay->getResponseCode(), $pay->getErrInfo(), null);
}
/**
* 威富通聚合支付--支付宝-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach)
{
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
}
/**
* 汇付宝聚合支付--微信-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_heepay_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_HEEPAY_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
//$openid = $this->userInfo['openid'];
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1));
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/heepaywechatpay'); /// 异步通知地址
//$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$pay_type = 30; /// 必填 支付类型30,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = 'https://'; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
/// 微信支付不涉及同步返回,此处可填写任意URL,没有实际使用
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode($title); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = JsonObjectToJsonString(array('id' => $pay_log['plid'], 'ver' => 1,)); ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$pay_code = ''; //char型,空字符串
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
/*************创建签名***************/
$sign_str = '';
$sign_str = $sign_str . 'version=' . $version;
$sign_str = $sign_str . '&agent_id=' . $agent_id;
$sign_str = $sign_str . '&agent_bill_id=' . $agent_bill_id;
$sign_str = $sign_str . '&agent_bill_time=' . $agent_bill_time;
$sign_str = $sign_str . '&pay_type=' . $pay_type;
$sign_str = $sign_str . '&pay_amt=' . $pay_amt;
$sign_str = $sign_str . '¬ify_url=' . $notify_url;
$sign_str = $sign_str . '&return_url=' . $return_url;
$sign_str = $sign_str . '&user_ip=' . $user_ip;
$sign_str = $sign_str . '&key=' . $sign_key;
$sign = md5($sign_str); /// 签名值
$param = array(
'version' => $version,
'agent_id' => $agent_id,
'agent_bill_id' => $agent_bill_id,
'agent_bill_time' => $agent_bill_time,
'pay_type' => $pay_type,
'pay_code' => $pay_code,
'pay_amt' => $pay_amt,
'notify_url' => $notify_url,
'return_url' => $return_url,
'user_ip' => $user_ip,
'goods_name' => $goods_name,
'goods_num' => $goods_num,
'goods_note' => $goods_note,
'remark' => $remark,
'sign' => $sign,
);
$result = Characet(SendPost('https://pay.heepay.com/Payment/Index.aspx', $param));
//{"code":"0000","message":"success","qr_code_url":"https://pay.swiftpass.cn/pay/qrcode?uuid=weixin%3A%2F%2Fwxpay%2Fbizpayurl%3Fpr%3Dl1zcih6"}
$object = json_decode($result);
if (is_null($object))
return new returnObject(1, 500, $result);
if ('0000' == $object->code)
return new returnObject(0, 0, '', array(
'code_img_url' => $object->qr_code_url,
'code_url' => substr(strstr($object->qr_code_url, 'uuid='), strlen('uuid=')),
///'code_status' => $resHandler->getParameter('code_status'),
));
else
return new returnObject(1, $object->code, $object->message);
}
/**
* 汇付宝聚合支付--支付宝-线下
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_offline_heepay_ali_v1($orderid, $fee, $title, $notice_url, $attach)
{
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_OFFLINE_HEEPAY_ALIPAY);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
//$openid = $this->userInfo['openid'];
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_paykey'];
//$attach = JsonObjectToJsonString(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1));
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/heepaywechatpay'); /// 异步通知地址
//$callback_url = $this->getFullUrl('/api/newpay/callback/v1?plid=' . $pay_log['plid']); /// 同步通知地址
/// 获取用户IP
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ClientIP = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ClientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']))
$ClientIP = $_SERVER['REMOTE_ADDR'];
else
$ClientIP = null;
$version = 1; /// 必填 当前接口版本号1
$pay_type = 22; /// 必填 支付类型22,(数据类型:int)
$agent_id = $mch_id; /// 必填 商户编号 如1234567(汇付宝商户编号:七位整数数字)
$agent_bill_id = $pay_log['out_trade_no']; /// 必填 商户系统内部的订单号(要保证唯一)。长度最长50字符
$pay_amt = $fee / 100; /// 必填 订单总金额 不可为空,取值范围(0.01到10000000.00),单位:元,小数点后保留两位。
//$notify_url = $notify_url; /// 必填 (异步回调)支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理) 提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
$return_url = 'https://'; /// 必填 (同步回调)支付后返回的商户显示页面,URL参数是以http://或https://开头的完整URL地址(前台显示),原则上该参数与notify_url提交的参数不一致。值可以为空,但不可以为null。
$user_ip = str_ireplace('.', '_', $ClientIP); /// 必填 用户所在客户端的真实ip其中的“.”替换为“_” 。如 127_127_12_12。因为近期我司发现用户在提交数据时,user_ip在网络层被篡改,导致签名错误,所以我们规定使用这种格式。
$agent_bill_time = date('YmdHis', time()); /// 必填 提交单据的时间yyyyMMddHHmmss 如:20100225102000该参数共计14位,当时不满14位时,在后面加0补足14位
$goods_name = rawurlencode($title); /// 必填 商品名称,长度最长50字符,不能为空(不参加签名)
$goods_num = 1; /// 选填 产品数量,长度最长20字符(不参加签名)
//$remark = rawurlencode($attach); /// 必填 商户自定义 原样返回,长度最长50字符,可以为空。(不参加签名)
$remark = JsonObjectToJsonString(array('id' => $pay_log['plid'], 'ver' => 1,)); ///
$goods_note = ''; /// 选填 支付说明,长度50字符(不参加签名)
//$timestamp = time(); /// 选填 时间戳,订单在+-1min内有效,超过时间订单不能提交。如果传此参数,此参数也需要参与签名,参数加在key后面
$sign_key = $secret_key; /// 签名密钥,需要商户使用为自己的真实KEY
/*************创建签名***************/
$sign = "version={$version}&agent_id={$agent_id}&agent_bill_id={$agent_bill_id}&agent_bill_time={$agent_bill_time}&pay_type={$pay_type}&pay_amt={$pay_amt}¬ify_url={$notify_url}&return_url={$return_url}&user_ip={$user_ip}&key={$sign_key}";
$sign = md5($sign); /// 签名值
$param = array(
'version' => $version,
'agent_id' => $agent_id,
'agent_bill_id' => $agent_bill_id,
'agent_bill_time' => $agent_bill_time,
'pay_type' => $pay_type,
'pay_code' => '',
'pay_amt' => $pay_amt,
'notify_url' => $notify_url,
'return_url' => $return_url,
'user_ip' => $user_ip,
'goods_name' => $goods_name,
'goods_num' => $goods_num,
'goods_note' => $goods_note,
'remark' => $remark,
'sign' => $sign,
);
$result = Characet(SendPost('https://pay.heepay.com/Payment/Index.aspx', $param));
//{"code":"0000","message":"success","qr_code_url":"https://pay.swiftpass.cn/pay/qrcode?uuid=weixin%3A%2F%2Fwxpay%2Fbizpayurl%3Fpr%3Dl1zcih6"}
$object = json_decode($result);
if (empty($object))
return new returnObject(1, 500, $result);
if ('0000' == $object->code)
return new returnObject(0, 0, '', array(
'code_img_url' => $object->qr_code_url,
'code_url' => substr(strstr($object->qr_code_url, 'uuid='), strlen('uuid=')),
///'code_status' => $resHandler->getParameter('code_status'),
));
else
return new returnObject(1, $object->code, $object->message);
}
/**
* 微信支付-移动
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_mobile_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
{
/// 保存支付记录
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '', $orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_MOBILE_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$notify_url = $this->getFullUrl('/api/newpay/notify/mobile/wechatpay'); /// 异步通知地址
load()->model('payment');
$wechat = array();
$wechat['appid'] = $this->marketInfo['weixin_appid']; /// 微信公众号APPID
$wechat['secret'] = $this->marketInfo['weixin_secret_appid'];
$wechat['mchid'] = $this->marketInfo['weixin_mchid']; /// 微信公众号商户号
$wechat['signkey'] = $this->marketInfo['weixin_paykey']; /// 支付秘钥
//$openid = $this->userInfo['openid'];
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1,), JSON_UNESCAPED_UNICODE);
///$tools = new AppPay();
$input = new WxPayUnifiedOrder();
$input->SetBody($title); /// 本次支付主题
$input->SetAttach($attach); /// 支付回传的值
$input->SetOut_trade_no($pay_log['out_trade_no']); /// 平台订单号
$input->SetTotal_fee($fee); /// 微信支付单位为分
$input->SetTime_start(date("YmdHis")); /// 支付发起时间戳
$input->SetTime_expire(date("YmdHis", time() + 600)); /// 支付有效期
$input->SetGoods_tag($title); ///
$input->SetNotify_url($notify_url); /// 通知地址
$input->SetTrade_type('APP'); /// 交易类型
$input->SetProduct_id($title); /// 商品ID(trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。)
$order = WxPayApi::unifiedOrder($input, 6, $wechat); /// 获得订单的基本信息,包括prepayid
//print_r($order);
///var_dump($order);
/// 在return_code和result_code都为SUCCESS的时候有返回
if ('SUCCESS' == $order['result_code'] && 'SUCCESS' == $order['return_code'])
{
///$appApiParameters = $tools->GetAppApiParameters($order, $wechat); /// 生成提交给app的一些参数
return new returnObject(0, 0, '', array(
'prepay_id' => $order['prepay_id'],
'nonce_str' => $order['nonce_str'],
'sign' => $order['sign'],
));
}
elseif ('SUCCESS' == $order['return_code'])
return new returnObject(500, $order['err_code'], $order['err_code_des']);
else
return new returnObject(500, $order['return_code'], $order['return_msg']);
}
/**
* 支付宝支付-移动
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _pay_mobile_ali_v1($orderid, $fee, $title, $notice_url, $attach)
{
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
}
/**
* 威富通聚合支付--微信-移动
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_mobile_swiftpass_wechat_v1($orderid, $fee, $title, $notice_url, $attach)
{
/// 保存支付记录
$pay_log = $this->saved_payinfo_v1($this->appid, $this->market_key, '', $orderid, $fee, $title, $notice_url, '', $attach, PAYTYPE_MOBILE_SWIFTPASS_WECHAT);
if (!$pay_log)
return new returnObject(500, 500, '写入支付信息失败, 请联系管理员或稍候再试!', null);
$mch_id = $this->marketInfo['swiftpass_mchid'];
$secret_key = $this->marketInfo['swiftpass_paykey'];
$attach = json_encode(array('app_id' => $this->appid, 'market_key' => $this->market_key, 'version' => 1), JSON_UNESCAPED_UNICODE);
$resHandler = new ClientResponseHandler();
$reqHandler = new RequestHandler();
$pay = new PayHttpClient();
$reqHandler->setGateUrl('https://pay.swiftpass.cn/pay/gateway');
$reqHandler->setKey($secret_key);
$notify_url = $this->getFullUrl('/api/newpay/notify/offline/swiftpasswechatpay', true); /// 异步通知地址
///$reqHandler->setReqParams($_POST, array('method'));
$reqHandler->setParameter('service', 'unified.trade.pay'); /// 接口类型
$reqHandler->setParameter('mch_id', $mch_id); /// 商户号,由平台分配
$reqHandler->setParameter('version', '2.0'); /// 版本号,version默认值是2.0
$reqHandler->setParameter('out_trade_no', $pay_log['out_trade_no']); /// 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
$reqHandler->setParameter('body', $title); /// 商品描述
$reqHandler->setParameter('attach', $attach); /// 商户附加信息,可做扩展参数,255字符内
$reqHandler->setParameter('total_fee', $fee); /// 总金额,以分为单位,不允许包含任何字、符号
$reqHandler->setParameter('mch_create_ip', $_SERVER['REMOTE_ADDR']); /// 订单生成的机器 IP
$reqHandler->setParameter('notify_url', $notify_url); /// 异步通知地址
$reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
$reqHandler->createSign(); /// 创建签名
$data = Utils::toXml($reqHandler->getAllParameters());
//var_dump($data);
$pay->setReqContent($reqHandler->getGateURL(), $data);
if ($pay->call())
{
$resHandler->setContent($pay->getResContent());
$resHandler->setKey($reqHandler->getKey());
if ($resHandler->isTenpaySign())
{
/// 当返回状态与业务结果都为0时才返回,其它结果请查看接口文档
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
{
///$resHandler->getParameter('services')
return new returnObject(0, 0, '', array('prepay_id' => $resHandler->getParameter('token_id'),));
}
else
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'), null);
}
else
return new returnObject(502, $resHandler->getParameter('status'), $resHandler->getParameter('message'), null);
}
else
return new returnObject(501, $pay->getResponseCode(), $pay->getErrInfo(), null);
}
/**
* 威富通聚合支付--支付宝-移动
* @param string $orderid 订单号
* @param integer $fee 支付金额(单位分)
* @param string $title 支付标题
* @param string $notice_url 回调地址(异步)
* @param array|mixed $attach 附带的其他参数
* @return returnObject
*/
private function _pay_mobile_swiftpass_ali_v1($orderid, $fee, $title, $notice_url, $attach)
{
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
$wechat['appid'] = $this->marketInfo['weixin_appid']; /// 微信公众号APPID
$wechat['secret'] = $this->marketInfo['weixin_secret_appid'];
$wechat['mchid'] = $this->marketInfo['weixin_mchid']; /// 微信公众号商户号
$wechat['signkey'] = $this->marketInfo['weixin_paykey']; /// 支付秘钥
$input = new WxPayRefund();
if (!empty($transaction_id))
$input->SetTransaction_id($transaction_id);
elseif (!empty($out_trade_no))
$input->SetOut_trade_no($out_trade_no);
else
return new returnObject(500, 13002, 'transaction_id和out_trade_no参数必须有一个不为空。', null);
$input->SetTotal_fee($total_fee);
$input->SetRefund_fee($refund_fee);
$input->SetOut_refund_no($wechat['mchid'] . date('YmdHis') . random(8, 1));
$input->SetOp_user_id($wechat['mchid']);
$refund_result = WxPayApi::refund($input, 6, $wechat, $this->db);
if (!empty($refund_result) && count($refund_result) > 0)
{
if (strcasecmp($refund_result['return_code'], 'SUCCESS') == 0)
{
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
return new returnObject(0, 0, '申请退款成功。', $attach);
else
return new returnObject(500, 1, '退款失败!');
}
else
return new returnObject(500, 13001, $refund_result);
}
else
return new returnObject(500, 13000, '申请退款返回消息为空。');
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_wechat_with_browser_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
if (empty($trade_no) && empty($out_trade_no))
return new returnObject(1, 13002, '至少传入一个订单号。', null);
$alipay_appid = $this->marketInfo['alipay_appid']; /// 支付宝appid
$sign_key = $this->marketInfo['signkey']; /// 签名key
$RequestBuilder = new AlipayTradeRefundContentBuilder_wappay();
/// 商户订单号和支付宝交易号不能同时为空。 trade_no、 out_trade_no如果同时存在优先取trade_no
$RequestBuilder->setTradeNo($trade_no); /// 支付宝交易号,和商户订单号二选一
$RequestBuilder->setOutTradeNo($out_trade_no); /// 商户订单号,和支付宝交易号二选一
$RequestBuilder->setRefundAmount($refund_fee / 100); /// 退款金额,不能大于订单总金额
$RequestBuilder->setRefundReason('申请退款'); /// 退款的原因说明
$RequestBuilder->setOutRequestNo($order_id); /// 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
$config = array (
'app_id' => $alipay_appid, /// 应用id
//'merchant_private_key' => '', /// 商户私钥,您的原始格式RSA私钥
'merchant_private_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/rsa_private_key.pem', /// 商户私钥文件名
//'notify_url' => $notify_url, /// 异步通知地址
//'return_url' => $callback_url, /// 同步通知地址
'charset' => 'utf-8', /// 编码格式
'sign_type' => 'RSA2', /// 签名方式
'gatewayUrl' => 'https://openapi.alipay.com/gateway.do', /// 支付宝网关
//'alipay_public_key' => '', /// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem', /// 支付宝公钥文件名
);
$Response = new AlipayTradeService_wappay($config);
$result = $Response->Refund($RequestBuilder);
if (10000 == $result->code)
{
if ($this->_notify_alipay_order_status_v1($this->appid, $this->market_key, $out_trade_no, $trade_no, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
return new returnObject(0, 0, '申请退款成功。', $attach);
else
return new returnObject(1, 1, '退款失败!');
}
else
return new returnObject(1, $result->code, $result->msg);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
$resHandler = new ClientResponseHandler();
$reqHandler = new RequestHandler();
$pay = new PayHttpClient();
//$reqHandler->setReqParams($_POST,array('method'));
//$reqParam = $reqHandler->getAllParameters();
if (empty($transaction_id) && empty($out_trade_no))
{
return new returnObject(500, 501, '请输入商户订单号或平台订单号!');
}
$mch_id = $this->marketInfo['swiftpass_mchid'];
$secret_key = $this->marketInfo['swiftpass_paykey'];
$reqHandler->setGateUrl('https://pay.swiftpass.cn/pay/gateway');
$reqHandler->setKey($secret_key);
$reqHandler->setParameter('version', '2.0');
$reqHandler->setParameter('service', 'unified.trade.refund'); /// 接口类型
$reqHandler->setParameter('mch_id', $mch_id); /// 必填项,商户号,由平台分配
$reqHandler->setParameter('out_trade_no', $out_trade_no); /// 商户订单号
$reqHandler->setParameter('transaction_id', $transaction_id); /// 微信订单号
$reqHandler->setParameter('out_refund_no', $order_id); /// 商户退款单号,32个字符内、可包含字母,确保在商户系统唯一。同个退款单号多次请求,平台当一个单处理,只会退一次款。如果出现退款不成功,请采用原退款单号重新发起,避免出现重复退款。
$reqHandler->setParameter('total_fee', $total_fee); /// 总金额
$reqHandler->setParameter('refund_fee', $refund_fee); /// 退款金额
$reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); /// 随机字符串,必填项,不长于 32 位
$reqHandler->setParameter('op_user_id', $mch_id); /// 必填项,操作员帐号,默认为商户号
$reqHandler->createSign(); /// 创建签名
$data = Utils::toXml($reqHandler->getAllParameters()); /// 将提交参数转为xml,目前接口参数也只支持XML方式
$pay->setReqContent($reqHandler->getGateURL(), $data);
if ($pay->call())
{
$resHandler->setContent($pay->getResContent());
$resHandler->setKey($reqHandler->getKey());
if ($resHandler->isTenpaySign())
{
//当返回状态与业务结果都为0时才返,其它结果请查看接口文档
if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0)
{
/*
$res = array('transaction_id'=>$resHandler->getParameter('transaction_id'),
'out_trade_no'=>$resHandler->getParameter('out_trade_no'),
'out_refund_no'=>$resHandler->getParameter('out_refund_no'),
'refund_id'=>$resHandler->getParameter('refund_id'),
'refund_channel'=>$resHandler->getParameter('refund_channel'),
'refund_fee'=>$resHandler->getParameter('refund_fee'),
'coupon_refund_fee'=>$resHandler->getParameter('coupon_refund_fee'));
*/
$res = $resHandler->getAllParameters();
///Utils::dataRecodes('提交退款', $res);
///echo json_encode(array('status'=>200,'msg'=>'退款成功,请查看result.txt文件!','data'=>$res));
///exit();
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
return new returnObject(0, 0, '申请退款成功。', $attach);
else
return new returnObject(500, 1, '退款失败!');
}
else
{
//echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$resHandler->getParameter('err_code').' Error Message:'.$resHandler->getParameter('err_msg')));
//exit();
return new returnObject(500, $resHandler->getParameter('err_code'), $resHandler->getParameter('err_msg'));
}
}
else
{
//echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$resHandler->getParameter('status').' Error Message:'.$resHandler->getParameter('message')));
return new returnObject(500, $resHandler->getParameter('status'), $resHandler->getParameter('message'));
}
}
else
{
//echo json_encode(array('status'=>500,'msg'=>'Response Code:'.$pay->getResponseCode().' Error Info:'.$pay->getErrInfo()));
return new returnObject(500, $pay->getResponseCode(), $pay->getErrInfo());
}
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_swiftpass_ali_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
}
/**
* @param string $XmlData
* @return array
*/
private function XmlToArray($XmlData)
{
$Parser = xml_parser_create();
xml_parse_into_struct($Parser, $XmlData, $Values, $Indexs);
xml_parser_free($Parser);
$Result = null;
foreach ($Indexs as $Key => $Value)
{
foreach ($Value as $Index)
{
if (isset($Values[$Index]['value']))
$Result[strtolower($Key)] = $Values[$Index]['value'];
}
}
return $Result;
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
if (empty($out_trade_no))
return new returnObject(500, 501, '请输入商户订单号或平台订单号!');
$refund = $refund_fee / 100;
$mch_id = $this->marketInfo['heepay_mchid'];
$secret_key = $this->marketInfo['heepay_refundkey'];
//$agent_bill_id = $out_trade_no; /// 选填 商户系统内部的支付订单号(要保证唯一)
$agent_id = $mch_id; /// 必填 商户编号如1234567(汇付宝商户编号:七位整数数字)
//$pay_type = 20; /// 必填 支付类型20,(数据类型:int)
$notify_url = 'https://'; /// 必填 接收异步通知退款结果的页面
$version = 1; /// 当前接口版本号1
$refund_details = "{$out_trade_no},{$refund},t{$out_trade_no}"; /// 商户系统内部的定单号(要保证唯一), 商户退款单号可为空,如果传了要保证唯一, 支持批量退款和部分退款, 商户原支付单号,金额,商户退款单号“|”商户原支付单号,金额,商户退款单号 分割最多支持50笔 注意:金额传0或为空默认做全额退款 样例(63548281250,0.01,5232112“|”6358281251,0,5232113)
$signstr = strtolower("agent_id={$agent_id}&key={$secret_key}¬ify_url={$notify_url}&refund_details={$refund_details}&version={$version}"); /// 必填 签名结果
$sign = strtolower(md5($signstr));
$param = array(
'version' => $version,
'agent_id' => $agent_id,
//'agent_bill_id' => $agent_bill_id,
//'pay_type' => $pay_type,
'refund_details' => $refund_details,
'notify_url' => $notify_url,
'sign' => $sign,
);
$result = SendPost('https://pay.heepay.com/API/Payment/PaymentRefund.aspx', $param);
$result = $this->XmlToArray(Characet($result));
///libxml_disable_entity_loader(true);
///$result = json_decode(json_encode(simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
if (strcmp($result->ret_code, '0000') == 0)
{
$sign = "agent_id={$result['agent_id']}&key={$secret_key}&ret_code={$result['ret_code']}&ret_msg={$result['ret_msg']}";
if ($sign != $result->sign)
return new returnObject(1, 500, '返回数据签名错误!', null);
else
{
if ($this->_notify_wechat_order_status_v1($this->appid, $this->market_key, $out_trade_no, $transaction_id, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
return new returnObject(0, 0, '申请退款成功。', $attach);
else
return new returnObject(500, 1, '退款失败!');
}
}
else
return new returnObject(1, intval($result['ret_code']), $result['ret_msg']);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_heepay_ali_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_online_heepay_wechat_with_browser_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
$alipay_appid = $this->marketInfo['alipay_appid']; /// 支付宝appid
$sign_key = $this->marketInfo['signkey']; /// 签名key
/// 第三方应用授权令牌,商户授权系统商开发模式下使用
$appAuthToken = ""; /// 根据真实值填写
/// 创建退款请求builder,设置参数
$refundRequestBuilder = new AlipayTradeRefundContentBuilder_f2fpay();
$refundRequestBuilder->setTradeNo($trade_no); /// 支付宝交易号,和商户订单号不能同时为空
$refundRequestBuilder->setOutTradeNo($out_trade_no); /// 订单支付时传入的商户订单号,不能和 trade_no同时为空。
$refundRequestBuilder->setRefundAmount($refund_fee / 100); /// 需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数
$refundRequestBuilder->setOutRequestNo($order_id); /// 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
$refundRequestBuilder->setAppAuthToken($appAuthToken); /// 第三方应用授权令牌,商户授权系统商开发模式下使用
$config = array (
'app_id' => $alipay_appid, /// 应用id
//'merchant_private_key' => '', /// 商户私钥,您的原始格式RSA私钥
'merchant_private_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/rsa_private_key.pem', /// 商户私钥文件名
//'notify_url' => $notify_url, /// 异步通知地址
//'return_url' => $callback_url, /// 同步通知地址
'charset' => 'utf-8', /// 编码格式
'sign_type' => 'RSA2', /// 签名方式
'gatewayUrl' => 'https://openapi.alipay.com/gateway.do', /// 支付宝网关
//'alipay_public_key' => '', /// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key_filepath' => dirname(dirname(__DIR__)) . '/payment/alipay/key/' . $alipay_appid . '/alipay_rsa_public_key.pem', /// 支付宝公钥文件名
);
/// 初始化类对象,调用refund获取退款应答
$refundResponse = new AlipayTradeService_f2fpay($config);
$refundResult = $refundResponse->refund($refundRequestBuilder);
$response = $refundResult->getResponse();
/// 根据交易状态进行处理
switch ($refundResult->getTradeStatus())
{
case "SUCCESS":
if ($this->_notify_alipay_order_status_v1($this->appid, $this->market_key, $out_trade_no, $trade_no, '', 0, $refund_fee, PAYSTATUS_REFUND, ''))
return new returnObject(0, 0, '申请退款成功。', $attach);
else
return new returnObject(1, 1, '退款失败!');
case "FAILED":
return new returnObject(1, $response->sub_code, $response->sub_msg);
case "UNKNOWN":
return new returnObject(1, $response->code, $response->msg);
default:
return new returnObject(1, 500, '不支持的返回状态,申请退款返回异常!!!');
}
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
return $this->_refund_online_heepay_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_offline_heepay_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_heepay_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_mobile_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_mobile_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $transaction_id 微信订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_mobile_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_swiftpass_wechat_v1($transaction_id, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $trade_no 支付宝订单号
* @param string $out_trade_no 平台订单号
* @param string $order_id 订单号
* @param int $total_fee 订单总金额
* @param int $refund_fee 退款金额
* @param array $attach 其他参数
* @return returnObject
*/
private function _refund_mobile_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach)
{
//return new returnObject(500, 500, '还没有实现该支付功能, 请关注平台后续更新!', null);
return $this->_refund_online_swiftpass_ali_v1($trade_no, $out_trade_no, $order_id, $total_fee, $refund_fee, $attach);
}
/**
* @param string $appid 应用id
* @param string $devkey 开发者id
* @param string $sid sid
* @param string $scode scode
* @param string $orderid 订单号
* @param int $fee 红包金额(单位分)
* @param string $wishing 红包祝福语
* @param string $act_name 活动名称
* @param string $remark 备注
* @param string $sign 签名
* @return array|returnObject
*/
private function verify_send_red_pack_v1($appid = '', $devkey = '', $sid = '', $scode = '', $orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $sign = '')
{
/// 验证公共参数是否合法
parent::init($appid, $devkey, $sid, $scode);
$verify_result = parent::verify();
if (!is_error_api($verify_result))
{
/// 校验签名
$param = $_REQUEST;
$sign_str = '';
if (isset($param['sign']))
{
unset($param['sign']);
$sign_str = SignParameter($param, $this->marketInfo['signkey']);
}
if ($sign_str != $sign)
return new returnObject(500, -1, '签名错误', null);
if (empty($orderid))
return new returnObject(500, 500, '请指定订单编号!', null);
if (!is_numeric($fee))
return new returnObject(500, 500, '请正确指定订单价格!', null);
if (empty($wishing))
return new returnObject(500, 500, '请指定红包祝福语!', null);
if (empty($act_name))
return new returnObject(500, 500, '请指定活动名称!', null);
if (empty($remark))
return new returnObject(500, 500, '请指定备注信息!', null);
/// 获取附加的参数
$attach = GetAttachParameters(array('appid', 'devkey', 'sid', 'scode', 'orderid', 'fee', 'wishing', 'act_name', 'remark', 'send_type', 'version', 'sign',));
$attach['paytime'] = time();
return $attach;
}
elseif ($verify_result instanceof returnObject)
{
return $verify_result;
}
else
{
$return = new returnObject();
$return->from_array((array)$verify_result);
return $verify_result;
}
}
/**
* @note 保存红包信息
* @param string $app_id 支付应用(int)
* @param string $market_key 门店key
* @param string $to_user 领取用户
* @param string $orderid 订单ID
* @param integer $fee 红包金额(单位分)
* @param string $wishing 红包祝福语
* @param string $act_name 活动名称
* @param string $remark 备注信息
* @param array $attach 支付附加参数
* @param string $type 发送方式
* @return mixed
**/
private function saved_redpack_info_v1($app_id, $market_key, $to_user, $orderid, $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = null, $type = '')
{
$tag = array();
$tag['wishing'] = $wishing; /// 红包祝福语
$tag['act_name'] = $act_name; /// 活动名称
$tag['client_ip'] = CLIENT_IP; /// 客户端ip
$tag['remark'] = $remark; /// 备注信息
$tag['attach'] = json_encode($attach, JSON_UNESCAPED_UNICODE);
$tag = json_encode($tag, JSON_UNESCAPED_UNICODE);
$record = array();
$record['type'] = $type; /// 支付方式
$record['app_key'] = $app_id; /// 支付应用(int)
$record['market_key'] = $market_key; /// 支付商家(int)
$record['user_id'] = $to_user; /// 领取用户
$record['order_id'] = $orderid; /// 订单编号
$record['fee'] = $fee; /// 红包金额(单位分)
$record['tag'] = $tag; /// 其他附加内容
$record['state'] = 0; /// 状态(0:创建;1:已成功)
$record['createtime'] = TIMESTAMP; /// 创建时间戳
//$record['out_trade_no'] = md5(date('YmdHis') . '_' . $app_id . '_' . $market_key . '_' . random(8, 1)); /// 支付唯一ID
$record['out_trade_no'] = substr(md5($market_key . TIMESTAMP . random(8, 1)), 0, 28); /// 支付唯一ID
$pdo = $this->db;
try
{
$pdo->beginTransaction();
/// 插入一条支付记录
$id = Sql::replaceInto('syweb_core_redpacklog')->values($record)->exec($pdo)->lastInsertId();
$pdo->commit();
$record['id'] = $id;
return $record;
}
catch(Exception $e)
{
$pdo->rollBack();
echo $e->getMessage();
return false;
}
}
/**
* 微信红包
* @param string $orderid 订单号
* @param integer $fee 红包金额(单位分)
* @param string $wishing 红包祝福语
* @param string $act_name 活动名称
* @param string $remark 备注信息
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _send_red_pack_wechat_v1($orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = array())
{
/// 验证用户登陆方式
if (AUTHTYPE_WECHAT != $this->userInfo['auth_type'])
return new returnObject(500, 500, '请使用微信登录再领取红包!', null);
/// 保存支付记录
$redpack_log = $this->saved_redpack_info_v1($this->appid, $this->market_key, $this->userInfo['openid'],
$orderid, $fee, $wishing, $act_name, $remark, $attach, PAYTYPE_ONLINE_WECHAT);
if (!$redpack_log)
return new returnObject(500, 500, '写入红包信息失败, 请联系管理员或稍候再试!', null);
$wechat = array('appid' => $this->marketInfo['weixin_appid'], /// 微信公众号APPID
'secret' => $this->marketInfo['weixin_secret_appid'],
'mchid' => $this->marketInfo['weixin_mchid'], /// 微信公众号商户号
'signkey' => $this->marketInfo['weixin_paykey'], /// 支付秘钥
);
$input = new WxPaySendredpack();
$input->SetMch_billno($redpack_log['out_trade_no']); /// 商户订单号
$input->SetSend_name($this->marketInfo['market_name']); /// 商户名称
$input->SetRe_openid($redpack_log['user_id']); /// 接受红包的用户的openid
$input->SetTotal_amount($redpack_log['fee']); /// 红包金额(单位分)
$input->SetTotal_num(1); /// 红包发放总人数
$input->SetWishing($wishing); /// 红包祝福语
$input->SetClient_ip(CLIENT_IP); /// 调用接口的机器Ip地址
$input->SetAct_name($act_name); /// 活动名称
$input->SetRemark($remark); /// 备注信息
$result = WxPayApi::sendredpack($input, 6, $wechat);
if (!empty($result) && count($result) > 0)
{
if ($result['return_code'] == 'SUCCESS')
{
if ($result['result_code'] == 'SUCCESS')
{
$this->db->beginTransaction();
Sql::update('syweb_core_redpacklog')->setArgs(array('state' => 1, 'transaction_id' => $result['send_listid'],))->where('id = ?', $redpack_log['id'])->exec($this->db);
$this->db->commit();
return new returnObject(0, 0, '申请红包发送成功!');
}
else
return new returnObject(1, $result['err_code'], $result['err_code_des']);
}
else
return new returnObject(1, $result['return_code'], $result['return_msg']);
}
else
return new returnObject(1, 14019, '申请发送红包返回消息为空。');
}
/**
* 支付宝红包
* @param string $orderid 订单号
* @param integer $fee 红包金额(单位分)
* @param string $wishing 红包祝福语
* @param string $act_name 活动名称
* @param string $remark 备注信息
* @param array|mixed $attach 附带的其他参数
* @return boolean
*/
private function _send_red_pack_ali_v1($orderid = '', $fee = 0, $wishing = '', $act_name = '', $remark = '', $attach = array())
{
return new returnObject(500, 500, '还没有实现该功能, 请关注平台后续更新!', null);
}
/**
* @property({"default":"@db"})
* @var PDO
*/
public $db;
}