博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php版本微信js-sdk支付接口类例子
阅读量:6610 次
发布时间:2019-06-24

本文共 12450 字,大约阅读时间需要 41 分钟。

hot3.png

本文章来为各位介绍一篇关于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::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格式:

   
   
           
   
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::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("密钥不能为空!" . "
");            }            $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["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不能为空!" . "
");            }            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 < $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 = "
";        foreach ($arr as $key=>$val) {            if ($key == 'TimeStamp' || $key == 'RetCode') {                $xml.="<".$key.">".$val."
";            } else                $xml.="<".$key.">
";        }        $xml .= "
";        return $xml;    }}

 

转载于:https://my.oschina.net/u/2965390/blog/780887

你可能感兴趣的文章
太感谢DUDU拉!有这样的管理员,博客园能不火吗?
查看>>
15.2. switchport trunk encapsulation dot1q 提示 invaild input at^marker.
查看>>
(EM算法)The EM Algorithm
查看>>
Linux~yum命令安装程序
查看>>
getline函数(精华版)
查看>>
互联网辅助代理IP软件的应用需守牢数据安全的“底线”
查看>>
快速排序及其优化
查看>>
web
查看>>
第七天 结构伪类选择器(一)
查看>>
程序猿生存指南-10 敲定工作
查看>>
JDBC练习题——登录系统
查看>>
代码即设计 | 掘金年度征文
查看>>
GuzzleSwoole v1.1.0,让 Guzzle 完美兼容 Swoole 协程
查看>>
javascript性能优化
查看>>
运维工程师笔试真题:美团点评 2017 春招真题
查看>>
关于绝对定位和overflow的可见与不可见
查看>>
Vue学习笔记2
查看>>
LDAP密码认证例子
查看>>
2019程序媛面试之美少女战士
查看>>
有限状态机是什么?
查看>>