>  기사  >  백엔드 개발  >  PHP WeChat 결제 공개계좌 결제 기능

PHP WeChat 결제 공개계좌 결제 기능

不言
不言원래의
2018-05-31 16:32:471713검색

이 글은 주로 PHP WeChat 결제의 공개 계정 결제 기능을 자세히 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.

인터넷에 있는 많은 PHP WeChat 스캔 코드 결제 액세스 튜토리얼은 매우 복잡하고 유용합니다. 많은 구성과 파일 소개가 필요합니다. 정리하여 단일 파일 버전을 제공했습니다. WeChat 스캔 코드 결제에 액세스하려는 모든 사람에게 도움과 참고가 되기를 바랍니다.

인증된 디렉터리에 파일을 넣고 WeChat에서 해당 파일에 액세스하여 시연 효과를 확인하세요. 효과는 다음과 같습니다:

주의 사항:

1 이 파일은 WeChat Pay 판매자 플랫폼->제품 센터-에서 설정할 수 있는 결제 승인 디렉터리에 있어야 합니다. >개발 구성.
2. 서명 오류가 표시되면 WeChat 결제 서명 확인 도구를 통해 확인할 수 있습니다: WeChat 공개 플랫폼 결제 인터페이스 디버깅 도구

코드는 다음과 같습니다:

