<?php
class
WxpayService
{
protected
$mchid
;
protected
$appid
;
protected
$key
;
public
function
__construct(
$mchid
,
$appid
,
$key
)
{
$this
->mchid =
$mchid
;
$this
->appid =
$appid
;
$this
->key =
$key
;
}
public
function
createJsBizPackage(
$openid
,
$totalFee
,
$outTradeNo
,
$orderName
,
$notifyUrl
,
$timestamp
)
{
$config
=
array
(
'mch_id'
=>
$this
->mchid,
'appid'
=>
$this
->appid,
'key'
=>
$this
->key,
);
$unified
=
array
(
'appid'
=>
$config
[
'appid'
],
'attach'
=>
'支付'
,
'body'
=>
$orderName
,
'mch_id'
=>
$config
[
'mch_id'
],
'nonce_str'
=> self::createNonceStr(),
'notify_url'
=>
$notifyUrl
,
'openid'
=>
$openid
,
'out_trade_no'
=>
$outTradeNo
,
'spbill_create_ip'
=>
'127.0.0.1'
,
'total_fee'
=>
intval
(
$totalFee
* 100),
'trade_type'
=>
'JSAPI'
,
);
$unified
[
'sign'
] = self::getSign(
$unified
,
$config
[
'key'
]);
$responseXml
= self::curlPost(
'https://api.mch.weixin.qq.com/pay/unifiedorder'
, self::arrayToXml(
$unified
));
$unifiedOrder
= simplexml_load_string(
$responseXml
,
'SimpleXMLElement'
, LIBXML_NOCDATA);
if
(
$unifiedOrder
=== false) {
die
(
'parse xml error'
);
}
if
(
$unifiedOrder
->return_code !=
'SUCCESS'
) {
die
(
$unifiedOrder
->return_msg);
}
if
(
$unifiedOrder
->result_code !=
'SUCCESS'
) {
die
(
$unifiedOrder
->err_code);
}
$arr
=
array
(
"appId"
=>
$config
[
'appid'
],
"timeStamp"
=>
$timestamp
,
"nonceStr"
=> self::createNonceStr(),
"package"
=>
"prepay_id="
.
$unifiedOrder
->prepay_id,
"signType"
=>
'MD5'
,
);
$arr
[
'paySign'
] = self::getSign(
$arr
,
$config
[
'key'
]);
return
$arr
;
}
public
function
notify()
{
$config
=
array
(
'mch_id'
=>
$this
->mchid,
'appid'
=>
$this
->appid,
'key'
=>
$this
->key,
);
$postStr
=
$GLOBALS
[
"HTTP_RAW_POST_DATA"
];
$postObj
= simplexml_load_string(
$postStr
,
'SimpleXMLElement'
, LIBXML_NOCDATA);
if
(
$postObj
=== false) {
die
(
'parse xml error'
);
}
if
(
$postObj
->return_code !=
'SUCCESS'
) {
die
(
$postObj
->return_msg);
}
if
(
$postObj
->result_code !=
'SUCCESS'
) {
die
(
$postObj
->err_code);
}
$arr
= (
array
)
$postObj
;
unset(
$arr
[
'sign'
]);
if
(self::getSign(
$arr
,
$config
[
'key'
]) ==
$postObj
->sign) {
echo
'<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'
;
return
$postObj
;
}
}
public
static
function
curlGet(
$url
=
''
,
$options
=
array
())
{
$ch
= curl_init(
$url
);
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch
, CURLOPT_TIMEOUT, 30);
if
(!
empty
(
$options
)) {
curl_setopt_array(
$ch
,
$options
);
}
curl_setopt(
$ch
, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt(
$ch
, CURLOPT_SSL_VERIFYHOST, false);
$data
= curl_exec(
$ch
);
curl_close(
$ch
);
return
$data
;
}
public
static
function
curlPost(
$url
=
''
,
$postData
=
''
,
$options
=
array
())
{
if
(
is_array
(
$postData
)) {
$postData
= http_build_query(
$postData
);
}
$ch
= curl_init();
curl_setopt(
$ch
, CURLOPT_URL,
$url
);
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch
, CURLOPT_POST, 1);
curl_setopt(
$ch
, CURLOPT_POSTFIELDS,
$postData
);
curl_setopt(
$ch
, CURLOPT_TIMEOUT, 30);
if
(!
empty
(
$options
)) {
curl_setopt_array(
$ch
,
$options
);
}
curl_setopt(
$ch
, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt(
$ch
, CURLOPT_SSL_VERIFYHOST, false);
$data
= curl_exec(
$ch
);
curl_close(
$ch
);
return
$data
;
}
public
static
function
createNonceStr(
$length
= 16)
{
$chars
=
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
;
$str
=
''
;
for
(
$i
= 0;
$i
<
$length
;
$i
++) {
$str
.=
substr
(
$chars
, mt_rand(0,
strlen
(
$chars
) - 1), 1);
}
return
$str
;
}
public
static
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
;
}
public
static
function
getSign(
$params
,
$key
)
{
ksort(
$params
, SORT_STRING);
$unSignParaString
= self::formatQueryParaMap(
$params
, false);
$signStr
=
strtoupper
(md5(
$unSignParaString
.
"&key="
.
$key
));
return
$signStr
;
}
protected
static
function
formatQueryParaMap(
$paraMap
,
$urlEncode
= false)
{
$buff
=
""
;
ksort(
$paraMap
);
foreach
(
$paraMap
as
$k
=>
$v
) {
if
(null !=
$v
&&
"null"
!=
$v
) {
if
(
$urlEncode
) {
$v
= urlencode(
$v
);
}
$buff
.=
$k
.
"="
.
$v
.
"&"
;
}
}
$reqPar
=
''
;
if
(
strlen
(
$buff
) > 0) {
$reqPar
=
substr
(
$buff
, 0,
strlen
(
$buff
) - 1);
}
return
$reqPar
;
}
}