CRMEB/extend/service/WxpayService.php
2018-12-31 13:39:11 +08:00

208 lines
7.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace service;
/**
* 微信扫码支付
* Class WxpayService
* @package service
*
* 调用实例
*
* $data['total_amount'] = $payAmount;//价格
$data['order_id'] = time().$themeEnlist['enlist_card'].mt_rand(10,99);//订单 不能超过32为
ThemeEnlistModel::edit($data,$idB);
$mchid = SystemConfig::getValue('pay_weixin_mchid'); //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送
$appid = SystemConfig::getValue('pay_weixin_appid'); //公众号APPID 通过微信支付商户资料审核后邮件发送
$apiKey = SystemConfig::getValue('pay_weixin_key'); //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
$wxPay = new WxpayService($mchid,$appid,$apiKey);//实例化微信扫码类
$outTradeNo = $data['order_id']; //你自己的商品订单号
$notifyUrl = SystemConfig::getValue('site_url').Url::build('index/Themeenlist/wapay_success_notify'); //付款成功后的回调地址(不要有问号)
$payTime = time(); //付款时间
$arr = $wxPay->createJsBizPackage($payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime);//创建成功会微信返回的数据
$url = 'http://pan.baidu.com/share/qrcode?w=104&h=100&url='.$arr['code_url'];//生成二维码 http://pan.baidu.com/share/qrcode 百度在线生成二维码链家
*/
class WxpayService
{
protected $mchid;
protected $appid;
protected $apiKey;
public function __construct($mchid, $appid, $key)
{
$this->mchid = $mchid;
$this->appid = $appid;
$this->apiKey = $key;
}
/**
* 发起订单
* @param float $totalFee 收款总费用 单位元
* @param string $outTradeNo 唯一的订单号
* @param string $orderName 订单名称
* @param string $notifyUrl 支付结果通知url 不要有问号
* @param string $timestamp 订单发起时间
* @return array
*/
public function createJsBizPackage($totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp)
{
$config = array(
'mch_id' => $this->mchid,
'appid' => $this->appid,
'key' => $this->apiKey,
);
//$orderName = iconv('GBK','UTF-8',$orderName);
$unified = array(
'appid' => $config['appid'],
'attach' => 'pay', //商家数据包原样返回如果填写中文请注意转换为utf-8
'body' => $orderName,
'mch_id' => $config['mch_id'],
'nonce_str' => self::createNonceStr(),
'notify_url' => $notifyUrl,
'out_trade_no' => $outTradeNo,
'spbill_create_ip' => '127.0.0.1',
'total_fee' => intval($totalFee * 100), //单位 转为分
'trade_type' => 'NATIVE',
);
$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);
}
$codeUrl = (array)($unifiedOrder->code_url);
if(!$codeUrl[0]) exit('get code_url error');
$arr = array(
"appId" => $config['appid'],
"timeStamp" => $timestamp,
"nonceStr" => self::createNonceStr(),
"package" => "prepay_id=" . $unifiedOrder->prepay_id,
"signType" => 'MD5',
"code_url" => $codeUrl[0],
);
$arr['paySign'] = self::getSign($arr, $config['key']);
return $arr;
}
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;
}
}