跳坑,小程序支付的坑

后台代码:

<?php
/**
 * 小程序支付接口
 * User: Administrator
 * Date: 2018/6/15 0015
 * Time: 14:42
 */

class Shop_pay_mini extends Controllers
{
    private $data = array(
        'appid'=>'xxxx',
        'mch_id'=>'xxxx',
        'nonce_str'=>'',
        'sign'=>'',
        'body'=>'xxxx',
        'out_trade_no'=>'',
        'total_fee'=>'',
        'spbill_create_ip'=>'',
        'time_start'=>'',
        'time_expire'=>'',
        'notify_url'=>'http://xxx/phone/pay/Wxpay/api/notify.php',
        'trade_type'=>'JSAPI',
        'openid'=>''
    );
    private $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    private $key = '';
    private $xmlData = '';
    private $app_secret = '';
    private $_new_notify_url = '';
    private $_random_str = '';
    private $session_key = '';
    public $openId = '';
    public $total_fee='';
    public $pay_sn='';
    public $user_id='';
    public $nonce_str='';
    public $random_str='';
public function __construct()
{

}

    public function shop_pay(){
        define('IS_MINI',1);
        //记录表中
        $random_str = get_random_str();
        $pay_client=1;
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
        $number=$yCode[intval(date('Y')) - 2018] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
        $data = [
            'pay_sn'=>$this->pay_sn,
            'add_time'=>time(),
            'random_char'=>$random_str,
            'pay_client'=>$pay_client,
            'money_account'=>$this->total_fee,
            'ip_address'=>$_SERVER['REMOTE_ADDR'],
            'is_pay'=>0,
            'user_id'=>$this->user_id
        ];
        $option = [
            'table'=>'assist_pay'
        ];
        $list=M()->insert($data,$option);
        unset($this->nonce_str,$this->random_str);
        $this->nonce_str=$this->nonce_str();
        $this->random_str=$random_str;
        //生成订单
        $this->data['time_start'] = date('YmdHis',time());
        $this->data['notify_url'] = $this->_new_notify_url;
        $this->data['out_trade_no'] =$this->random_str;
        $this->data['total_fee'] = $this->total_fee;
        $this->data['notify_url'] = 'http://www.e-hl.cc/phone/pay/Wxpay/api/notify_mini.php';
        $this->data['nonce_str'] = $this->nonce_str;
        $this->data['openid'] = $this->openId;
        $this->data['sign'] = $this->_get_sign();
        $this->xmlData = $this->_get_xml();
        $this->_curl();
    }
    /**
     * 小程序获取openid
     */
    public function get_wx_openid(){
        $this->user_id=$this->is_index();
        $code = isset($_GET['code'])?$_GET['code']:$_POST['code'];
        $this->pay_sn = isset($_GET['pay_sn'])?$_GET['pay_sn']:$_POST['pay_sn'];
        $this->total_fee=isset($_POST['money'])?$_POST['money']*100:$_GET['money']*100;
        $urls = 'https://api.weixin.qq.com/sns/jscode2session?appid=wx3670f6b94f08b57e&secret=dd8357c95ef1c8d1c5c7068eda56112e&js_code='.$code.'&grant_type=authorization_code';
        $this->curl = new Lib\Curl();
        $this->curl->setUrl($urls);
        $return = $this->curl->execute(true);
        $this->session_key = $return->session_key;
        $this->openId = $return->openid;
        $this->shop_pay();
    }
    private function _curl(){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->url); //定义表单提交地址
        curl_setopt($curl, CURLOPT_POST, 1);   //定义提交类型 1:POST ;0:GET
        curl_setopt($curl, CURLOPT_HEADER, 0); //定义是否显示状态头 1:显示 ; 0:不显示
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//定义是否直接输出返回流
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_HTTPHEADER, 'Content-type: text/xml');
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $this->xmlData); //定义提交的数据,这里是XML文件
        $returnData = curl_exec($curl);
        curl_close($curl);
        $returnData = $this->xmlstr_to_array($returnData);
        if(!empty($returnData['err_code_des'])){
            output_error('请按首次操作微信支付');
        }
        if($returnData['return_code'] == 'SUCCESS' && $returnData['result_code'] == 'SUCCESS'){
            $time = time();
            $tmp='';//临时数组用于签名
            $tmp['appId'] = 'xxxx';
            $tmp['nonceStr'] = $this->nonce_str;
            $tmp['package'] = 'prepay_id='.$returnData['prepay_id'];
            $tmp['signType'] = 'MD5';
            $tmp['timeStamp'] = "$time";

            $data['test']=$returnData;
            $data['state'] = 200;
            $data['timeStamp'] = "$time";//时间戳
            $data['nonceStr'] = $this->nonce_str;//随机字符串
            $data['signType'] = 'MD5';//签名算法,暂支持 MD5
            $data['package'] = 'prepay_id='.$returnData['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
            $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
            $data['out_trade_no'] = $this->random_str;
        }else{
            $data['state'] = 0;
            $data['text'] = "错误";
            $data['RETURN_CODE'] = $returnData['RETURN_CODE'];
            $data['RETURN_MSG'] = $returnData['RETURN_MSG'];
        }
        echo json_encode($data);
    }
    private function _get_xml(){
        $xml = '<xml>';
        foreach ($this->data as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml .= '</xml>';
        return $xml;
    }
    private function xmlstr_to_array($xmlstr) {
        $doc = new DOMDocument();
        $doc->loadXML($xmlstr);
        return $this->domnode_to_array($doc->documentElement);
    }

    private function domnode_to_array($node) {
        $output = array();
        switch ($node->nodeType) {
            case XML_CDATA_SECTION_NODE:
            case XML_TEXT_NODE:
                $output = trim($node->textContent);
                break;
            case XML_ELEMENT_NODE:
                for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
                    $child = $node->childNodes->item($i);
                    $v = $this->domnode_to_array($child);
                    if(isset($child->tagName)) {
                        $t = $child->tagName;
                        if(!isset($output[$t])) {
                            $output[$t] = array();
                        }
                        $output[$t][] = $v;
                    }
                    elseif($v) {
                        $output = (string) $v;
                    }
                }
                if(is_array($output)) {
                    if($node->attributes->length) {
                        $a = array();
                        foreach($node->attributes as $attrName => $attrNode) {
                            $a[$attrName] = (string) $attrNode->value;
                        }
                        $output['@attributes'] = $a;
                    }
                    foreach ($output as $t => $v) {
                        if(is_array($v) && count($v)==1 && $t!='@attributes') {
                            $output[$t] = $v[0];
                        }
                    }
                }
                break;
        }
        return $output;
    }

    private function _get_sign(){
        $temArr = array();
        ksort($this->data);
        foreach ($this->data as $k=>$v){
            if(!empty($v)){
                $temArr[] = $k.'='.$v;
            }
        }
        $str = implode('&',$temArr).'&key='.$this->key;
        return strtoupper(md5($str));
    }
