找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 289|回复: 0
打印 上一主题 下一主题

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

[复制链接]

2617

主题

2617

帖子

7789

积分

论坛元老

Rank: 8Rank: 8

积分
7789
跳转到指定楼层
楼主
发表于 2018-2-14 05:32:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            本文实例讲述了php版微信js-sdk支付接口类用法。分享给大家供大家参考,具体如下:
这个支付类是根据官方的文档修改而来!主要实现生成JS API 、Native的package签名包和Native响应的XML格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等
= 1 && $argv[0] == __FILE__) {
  //初始化pay的必要信息
  $pay = new WechatPay(array(
    WechatPay::APPID => 'wx99dabzpiuq83985b8',
    WechatPay::APPSERCER => 'ac12e7e4abaer63hkoa0cc36a9663fa',
    WechatPay:ARTNERKEY => 'bae4sfa3562rsfaq23s2045',
    WechatPay:ARTNERID => '1268969802',
    WechatPay:AYSIGNKEY => '9Fqsxb3PK4IVOCEc4yCquy5zecS9LeeMjF2Nn4B4YKoOxPwaQdFwMezKT8oNlBYaWcuT',
    WechatPay::SIGNTYPE => 'sha1',
  ));
  //设置package 必要的参数 jsapi native都通用
  $pay->setParams(WechatPay::BANK_TYPE, "WX");
  $pay->setParams(WechatPay::BODY, "test");
  $pay->setParams(WechatPay:ARTNER, $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格式:
  
  
   
  
  1409296124
  
  0
  
  
  
Native的URL链接:
weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=VY7cVA6mtVrc1BVq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73&timestamp=1409296323
无论哪一种方式,我们都要通过setParams来设置必要初始化参数和商品价格和状态等!
WechatPay class:
_appid = $options[self::APPID];
    $this->_appkey = $options[self:AYSIGNKEY];
    $this->_signtype = $options[self::SIGNTYPE];
    $this->_partnerkey = $options[self:ARTNERKEY];
    $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 params[self::BANK_TYPE] == null || $this->params[self::BODY] == null || $this->params[self:ARTNER] == 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("密钥不能为空!" . "
");
      }
      $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为空!" . "
");
      }
      $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参数缺失!" . "
");
      }
      $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参数缺失!" . "
");
      }
      $nativeObj["AppId"] = $this->_appid;
      $nativeObj["ackage"] = $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不能为空!" . "
");
      }
      if (null == $content) {
        throw new Exception("财付通签名内容不能为空" . "
");
      }
      $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  $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 = "";
    foreach ($arr as $key=>$val) {
      if ($key == 'TimeStamp' || $key == 'RetCode') {
        $xml.="".$val."";
      } else
        $xml.="";
    }
    $xml .= "";
    return $xml;
  }
}
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP微信开发技巧汇总》、《PHP编码与转码操作技巧汇总》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总
希望本文所述对大家PHP程序设计有所帮助。
            
            
您可能感兴趣的文章:
  • Java通过JsApi方式实现微信支付
  • java开发微信公众号支付
  • 微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
  • 微信支付 JS API支付接口详解
  • 前端微信支付js代码
  • 微信支付java版本之JSAPI支付+发送模板消息
  • JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
  • nodejs微信公众号支付开发
  • 最详细的ASP.NET微信JS-SDK支付代码
  • js微信支付实现代码
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端