ѡ̳
标题:
增加微信公众号支付
[打印本页]
作者:
admin
时间:
2018-12-27 22:12
标题:
增加微信公众号支付
<?php
defined(
'IN_PHPCMS'
)
or exit
(
'No permission resources.'
)
;
if
(
isset
($set_modules) && $set_modules ==
TRUE
)
{
$i =
isset
($modules) ? count($modules) :
0
;
$modules[$i][
'code'
] = basename(
__FILE__
,
'.class.php'
)
;
$modules[$i][
'name'
] = L(
'weixinpay'
,
''
,
'pay'
)
;
$modules[$i][
'desc'
] = L(
'weixinpay_desc'
,
''
,
'pay'
)
;
$modules[$i][
'is_cod'
] =
'0'
;
$modules[$i][
'is_online'
] =
'1'
;
$modules[$i][
'author'
] =
'
易百讯开发团队
'
;
$modules[$i][
'website'
] =
'http://www.yibaixun.com/'
;
$modules[$i][
'version'
] =
'1.0.0'
;
$modules[$i][
'config'
] =
array
(
array
(
'name'
=>
'weixinpay_appid'
,
'type'
=>
'text'
,
'value'
=>
''
)
,
array
(
'name'
=>
'weixinpay_appsecret'
,
'type'
=>
'text'
,
'value'
=>
''
)
,
array
(
'name'
=>
'weixinpay_mchid'
,
'type'
=>
'text'
,
'value'
=>
''
)
,
array
(
'name'
=>
'weixinpay_key'
,
'type'
=>
'text'
,
'value'
=>
''
)
,
)
;
return
;
}
pc_base
::
load_app_class
(
'pay_abstract'
,
''
,
'0'
)
;
//
开启
session
$session_storage =
'session_'
.
pc_base
::
load_config
(
'system'
,
'session_storage'
)
;
pc_base
::
load_sys_class
($session_storage)
;
class
Weixinpay
extends
paymentabstract{
public function
__construct
($config =
array
()) {
if
(!
empty
($config)) $this->
set_config
($config)
;
$this->
config
[
'return_url'
] = return_url(
'Weixinpay'
)
;
//
大写
$this->
config
[
'weixinpay_signtype'
] =
'MD5'
;
}
public function
getpreparedata
() {
$prepare_data =
array
()
;
return
$prepare_data
;
}
public function
get_code
()
{
if
(!defined(
'CHARSET'
))
{
$charset =
'utf-8'
;
}
else
{
$charset =
CHARSET
;
}
$charset = strtoupper($charset)
;
//
配置参数
$this->
payments
= $this->
config
;
//"Weixinpay";
//
根目录
url
$root_url =
'/'
;
//
查找
openid
$account_db =
pc_base
::
load_model
(
'pay_account_model'
)
;
$member_db =
pc_base
::
load_model
(
'member_model'
)
;
$payorderinfo = $account_db->
get_one
(
array
(
'id'
=> $this->
order_info
[
'id'
])
,
'`userid`'
)
;
$memberinfo = $member_db->
get_one
(
array
(
'userid'
=> $payorderinfo[
'userid'
])
,
'`connectid`'
)
;
//
这里需要获取会员的
openid
//$openid = $memberinfo['connectid'];
$openid = $_SESSION[
'openid'
]
;
if
(
empty
($openid)){
echo
"
获取
openid
失败!
"
;
//
这个
openid
需要预先获取 一般在网站入口那里 设置 :不存在
openid
测请求 返回
code
通过
code
获取
openid
}
$this->
setParameter
(
"openid"
,
$openid)
;
//
商品描述
$this->
setParameter
(
"body"
,
$this->
order_info
[
'id'
])
;
//
商户订单号
$this->
setParameter
(
"out_trade_no"
,
$this->
order_info
[
'id'
])
;
//
订单总金额
$this->
setParameter
(
"total_fee"
,
$this->
product_info
[
'price'
] *
100
)
;
//
支付币种
//$this->setParameter("fee_type", "1");
//
通知
URL
$this->
setParameter
(
"notify_url"
,
$this->
config
[
'return_url'
])
;
//
订单生成的机器
IP
$this->
setParameter
(
"spbill_create_ip"
,
ip())
;
//
传入参数字符编码
$this->
setParameter
(
"input_charset"
,
$charset)
;
//
交易类型
$this->
setParameter
(
"trade_type"
,
"JSAPI"
)
;
$prepay_id = $this->
getPrepayId
()
;
$this->
setPrepayId
($prepay_id)
;
//
为微信支付返回不能带参数 只能伪静态
// echo $this->config['return_url'];
$jsapi = $this->
getParameters
()
;
$price = $this->
product_info
[
'price'
]
;
// print_r(json_decode($jsapi,true));
//wxjsbridge
$html = <<<EOF
<html> <head><title>
微信支付
</title> </head>
<body style="display: flex;
justify-content:center;
align-items: center; width: 100%;">
<br/>
<div align="center" style="width:100%; display: block;" >
<font color="#9ACD32"><b>
该笔订单支付金额为
<span style="color:#f00;font-size:50px">
$price
</span>
元
</b></font><br/><br/>
<button style="width:90%; height:100px; line-height: 100px; border-radius:5px;background-color:#00b43c; border:0px #00b43c solid; cursor: pointer; color:white; font-size:36px;" type="button"color:#34b434;font-style:italic;">callpay
()" >
立即支付
</button>
</div>
</body>
</html>
<script type="text/javascript">
//
调用微信
JS api
支付
function
jsApiCall
()
{
WeixinJSBridge.
invoke
(
'getBrandWCPayRequest',
$jsapi
,
function(
res
){
WeixinJSBridge.
log
(
res
.err_msg);
if(
res
.err_msg == "get_brand_wcpay_request
k") {
location.
href
='/index.php?m=member';
}else{
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
();
}
}
callpay
();
</script>
EOF
;
$button = $html
;
return
$button
;
}
/**
*
客户端接收数据
*
状态码说明 (
0
交易完成
1
交易失败
2
交易超时
3
交易处理中
4
交易未支付)
*
*
*
*
执行日期:
2016-11-18-00:37:17
【接收到的
notify
通知】
:
<xml><appid><![CDATA[wxe3d0167cf9c9fbb2]]></appid>
<attach><![CDATA[10]]></attach>
<bank_type><![CDATA[CFT]]></bank_type>
<cash_fee><![CDATA[2]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<mch_id><![CDATA[1383733802]]></mch_id>
<nonce_str><![CDATA[s4l9wggn9dxx356pie7jguv0mahu8fbq]]></nonce_str>
<openid><![CDATA[oudtvwBsblPqpKiGPSi-2qaPsm30]]></openid>
<out_trade_no><![CDATA[14794006211967]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[51520F6851E5CC3B46F37D7CA8A22898]]></sign>
<time_end><![CDATA[20161118003718]]></time_end>
<total_fee>2</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[4002572001201611180049986614]]></transaction_id>
</xml>
*
*
*/
public function
receive
() {
//
获取通知的数据
$xml = $GLOBALS[
'HTTP_RAW_POST_DATA'
]
;
//$xml = file_get_contents('php://input');
$postdata=$this->
xmlToArray
($xml)
;
//$this->logResult("log::respond::postdata:",$postdata);
$wxsign = $postdata[
'sign'
]
;
$this->
payments
= $this->
config
;
//
同步系统配置参数
//
排除无关的
sign
unset
($postdata[
'sign'
])
;
$sign = $this->
getSign
($postdata)
;
$return_data[
'order_status'
] =
5
;
//
必要参数
$sinarr =
array
(
'wxsign'
=>$wxsign
,
'sign'
=>$sign
,
'key'
=>$this->
payments
[
'weixinpay_key'
])
;
$this->
logResult
(
"log::respond::sign_pk_data:"
,
$sinarr)
;
//
先不比对签名
if
($wxsign == $sign) {
//
交易成功
if
($postdata[
'result_code'
] ==
'SUCCESS'
) {
//
获取
out_trade_no
传过去的订单号
$return_data[
'order_id'
] = $postdata[
'out_trade_no'
]
;
//
必要参数
$return_data[
'order_status'
] =
0
;
// $this->logResult("log::respond::success_data:",$return_data);
$returndata[
'return_code'
] =
'SUCCESS'
;
//order_paid($order_sn, 2);
}
}
else
{
$return_data[
'order_status'
] =
5
;
$returndata[
'return_code'
] =
'FAIL'
;
$returndata[
'return_msg'
] =
'
签名失败
'
;
}
return
$return_data
;
}
/**
*
相应服务器应答状态
*
@param
$result
*/
public function
response
($result) {
if
(
FALSE
== $result)
echo
'ok'
;
else echo
'success'
;
}
/**
*
返回字符过滤
*
@param
$parameter
*/
private function
filterParameter
($parameter)
{
$para =
array
()
;
foreach
($parameter
as
$key => $value)
{
if
(
'sign'
== $key ||
'sign_type'
== $key ||
''
== $value ||
'm'
== $key ||
'a'
== $key ||
'c'
== $key ||
'code'
== $key )
continue
;
else
$para[$key] = $value
;
}
return
$para
;
}
//
设置请求参数
function
setParameter
($parameter
,
$parameterValue) {
$this->
parameters
[$this->
trimString
($parameter)] = $this->
trimString
($parameterValue)
;
}
//
设置参数时需要用到的字符处理函数
function
trimString
($value){
$ret =
null
;
if
(
null
!= $value) {
$ret = $value
;
if
(strlen($ret) ==
0
) {
$ret =
null
;
}
}
return
$ret
;
}
//
生成随机数
function
create_noncestr
( $length =
32
) {
$chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
;
$str =
""
;
for
( $i =
0
;
$i < $length
;
$i++ ) {
$str.= substr($chars
,
mt_rand(
0
,
strlen($chars)-
1
)
,
1
)
;
}
return
$str
;
}
//
获取
prepay_id
function
getPrepayId
()
{
$this->
postXml
()
;
$this->
result
= $this->
xmlToArray
($this->
response
)
;
$prepay_id = $this->
result
[
"prepay_id"
]
;
return
$prepay_id
;
}
// post
请求
xml
function
postXml
()
{
$xml = $this->
createXml
()
;
$this->
response
= $this->
postXmlCurl
($xml
,
'https://api.mch.weixin.qq.com/pay/unifiedorder'
,
'30'
)
;
//var_dump($this->response);
return
$this->
response
;
}
//
设置标配的请求参数,生成签名,生成接口参数
xml
function
createXml
()
{
$this->
parameters
[
"appid"
] = $this->
payments
[
'weixinpay_appid'
]
;
//
公众账号
ID
$this->
parameters
[
"mch_id"
] = $this->
payments
[
'weixinpay_mchid'
]
;
//
商户号
$this->
parameters
[
"nonce_str"
] = $this->
create_noncestr
()
;
//
随机字符串
$this->
parameters
[
"sign"
] = $this->
getSign
($this->
parameters
)
;
//
签名
//print_r($this->parameters);
return
$this->
arrayToXml
($this->
parameters
)
;
}
function
xmlToArray
($xml)
{
//
将
XML
转为
array
$array_data = json_decode(json_encode(simplexml_load_string($xml
,
'SimpleXMLElement'
,
LIBXML_NOCDATA
))
,
true
)
;
return
$array_data
;
}
function
arrayToXml
($arr)
{
$xml =
"<xml>"
;
foreach
($arr
as
$key=>$val)
{
if
(is_numeric($val))
{
$xml.=
"<"
.$key.
">"
.$val.
"</"
.$key.
">"
;
}
else
$xml.=
"<"
.$key.
"><![CDATA["
.$val.
"]]></"
.$key.
">"
;
}
$xml.=
"</xml>"
;
return
$xml
;
}
/**
*
@brief
从
xml
到
array
转换数据格式
*
@param
xml $xmlData
*
@return
array
*/
private function
converArray
($xmlData)
{
$result =
array
()
;
$xmlHandle = xml_parser_create()
;
xml_parse_into_struct($xmlHandle
,
$xmlData
,
$resultArray)
;
foreach
($resultArray
as
$key => $val)
{
if
($val[
'tag'
] !=
'XML'
)
{
$result[$val[
'tag'
]] = $val[
'value'
]
;
}
}
return
array_change_key_case($result)
;
}
function
postXmlCurl
($xml
,
$url
,
$second=
30
)
{
//
初始化
curl
$ch = curl_init()
;
curl_setopt($ch
,
CURLOPT_URL
,
$url)
;
curl_setopt($ch
,
CURLOPT_SSL_VERIFYPEER
,
FALSE
)
;
curl_setopt($ch
,
CURLOPT_SSL_VERIFYHOST
,
FALSE
)
;
//
设置
header
curl_setopt($ch
,
CURLOPT_HEADER
,
FALSE
)
;
//
要求结果为字符串且输出到屏幕上
curl_setopt($ch
,
CURLOPT_RETURNTRANSFER
,
TRUE
)
;
//post
提交方式
curl_setopt($ch
,
CURLOPT_POST
,
TRUE
)
;
curl_setopt($ch
,
CURLOPT_POSTFIELDS
,
$xml)
;
//
运行
curl
$data = curl_exec($ch)
;
curl_close($ch)
;
//var_dump($data);
if
($data)
{
//curl_close($ch);
return
$data
;
}
else
{
$error = curl_errno($ch)
;
echo
"curl
出错,错误码
:
$error
"
.
"<br>"
;
echo
"<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>
错误原因查询
</a></br>"
;
curl_close($ch)
;
return false
;
}
}
//
作用:生成签名
public function
getSign
($Obj)
{
foreach
($Obj
as
$k => $v)
{
$Parameters[$k] = $v
;
}
//
签名步骤一:按字典序排序参数
ksort($Parameters)
;
$String = $this->
formatBizQueryParaMap
($Parameters
,
false
)
;
//echo '
【
string1
】
'.$String.'</br>';
//
签名步骤二:在
string
后加入
KEY
$String = $String.
"&key="
.$this->
payments
[
'weixinpay_key'
]
;
//echo "
【
string2
】
".$String."</br>";
//
签名步骤三:
MD5
加密
$String = md5($String)
;
//echo "
【
string3
】
".$String."</br>";
//
签名步骤四:所有字符转为大写
$result_ = strtoupper($String)
;
//echo "
【
result
】
".$result_."</br>";
return
$result_
;
}
/**
*
格式化参数,签名过程需要使用
*/
function
formatBizQueryParaMap
($paraMap
,
$urlencode)
{
$buff =
""
;
ksort($paraMap)
;
foreach
($paraMap
as
$k => $v)
{
if
($urlencode)
{
$v = urlencode($v)
;
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k .
"="
. $v .
"&"
;
}
$reqPar
;
if
(strlen($buff) >
0
)
{
$reqPar = substr($buff
,
0
,
strlen($buff)-
1
)
;
}
return
$reqPar
;
}
function
setPrepayId
($prepayId)
{
$this->
prepay_id
= $prepayId
;
}
/**
*
设置
jsapi
的参数
*/
function
getParameters
()
{
$jsApiObj[
"appId"
] = $this->
payments
[
'weixinpay_appid'
]
;
$timeStamp = time()
;
$jsApiObj[
"timeStamp"
] =
"
$timeStamp
"
;
$jsApiObj[
"nonceStr"
] = $this->
create_noncestr
()
;
$jsApiObj[
"package"
] =
"prepay_id=
$this->
prepay_id
"
;
$jsApiObj[
"signType"
] = $this->
payments
[
'weixinpay_signtype'
]
;
$jsApiObj[
"paySign"
] = $this->
getSign
($jsApiObj)
;
$this->
parameters
= json_encode($jsApiObj)
;
return
$this->
parameters
;
}
//
增加
function
logResult
($word =
''
,
$var=
array
()) {
$output= strftime(
"%Y%m%d %H:%M:%S"
,
time()) .
"
\n
"
;
$output .= $word.
"
\n
"
;
if
(!
empty
($var)){
$output .= print_r($var
,
true
).
"
\n
"
;
}
$output.=
"
\n
"
;
$log_path=
PHPCMS_PATH
.
"/log/"
;
if
(!is_dir($log_path)){
@mkdir($log_path
,
0777
,
true
)
;
}
file_put_contents($log_path.
"weixin.txt"
,
$output
,
FILE_APPEND
|
LOCK_EX
)
;
}
}
?>
作者:
admin
时间:
2018-12-27 22:14
预先获取openid, 返回路径不能带参数 只能伪静态, 签名 时带上key .
#
微信支付通知的专用的伪静态
RewriteRule
^pay/respond_Weixinpay.html index.php?m=pay&c=respond&a=respond&code=Weixinpay
作者:
admin
时间:
2018-12-27 22:18
//
微信浏览器
if
(isMobile()&&strstr($_SERVER[
'HTTP_USER_AGENT'
]
,
'MicroMessenger'
)){
$session_storage =
'session_'
.
pc_base
::
load_config
(
'system'
,
'session_storage'
)
;
pc_base
::
load_sys_class
($session_storage)
;
$weixin_arr = M(
'pay_payment'
)->
where
(
array
(
'pay_code'
=>
'Weixinpay'
))->
find
()
;
$weixin_config = json_decode($weixin_arr[
'config'
]
,
true
)
;
$appid = $weixin_config[
'weixinpay_appid'
][
'value'
]
;
$appkey = $weixin_config[
'weixinpay_appsecret'
][
'value'
]
;
if
(
empty
($_SESSION[
'openid'
])&&!
isset
($_GET[
'code'
])){
if
($weixin_config[
'weixinpay_appid'
][
'value'
]){
$backurl =
APP_PATH
.
"index.php"
;
header(
"location:
http://open.weixin.qq.com/connect/oauth2/authorize?appid=
"
.$appid.
"&redirect_uri="
.$backurl.
"&response_type=code&scope=snsapi_base&state=qqchongzhi#wechat_redirect"
)
;
}
}
if
(
isset
($_GET[
'code'
])&&strlen($_GET[
'code'
])>
30
){
$code = $_GET[
'code'
]
;
$url =
"https://api.weixin.qq.com/sns/oauth2/access_token?appid=
$appid
&secret=
$appkey
&code=
$code
&grant_type=authorization_code"
;
$content = file_get_contents( $url)
;
$resdata = json_decode($content
,
true
)
;
$_SESSION[
'openid'
] = $resdata[
'openid'
]
;
}
//header('location:'.$siteurl.'index.php?m=wap&siteid='.$siteid);
}
欢迎光临 ѡ̳ (http://www.sunminxuan.cn/bbs/)
Powered by Discuz! X3.4