小程序前端JS部分:
wx.request({ url: '下单接口', //仅为示例,并非真实的接口地址 data: { openid:that.data.userinfo.openid //openid尽量先让用户登录后,存入data中,支付时直接调用即可 }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { if(res.data.code==0){ var orderno = res.data.orderno; wx.requestPayment({ 'timeStamp': res.data.data.timeStamp, 'nonceStr': res.data.data.nonceStr, 'package': res.data.data.package, 'signType': 'MD5', 'paySign': res.data.data.paySign, 'success': function (res) { console.log(res); wx.showToast({ title: '支付成功', icon: 'success', duration: 3000, success:function(){ wx.redirectTo({ url: '跳转页面链接' }) } }); }, 'fail': function (res) { //console.log(res); wx.showToast({ title: '支付失败!', icon: 'error', duration: 2500 }) }, 'complete': function (res) { console.log('complete'); } }) }else{ wx.showToast({ title: res.data.msg, icon: 'error', duration: 2500 }) } } })
PHP后端部分:
function createOrder($orderno,$total,$openid){ $wxpay = [ 'app_id' => $this->webconf['wxappid'], //小程序appid 'app_secret' => $this->webconf['wxsecret'], //小程序secret 'mch_id' => $this->webconf['mch_id'], //商户平台商户号 'key' => $this->webconf['xcxkey'], //商户平台密钥key 'notify_url' => get_domain().'/api/notifypay', //支付异步回调地址--此处有坑,应该使用http协议 'name' => '支付测试', //商品简单描述 ]; $param = array( 'appid' => $wxpay['app_id'],//小程序id 'mch_id'=>$wxpay['mch_id'],//商户 idC('WX_ID') 'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],//终端ip 'notify_url'=>$wxpay['notify_url'], //回调通知地址 'nonce_str'=> $this->createNoncestr(),//随机字符串 'out_trade_no'=>$orderno,//商户订单编号 'total_fee'=>$total*100, //总金额 'openid'=>$openid,//用户openid 'trade_type'=>'JSAPI',//交易类型 'body' =>$wxpay['name'], //商品信息 ); //通过签名算法计算得出的签名值,详见签名生成算法 $param['sign'] = $this->getSign($param); //var_dump($param);die; //将数组内容转为xml格式,向微信发出请求 $xmlData = $this->arrayToXml($param); $xml_result = $this->postXmlCurl($xmlData,'https://api.mch.weixin.qq.com/pay/unifiedorder',60); //var_dump($xml_result,$xmlData);die; $array = $this->xmlToArray($xml_result); if($array['return_code'] == 'SUCCESS' && $array['result_code'] == 'SUCCESS'){ $time = time(); $key=$wxpay['key']; $tmp = [];//临时数组用于签名 $tmp['appId'] = $wxpay['app_id']; $tmp['nonceStr'] = $array['nonce_str']; $tmp['package'] = 'prepay_id='.$array['prepay_id']; $tmp['signType'] = 'MD5'; $tmp['timeStamp'] = (string)$time; $result['nonceStr'] = $array['nonce_str'];//随机字符串 $result['signType'] = 'MD5';//签名算法,暂支持 MD5 $result['package'] = 'prepay_id='.$array['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* $result['paySign'] = $this->getSign($tmp); $result['timeStamp'] =(string)$time; $result['appId'] = $array['appid']; }else{ $result['return_code'] = $array['return_code']; $result['return_msg'] = $array['return_msg']; } //echo json_encode($result,JSON_UNESCAPED_UNICODE); return $result; } /* * 生成随机字符串方法 */ function createNoncestr($length = 32 ){ $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } /* * 对要发送到微信统一下单接口的数据进行签名 */ function getSign($Obj){ foreach ($Obj as $k => $v){ $param[$k] = $v; } //签名步骤一:按字典序排序参数 ksort($param); $String = $this->formatBizQueryParaMap($param, false); //签名步骤二:在string后加入KEY $wx_key=$this->webconf['xcxkey']; //申请支付后有给予一个商户账号和密码,登陆后自己设置的key $String = $String."&key=".$wx_key; //签名步骤三:MD5加密 $String = md5($String); //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); // var_dump($result_); return $result_; } /* *排序并格式化参数方法,签名时需要使用 */ protected function formatBizQueryParaMap($paraMap, $urlencode){ $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v){ if($urlencode){ $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar = ""; if (strlen($buff) > 0){ $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } //数组转字符串方法 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; } //发送xml请求方法 function postXmlCurl($xml, $url, $second = 30) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验 //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); curl_setopt($ch, CURLOPT_TIMEOUT, 40); set_time_limit(0); //运行curl $data = curl_exec($ch); //返回结果 if ($data) { curl_close($ch); return $data; }else { $error = curl_errno($ch); curl_close($ch); throw new WxPayException("curl出错,错误码:$error"); } } //xml 转换成数组 function xmlToArray($xml) { //禁止引用外部 xml 实体 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring), true); return $val; }
版权声明:本文发布于与老涂一起写代码 内容均来源于互联网 如有侵权联系删除
快来评论,快来抢沙发吧~