欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

php版微信js-sdk支付接口类用法示例

程序员文章站 2024-03-01 22:17:10
本文实例讲述了php版微信js-sdk支付接口类用法。分享给大家供大家参考,具体如下: 这个支付类是根据官方的文档修改而来!主要实现生成js api 、native的pa...

本文实例讲述了php版微信js-sdk支付接口类用法。分享给大家供大家参考,具体如下:

这个支付类是根据官方的文档修改而来!主要实现生成js api 、native的package签名包和native响应的xml格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等

<?php
if (isset($argc) && $argc >= 1 && $argv[0] == __file__) {
  //初始化pay的必要信息
  $pay = new wechatpay(array(
    wechatpay::appid => 'wx99dabzpiuq83985b8',
    wechatpay::appsercer => 'ac12e7e4abaer63hkoa0cc36a9663fa',
    wechatpay::partnerkey => 'bae4sfa3562rsfaq23s2045',
    wechatpay::partnerid => '1268969802',
    wechatpay::paysignkey => '9fqsxb3pk4ivocec4ycquy5zecs9leemjf2nn4b4ykooxpwaqdfwmezkt8onlbyawcut',
    wechatpay::signtype => 'sha1',
  ));
  //设置package 必要的参数 jsapi native都通用
  $pay->setparams(wechatpay::bank_type, "wx");
  $pay->setparams(wechatpay::body, "test");
  $pay->setparams(wechatpay::partner, $pay->partnerid);
  $pay->setparams(wechatpay::out_trade_no, commonutil::createnoncestr());
  $pay->setparams(wechatpay::total_fee, "1");
  $pay->setparams(wechatpay::fee_type, "1");
  $pay->setparams(wechatpay::timestamp, time());
  $pay->setparams(wechatpay::notify_url, "http://www.demo.com/notify");
  $pay->setparams(wechatpay::spbill_create_ip, "127.0.0.1");
  $pay->setparams(wechatpay::input_charset, "utf-8");
  //jsapi的签名json
  print_r($pay->createjsapipackage());
  //生成native xml
  print_r($pay->createnativepackage());
  //生成native url
  print_r($pay->createnativeurl("9701"));
}

js api生成的package签名包参数:

{
  "appid":"wx9998ff5f4dede5b7",
  "package":"bank_type=wx&body=test&fee_type=1&input_charset=utf-8&notify_url=http%3a%2f%2fwww.demo.com%2fnotify&out_trade_no=vf5qsswtu0hc2loh&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1&timestamp=1409295711&total_fee=1&sign=fee0167bd0d89a88bf6850590ea889b6",
  "timestamp":1409295711,
  "noncestr":"vf5qsswtu0hc2loh",
  "paysign":"f816264c750923863c370a1739640244b0c2d39c",
  "signtype":"sha1"
}

native 响应的xml格式:

<xml>
  <appid><![cdata[wx9998ff5f4dede5b7]]></appid>
  <package>
    <![cdata[bank_type=wx&body=test&fee_type=1&input_charset=utf-8&notify_url=http%3a%2f%2fwww.demo.com%2fnotify&out_trade_no=gdl3what4saldead&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1&timestamp=1409296124&total_fee=1&sign=bf949b85570644b939b369fd44b0c4a9]]>
  </package>
  <timestamp>1409296124</timestamp>
  <noncestr><![cdata[gdl3what4saldead]]></noncestr>
  <retcode>0</retcode>
  <reterrmsg><![cdata[ok]]></reterrmsg>
  <appsignature><![cdata[ca4a2467b817a62c38a9801fcf451f51692027bf]]></appsignature>
  <signmethod><![cdata[sha1]]></signmethod>
</xml>

native的url链接:

weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=vy7cva6mtvrc1bvq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73&timestamp=1409296323

无论哪一种方式,我们都要通过setparams来设置必要初始化参数和商品价格和状态等!

wechatpay class:

