tp5微信支付踩坑

<?php
/**
 * Created by  snow.
 * IDE: PhpStorm
 * Date: 2019/3/29
 * Time: 8:33
 */
namespace app\park\controller;
use think\Request;

class NewPay
{

    private $APPID =  ;//小程序ID
    private $WE_CHAT_PAY_KEY = ;//微信支付秘钥
    private $MCH_ID = ;//微信支付商户号

    public function pay()
    {
        $request = Request::instance();
        //fee: 支付的金额
        //openId:从前端传来,
        //notify:支付成功回调url,暂时不用
        $openid=$request->post('open_id');
        $billid=$request->post('bill_id');
        $fee=$request->post('fee');
        $payResult = $this->make($fee, '第二次付款', $request->ip(), $openid, '回调地址');
        if (is_null($payResult)) {
            return [
                'code' => 300,
                'msg' => 'pay error'
            ];
        }
        $orderId = $payResult['orderNum'];//随机生成的订单号
        $responseData = $payResult['response'];
        if (isset($responseData['return_code']) && $responseData['return_code'] == 'SUCCESS') {//下单成功
            //构造返回数据
            $dataArr = [
                'appId' => $this->APPID,
                'nonceStr' => $this->getRandChar(30),
                'package' => 'prepay_id=' . $responseData['prepay_id'],
                'signType' => 'MD5',
                'timeStamp' => (string)time()
            ];

            $dataArr['paySign'] = $this->signString($dataArr);
            unset($dataArr['appId']);
            return [
                'code' => 200,
                'result' => [
                    'billId' => $billid,
                    'payData' => $dataArr
                ],
            ];
        }
        //下单失败返回
        return [
            'code' => 400,
            'msg' => 'make order error'
        ];

    }


    public function make($fee, $body, $requestIP, $openId, $notify)
    {
        $data['appid'] = $this->APPID;//小程序Id
        $data['mch_id'] = $this->MCH_ID;//微信商户号
        $data['nonce_str'] = $this->getRandChar(30);//30为随机字符
        $data['out_trade_no'] = $this->makeOrderId();//商户订单号,10位时间戳+6位随机
        $data['body'] = $body;//商品描述
        $data['total_fee'] = $fee;//金额
        $data['spbill_create_ip'] = $requestIP;//终端ip
        $data['notify_url'] = $notify;//通知地址
        $data['trade_type'] = 'JSAPI';
        $data['openid'] = $openId;
        $sign = $this->signString($data);

        $data['sign'] = $sign;

        $xmlData = $this->arrayToXML($data);

        $result = $this->sendData($xmlData, 'https://api.mch.weixin.qq.com/pay/unifiedorder');

        if (is_null($result)) {//网络错误
            return null;
        }
        $payResult = $this->xmlToArray($result);
        //xml字符串转数组,返回
        return [
            'orderNum' => $data['out_trade_no'],
            'response' => $payResult
        ];
    }


    /*
     * 发送数据到微信服务器,获取支付信息
     */
    private function sendData($data, $url)
    {
        $ch = curl_init();
        //设置获取的信息以文件流的形式返回,而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //不校验ssl证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_URL, $url);
        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            return null;
        }
        curl_close($ch);
        return $result;
    }


    /**
     * 生成签名
     * @param $dataArr
     * @return string
     */
    public
    function signString($dataArr)
    {
        ksort($dataArr);//参数必须由abcd排序
        $buff = "";
        foreach ($dataArr as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        $buff .= '&key=' . $this->WE_CHAT_PAY_KEY;
        return md5($buff);
    }

    /**
     * 获取指定长度随机字符串
     * @param $length
     * @return null|string
     */
    public
    function getRandChar($length)
    {
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;
        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol[rand(0, $max)];
        }

        return $str;
    }


    /**
     * 生成商户订单号,10位时间戳+6位随机
     * @return string
     */
    public
    function makeOrderId()
    {
        return time() . mt_rand(100000, 999999);
    }


    /**
     * 数组转xml
     * @param $arr
     * @return string
     */
    public
    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字符串转数组
     * @param $xmlStr
     * @return array
     */
    public function xmlToArray($xmlStr)
    {
        try {
            return (array)simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        } catch (\Exception $e) {
            return null;
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值