学习
实践
活动
工具
TVP
写文章

点三方支付之微信APP支付 PHP服务端demo

mchid = '9999999999'; // 微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 $this->appid = 'wxff9999999999'; //公众号APPID 通过微信支付商户资料审核后邮件发送 $this->key = 'Demo9999999999'; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 // 设置自定义行为 \Think\Hook::add('paystatus', 'Home\\Behaviors\\PaystatusBehavior'); } public function wxpay(){ $uid=$_POST['uid']; $orderid=$_POST['orderid']; $where['uid']=$uid; $where['orderid']=$orderid; $order_info=M('order')->where($where)->find(); if(empty($order_info)){ $msg=array('code'=>'300','msg'=>'订单不存在'); $this->ajaxReturn($msg); } $outTradeNo=$order_info['tag'].time(); //$totalFee=$order_info['total_money']*100; $totalFee=$order_info['total_money']*100; //$outTradeNo=201801151686367077; $total = round(floatval($totalFee),2); if (!$total) { $total = 0; } $notifyUrl = "https://".$_SERVER['HTTP_HOST']."/App/wxpay/wx_notify"; $orderName = "订单编号:".$order_info['orderid']; $spbillIp = $_SERVER['SERVER_ADDR']; $this->createJsBizPackage($total, $outTradeNo, $orderName, $notifyUrl, $spbillIp); } protected function createJsBizPackage($totalFee, $outTradeNo, $orderName, $notifyUrl, $spbillIp) { $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->key, ); $unified = array( 'appid' => $config['appid'], 'body' => $orderName, 'mch_id' => $config['mch_id'], 'nonce_str' => $this->createNonceStr(), 'notify_url' => $notifyUrl, 'out_trade_no' => $outTradeNo, 'spbill_create_ip' => $spbillIp, 'total_fee' => intval($totalFee * 1), //单位 转为分 'trade_type' => 'APP', ); $unified['sign'] = $this->getSign($unified, $config['key']); //第一次签名 //print_R($this->arrayToXml($unified)); $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($unified)); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); //print_r($unifiedOrder);die; if ($unifiedOrder === false) { $this->error('parse xml error'); die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { $this->error($unifiedOrder->return_msg); die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { $this->error($unifiedOrder->err_code); die($unifiedOrder->err_code); } //$unifiedOrder->trade_type 交易类型 调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP //$unifiedOrder->prepay_id 预支付交易会话标识 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时 //$unifiedOrder->code_url 二维码链接 trade_type为NATIVE是有返回,可将该参数值生成二维码展示出来进行扫码支付 //该数组内容是需要二次签名返回给客服端的,必须有时间戳,键名命名不能用驼峰法,不能有下划线或其他任何符号 //而且只能是微信要求的这个参数参与签名,其余的不能参与签名,否则客服端会报签名错误 //以下是标准命名,已在线上测试通过 /*$nonce_str = $this->toArray($unifiedOrder->nonce_str); print_R($nonce_str);die; $prepay_id = $this->toArray($unifiedOrder->prepay_id);*/ $nonce_str = $unifiedOrder->nonce_str; $nonce_str = (String)$nonce_str; $prepay_id = $unifiedOrder->prepay_id; $prepay_id = (String)$prepay_id; $arr = array( "appid" => $config['appid'], "partnerid" => $config['mch_id'], "timestamp" => time(), "noncestr" => $nonce_str, "prepayid" => $prepay_id, "package" => 'Sign=WXPay', ); $arr['sign'] = $this->getSign($arr, $config['key']); //第二次签名 $arr['outtradeno'] = $unified['out_trade_no']; //返回商户订单号 //print_R($arr);die; $this->ajaxReturn($arr) ; } public static function toArray($simplexml_obj, $array_tags=array(), $strip_white=1) { if( $simplexml_obj ) { if( count($simplexml_obj)==0 ){ return $strip_white?trim((string)$simplexml_obj):(string)$simplexml_obj; } $attr = array(); foreach ($simplexml_obj as $k=>$val) { if( !empty($array_tags) && in_array($k, $array_tags) ) { $attr[] = self::toArray($val, $array_tags, $strip_white); }else{ $attr[$k] = self::toArray($val, $array_tags, $strip_white); } } return $attr; } return false; } /** * 生成随机字符串 * @param type $length 设置随机长度,默认32位 */ protected function createNonceStr($length = 32) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i U~5cB /** * 签名规则 * @param type $paraMap * @param type $urlEncode * @return type */ private 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 = ''; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } /** * curl post * @param type $url * @param type $postData * @param type $options * @return type */ protected function curlPost($url = '', $postData = '', $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; } /** * curl get * @param string $url * @param array $options * @return mixed */ protected function curlGet($url = '', $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; } /** * 数组转化为XML * @param type $arr * @return string */ protected function arrayToXml($arr) { $xml = ""; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "" . $val . ""; } else $xml .= ""; } $xml .= ""; return $xml; } public function logResult($postStr){ $world = date("Y-m-d h:i:s",time()); $file = $_SERVER['DOCUMENT_ROOT'].'/log/Wxpay_app_notify.txt'; date_default_timezone_set("PRC"); $fp = fopen($file,"a"); flock($fp, LOCK_EX) ; fwrite($fp,"执行日期:".print_r($postStr,true)."\n".$world."\n"); flock($fp, LOCK_UN); fclose($fp); } 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; } /** * 微信回调地址 * @return type * 通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒 */ public function wx_notify(){ //echo "123";die; $config = array( 'mch_id' => '999999999', 'appid' => 'wxff99999999999', 'key' => 'Demo99999999999999', ); $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //获取微信返回的数据 //$this->logResult($postStr); $this->logResult($postStr); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); //转化数据,进行验签 if ($postObj === false) { die('parse xml error'); } if ($postObj->return_code != 'SUCCESS') { die($postObj->return_msg); } if ($postObj->result_code != 'SUCCESS') { die($postObj->err_code); } $arr = (array) $postObj; unset($arr['sign']); if ($this->getSign($arr, $config['key']) == $postObj->sign) { if ($postObj->return_code == "FAIL") { //此处应该更新一下订单状态,商户自行增删操作;失败 echo ''; //通知微信支付失败;设置返回码 return $postObj; } else if ($postObj->result_code == "FAIL") { //此处应该更新一下订单状态,商户自行增删操作;失败 echo ''; //通知微信支付失败;设置返回码 return $postObj; } else { $tag=substr($arr['out_trade_no'],0,strlen($arr['out_trade_no'])-10); $where['tag']=substr($arr['out_trade_no'],0,strlen($arr['out_trade_no'])-10); //$where['tag']=$arr['out_trade_no']; $order=M("order"); $re=$order->where($where)->find(); if($re['status'] == -1){ // 监听用户支付状态 \Think\Hook::listen('paystatus',$tag); $order->status=1; $order->ispay=2; $order->wx_transaction_id=$arr['transaction_id']; $order->time_pay = $arr['time_end']; $order->payway=4; $order->where($where)->save(); //改变销量 $data=M('shoplist')->where($where)->getField('goodid,num'); foreach ($data as $k=>$v) { $whereid['id']=array('eq',$k); $sale=M('document')->where($whereid)->getField('sale'); $set['sale']=intval($v)+intval($sale); M('document')->where($where)->setField($set); } } echo exit(''); //此处应该更新一下订单状态,商户自行增删操作;操作成功 //这里就可以做自己数据库订单判断及操作了 //这里可以选择直接sql操作数据库,也可以根据自己需要,模拟自己的加密算法去请求自己的接口 } } else { echo ''; //通知微信支付失败;设置返回码 return $postObj; } }}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180905G17GEU00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券