//随机32位字符串
    private function nonce_str(){
        $result = '';
        $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
        for ($i=0;$i<32;$i++){
            $result .= $str[rand(0,48)];
        }
        return $result;
    }

    //签名 $data要先排好顺序
    private function sign($data){
        $stringA = '';
        foreach ($data as $key=>$value){
            if(!$value) continue;
            if($stringA) $stringA .= '&'.$key."=".$value;
            else $stringA = $key."=".$value;
        }
        $wx_key = 'YinWenTao118YinWenTao118YinWenTa';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
        $stringSignTemp = $stringA.'&key='.$wx_key;
        return strtoupper(md5($stringSignTemp));
    }

}

 

 

 

小程序js:
 

//下单成功,开始支付

// var code='';

// 登录

wx.login({

success: res => {

// code=res.code;

var that = this

com.POST({

url: 'Shop_pay_mini/get_wx_openid',

data: {

key: com.key,

code: res.code,

pay_sn: msg.data.datas.pay_sn,

money: msg.data.datas.end_price

},

success: function (msg) {

var paySign = msg.data.paySign;

var pack = msg.data.package;

var timeStamp = msg.data.timeStamp;

var nonceStr = msg.data.nonceStr;

wx.requestPayment({

'timeStamp': timeStamp ,

'nonceStr': nonceStr,

'package': pack ,

'signType': 'MD5',

'paySign': paySign,

'success': function (res) {

console.log(res);

},

'fail': function (res) {

console.log(res);

},

 

})

}

})

// 发送 res.code 到后台换取 openId, sessionKey, unionId

}

})

 

 

APP支付

//下单支付
private function _curl($url)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url); //定义表单提交地址
    curl_setopt($curl, CURLOPT_POST, 1);   //定义提交类型 1:POST ;0:GET
    curl_setopt($curl, CURLOPT_HEADER, 0); //定义是否显示状态头 1:显示 ; 0:不显示
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//定义是否直接输出返回流
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_HTTPHEADER, 'Content-type: text/xml');
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $this->xmlData); //定义提交的数据,这里是XML文件
    $returnData = curl_exec($curl);
    curl_close($curl);
    $returnData = $this->xmlstr_to_array($returnData);
    if (!empty($returnData['err_code_des'])) {
        output_error('请按首次操作微信支付');
    }
    $nonce = $this->nonce_str();
    if ($returnData['return_code'] == 'SUCCESS' && $returnData['result_code'] == 'SUCCESS') {
        $time             = time();
        $tmp              = [];//临时数组用于签名
        $tmp['appid']     = $this->appid;
        $tmp['partnerid'] = $this->mch_id;
        $tmp['prepayid']  = $returnData['prepay_id'];
        $tmp['noncestr']  = $nonce;
        $tmp['package']   = 'Sign=WXPay';
        $tmp['timestamp'] = "$time";

        // $data['test']  = $returnData;
        $data['state'] = 200;

        $data['appid']     = $this->appid;
        $data['partnerid'] = $this->mch_id;
        $data['prepayid']  = $returnData['prepay_id'];
        $data['noncestr']  = $nonce;//随机字符串
        $data['packages']  = 'Sign=WXPay';//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
        $data['timestamp'] = "$time";//时间戳
        $data['sign']      = $this->_get_sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
        output_data($data);
    } else {
        $data['state']       = 0;
        $data['text']        = "错误";
        $data['RETURN_CODE'] = $returnData['RETURN_CODE'];
        $data['RETURN_MSG']  = $returnData['RETURN_MSG'];
        output_errors($data);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值