<?php
header(&#39;Content-type:text/html; Charset=utf-8&#39;);
$mchid = &#39;xxxxx&#39;;   //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送
$appid = &#39;xxxxx&#39;; //微信支付申请对应的公众号的APPID
$appKey = &#39;xxxxx&#39;; //微信支付申请对应的公众号的APP Key
$apiKey = &#39;xxxxx&#39;; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥

//①、获取用户openid
$wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey);
$openId = $wxPay->GetOpenid();  //获取openid
if(!$openId) exit(&#39;获取openid失败&#39;);
//②、统一下单
$outTradeNo = uniqid();  //你自己的商品订单号
$payAmount = 0.01;   //付款金额,单位:元
$orderName = &#39;支付测试&#39;; //订单标题
$notifyUrl = &#39;https://www.xxx.com/wx/&#39;;  //付款成功后的回调地址(不要有问号)
$payTime = time();  //付款时间
$jsApiParameters = $wxPay->createJsBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime);
$jsApiParameters = json_encode($jsApiParameters);
?>
 <html>
 <head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>微信支付样例-支付</title>
  <script type="text/javascript">
   //调用微信JS api 支付
   function jsApiCall()
   {
    WeixinJSBridge.invoke(
     &#39;getBrandWCPayRequest&#39;,
     <?php echo $jsApiParameters; ?>,
     function(res){
      WeixinJSBridge.log(res.err_msg);
      alert(res.err_code+res.err_desc+res.err_msg);
     }
    );
   }
   function callpay()
   {
    if (typeof WeixinJSBridge == "undefined"){
     if( document.addEventListener ){
      document.addEventListener(&#39;WeixinJSBridgeReady&#39;, jsApiCall, false);
     }else if (document.attachEvent){
      document.attachEvent(&#39;WeixinJSBridgeReady&#39;, jsApiCall);
      document.attachEvent(&#39;onWeixinJSBridgeReady&#39;, jsApiCall);
     }
    }else{
     jsApiCall();
    }
   }
  </script>
 </head>
 <body>
 <br/>
 <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px"><?php echo $payAmount?>元</span>钱</b></font><br/><br/>
 <p align="center">
  <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
 </p>
 </body>
 </html>
<?php
class WxpayService
{
 protected $mchid;
 protected $appid;
 protected $appKey;
 protected $apiKey;
 public $data = null;

 public function __construct($mchid, $appid, $appKey,$key)
 {
  $this->mchid = $mchid; //https://pay.weixin.qq.com 产品中心-开发配置-商户号
  $this->appid = $appid; //微信支付申请对应的公众号的APPID
  $this->appKey = $appKey; //微信支付申请对应的公众号的APP Key
  $this->apiKey = $key; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
 }

 /**
  * 通过跳转获取用户的openid,跳转流程如下:
  * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
  * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
  * @return 用户的openid
  */
 public function GetOpenid()
 {
  //通过code获得openid
  if (!isset($_GET[&#39;code&#39;])){
   //触发微信返回code码
   $scheme = $_SERVER[&#39;HTTPS&#39;]==&#39;on&#39; ? &#39;https://&#39; : &#39;http://&#39;;
   $baseUrl = urlencode($scheme.$_SERVER[&#39;HTTP_HOST&#39;].$_SERVER[&#39;PHP_SELF&#39;].$_SERVER[&#39;QUERY_STRING&#39;]);
   $url = $this->__CreateOauthUrlForCode($baseUrl);
   Header("Location: $url");
   exit();
  } else {
   //获取code码,以获取openid
   $code = $_GET[&#39;code&#39;];
   $openid = $this->getOpenidFromMp($code);
   return $openid;
  }
 }

 /**
  * 通过code从工作平台获取openid机器access_token
  * @param string $code 微信跳转回来带上的code
  * @return openid
  */
 public function GetOpenidFromMp($code)
 {
  $url = $this->__CreateOauthUrlForOpenid($code);
  $res = self::curlGet($url);
  //取出openid
  $data = json_decode($res,true);
  $this->data = $data;
  $openid = $data[&#39;openid&#39;];
  return $openid;
 }

 /**
  * 构造获取open和access_toke的url地址
  * @param string $code,微信跳转带回的code
  * @return 请求的url
  */
 private function __CreateOauthUrlForOpenid($code)
 {
  $urlObj["appid"] = $this->appid;
  $urlObj["secret"] = $this->appKey;
  $urlObj["code"] = $code;
  $urlObj["grant_type"] = "authorization_code";
  $bizString = $this->ToUrlParams($urlObj);
  return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
 }

 /**
  * 构造获取code的url连接
  * @param string $redirectUrl 微信服务器回跳的url,需要url编码
  * @return 返回构造好的url
  */
 private function __CreateOauthUrlForCode($redirectUrl)
 {
  $urlObj["appid"] = $this->appid;
  $urlObj["redirect_uri"] = "$redirectUrl";
  $urlObj["response_type"] = "code";
  $urlObj["scope"] = "snsapi_base";
  $urlObj["state"] = "STATE"."#wechat_redirect";
  $bizString = $this->ToUrlParams($urlObj);
  return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
 }

 /**
  * 拼接签名字符串
  * @param array $urlObj
  * @return 返回已经拼接好的字符串
  */
 private function ToUrlParams($urlObj)
 {
  $buff = "";
  foreach ($urlObj as $k => $v)
  {
   if($k != "sign") $buff .= $k . "=" . $v . "&";
  }
  $buff = trim($buff, "&");
  return $buff;
 }

 /**
  * 统一下单
  * @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid
  * @param float $totalFee 收款总费用 单位元
  * @param string $outTradeNo 唯一的订单号
  * @param string $orderName 订单名称
  * @param string $notifyUrl 支付结果通知url 不要有问号
  * @param string $timestamp 支付时间
  * @return string
  */
 public function createJsBizPackage($openid, $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;openid&#39; => $openid,   //rade_type=JSAPI,此参数必传
   &#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;JSAPI&#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);
  }
  $arr = array(
   "appId" => $config[&#39;appid&#39;],
   "timeStamp" => "$timestamp",  //这里是字符串的时间戳,不是int,所以需加引号
   "nonceStr" => self::createNonceStr(),
   "package" => "prepay_id=" . $unifiedOrder->prepay_id,
   "signType" => &#39;MD5&#39;,
  );
  $arr[&#39;paySign&#39;] = self::getSign($arr, $config[&#39;key&#39;]);
  return $arr;
 }

 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>";
  file_put_contents(&#39;1.txt&#39;,$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;
 }
}
?>

관련 권장 사항:

php에서 위챗결제 현금 빨간봉투 구현

php에서 기업결제용 위챗결제

위 내용은 PHP WeChat 결제 공개계좌 결제 기능의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.