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

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

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

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

 


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


相关教程