2020.02新版
This commit is contained in:
181
plugins/swiftpass/alipay.php
Normal file
181
plugins/swiftpass/alipay.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.alipay.native');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$code_url = $resHandler->getParameter('code_url');
|
||||
}else{
|
||||
sysmsg('支付宝支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付宝支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Language" content="zh-cn">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>支付宝扫码支付 - <?php echo $sitename?></title>
|
||||
<link href="/assets/css/alipay_pay.css" rel="stylesheet" media="screen">
|
||||
</head>
|
||||
<body>
|
||||
<div class="body">
|
||||
<h1 class="mod-title">
|
||||
<span class="ico-wechat"></span><span class="text">支付宝扫码支付</span>
|
||||
</h1>
|
||||
<div class="mod-ct">
|
||||
<div class="order">
|
||||
</div>
|
||||
<div class="amount">¥<?php echo $order['money']?></div>
|
||||
<div class="qr-image" id="qrcode">
|
||||
</div>
|
||||
|
||||
<div class="detail" id="orderDetail">
|
||||
<dl class="detail-ct" style="display: none;">
|
||||
<dt>商家</dt>
|
||||
<dd id="storeName"><?php echo $sitename?></dd>
|
||||
<dt>购买物品</dt>
|
||||
<dd id="productName"><?php echo $order['name']?></dd>
|
||||
<dt>商户订单号</dt>
|
||||
<dd id="billId"><?php echo $order['trade_no']?></dd>
|
||||
<dt>创建时间</dt>
|
||||
<dd id="createTime"><?php echo $order['addtime']?></dd>
|
||||
</dl>
|
||||
<a href="javascript:void(0)" class="arrow"><i class="ico-arrow"></i></a>
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span class="dec dec-left"></span>
|
||||
<span class="dec dec-right"></span>
|
||||
<div class="ico-scan"></div>
|
||||
<div class="tip-text">
|
||||
<p>请使用支付宝扫一扫</p>
|
||||
<p>扫描二维码完成支付</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip-text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<div class="inner">
|
||||
<div id="J_downloadInteraction" class="download-interaction download-interaction-opening">
|
||||
<div class="inner-interaction">
|
||||
<p class="download-opening">正在打开支付宝<span class="download-opening-1">.</span><span class="download-opening-2">.</span><span class="download-opening-3">.</span></p>
|
||||
<p class="download-asking">如果没有打开支付宝,<a id="J_downloadBtn" href="javascript:;" onclick="openAli();">请点此重新唤起</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/js/jquery-qrcode.min.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script>
|
||||
var code_url = '<?php echo $code_url?>';
|
||||
$('#qrcode').qrcode({
|
||||
text: code_url,
|
||||
width: 230,
|
||||
height: 230,
|
||||
foreground: "#000000",
|
||||
background: "#ffffff",
|
||||
typeNumber: -1
|
||||
});
|
||||
// 订单详情
|
||||
$('#orderDetail .arrow').click(function (event) {
|
||||
if ($('#orderDetail').hasClass('detail-open')) {
|
||||
$('#orderDetail .detail-ct').slideUp(500, function () {
|
||||
$('#orderDetail').removeClass('detail-open');
|
||||
});
|
||||
} else {
|
||||
$('#orderDetail .detail-ct').slideDown(500, function () {
|
||||
$('#orderDetail').addClass('detail-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function openAli(){
|
||||
var scheme = 'alipays://platformapi/startapp?saId=10000007&qrcode=';
|
||||
scheme += encodeURIComponent(code_url);
|
||||
|
||||
if(navigator.userAgent.indexOf("Safari") > -1){
|
||||
window.location.href = scheme;
|
||||
}
|
||||
else{
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.style.display = "none";
|
||||
iframe.src = scheme;
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
}
|
||||
window.onload = function(){
|
||||
openAli();
|
||||
setTimeout("loadmsg()", 2000);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
21
plugins/swiftpass/config.ini
Normal file
21
plugins/swiftpass/config.ini
Normal file
@@ -0,0 +1,21 @@
|
||||
[config]
|
||||
;支付插件英文名称,需和目录名称一致,不能有重复
|
||||
name = "swiftpass"
|
||||
|
||||
;支付插件显示名称
|
||||
showname = "威富通"
|
||||
|
||||
;支付插件作者
|
||||
author = "威富通"
|
||||
|
||||
;支付插件作者链接
|
||||
link = "https://www.swiftpass.cn/"
|
||||
|
||||
;支付插件支持的支付方式,多种方式用英文,隔开,可选的有alipay,qqpay,wxpay,bank
|
||||
types = "alipay,wxpay,qqpay,bank,jdpay"
|
||||
|
||||
;支付插件要求传入的参数以及参数显示名称,可选的有appid,appkey,appsecret,appurl,appmchid
|
||||
inputs = "appid:商户号,appkey:RSA平台公钥,appsecret:RSA应用私钥"
|
||||
|
||||
;支付插件要求传入的支付方式参数
|
||||
select = "1:微信公众号支付,2:微信H5支付"
|
||||
167
plugins/swiftpass/inc/WxPay.JsApiPay.php
Normal file
167
plugins/swiftpass/inc/WxPay.JsApiPay.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* 配置账号信息
|
||||
*/
|
||||
|
||||
class WxPayConfig
|
||||
{
|
||||
//微信公众号APPID
|
||||
const APPID = '';
|
||||
|
||||
//微信公众号APPSECRET
|
||||
const APPSECRET = '';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 微信支付API异常类
|
||||
* @author widyhu
|
||||
*
|
||||
*/
|
||||
class WxPayException extends Exception {
|
||||
public function errorMessage()
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* JSAPI支付实现类
|
||||
* 该类实现了从微信公众平台获取code、通过code获取openid和access_token、
|
||||
* 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数
|
||||
*
|
||||
* 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发
|
||||
*
|
||||
* @author widy
|
||||
*
|
||||
*/
|
||||
class JsApiPay
|
||||
{
|
||||
/**
|
||||
*
|
||||
* 网页授权接口微信服务器返回的数据,返回样例如下
|
||||
* {
|
||||
* "access_token":"ACCESS_TOKEN",
|
||||
* "expires_in":7200,
|
||||
* "refresh_token":"REFRESH_TOKEN",
|
||||
* "openid":"OPENID",
|
||||
* "scope":"SCOPE",
|
||||
* "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
|
||||
* }
|
||||
* 其中access_token可用于获取共享收货地址
|
||||
* openid是微信支付jsapi支付接口必须的参数
|
||||
* @var array
|
||||
*/
|
||||
public $data = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* 通过跳转获取用户的openid,跳转流程如下:
|
||||
* 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
|
||||
* 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
|
||||
*
|
||||
* @return 用户的openid
|
||||
*/
|
||||
public function GetOpenid()
|
||||
{
|
||||
//通过code获得openid
|
||||
if (!isset($_GET['code'])){
|
||||
//触发微信返回code码
|
||||
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
|
||||
$url = $this->__CreateOauthUrlForCode($baseUrl);
|
||||
Header("Location: $url");
|
||||
exit();
|
||||
} else {
|
||||
//获取code码,以获取openid
|
||||
$code = $_GET['code'];
|
||||
$openid = $this->GetOpenidFromMp($code);
|
||||
return $openid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 通过code从工作平台获取openid机器access_token
|
||||
* @param string $code 微信跳转回来带上的code
|
||||
*
|
||||
* @return openid
|
||||
*/
|
||||
public function GetOpenidFromMp($code)
|
||||
{
|
||||
$url = $this->__CreateOauthUrlForOpenid($code);
|
||||
//初始化curl
|
||||
$ch = curl_init();
|
||||
//设置超时
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
|
||||
curl_setopt($ch, CURLOPT_HEADER, FALSE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
//运行curl,结果以jason形式返回
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
//取出openid
|
||||
$data = json_decode($res,true);
|
||||
$this->data = $data;
|
||||
$openid = $data['openid'];
|
||||
return $openid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 拼接签名字符串
|
||||
* @param array $urlObj
|
||||
*
|
||||
* @return 返回已经拼接好的字符串
|
||||
*/
|
||||
private function ToUrlParams($urlObj)
|
||||
{
|
||||
$buff = "";
|
||||
foreach ($urlObj as $k => $v)
|
||||
{
|
||||
if($k != "sign"){
|
||||
$buff .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
|
||||
$buff = trim($buff, "&");
|
||||
return $buff;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 构造获取code的url连接
|
||||
* @param string $redirectUrl 微信服务器回跳的url,需要url编码
|
||||
*
|
||||
* @return 返回构造好的url
|
||||
*/
|
||||
private function __CreateOauthUrlForCode($redirectUrl)
|
||||
{
|
||||
$urlObj["appid"] = WxPayConfig::APPID;
|
||||
$urlObj["redirect_uri"] = $redirectUrl;
|
||||
$urlObj["response_type"] = "code";
|
||||
$urlObj["scope"] = "snsapi_base";
|
||||
$urlObj["state"] = "STATE"."#wechat_redirect";
|
||||
$bizString = $this->ToUrlParams($urlObj);
|
||||
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 构造获取open和access_toke的url地址
|
||||
* @param string $code,微信跳转带回的code
|
||||
*
|
||||
* @return 请求的url
|
||||
*/
|
||||
private function __CreateOauthUrlForOpenid($code)
|
||||
{
|
||||
$urlObj["appid"] = WxPayConfig::APPID;
|
||||
$urlObj["secret"] = WxPayConfig::APPSECRET;
|
||||
$urlObj["code"] = $code;
|
||||
$urlObj["grant_type"] = "authorization_code";
|
||||
$bizString = $this->ToUrlParams($urlObj);
|
||||
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
|
||||
}
|
||||
}
|
||||
236
plugins/swiftpass/inc/class/ClientResponseHandler.class.php
Normal file
236
plugins/swiftpass/inc/class/ClientResponseHandler.class.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 后台应答类
|
||||
* ============================================================================
|
||||
* api说明:
|
||||
* getKey()/setKey(),获取/设置密钥
|
||||
* getContent() / setContent(), 获取/设置原始内容
|
||||
* getParameter()/setParameter(),获取/设置参数值
|
||||
* getAllParameters(),获取所有参数
|
||||
* isTenpaySign(),是否平台签名,true:是 false:否
|
||||
* getDebugInfo(),获取debug信息
|
||||
*
|
||||
* ============================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
class ClientResponseHandler {
|
||||
|
||||
/** MD5密钥 */
|
||||
var $key;
|
||||
|
||||
/* 平台RSA公钥 */
|
||||
var $public_rsa_key;
|
||||
|
||||
var $signtype;
|
||||
|
||||
/** 应答的参数 */
|
||||
var $parameters;
|
||||
|
||||
/** debug信息 */
|
||||
var $debugInfo;
|
||||
|
||||
//原始内容
|
||||
var $content;
|
||||
|
||||
function __construct() {
|
||||
$this->ClientResponseHandler();
|
||||
}
|
||||
|
||||
function ClientResponseHandler() {
|
||||
$this->key = "";
|
||||
$this->public_rsa_key = "";
|
||||
$this->signtype = "";
|
||||
$this->parameters = array();
|
||||
$this->debugInfo = "";
|
||||
$this->content = "";
|
||||
}
|
||||
|
||||
/**
|
||||
*获取密钥
|
||||
*/
|
||||
function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
*设置密钥
|
||||
*/
|
||||
function setKey($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/*设置平台公钥*/
|
||||
function setRSAKey($key) {
|
||||
$this->public_rsa_key = $key;
|
||||
}
|
||||
|
||||
function setSignType($type) {
|
||||
$this->signtype = $type;
|
||||
}
|
||||
|
||||
//设置原始内容
|
||||
function setContent($content) {
|
||||
$this->content = $content;
|
||||
|
||||
libxml_disable_entity_loader(true);
|
||||
$xml = simplexml_load_string($this->content);
|
||||
$encode = $this->getXmlEncode($this->content);
|
||||
|
||||
if($xml && $xml->children()) {
|
||||
foreach ($xml->children() as $node){
|
||||
//有子节点
|
||||
if($node->children()) {
|
||||
$k = $node->getName();
|
||||
$nodeXml = $node->asXML();
|
||||
$v = substr($nodeXml, strlen($k)+2, strlen($nodeXml)-2*strlen($k)-5);
|
||||
|
||||
} else {
|
||||
$k = $node->getName();
|
||||
$v = (string)$node;
|
||||
}
|
||||
|
||||
if($encode!="" && $encode != "UTF-8") {
|
||||
$k = iconv("UTF-8", $encode, $k);
|
||||
$v = iconv("UTF-8", $encode, $v);
|
||||
}
|
||||
|
||||
$this->setParameter($k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取原始内容
|
||||
function getContent() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取参数值
|
||||
*/
|
||||
function getParameter($parameter) {
|
||||
return isset($this->parameters[$parameter])?$this->parameters[$parameter] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
*设置参数值
|
||||
*/
|
||||
function setParameter($parameter, $parameterValue) {
|
||||
$this->parameters[$parameter] = $parameterValue;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取所有请求的参数
|
||||
*@return array
|
||||
*/
|
||||
function getAllParameters() {
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
*是否平台签名,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
|
||||
*true:是
|
||||
*false:否
|
||||
*/
|
||||
function isTenpaySign() {
|
||||
$swiftpassSign = strtolower($this->getParameter("sign"));
|
||||
if ($this->getParameter('sign_type') == 'MD5') {
|
||||
return $this->getMD5Sign() == $swiftpassSign;
|
||||
} else if ($this->getParameter('sign_type') == 'RSA_1_1' || $this->getParameter('sign_type') == 'RSA_1_256') {
|
||||
return $this->verifyRSASign();
|
||||
}
|
||||
}
|
||||
|
||||
function getMD5Sign() {
|
||||
$signPars = "";
|
||||
ksort($this->parameters);
|
||||
foreach($this->parameters as $k => $v) {
|
||||
if("sign" != $k && "" != $v) {
|
||||
$signPars .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
$signPars .= "key=" . $this->getKey();
|
||||
|
||||
return strtolower(md5($signPars));
|
||||
}
|
||||
|
||||
function verifyRSASign() {
|
||||
$signPars = "";
|
||||
ksort($this->parameters);
|
||||
foreach($this->parameters as $k => $v) {
|
||||
if("sign" != $k && "" != $v) {
|
||||
$signPars .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
|
||||
$signPars = substr($signPars, 0, strlen($signPars) - 1);
|
||||
$res = openssl_get_publickey($this->public_rsa_key);
|
||||
if ($this->getParameter('sign_type') == 'RSA_1_1') {
|
||||
$result = (bool)openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res);
|
||||
openssl_free_key($res);
|
||||
return $result;
|
||||
} else if($this->getParameter('sign_type') == 'RSA_1_256') {
|
||||
$result = (bool)openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res, OPENSSL_ALGO_SHA256);
|
||||
openssl_free_key($res);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*获取debug信息
|
||||
*/
|
||||
function getDebugInfo() {
|
||||
return $this->debugInfo;
|
||||
}
|
||||
|
||||
//获取xml编码
|
||||
function getXmlEncode($xml) {
|
||||
$ret = preg_match ("/<?xml[^>]* encoding=\"(.*)\"[^>]* ?>/i", $xml, $arr);
|
||||
if($ret) {
|
||||
return strtoupper ( $arr[1] );
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*设置debug信息
|
||||
*/
|
||||
function _setDebugInfo($debugInfo) {
|
||||
$this->debugInfo = $debugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否财付通签名
|
||||
* @param signParameterArray 签名的参数数组
|
||||
* @return boolean
|
||||
*/
|
||||
function _isTenpaySign($signParameterArray) {
|
||||
|
||||
$signPars = "";
|
||||
foreach($signParameterArray as $k) {
|
||||
$v = $this->getParameter($k);
|
||||
if("sign" != $k && "" != $v) {
|
||||
$signPars .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
$signPars .= "key=" . $this->getKey();
|
||||
|
||||
$sign = strtolower(md5($signPars));
|
||||
|
||||
$tenpaySign = strtolower($this->getParameter("sign"));
|
||||
|
||||
//debug信息
|
||||
$this->_setDebugInfo($signPars . " => sign:" . $sign .
|
||||
" tenpaySign:" . $this->getParameter("sign"));
|
||||
|
||||
return $sign == $tenpaySign;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
119
plugins/swiftpass/inc/class/PayHttpClient.class.php
Normal file
119
plugins/swiftpass/inc/class/PayHttpClient.class.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* http、https通信类
|
||||
* ============================================================================
|
||||
* api说明:
|
||||
* setReqContent($reqContent),设置请求内容
|
||||
* getResContent(), 获取应答内容
|
||||
* setMethod($method),设置请求方法,post或者get
|
||||
* getErrInfo(),获取错误信息
|
||||
* setCertInfo($certFile, $certPasswd, $certType="PEM"),设置证书,双向https时需要使用
|
||||
* setCaInfo($caFile), 设置CA,格式未pem,不设置则不检查
|
||||
* setTimeOut($timeOut), 设置超时时间,单位秒
|
||||
* getResponseCode(), 取返回的http状态码
|
||||
* call(),真正调用接口
|
||||
*
|
||||
* ============================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
class PayHttpClient {
|
||||
//请求内容,无论post和get,都用get方式提供
|
||||
var $reqUrl;
|
||||
var $reqContent;
|
||||
//应答内容
|
||||
var $resContent;
|
||||
|
||||
//错误信息
|
||||
var $errInfo;
|
||||
|
||||
//超时时间
|
||||
var $timeOut;
|
||||
|
||||
//http状态码
|
||||
var $responseCode;
|
||||
|
||||
function __construct() {
|
||||
$this->PayHttpClient();
|
||||
}
|
||||
|
||||
|
||||
function PayHttpClient() {
|
||||
$this->reqContent = "";
|
||||
$this->resContent = "";
|
||||
|
||||
$this->errInfo = "";
|
||||
|
||||
$this->timeOut = 120;
|
||||
|
||||
$this->responseCode = 0;
|
||||
|
||||
}
|
||||
|
||||
//设置请求内容
|
||||
function setReqContent($url,$data) {
|
||||
$this->reqUrl=$url;
|
||||
$this->reqContent=$data;
|
||||
}
|
||||
|
||||
//获取结果内容
|
||||
function getResContent() {
|
||||
return $this->resContent;
|
||||
}
|
||||
|
||||
//获取错误信息
|
||||
function getErrInfo() {
|
||||
return $this->errInfo;
|
||||
}
|
||||
|
||||
//设置超时时间,单位秒
|
||||
function setTimeOut($timeOut) {
|
||||
$this->timeOut = $timeOut;
|
||||
}
|
||||
|
||||
//执行http调用
|
||||
function call() {
|
||||
//启动一个CURL会话
|
||||
$ch = curl_init();
|
||||
|
||||
// 设置curl允许执行的最长秒数
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeOut);
|
||||
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
|
||||
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
|
||||
// 获取的信息以文件流的形式返回,而不是直接输出。
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
|
||||
|
||||
//发送一个常规的POST请求。
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_URL, $this->reqUrl);
|
||||
//要传送的所有数据
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->reqContent);
|
||||
|
||||
// 执行操作
|
||||
$res = curl_exec($ch);
|
||||
$this->responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($res == NULL) {
|
||||
$this->errInfo = "call http err :" . curl_errno($ch) . " - " . curl_error($ch) ;
|
||||
curl_close($ch);
|
||||
return false;
|
||||
} else if($this->responseCode != "200") {
|
||||
$this->errInfo = "call http err httpcode=" . $this->responseCode ;
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
$this->resContent = $res;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getResponseCode() {
|
||||
return $this->responseCode;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
225
plugins/swiftpass/inc/class/RequestHandler.class.php
Normal file
225
plugins/swiftpass/inc/class/RequestHandler.class.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* 请求类
|
||||
* ============================================================================
|
||||
* api说明:
|
||||
* init(),初始化函数,默认给一些参数赋值,如cmdno,date等。
|
||||
* getGateURL()/setGateURL(),获取/设置入口地址,不包含参数值
|
||||
* getKey()/setKey(),获取/设置密钥
|
||||
* getParameter()/setParameter(),获取/设置参数值
|
||||
* getAllParameters(),获取所有参数
|
||||
* getRequestURL(),获取带参数的请求URL
|
||||
* getDebugInfo(),获取debug信息
|
||||
*
|
||||
* ============================================================================
|
||||
*
|
||||
*/
|
||||
class RequestHandler {
|
||||
|
||||
/** 网关url地址 */
|
||||
var $gateUrl;
|
||||
|
||||
/** 密钥 */
|
||||
var $key;
|
||||
|
||||
/* RSA私钥*/
|
||||
var $private_rsa_key;
|
||||
|
||||
var $signtype;
|
||||
|
||||
/** 请求的参数 */
|
||||
var $parameters;
|
||||
|
||||
/** debug信息 */
|
||||
var $debugInfo;
|
||||
|
||||
function __construct() {
|
||||
$this->RequestHandler();
|
||||
}
|
||||
|
||||
function RequestHandler() {
|
||||
$this->gateUrl = "";
|
||||
$this->key = "";
|
||||
$this->private_rsa_key = "";
|
||||
$this->signtype = "";
|
||||
$this->parameters = array();
|
||||
$this->debugInfo = "";
|
||||
}
|
||||
|
||||
/**
|
||||
*初始化函数。
|
||||
*/
|
||||
function init() {
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
*获取入口地址,不包含参数值
|
||||
*/
|
||||
function getGateURL() {
|
||||
return $this->gateUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
*设置入口地址,不包含参数值
|
||||
*/
|
||||
function setGateURL($gateUrl) {
|
||||
$this->gateUrl = $gateUrl;
|
||||
}
|
||||
|
||||
function setSignType($type) {
|
||||
$this->signtype = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取MD5密钥
|
||||
*/
|
||||
function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
*设置MD5密钥
|
||||
*/
|
||||
function setKey($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/*设置RSA私钥*/
|
||||
function setRSAKey($key) {
|
||||
$this->private_rsa_key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取参数值
|
||||
*/
|
||||
function getParameter($parameter) {
|
||||
return isset($this->parameters[$parameter])?$this->parameters[$parameter]:'';
|
||||
}
|
||||
|
||||
/**
|
||||
*设置参数值
|
||||
*/
|
||||
function setParameter($parameter, $parameterValue) {
|
||||
$this->parameters[$parameter] = $parameterValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性设置参数
|
||||
*/
|
||||
function setReqParams($post,$filterField=null){
|
||||
if($filterField !== null){
|
||||
forEach($filterField as $k=>$v){
|
||||
unset($post[$v]);
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否存在空值,空值不提交
|
||||
forEach($post as $k=>$v){
|
||||
if(empty($v)){
|
||||
unset($post[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->parameters = $post;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取所有请求的参数
|
||||
*@return array
|
||||
*/
|
||||
function getAllParameters() {
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取带参数的请求URL
|
||||
*/
|
||||
function getRequestURL() {
|
||||
|
||||
$this->createSign();
|
||||
|
||||
$reqPar = "";
|
||||
ksort($this->parameters);
|
||||
foreach($this->parameters as $k => $v) {
|
||||
$reqPar .= $k . "=" . urlencode($v) . "&";
|
||||
}
|
||||
|
||||
//去掉最后一个&
|
||||
$reqPar = substr($reqPar, 0, strlen($reqPar)-1);
|
||||
|
||||
$requestURL = $this->getGateURL() . "?" . $reqPar;
|
||||
|
||||
return $requestURL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*获取debug信息
|
||||
*/
|
||||
function getDebugInfo() {
|
||||
return $this->debugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
*创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
|
||||
*/
|
||||
function createSign() {
|
||||
if($this->signtype == 'MD5') {
|
||||
$this->createMD5Sign();
|
||||
} else {
|
||||
$this->createRSASign();
|
||||
}
|
||||
}
|
||||
|
||||
function createMD5Sign() {
|
||||
$signPars = "";
|
||||
ksort($this->parameters);
|
||||
foreach($this->parameters as $k => $v) {
|
||||
if("" != $v && "sign" != $k) {
|
||||
$signPars .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
$signPars .= "key=" . $this->getKey();
|
||||
$sign = strtoupper(md5($signPars));
|
||||
$this->setParameter("sign", $sign);
|
||||
|
||||
//debug信息
|
||||
$this->_setDebugInfo($signPars . " => sign:" . $sign);
|
||||
}
|
||||
|
||||
function createRSASign() {
|
||||
$signPars = "";
|
||||
ksort($this->parameters);
|
||||
foreach($this->parameters as $k => $v) {
|
||||
if("" != $v && "sign" != $k) {
|
||||
$signPars .= $k . "=" . $v . "&";
|
||||
}
|
||||
}
|
||||
|
||||
$signPars = substr($signPars, 0, strlen($signPars) - 1);
|
||||
|
||||
$res = openssl_get_privatekey($this->private_rsa_key);
|
||||
if ($this->signtype == 'RSA_1_1') {
|
||||
openssl_sign($signPars, $sign, $res);
|
||||
} else if ($this->signtype == 'RSA_1_256') {
|
||||
openssl_sign($signPars, $sign, $res, OPENSSL_ALGO_SHA256);
|
||||
}
|
||||
openssl_free_key($res);
|
||||
$sign = base64_encode($sign);
|
||||
$this->setParameter("sign", $sign);
|
||||
|
||||
//debug信息
|
||||
$this->_setDebugInfo($signPars . " => sign:" . $sign);
|
||||
}
|
||||
|
||||
/**
|
||||
*设置debug信息
|
||||
*/
|
||||
function _setDebugInfo($debugInfo) {
|
||||
$this->debugInfo = $debugInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
73
plugins/swiftpass/inc/class/Utils.class.php
Normal file
73
plugins/swiftpass/inc/class/Utils.class.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
class Utils{
|
||||
/**
|
||||
* 将数据转为XML
|
||||
*/
|
||||
public static function toXml($array){
|
||||
$xml = '<xml>';
|
||||
forEach($array as $k=>$v){
|
||||
$xml.='<'.$k.'><![CDATA['.$v.']]></'.$k.'>';
|
||||
}
|
||||
$xml.='</xml>';
|
||||
return $xml;
|
||||
}
|
||||
|
||||
public static function dataRecodes($title,$data){
|
||||
$handler = fopen('result.txt','a+');
|
||||
$content = "================".$title."===================\n";
|
||||
if(is_string($data) === true){
|
||||
$content .= $data."\n";
|
||||
}
|
||||
if(is_array($data) === true){
|
||||
forEach($data as $k=>$v){
|
||||
$content .= "key: ".$k." value: ".$v."\n";
|
||||
}
|
||||
}
|
||||
$flag = fwrite($handler,$content);
|
||||
fclose($handler);
|
||||
return $flag;
|
||||
}
|
||||
|
||||
public static function parseXML($xmlSrc){
|
||||
if(empty($xmlSrc)){
|
||||
return false;
|
||||
}
|
||||
$array = array();
|
||||
libxml_disable_entity_loader(true);
|
||||
$xml = simplexml_load_string($xmlSrc);
|
||||
$encode = Utils::getXmlEncode($xmlSrc);
|
||||
|
||||
if($xml && $xml->children()) {
|
||||
foreach ($xml->children() as $node){
|
||||
//有子节点
|
||||
if($node->children()) {
|
||||
$k = $node->getName();
|
||||
$nodeXml = $node->asXML();
|
||||
$v = substr($nodeXml, strlen($k)+2, strlen($nodeXml)-2*strlen($k)-5);
|
||||
|
||||
} else {
|
||||
$k = $node->getName();
|
||||
$v = (string)$node;
|
||||
}
|
||||
|
||||
if($encode!="" && $encode != "UTF-8") {
|
||||
$k = iconv("UTF-8", $encode, $k);
|
||||
$v = iconv("UTF-8", $encode, $v);
|
||||
}
|
||||
$array[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
//获取xml编码
|
||||
public static function getXmlEncode($xml) {
|
||||
$ret = preg_match ("/<?xml[^>]* encoding=\"(.*)\"[^>]* ?>/i", $xml, $arr);
|
||||
if($ret) {
|
||||
return strtoupper ( $arr[1] );
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
20
plugins/swiftpass/inc/config.php
Normal file
20
plugins/swiftpass/inc/config.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//威富通配置文件
|
||||
define("PAY_API_APPID", $channel['appid']);
|
||||
define("PAY_API_KEY", $channel['appkey']);
|
||||
define("PAY_API_APPSECRET", $channel['appsecret']);
|
||||
class Config{
|
||||
private $cfg = array(
|
||||
'url'=>'https://pay.swiftpass.cn/pay/gateway', /*支付接口请求地址 */
|
||||
'mchId'=>PAY_API_APPID, /* 商户号,于申请成功后的开户邮件中获取 */
|
||||
'version'=>'2.0',
|
||||
'sign_type'=>'RSA_1_256',
|
||||
'public_rsa_key'=>PAY_API_KEY, /* RSA验签平台公钥 */
|
||||
'private_rsa_key'=>PAY_API_APPSECRET /* RSA签名私钥 */
|
||||
);
|
||||
|
||||
public function C($cfgName){
|
||||
return $this->cfg[$cfgName];
|
||||
}
|
||||
}
|
||||
?>
|
||||
157
plugins/swiftpass/jdpay.php
Normal file
157
plugins/swiftpass/jdpay.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.jdpay.native');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$code_url = $resHandler->getParameter('code_url');
|
||||
}else{
|
||||
sysmsg('京东支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('京东支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Language" content="zh-cn">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>京东扫码支付 - <?php echo $sitename?></title>
|
||||
<link href="/assets/css/jd_pay.css" rel="stylesheet" media="screen">
|
||||
</head>
|
||||
<body>
|
||||
<div class="body">
|
||||
<h1 class="mod-title">
|
||||
<span class="ico-wechat"></span><span class="text">京东扫码支付</span>
|
||||
</h1>
|
||||
<div class="mod-ct">
|
||||
<div class="order">
|
||||
</div>
|
||||
<div class="amount">¥<?php echo $order['money']?></div>
|
||||
<div class="qr-image" id="qrcode">
|
||||
</div>
|
||||
|
||||
<div class="detail" id="orderDetail">
|
||||
<dl class="detail-ct" style="display: none;">
|
||||
<dt>商家</dt>
|
||||
<dd id="storeName"><?php echo $sitename?></dd>
|
||||
<dt>购买物品</dt>
|
||||
<dd id="productName"><?php echo $order['name']?></dd>
|
||||
<dt>商户订单号</dt>
|
||||
<dd id="billId"><?php echo $order['trade_no']?></dd>
|
||||
<dt>创建时间</dt>
|
||||
<dd id="createTime"><?php echo $order['addtime']?></dd>
|
||||
</dl>
|
||||
<a href="javascript:void(0)" class="arrow"><i class="ico-arrow"></i></a>
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span class="dec dec-left"></span>
|
||||
<span class="dec dec-right"></span>
|
||||
<div class="ico-scan"></div>
|
||||
<div class="tip-text">
|
||||
<p>请使用京东APP扫一扫</p>
|
||||
<p>扫描二维码完成支付</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip-text">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/js/jquery-qrcode.min.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script>
|
||||
var code_url = '<?php echo $code_url?>';
|
||||
$('#qrcode').qrcode({
|
||||
text: code_url,
|
||||
width: 230,
|
||||
height: 230,
|
||||
foreground: "#000000",
|
||||
background: "#ffffff",
|
||||
typeNumber: -1
|
||||
});
|
||||
// 订单详情
|
||||
$('#orderDetail .arrow').click(function (event) {
|
||||
if ($('#orderDetail').hasClass('detail-open')) {
|
||||
$('#orderDetail .detail-ct').slideUp(500, function () {
|
||||
$('#orderDetail').removeClass('detail-open');
|
||||
});
|
||||
} else {
|
||||
$('#orderDetail .detail-ct').slideDown(500, function () {
|
||||
$('#orderDetail').addClass('detail-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "jdpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = function(){
|
||||
setTimeout("loadmsg()", 2000);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
39
plugins/swiftpass/notify.php
Normal file
39
plugins/swiftpass/notify.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once('./includes/common.php');
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$cfg = new Config();
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
|
||||
$resHandler->setContent($xml);
|
||||
|
||||
$resHandler->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$transaction_id = $resHandler->getParameter('transaction_id');
|
||||
$out_trade_no = $resHandler->getParameter('out_trade_no');
|
||||
$total_fee = $resHandler->getParameter('total_fee');
|
||||
$fee_type = $resHandler->getParameter('fee_type');
|
||||
$openid = $resHandler->getParameter('openid');
|
||||
if($out_trade_no == TRADE_NO && $total_fee==strval($order['money']*100) && $order['status']==0){
|
||||
if($DB->exec("update `pre_order` set `status` ='1' where `trade_no`='".TRADE_NO."'")){
|
||||
$DB->exec("update `pre_order` set `api_trade_no` ='$transaction_id',`endtime` ='$date',`buyer` ='$openid',`date`=NOW() where `trade_no`='".TRADE_NO."'");
|
||||
processOrder($order);
|
||||
}
|
||||
}
|
||||
//Utils::dataRecodes('½Ó¿Ú»Øµ÷ÊÕµ½Í¨Öª²ÎÊý',$resHandler->getAllParameters());
|
||||
echo 'success';
|
||||
exit();
|
||||
}else{
|
||||
echo 'failure1';
|
||||
exit();
|
||||
}
|
||||
}else{
|
||||
echo 'failure2';
|
||||
}
|
||||
?>
|
||||
166
plugins/swiftpass/qqpay.php
Normal file
166
plugins/swiftpass/qqpay.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.tenpay.native');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$code_url = $resHandler->getParameter('code_url');
|
||||
if(strpos($code_url,'myun.tenpay.com')){
|
||||
$qrcode=explode('&t=',$code_url);
|
||||
$code_url = 'https://qpay.qq.com/qr/'.$qrcode[1];
|
||||
}
|
||||
}else{
|
||||
sysmsg('QQ钱包支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('QQ钱包支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Language" content="zh-cn">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>QQ钱包安全支付 - <?php echo $sitename?></title>
|
||||
<link href="/assets/css/mqq_pay.css?v=1" rel="stylesheet" media="screen">
|
||||
</head>
|
||||
<body>
|
||||
<div class="body">
|
||||
<h1 class="mod-title">
|
||||
<span class="ico-wechat"></span><span class="text">QQ钱包支付</span>
|
||||
</h1>
|
||||
<div class="mod-ct">
|
||||
<div class="order">
|
||||
</div>
|
||||
<div class="amount">¥<?php echo $order['money']?></div>
|
||||
<div class="qr-image" id="qrcode">
|
||||
</div>
|
||||
|
||||
<div class="detail" id="orderDetail">
|
||||
<dl class="detail-ct" style="display: none;">
|
||||
<dt>商家</dt>
|
||||
<dd id="storeName"><?php echo $sitename?></dd>
|
||||
<dt>购买物品</dt>
|
||||
<dd id="productName"><?php echo $order['name']?></dd>
|
||||
<dt>商户订单号</dt>
|
||||
<dd id="billId"><?php echo $order['trade_no']?></dd>
|
||||
<dt>创建时间</dt>
|
||||
<dd id="createTime"><?php echo $order['addtime']?></dd>
|
||||
</dl>
|
||||
<a href="javascript:void(0)" class="arrow"><i class="ico-arrow"></i></a>
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span class="dec dec-left"></span>
|
||||
<span class="dec dec-right"></span>
|
||||
<div class="ico-scan"></div>
|
||||
<div class="tip-text">
|
||||
<p>请使用手机QQ扫一扫</p>
|
||||
<p>扫描二维码完成支付</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip-text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<div class="inner">
|
||||
<p>手机用户可保存上方二维码到手机中</p>
|
||||
<p>在手机QQ扫一扫中选择“相册”即可</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/js/jquery-qrcode.min.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script>
|
||||
var code_url = '<?php echo $code_url?>';
|
||||
$('#qrcode').qrcode({
|
||||
text: code_url,
|
||||
width: 230,
|
||||
height: 230,
|
||||
foreground: "#000000",
|
||||
background: "#ffffff",
|
||||
typeNumber: -1
|
||||
});
|
||||
// 订单详情
|
||||
$('#orderDetail .arrow').click(function (event) {
|
||||
if ($('#orderDetail').hasClass('detail-open')) {
|
||||
$('#orderDetail .detail-ct').slideUp(500, function () {
|
||||
$('#orderDetail').removeClass('detail-open');
|
||||
});
|
||||
} else {
|
||||
$('#orderDetail .detail-ct').slideDown(500, function () {
|
||||
$('#orderDetail').addClass('detail-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "qqpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = loadmsg();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
146
plugins/swiftpass/qqwappay.php
Normal file
146
plugins/swiftpass/qqwappay.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.tenpay.native');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$code_url = $resHandler->getParameter('code_url');
|
||||
}else{
|
||||
sysmsg('QQ钱包支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('QQ钱包支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
if(strpos($_SERVER['HTTP_USER_AGENT'], 'QQ/')!==false){
|
||||
exit("<script>window.location.href='{$code_url}';</script>");
|
||||
}
|
||||
|
||||
?>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>QQ钱包支付</title>
|
||||
<link href="//cdn.staticfile.org/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="col-xs-12 col-sm-10 col-md-8 col-lg-6 center-block" style="float: none;">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" style="text-align: center;"><h3 class="panel-title">
|
||||
<img src="assets/icon/qqpay.ico">QQ钱包支付手机版
|
||||
</div>
|
||||
<div class="list-group" style="text-align: center;">
|
||||
<div class="list-group-item"><h1>¥<?php echo $order['money']?><h1></div>
|
||||
<div class="list-group-item">商品名称:<?php echo $order['name']?><br/>商户订单号:<?php echo $order['trade_no']?><br/>创建时间:<?php echo $order['addtime']?></div>
|
||||
<div class="list-group-item"><a href="" id="openUrl" class="btn btn-primary btn-block">跳转到QQ支付</a></div>
|
||||
<div class="list-group-item"><a href="#" onclick="checkresult()" class="btn btn-success btn-block">检测支付状态</a></div>
|
||||
<div class="list-group-item"><a href="/pay/swiftpass/qqpay/<?php echo TRADE_NO?>/" class="btn btn-default btn-sm btn-block">使用扫码支付</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script>
|
||||
var isSafari = navigator.userAgent.indexOf("Safari") > -1;
|
||||
var code_url = '<?php echo $code_url?>';
|
||||
var tencentSeries = 'mqqapi://forward/url?src_type=web&style=default&=1&version=1&url_prefix='+window.btoa(code_url);
|
||||
if(isSafari){
|
||||
location.href = tencentSeries;
|
||||
}
|
||||
else{
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.style.display = "none";
|
||||
iframe.src = tencentSeries;
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
document.getElementById("openUrl").href = tencentSeries;
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "qqpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function checkresult() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "qqpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = loadmsg();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
64
plugins/swiftpass/return.php
Normal file
64
plugins/swiftpass/return.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
* 微信H5支付返回中转页面
|
||||
*/
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
||||
<link href="//cdn.staticfile.org/ionic/1.3.2/css/ionic.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="bar bar-header bar-light" align-title="center">
|
||||
<h1 class="title">订单处理结果</h1>
|
||||
</div>
|
||||
<div class="has-header" style="padding: 5px;position: absolute;width: 100%;">
|
||||
<div class="text-center" style="color: #a09ee5;">
|
||||
<i class="icon ion-information-circled" style="font-size: 80px;"></i><br>
|
||||
<span>正在检测付款结果...</span>
|
||||
<script src="//cdn.staticfile.org/jquery/1.12.4/jquery.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/layer/2.3/layer.js"></script>
|
||||
<script>
|
||||
$(document).on('touchmove',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo TRADE_NO?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
window.location.href=data.backurl;
|
||||
}else{
|
||||
setTimeout("loadmsg()", 3000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = loadmsg();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
28
plugins/swiftpass/submit.php
Normal file
28
plugins/swiftpass/submit.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
if($order['typename']=='alipay'){
|
||||
echo "<script>window.location.href='/pay/swiftpass/alipay/{$trade_no}/';</script>";
|
||||
}elseif($order['typename']=='wxpay'){
|
||||
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')!==false){
|
||||
echo "<script>window.location.href='/pay/swiftpass/wxjspay/{$trade_no}/?d=1';</script>";
|
||||
}elseif(checkmobile()==true){
|
||||
if(in_array('2',$channel['apptype'])){
|
||||
echo "<script>window.location.href='/pay/swiftpass/wxh5pay/{$trade_no}/';</script>";
|
||||
}else{
|
||||
echo "<script>window.location.href='/pay/swiftpass/wxwappay/{$trade_no}/';</script>";
|
||||
}
|
||||
}else{
|
||||
echo "<script>window.location.href='/pay/swiftpass/wxpay/{$trade_no}/';</script>";
|
||||
}
|
||||
}elseif($order['typename']=='qqpay'){
|
||||
if(checkmobile()==true){
|
||||
echo "<script>window.location.href='/pay/swiftpass/qqwappay/{$trade_no}/';</script>";
|
||||
}else{
|
||||
echo "<script>window.location.href='/pay/swiftpass/qqpay/{$trade_no}/';</script>";
|
||||
}
|
||||
}elseif($order['typename']=='jdpay'){
|
||||
echo "<script>window.location.href='/pay/swiftpass/jdpay/{$trade_no}/';</script>";
|
||||
}elseif($order['typename']=='bank'){
|
||||
echo "<script>window.location.href='/pay/swiftpass/bank/{$trade_no}/';</script>";
|
||||
}
|
||||
57
plugins/swiftpass/wxh5pay.php
Normal file
57
plugins/swiftpass/wxh5pay.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.weixin.wappay');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('device_info', 'AND_WAP');//应用类型
|
||||
$reqHandler->setParameter('mch_app_name',$sitename);//应用名
|
||||
$reqHandler->setParameter('mch_app_id',$siteurl);//应用标识
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$reqHandler->setParameter('callback_url',$siteurl.'pay/swiftpass/return/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$pay_info = $resHandler->getParameter('pay_info');
|
||||
exit("<script>window.location.replace('{$pay_info}');</script>");
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
?>
|
||||
160
plugins/swiftpass/wxjspay.php
Normal file
160
plugins/swiftpass/wxjspay.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require_once PAY_ROOT."inc/WxPay.JsApiPay.php";
|
||||
//①、获取用户openid
|
||||
$tools = new JsApiPay();
|
||||
$openId = $tools->GetOpenid();
|
||||
//②、统一下单
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.weixin.jspay');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('is_raw','1');
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('sub_appid',WxPayConfig::APPID);
|
||||
$reqHandler->setParameter('sub_openid',$openId);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('device_info', 'AND_WAP');//应用类型
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$pay_info = $resHandler->getParameter('pay_info');
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
if($_GET['d']==1){
|
||||
$redirect_url='window.location.href=data.backurl';
|
||||
}else{
|
||||
$redirect_url='WeixinJSBridge.invoke("closeWindow", {}, function(e) {});';
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
||||
<link href="//cdn.staticfile.org/ionic/1.3.2/css/ionic.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="bar bar-header bar-light" align-title="center">
|
||||
<h1 class="title">微信安全支付</h1>
|
||||
</div>
|
||||
<div class="has-header" style="padding: 5px;position: absolute;width: 100%;">
|
||||
<div class="text-center" style="color: #a09ee5;">
|
||||
<i class="icon ion-information-circled" style="font-size: 80px;"></i><br>
|
||||
<span>正在跳转...</span>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script>
|
||||
$(document).on('touchmove',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
//调用微信JS api 支付
|
||||
function jsApiCall()
|
||||
{
|
||||
WeixinJSBridge.invoke(
|
||||
'getBrandWCPayRequest',
|
||||
<?php echo $pay_info; ?>,
|
||||
function(res){
|
||||
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
|
||||
loadmsg();
|
||||
}
|
||||
//WeixinJSBridge.log(res.err_msg);
|
||||
//alert(res.err_code+res.err_desc+res.err_msg);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function callpay()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
// 订单详情
|
||||
$('#orderDetail .arrow').click(function (event) {
|
||||
if ($('#orderDetail').hasClass('detail-open')) {
|
||||
$('#orderDetail .detail-ct').slideUp(500, function () {
|
||||
$('#orderDetail').removeClass('detail-open');
|
||||
});
|
||||
} else {
|
||||
$('#orderDetail .detail-ct').slideDown(500, function () {
|
||||
$('#orderDetail').addClass('detail-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
<?php echo $redirect_url?>
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = callpay();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
161
plugins/swiftpass/wxpay.php
Normal file
161
plugins/swiftpass/wxpay.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
require(PAY_ROOT.'inc/class/Utils.class.php');
|
||||
require(PAY_ROOT.'inc/config.php');
|
||||
require(PAY_ROOT.'inc/class/RequestHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/ClientResponseHandler.class.php');
|
||||
require(PAY_ROOT.'inc/class/PayHttpClient.class.php');
|
||||
|
||||
$resHandler = new ClientResponseHandler();
|
||||
$reqHandler = new RequestHandler();
|
||||
$pay = new PayHttpClient();
|
||||
$cfg = new Config();
|
||||
|
||||
$reqHandler->setGateUrl($cfg->C('url'));
|
||||
$reqHandler->setSignType($cfg->C('sign_type'));
|
||||
$reqHandler->setRSAKey($cfg->C('private_rsa_key'));
|
||||
$reqHandler->setParameter('service','pay.weixin.native');//接口类型
|
||||
$reqHandler->setParameter('mch_id',$cfg->C('mchId'));//必填项,商户号,由平台分配
|
||||
$reqHandler->setParameter('version',$cfg->C('version'));
|
||||
$reqHandler->setParameter('sign_type',$cfg->C('sign_type'));
|
||||
$reqHandler->setParameter('body',$order['name']);
|
||||
$reqHandler->setParameter('total_fee',strval($order['money']*100));
|
||||
$reqHandler->setParameter('mch_create_ip',$clientip);
|
||||
$reqHandler->setParameter('out_trade_no',TRADE_NO);
|
||||
$reqHandler->setParameter('notify_url',$conf['localurl'].'pay/swiftpass/notify/'.TRADE_NO.'/');
|
||||
$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->setRSAKey($cfg->C('public_rsa_key'));
|
||||
if($resHandler->isTenpaySign()){
|
||||
//当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
|
||||
if($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0){
|
||||
$code_url = $resHandler->getParameter('code_url');
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('err_code').']'.$resHandler->getParameter('err_msg'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('微信支付下单失败 ['.$resHandler->getParameter('status').']'.$resHandler->getParameter('message'));
|
||||
}
|
||||
}else{
|
||||
sysmsg('支付接口调用失败 ['.$pay->getResponseCode().']'.$pay->getErrInfo());
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Language" content="zh-cn">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>微信安全支付 - <?php echo $sitename?></title>
|
||||
<link href="/assets/css/wechat_pay.css" rel="stylesheet" media="screen">
|
||||
</head>
|
||||
<body>
|
||||
<div class="body">
|
||||
<h1 class="mod-title">
|
||||
<span class="ico-wechat"></span><span class="text">微信支付</span>
|
||||
</h1>
|
||||
<div class="mod-ct">
|
||||
<div class="order">
|
||||
</div>
|
||||
<div class="amount">¥<?php echo $order['money']?></div>
|
||||
<div class="qr-image" id="qrcode">
|
||||
</div>
|
||||
|
||||
<div class="detail" id="orderDetail">
|
||||
<dl class="detail-ct" style="display: none;">
|
||||
<dt>商家</dt>
|
||||
<dd id="storeName"><?php echo $sitename?></dd>
|
||||
<dt>购买物品</dt>
|
||||
<dd id="productName"><?php echo $order['name']?></dd>
|
||||
<dt>商户订单号</dt>
|
||||
<dd id="billId"><?php echo $order['trade_no']?></dd>
|
||||
<dt>创建时间</dt>
|
||||
<dd id="createTime"><?php echo $order['addtime']?></dd>
|
||||
</dl>
|
||||
<a href="javascript:void(0)" class="arrow"><i class="ico-arrow"></i></a>
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span class="dec dec-left"></span>
|
||||
<span class="dec dec-right"></span>
|
||||
<div class="ico-scan"></div>
|
||||
<div class="tip-text">
|
||||
<p>请使用微信扫一扫</p>
|
||||
<p>扫描二维码完成支付</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip-text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<div class="inner">
|
||||
<p>手机用户可保存上方二维码到手机中</p>
|
||||
<p>在微信扫一扫中选择“相册”即可</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/js/jquery-qrcode.min.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script>
|
||||
$('#qrcode').qrcode({
|
||||
text: '<?php echo $code_url?>',
|
||||
width: 230,
|
||||
height: 230,
|
||||
foreground: "#000000",
|
||||
background: "#ffffff",
|
||||
typeNumber: -1
|
||||
});
|
||||
// 订单详情
|
||||
$('#orderDetail .arrow').click(function (event) {
|
||||
if ($('#orderDetail').hasClass('detail-open')) {
|
||||
$('#orderDetail .detail-ct').slideUp(500, function () {
|
||||
$('#orderDetail').removeClass('detail-open');
|
||||
});
|
||||
} else {
|
||||
$('#orderDetail .detail-ct').slideDown(500, function () {
|
||||
$('#orderDetail').addClass('detail-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = loadmsg();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
106
plugins/swiftpass/wxwappay.php
Normal file
106
plugins/swiftpass/wxwappay.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
if(!defined('IN_PLUGIN'))exit();
|
||||
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$target_url = $siteurl.'pay/swiftpass/wxjspay/'.TRADE_NO.'/';
|
||||
?>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>微信支付</title>
|
||||
<link href="//cdn.staticfile.org/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="col-xs-12 col-sm-10 col-md-8 col-lg-6 center-block" style="float: none;">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading" style="text-align: center;"><h3 class="panel-title">
|
||||
<img src="/assets/icon/wechat.ico">微信支付手机版
|
||||
</div>
|
||||
<div class="list-group" style="text-align: center;">
|
||||
<div class="list-group-item list-group-item-info">长按保存到相册使用扫码扫码完成支付</div>
|
||||
<div class="list-group-item">
|
||||
<div class="qr-image" id="qrcode"></div>
|
||||
</div>
|
||||
<div class="list-group-item list-group-item-info">或复制以下链接到微信打开:</div>
|
||||
<div class="list-group-item">
|
||||
<a href="<?php echo $target_url?>"><?php echo $target_url?></a><br/><button id="copy-btn" data-clipboard-text="<?php echo $target_url?>" class="btn btn-info btn-sm">一键复制</button>
|
||||
</div>
|
||||
<div class="list-group-item"><small>提示:你可以将以上链接发到自己微信的聊天框(在微信顶部搜索框可以搜到自己的微信),即可点击进入支付</small></div>
|
||||
<div class="list-group-item"><a href="weixin://" class="btn btn-primary">打开微信</a> <a href="#" onclick="checkresult()" class="btn btn-success">检测支付状态</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/js/qcloud_util.js"></script>
|
||||
<script src="/assets/js/jquery-qrcode.min.js"></script>
|
||||
<script src="/assets/layer/layer.js"></script>
|
||||
<script src="//cdn.staticfile.org/clipboard.js/1.7.1/clipboard.min.js"></script>
|
||||
<script>
|
||||
var clipboard = new Clipboard('#copy-btn');
|
||||
clipboard.on('success', function(e) {
|
||||
layer.msg('复制成功,请到微信里面粘贴');
|
||||
});
|
||||
clipboard.on('error', function(e) {
|
||||
layer.msg('复制失败,请长按链接后手动复制');
|
||||
});
|
||||
$('#qrcode').qrcode({
|
||||
text: "<?php echo $target_url?>",
|
||||
width: 230,
|
||||
height: 230,
|
||||
foreground: "#000000",
|
||||
background: "#ffffff",
|
||||
typeNumber: -1
|
||||
});
|
||||
// 检查是否支付完成
|
||||
function loadmsg() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}else{
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
if (textStatus == "timeout") {
|
||||
setTimeout("loadmsg()", 1000);
|
||||
} else { //异常
|
||||
setTimeout("loadmsg()", 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function checkresult() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/getshop.php",
|
||||
timeout: 10000, //ajax请求超时时间10s
|
||||
data: {type: "wxpay", trade_no: "<?php echo $order['trade_no']?>"}, //post数据
|
||||
success: function (data, textStatus) {
|
||||
//从服务器得到数据,显示数据并继续查询
|
||||
if (data.code == 1) {
|
||||
layer.msg('支付成功,正在跳转中...', {icon: 16,shade: 0.01,time: 15000});
|
||||
setTimeout(window.location.href=data.backurl, 1000);
|
||||
}
|
||||
},
|
||||
//Ajax请求超时,继续查询
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
window.onload = loadmsg();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user