forked from dedemao/weixinPay
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
<?php | ||
header('Content-type:text/html; Charset=utf-8'); | ||
$mchid = 'xxxxx'; //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 | ||
$appid = 'xxxxx'; //公众号APPID 通过微信支付商户资料审核后邮件发送 | ||
$apiKey = 'xxxxx'; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 | ||
$outTradeNo = uniqid(); //你自己的商品订单号,不能重复 | ||
$payAmount = 0.01; //付款金额,单位:元 | ||
$orderName = '支付测试'; //订单标题 | ||
$authCode = 'xxxxx'; //用户付款码(商户使用设备扫码用户的付款条码读取到的条码数字,或 打开微信-》我-》钱包-》收付款 点击可查看付款码数字) | ||
|
||
$wxPay = new WxpayService($mchid,$appid,$apiKey); | ||
$wxPay->setTotalFee($payAmount); | ||
$wxPay->setOutTradeNo($outTradeNo); | ||
$wxPay->setOrderName($orderName); | ||
$wxPay->setAuthCode($authCode); | ||
$arr = $wxPay->createJsBizPackage(); | ||
if($arr['return_code']=='SUCCESS'){ | ||
echo '付款成功!返回信息如下:<br><hr>'; | ||
echo '<pre>'.print_r($arr).'</pre>'; | ||
exit(); | ||
} | ||
exit('error'); | ||
class WxpayService | ||
{ | ||
protected $mchid; | ||
protected $appid; | ||
protected $apiKey; | ||
protected $totalFee; | ||
protected $outTradeNo; | ||
protected $orderName; | ||
protected $authCode; | ||
public function __construct($mchid='', $appid='', $key='') | ||
{ | ||
$this->mchid = $mchid; | ||
$this->appid = $appid; | ||
$this->apiKey = $key; | ||
} | ||
|
||
public function setTotalFee($totalFee) | ||
{ | ||
$this->totalFee = $totalFee; | ||
} | ||
|
||
public function setOutTradeNo($outTradeNo) | ||
{ | ||
$this->outTradeNo = $outTradeNo; | ||
} | ||
|
||
public function setOrderName($orderName) | ||
{ | ||
$this->orderName = $orderName; | ||
} | ||
|
||
public function setAuthCode($authCode) | ||
{ | ||
$this->authCode = $authCode; | ||
} | ||
|
||
/** | ||
* 发起订单 | ||
* @return array | ||
*/ | ||
public function createJsBizPackage() | ||
{ | ||
$config = array( | ||
'mch_id' => $this->mchid, | ||
'appid' => $this->appid, | ||
'key' => $this->apiKey, | ||
'total_fee' => $this->totalFee, | ||
'out_trade_no' => $this->outTradeNo, | ||
'order_name' => $this->orderName, | ||
'auth_code' => $this->authCode, | ||
); | ||
//$orderName = iconv('GBK','UTF-8',$orderName); | ||
$unified = array( | ||
'appid' => $config['appid'], | ||
'attach' => 'pay', //商家数据包,原样返回,如果填写中文,请注意转换为utf-8 | ||
'body' => $config['order_name'], | ||
'mch_id' => $config['mch_id'], | ||
'nonce_str' => self::createNonceStr(), | ||
'out_trade_no' => $config['out_trade_no'], | ||
'spbill_create_ip' => '127.0.0.1', | ||
'total_fee' => intval($config['total_fee'] * 100), //单位 转为分 | ||
'auth_code'=>$config['auth_code'], //收款码, | ||
'device_info'=>'dedemao001', //终端设备号(商户自定义,如门店编号) | ||
// 'limit_pay'=>'no_credit' //指定支付方式 no_credit--指定不能使用信用卡支付 | ||
); | ||
$unified['sign'] = self::getSign($unified, $config['key']); | ||
$responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/micropay', 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->err_code.'。错误码说明:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1#7'); | ||
} | ||
if ($unifiedOrder->result_code != 'SUCCESS') { | ||
die('支付失败:错误码:'.$unifiedOrder->err_code.'。错误码说明:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1#7'); | ||
} | ||
return (array)$unifiedOrder; | ||
} | ||
public function notify() | ||
{ | ||
$config = array( | ||
'mch_id' => $this->mchid, | ||
'appid' => $this->appid, | ||
'key' => $this->apiKey, | ||
); | ||
$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; | ||
} | ||
} | ||
/** | ||
* curl get | ||
* | ||
* @param string $url | ||
* @param array $options | ||
* @return mixed | ||
*/ | ||
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); | ||
} | ||
//https请求 不验证证书和host | ||
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); //设置cURL允许执行的最长秒数 | ||
if (!empty($options)) { | ||
curl_setopt_array($ch, $options); | ||
} | ||
//https请求 不验证证书和host | ||
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; | ||
} | ||
} |