<?php
class wechatpay {
  const
    bank_type = 'bank_type',
    body = 'body',
    partner = 'partner',
    out_trade_no = 'out_trade_no',
    timestamp = 'timestamp',
    total_fee = 'total_fee',
    fee_type = 'fee_type',
    notify_url = 'notify_url',
    spbill_create_ip = 'spbill_create_ip',
    input_charset = 'input_charset',
    appid = 'appid',
    appsercer = 'appsercer',
    paysignkey = 'appkey',
    partnerid = 'partnerid',
    partnerkey = 'partnerkey',
    signtype = 'signtype';
  public
    $params = array(), $partnerid = '';
  static protected
    $_instance;
  protected
    $_appid, $_appkey, $_signtype, $_partnerkey, $_appsercer;
  static public function getinstance(array $options = array()) {
    if (empty(self::$_instance)) {
      self::$_instance = new self ($options);
    }
    return self::$_instance;
  }
  public function __construct(array $options = array()){
    $this->_appid = $options[self::appid];
    $this->_appkey = $options[self::paysignkey];
    $this->_signtype = $options[self::signtype];
    $this->_partnerkey = $options[self::partnerkey];
    $this->_appsercer = $options[self::appsercer];
    $this->partnerid = $options[self::appid];
  }
  public function setparams($param, $paramvalue) {
    $this->params[commonutil::trimstring($param)] = commonutil::trimstring($paramvalue);
  }
  public function getparams($param) {
    return $this->params[$param];
  }
  protected 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 function checkparams(){
    //必要的9个参与签名的参数
    if($this->params[self::bank_type] == null || $this->params[self::body] == null || $this->params[self::partner] == null ||
      $this->params[self::out_trade_no] == null || $this->params[self::total_fee] == null || $this->params[self::fee_type] == null ||
      $this->params[self::notify_url] == null || $this->params[self::spbill_create_ip] == null || $this->params[self::input_charset] == null
    ) {
      return false;
    }
    return true;
  }
  /*
   * 生成package包
   * @params 初始化类时用setparams方法定义必要的9个参数
   * 排序后格式化url query形式 再md5signutil类签名,再给合url
   */
  protected function getpackagesign(){
    try {
      if (null == $this->_partnerkey || "" == $this->_partnerkey ) {
        throw new exception("密钥不能为空!" . "<br>");
      }
      $commonutil = new commonutil();
      ksort($this->params);
      $unsignparastring = $commonutil->formaturlquery($this->params, false);
      $parastring = $commonutil->formaturlquery($this->params, true);
      $md5signutil = new md5signutil();
      return $parastring . "&sign=" . $md5signutil->sign($unsignparastring,commonutil::trimstring($this->_partnerkey));
    } catch (exception $e) {
      echo ($e->getmessage());
    }
  }
  /*
   * 生成签名方法
   * @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数
   */
  public function getpaysign($signobj){
    foreach ($signobj as $k => $v){
      $signparams[strtolower($k)] = $v;
    }
    try {
      if ($this->_appkey == "") {
        throw new exception("appkey为空!" . "<br>");
      }
      $signparams["appkey"] = $this->_appkey;
      ksort($signparams, sort_string);
      $commonutil = new commonutil();
      $signstring = $commonutil->formatpayurlquery($signparams, false);
      return sha1($signstring);
    } catch (exception $e) {
      echo ($e->getmessage());
    }
  }
  //js api 签名 其中noncestr是作为订单号 灌穿整个支付流程
  public function createjsapipackage(){
    try {
      if($this->checkparams() == false) {
        throw new exception("生成package参数缺失!" . "<br>");
      }
      $payobj["appid"] = $this->_appid;
      $payobj["package"] = $this->getpackagesign();
      $payobj["timestamp"] = $this->getparams(self::timestamp);
      $payobj["noncestr"] = $this->getparams(self::out_trade_no);
      $payobj["paysign"] = $this->getpaysign($payobj);
      $payobj["signtype"] = $this->_signtype;
      return json_encode($payobj);
    } catch (exception $e) {
      die($e->getmessage());
    }
  }
  /*
   * 构建发货状态数组 主要三个参数openid transid orderid
   */
  public function createdeliverpost(array $params) {
    $deliver = array();
    $deliver['appid'] = $this->_appid;
    $deliver['openid'] = $params['openid'];
    $deliver['transid'] = $params['transid'];
    $deliver['out_trade_no'] = $params['out_trade_no'];
    $deliver['deliver_timestamp'] = current_time('timestamp');
    $deliver['deliver_status'] = 1;
    $deliver['deliver_msg'] = 'ok';
    $deliver['app_signature'] = $this->getpaysign($deliver);
    $deliver['sign_method'] = 'sha1';
    return $deliver;
  }
  /*
   * 生成扫描或者点击原生url后,响应的xml格式
   * @params $retcode $reterrmsg 定义该商品的状态
   */
  public function createnativepackage($retcode = 0, $reterrmsg = "ok") {
    try {
      if ($this->checkparams() == false && $retcode == 0) {  //如果是正常的返回, 检查财付通的参数
        throw new exception("生成package参数缺失!" . "<br>");
      }
      $nativeobj["appid"] = $this->_appid;
      $nativeobj["package"] = $this->getpackagesign();
      $nativeobj["timestamp"] = $this->getparams(self::timestamp);
      $nativeobj["noncestr"] = $this->getparams(self::out_trade_no);
      $nativeobj["retcode"] = $retcode;
      $nativeobj["reterrmsg"] = $reterrmsg;
      $nativeobj["appsignature"] = $this->getpaysign($nativeobj);
      $nativeobj["signmethod"] = $this->_signtype;
      $commonutil = new commonutil();
      $xml = $commonutil->arraytoxml($nativeobj);
      exit($xml);
    }catch (exception $e) {
      echo ($e->getmessage());
    }
  }
  /*
   * 生成原生url 以订单号为参数 这是灌穿整个支付流程
   */
  public function createnativeurl($productid) {
    $commonutil = new commonutil();
    $nativeobj["appid"] = $this->_appid;
    $nativeobj["productid"] = urlencode($productid);
    $nativeobj["timestamp"] = time();
    $nativeobj["noncestr"] = commonutil::createnoncestr();
    $nativeobj["sign"] = $this->getpaysign($nativeobj);
    $nativestring = $commonutil->formatpayurlquery($nativeobj, false);
    return "weixin://wxpay/bizpayurl?".$nativestring;
  }
  /*
   * 取ip地址
   */
  public function getip(){
    switch(true) {
      case !empty($_server["http_client_ip"]):
        $ip = $_server["http_client_ip"];
        break;
      case !empty($_server["http_x_forwarded_for"]):
        $ip = $_server["http_x_forwarded_for"];
        break;
      case !empty($_server["remote_addr"]):
        $ip = $_server["remote_addr"];
        break;
      default:
        $ip = "127.0.0.1";
    }
    return $ip;
  }
}
class md5signutil {
  public function sign($content, $key) {
    try {
      if (null == $key) {
        throw new exception("财付通签名key不能为空!" . "<br>");
      }
      if (null == $content) {
        throw new exception("财付通签名内容不能为空" . "<br>");
      }
      $signstr = $content . "&key=" . $key;
      return strtoupper(md5($signstr));
    } catch (exception $e) {
      echo ($e->getmessage());
    }
  }
  public static function verifysignature($content, $sign, $md5key) {
    $signstr = $content . "&key=" . $md5key;
    $calculatesign = strtolower(md5($signstr));
    $tenpaysign = strtolower($sign);
    return $calculatesign == $tenpaysign;
  }
}
class commonutil {
  public function genallurl($tourl, $paras) {
    $allurl = null;
    if (null == $tourl) {
      die("tourl is null");
    }
    if (strripos($tourl,"?") =="") {
      $allurl = $tourl . "?" . $paras;
    } else {
      $allurl = $tourl . "&" . $paras;
    }
    return $allurl;
  }
  //订单号,可根据实际自定义
  static public function createorderno() {
    $nonce = commonutil::createnoncestr(4);
    return strtoupper(date('ymds').substr(microtime(),2,4).$nonce);
  }
  //随机字符串
  static public 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 function splitparastr($src, $token) {
    $resmap = array();
    $items = explode($token,$src);
    foreach ($items as $item){
      $paraandvalue = explode("=",$item);
      if ($paraandvalue != "") {
        $resmap[$paraandvalue[0]] = $paraandvalue[1];
      }
    }
    return $resmap;
  }
  static function trimstring($value) {
    $ret = null;
    if (null != $value) {
      $ret = $value;
      if (strlen($ret) == 0) {
        $ret = null;
      }
    }
    return $ret;
  }
  public function formaturlquery($paramap, $urlencode) {
    $buff = "";
    ksort($paramap, sort_string);
    foreach ($paramap as $k => $v) {
      if (null != $v && "null" != $v && "sign" != $k) {
        if($urlencode) {
          $v = urlencode($v);
        }
        $buff .= $k . "=" . $v . "&";
      }
    }
    $reqpar = '';
    if (strlen($buff) > 0) {
      $reqpar = substr($buff, 0, strlen($buff)-1);
    }
    return $reqpar;
  }
  public function formatpayurlquery($paramap, $urlencode) {
    $buff = "";
    ksort($paramap, sort_string);
    foreach ($paramap as $k => $v) {
      if($urlencode){
        $v = urlencode($v);
      }
      $buff .= strtolower($k) . "=" . $v . "&";
    }
    $reqpar = '';
    if (strlen($buff) > 0) {
      $reqpar = substr($buff, 0, strlen($buff)-1);
    }
    return $reqpar;
  }
  /*
   * 输出一级数组的xml格式
   */
  public function arraytoxml($arr) {
    $xml = "<xml>";
    foreach ($arr as $key=>$val) {
      if ($key == 'timestamp' || $key == 'retcode') {
        $xml.="<".$key.">".$val."</".$key.">";
      } else
        $xml.="<".$key."><![cdata[".$val."]]></".$key.">";
    }
    $xml .= "</xml>";
    return $xml;
  }
}

更多关于php相关内容感兴趣的读者可查看本站专题:《php微信开发技巧汇总》、《php编码与转码操作技巧汇总》、《php网络编程技巧总结》、《php基本语法入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家php程序设计有所帮助。