Heim > Backend-Entwicklung > PHP-Tutorial > 一文详解php实现微信原生支付功能(附代码)

一文详解php实现微信原生支付功能(附代码)

PHPz
Freigeben: 2023-02-17 09:37:47
nach vorne
2900 Leute haben es durchsucht

网上的很多PHP微信扫码支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,只有200行代码,希望可以给各位想接入微信扫码支付的带来些许帮助和借鉴意义。

一文详解php实现微信原生支付功能(附代码)

直接运行该文件即可得到一个支付二维码的图片。

需要注意的事项:

1.该文件需放到支付授权目录下,可以在微信支付商户平台->产品中心->开发配置中设置。
2.如提示签名错误可以通过微信支付签名验证工具进行验证:微信公众平台支付接口调试工具

代码如下:

<?php
header(&#39;Content-type:text/html; Charset=utf-8&#39;);
$mchid = &#39;xxxxx&#39;;     //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送
$appid = &#39;xxxxx&#39;; //公众号APPID 通过微信支付商户资料审核后邮件发送
$apiKey = &#39;xxxxx&#39;;  //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
$wxPay = new WxpayService($mchid,$appid,$apiKey);
$outTradeNo = uniqid();   //你自己的商品订单号
$payAmount = 0.01;     //付款金额,单位:元
$orderName = &#39;支付测试&#39;;  //订单标题
$notifyUrl = &#39;https://www.xxx.com/wx/&#39;;   //付款成功后的回调地址(不要有问号)
$payTime = time();   //付款时间
$arr = $wxPay->createJsBizPackage($payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime);
//生成二维码
$url = &#39;http://qr.liantu.com/api.php?text=&#39;.$arr[&#39;code_url&#39;];
echo "<img src=&#39;{$url}&#39; style=&#39;width:300px;&#39;>";

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(
      &#39;mch_id&#39; => $this->mchid,
      &#39;appid&#39; => $this->appid,
      &#39;key&#39; => $this->apiKey,
    );
    $orderName = iconv(&#39;GBK&#39;,&#39;UTF-8&#39;,$orderName);
    $unified = array(
      &#39;appid&#39; => $config[&#39;appid&#39;],
      &#39;attach&#39; => &#39;pay&#39;,       //商家数据包,原样返回,如果填写中文,请注意转换为utf-8
      &#39;body&#39; => $orderName,
      &#39;mch_id&#39; => $config[&#39;mch_id&#39;],
      &#39;nonce_str&#39; => self::createNonceStr(),
      &#39;notify_url&#39; => $notifyUrl,
      &#39;out_trade_no&#39; => $outTradeNo,
      &#39;spbill_create_ip&#39; => &#39;127.0.0.1&#39;,
      &#39;total_fee&#39; => intval($totalFee * 100),    //单位 转为分
      &#39;trade_type&#39; => &#39;NATIVE&#39;,
    );
    $unified[&#39;sign&#39;] = self::getSign($unified, $config[&#39;key&#39;]);
    $responseXml = self::curlPost(&#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;, self::arrayToXml($unified));
    $unifiedOrder = simplexml_load_string($responseXml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
    if ($unifiedOrder === false) {
      die(&#39;parse xml error&#39;);
    }
    if ($unifiedOrder->return_code != &#39;SUCCESS&#39;) {
      die($unifiedOrder->return_msg);
    }
    if ($unifiedOrder->result_code != &#39;SUCCESS&#39;) {
      die($unifiedOrder->err_code);
    }
    $codeUrl = (array)($unifiedOrder->code_url);
    if(!$codeUrl[0]) exit(&#39;get code_url error&#39;);
    $arr = array(
      "appId" => $config[&#39;appid&#39;],
      "timeStamp" => $timestamp,
      "nonceStr" => self::createNonceStr(),
      "package" => "prepay_id=" . $unifiedOrder->prepay_id,
      "signType" => &#39;MD5&#39;,
      "code_url" => $codeUrl[0],
    );
    $arr[&#39;paySign&#39;] = self::getSign($arr, $config[&#39;key&#39;]);
    return $arr;
  }


  public function notify()
  {
    $config = array(
      &#39;mch_id&#39; => $this->mchid,
      &#39;appid&#39; => $this->appid,
      &#39;key&#39; => $this->apiKey,
    );
    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

    $postObj = simplexml_load_string($postStr, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
    if ($postObj === false) {
      die(&#39;parse xml error&#39;);
    }
    if ($postObj->return_code != &#39;SUCCESS&#39;) {
      die($postObj->return_msg);
    }
    if ($postObj->result_code != &#39;SUCCESS&#39;) {
      die($postObj->err_code);
    }
    $arr = (array)$postObj;
    unset($arr[&#39;sign&#39;]);
    if (self::getSign($arr, $config[&#39;key&#39;]) == $postObj->sign) {
      echo &#39;<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>&#39;;
      return $postObj;
    }
  }

  /**
   * curl get
   *
   * @param string $url
   * @param array $options
   * @return mixed
   */
  public static function curlGet($url = &#39;&#39;, $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 = &#39;&#39;, $postData = &#39;&#39;, $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 = &#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&#39;;
    $str = &#39;&#39;;
    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 = &#39;&#39;;
    if (strlen($buff) > 0) {
      $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
  }
}
Nach dem Login kopieren

github下载地址:weixinPay

推荐学习:《PHP视频教程

Verwandte Etiketten:
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage