VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > PHP >
  • PHP 微信支付类 demo

这篇文章主要介绍了PHP 微信支付类 demo的相关资料,需要的朋友可以参考下,一切尽在代码中,代码附有注释,欢迎大家参考。

  1. <?php 
  2. class WxpayService 
  3. { 
  4.   protected $mchid; 
  5.   protected $appid; 
  6.   protected $key; 
  7.   public function __construct($mchid, $appid, $key) 
  8.   { 
  9.     $this->mchid = $mchid; // 微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 
  10.     $this->appid = $appid; //公众号APPID 通过微信支付商户资料审核后邮件发送 
  11.     $this->key = $key;   //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 
  12.   } 
  13.   /** 
  14.    * @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid 
  15.    * @param float $totalFee 收款总费用 单位元 
  16.    * @param string $outTradeNo 唯一的订单号 
  17.    * @param string $orderName 订单名称 
  18.    * @param string $notifyUrl 支付结果通知url 不要有问号 
  19.    *   https://mp.weixin.qq.com/ 微信支付-开发配置-测试目录 
  20.    *   测试目录 http://mp.izhanlue.com/paytest/  最后需要斜线,(需要精确到二级或三级目录) 
  21.    * @return string 
  22.    */ 
  23.   public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp) 
  24.   { 
  25.     $config = array( 
  26.       'mch_id' => $this->mchid, 
  27.       'appid' => $this->appid, 
  28.       'key' => $this->key, 
  29.     ); 
  30.     $unified = array( 
  31.       'appid' => $config['appid'], 
  32.       'attach' => '支付',             //商家数据包,原样返回 
  33.       'body' => $orderName, 
  34.       'mch_id' => $config['mch_id'], 
  35.       'nonce_str' => self::createNonceStr(), 
  36.       'notify_url' => $notifyUrl, 
  37.       'openid' => $openid,            //rade_type=JSAPI,此参数必传 
  38.       'out_trade_no' => $outTradeNo, 
  39.       'spbill_create_ip' => '127.0.0.1', 
  40.       'total_fee' => intval($totalFee * 100),       //单位 转为分 
  41.       'trade_type' => 'JSAPI', 
  42.     ); 
  43.     $unified['sign'] = self::getSign($unified, $config['key']); 
  44.     $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); 
  45.     /* 
  46.     <xml> 
  47.     <return_code><![CDATA[SUCCESS]]></return_code> 
  48.     <return_msg><![CDATA[OK]]></return_msg> 
  49.     <appid><![CDATA[wx00e5904efec77699]]></appid> 
  50.     <mch_id><![CDATA[1220647301]]></mch_id> 
  51.     <nonce_str><![CDATA[1LHBROsdmqfXoWQR]]></nonce_str> 
  52.     <sign><![CDATA[ACA7BC8A9164D1FBED06C7DFC13EC839]]></sign> 
  53.     <result_code><![CDATA[SUCCESS]]></result_code> 
  54.     <prepay_id><![CDATA[wx2015032016590503f1bcd9c30421762652]]></prepay_id> 
  55.     <trade_type><![CDATA[JSAPI]]></trade_type> 
  56.     </xml> 
  57.     */ 
  58.     $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); 
  59.     if ($unifiedOrder === false) { 
  60.       die('parse xml error'); 
  61.     } 
  62.     if ($unifiedOrder->return_code != 'SUCCESS') { 
  63.       die($unifiedOrder->return_msg); 
  64.     } 
  65.     if ($unifiedOrder->result_code != 'SUCCESS') { 
  66.       die($unifiedOrder->err_code); 
  67.       /* 
  68.       NOAUTH 商户无此接口权限 
  69.       NOTENOUGH 余额不足 
  70.       ORDERPAID 商户订单已支付 
  71.       ORDERCLOSED 订单已关闭 
  72.       SYSTEMERROR 系统错误 
  73.       APPID_NOT_EXIST   APPID不存在 
  74.       MCHID_NOT_EXIST MCHID不存在 
  75.       APPID_MCHID_NOT_MATCH appid和mch_id不匹配 
  76.       LACK_PARAMS 缺少参数 
  77.       OUT_TRADE_NO_USED 商户订单号重复 
  78.       SIGNERROR 签名错误 
  79.       XML_FORMAT_ERROR XML格式错误 
  80.       REQUIRE_POST_METHOD 请使用post方法 
  81.       POST_DATA_EMPTY post数据为空 
  82.       NOT_UTF8 编码格式错误 
  83.       */ 
  84.     } 
  85.     //$unifiedOrder->trade_type 交易类型 调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP 
  86.     //$unifiedOrder->prepay_id 预支付交易会话标识 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时 
  87.     //$unifiedOrder->code_url 二维码链接 trade_type为NATIVE是有返回,可将该参数值生成二维码展示出来进行扫码支付 
  88.     $arr = array( 
  89.       "appId" => $config['appid'], 
  90.       "timeStamp" => $timestamp, 
  91.       "nonceStr" => self::createNonceStr(), 
  92.       "package" => "prepay_id=" . $unifiedOrder->prepay_id, 
  93.       "signType" => 'MD5', 
  94.     ); 
  95.     $arr['paySign'] = self::getSign($arr, $config['key']); 
  96.     return $arr; 
  97.   } 
  98.   public function notify() 
  99.   { 
  100.     $config = array( 
  101.       'mch_id' => $this->mchid, 
  102.       'appid' => $this->appid, 
  103.       'key' => $this->key, 
  104.     ); 
  105.     $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 
  106.     //error_log($postStr, 3, './str.txt'); 
  107.     /* 
  108.     $postStr = '<xml> 
  109.     <appid><![CDATA[wx00e5904efec77699]]></appid> 
  110.     <attach><![CDATA[支付测试]]></attach> 
  111.     <bank_type><![CDATA[CMB_CREDIT]]></bank_type> 
  112.     <cash_fee><![CDATA[1]]></cash_fee> 
  113.     <fee_type><![CDATA[CNY]]></fee_type> 
  114.     <is_subscribe><![CDATA[Y]]></is_subscribe> 
  115.     <mch_id><![CDATA[1220647301]]></mch_id> 
  116.     <nonce_str><![CDATA[a0tZ41phiHm8zfmO]]></nonce_str> 
  117.     <openid><![CDATA[oU3OCt5O46PumN7IE87WcoYZY9r0]]></openid> 
  118.     <out_trade_no><![CDATA[550bf2990c51f]]></out_trade_no> 
  119.     <result_code><![CDATA[SUCCESS]]></result_code> 
  120.     <return_code><![CDATA[SUCCESS]]></return_code> 
  121.     <sign><![CDATA[F6F519B4DD8DB978040F8C866C1E6250]]></sign> 
  122.     <time_end><![CDATA[20150320181606]]></time_end> 
  123.     <total_fee>1</total_fee> 
  124.     <trade_type><![CDATA[JSAPI]]></trade_type> 
  125.     <transaction_id><![CDATA[1008840847201503200034663980]]></transaction_id> 
  126.     </xml>'; 
  127.     */ 
  128.     $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 
  129.     if ($postObj === false) { 
  130.       die('parse xml error'); 
  131.     } 
  132.     if ($postObj->return_code != 'SUCCESS') { 
  133.       die($postObj->return_msg); 
  134.     } 
  135.     if ($postObj->result_code != 'SUCCESS') { 
  136.       die($postObj->err_code); 
  137.     } 
  138.     $arr = (array)$postObj; 
  139.     unset($arr['sign']); 
  140.     if (self::getSign($arr, $config['key']) == $postObj->sign) { 
  141.       // $mch_id = $postObj->mch_id; //微信支付分配的商户号 
  142.       // $appid = $postObj->appid; //微信分配的公众账号ID 
  143.       // $openid = $postObj->openid; //用户在商户appid下的唯一标识 
  144.       // $transaction_id = $postObj->transaction_id;//微信支付订单号 
  145.       // $out_trade_no = $postObj->out_trade_no;//商户订单号 
  146.       // $total_fee = $postObj->total_fee; //订单总金额,单位为分 
  147.       // $is_subscribe = $postObj->is_subscribe; //用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效 
  148.       // $attach = $postObj->attach;//商家数据包,原样返回 
  149.       // $time_end = $postObj->time_end;//支付完成时间 
  150.       echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; 
  151.       return $postObj; 
  152.     } 
  153.   } 
  154.   /** 
  155.    * curl get 
  156.    * 
  157.    * @param string $url 
  158.    * @param array $options 
  159.    * @return mixed 
  160.    */ 
  161.   public static function curlGet($url = '', $options = array()) 
  162.   { 
  163.     $ch = curl_init($url); 
  164.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  165.     curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
  166.     if (!emptyempty($options)) { 
  167.       curl_setopt_array($ch, $options); 
  168.     } 
  169.     //https请求 不验证证书和host 
  170.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  171.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
  172.     $data = curl_exec($ch); 
  173.     curl_close($ch); 
  174.     return $data; 
  175.   } 
  176.   public static function curlPost($url = '', $postData = '', $options = array()) 
  177.   { 
  178.     if (is_array($postData)) { 
  179.       $postData = http_build_query($postData); 
  180.     } 
  181.     $ch = curl_init(); 
  182.     curl_setopt($ch, CURLOPT_URL, $url); 
  183.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  184.     curl_setopt($ch, CURLOPT_POST, 1); 
  185.     curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 
  186.     curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 
  187.     if (!emptyempty($options)) { 
  188.       curl_setopt_array($ch, $options); 
  189.     } 
  190.     //https请求 不验证证书和host 
  191.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  192.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
  193.     $data = curl_exec($ch); 
  194.     curl_close($ch); 
  195.     return $data; 
  196.   } 
  197.   public static function createNonceStr($length = 16) 
  198.   { 
  199.     $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; 
  200.     $str = ''; 
  201.     for ($i = 0; $i < $length; $i++) { 
  202.       $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 
  203.     } 
  204.     return $str; 
  205.   } 
  206.   public static function arrayToXml($arr) 
  207.   { 
  208.     $xml = "<xml>"; 
  209.     foreach ($arr as $key => $val) { 
  210.       if (is_numeric($val)) { 
  211.         $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; 
  212.       } else 
  213.         $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; 
  214.     } 
  215.     $xml .= "</xml>"; 
  216.     return $xml; 
  217.   } 
  218.   /** 
  219.    * 例如: 
  220.    * appid:  wxd930ea5d5a258f4f 
  221.    * mch_id:  10000100 
  222.    * device_info: 1000 
  223.    * Body:  test 
  224.    * nonce_str: ibuaiVcKdpRxkhJA 
  225.    * 第一步:对参数按照 key=value 的格式,并按照参数名 ASCII 字典序排序如下: 
  226.    * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_i 
  227.    * d=10000100&nonce_str=ibuaiVcKdpRxkhJA"; 
  228.    * 第二步:拼接支付密钥: 
  229.    * stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d" 
  230.    * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" 
  231.    */ 
  232.   public static function getSign($params, $key) 
  233.   { 
  234.     ksort($params, SORT_STRING); 
  235.     $unSignParaString = self::formatQueryParaMap($params, false); 
  236.     $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); 
  237.     return $signStr; 
  238.   } 
  239.   protected static function formatQueryParaMap($paraMap, $urlEncode = false) 
  240.   { 
  241.     $buff = ""; 
  242.     ksort($paraMap); 
  243.     foreach ($paraMap as $k => $v) { 
  244.       if (null != $v && "null" != $v) { 
  245.         if ($urlEncode) { 
  246.           $v = urlencode($v); 
  247.         } 
  248.         $buff .= $k . "=" . $v . "&"; 
  249.       } 
  250.     } 
  251.     $reqPar = ''; 
  252.     if (strlen($buff) > 0) { 
  253.       $reqPar = substr($buff, 0, strlen($buff) - 1); 
  254.     } 
  255.     return $reqPar; 
  256.   } 
  257. } 

以上代码大家都能看得懂吧,有哪里不明白的地方欢迎给我留言,我会在第一时间和大家取得联系的。谢谢大家对脚本之家网站的支持。

 


出处:http://www.phpfensi.com/php/20210627/16755.html
 


相关教程