微信APP支付,被-1整的懵懵的

微信APP支付,后端返回预支付信息,前端APP拉起支付,死活不能唤醒微信支付界面。我们的前端,对着包名一遍又一遍的对应,我这边对着签名一遍又一遍的生成校对。
网上说的各种坑,我们都踩过了,唉,最后却是意外之坑啊。返回前端的数据时json,里面有status状态值,和预支付信息,谁曾想,前端直接把结果全部丢给了微信支付的接口,累死也掉不起来。
吃一堑,长一智,希望下次都注重数据结构,不要想当然。

话不多,源码线上:

<?php


namespace app\wxpay\controller;
class WxappController extends HomeBaseController
{
    public function paywx()
    {
        $app_id="00000000000000000";
        $mch_id='000000000';
        $app_key='000000000000000000000000000000';
        $payTime = time();
        $oid=input('oid');       // 订单号
        $order = Db::name('jjr_morder')->where('id',$oid)->find();
        $orderIds = $order['order_num'];
        $prepay_id = $this->generatePrepayId($app_id, $mch_id, $app_key,$orderIds,$order['paymount'],$order['title']);
        $response = array(
            'appid' => $app_id,
            'noncestr' => $this->generateNonce(),
            'partnerid' => $mch_id,
            'package' => 'Sign=WXPay',
            'prepayid' => $prepay_id,
            'timestamp' =>$payTime,
        );
        $response['sign'] = $this->calculateSign($response, $app_key);
        return json_encode($response);
    }

    public static 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;
    }
    /**
     * 随机数
     *
     */

    private function generateNonce($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    /**
     * a-z拼接 md5生成signval
     *
     */
    function calculateSign($arr, $key){
        ksort($arr);
        $buff = "";
        foreach ($arr as $k => $v) {
            if ($k != "sign" && $k != "key" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");

        return strtoupper(md5($buff . "&key=" . $key));
    }

    /**
     * Get xml from array
     */
    function getXMLFromArray($arr){
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= sprintf("<%s>%s</%s>", $key, $val, $key);
            } else {
                $xml .= sprintf("<%s><![CDATA[%s]]></%s>", $key, $val, $key);
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * Generate a prepay id
     *
     */
    public static function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = self::formatQueryParaMap($params, false);
        $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
        return $signStr;
    }
    public static 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;
    }
    function generatePrepayId($appId, $mchId, $appKey, $orderIds,$order_amount,$attach)
    {
        $params = array(
            'appid'                         => $appId,
            'mch_id'                        => $mchId,
            'nonce_str'                     => $this->generateNonce(),
            'body'                          => "经纪人大学-".$attach,
            'out_trade_no'                  => $orderIds,
            'total_fee'                     => intval($order_amount * 100),
            'spbill_create_ip'              => $this->getIP(),
            'notify_url'                    => 'http://www.test.net/wx/notify/index',       // 回调地址,不能带特殊符号
            'trade_type'                    => 'APP'
        );

        $params['sign'] =  $this->calculateSign($params, $appKey);
        $xml = $this->getXMLFromArray($params);

        $ch = curl_init();
        curl_setopt_array($ch, array(
            CURLOPT_URL            => "https://api.mch.weixin.qq.com/pay/unifiedorder",
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_POST           => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER         => false,
            CURLOPT_POSTFIELDS     => $xml,
        ));
        $result = curl_exec($ch);
        curl_close($ch);
        $xml = simplexml_load_string($result);

        $unifiedOrder = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($unifiedOrder === false) {
            die('parse xml error');
        }
        if ($unifiedOrder->return_code != 'SUCCESS') {
            die($unifiedOrder->return_msg);
        }
        if ($unifiedOrder->result_code != 'SUCCESS') {
            die($unifiedOrder->err_code);
        }
//        dump($unifiedOrder);
        return (string)$xml->prepay_id;
    }

    function getIP() {
        if (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        }
        elseif (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        }
        elseif (getenv('HTTP_X_FORWARDED')) {
            $ip = getenv('HTTP_X_FORWARDED');
        }
        elseif (getenv('HTTP_FORWARDED_FOR')) {
            $ip = getenv('HTTP_FORWARDED_FOR');

        }
        elseif (getenv('HTTP_FORWARDED')) {
            $ip = getenv('HTTP_FORWARDED');
        }
        else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值