lokielse / omnipay-wechatpay

(微信支付)WeChatPay driver for the Omnipay PHP payment processing library
MIT License
315 stars 103 forks source link

Wechat timeStamp is string #22

Closed getpu closed 7 years ago

getpu commented 7 years ago

公众号 iphone 6s plus error "微信支付调用JSAPI缺少参数:timeStamp"

public function getOrderData()
{
    if ($this->isSuccessful()) {
        $timestamp = time();
        $data = array (
            'app_id'    => $this->request->getAppId(),
            'mch_id'    => $this->request->getMchId(),
            'prepay_id' => $this->getPrepayId(),
            'package'   => 'Sign=WXPay',
            'nonce'     => md5(uniqid()),
            'timestamp' => "$timestamp",
        );

        $data['sign'] = Helper::sign($data, $this->request->getApiKey());
    } else {
        $data = null;
    }

    return $data;
}

很迷芒 虽然这是官方的写法 但按照你以前写的 , 安卓 iphone5s 并没有报错,唯独在 6s plus 下面报这个错

lokielse commented 7 years ago

@getpu 返回的数据中是timestamp,报错信息是timeStamp, 明显大小写不一样。 你需要在客户端将返回的数据再标准化一下,再传入前端的SDK中。

getpu commented 7 years ago

@lokielse 我刚刚试了一遍 还是不行 但我改了上面的代码是可以的 具体是 iphone6s plus 其他的几套测试均正常 以下是官方的 :

    /**
     * 
     * 获取jsapi支付的参数
     * @param array $UnifiedOrderResult 统一支付接口返回的数据
     * @throws WxPayException
     * 
     * @return json数据,可直接填入js函数作为参数
     */
    public function GetJsApiParameters($UnifiedOrderResult)
    {
        if(!array_key_exists("appid", $UnifiedOrderResult)
        || !array_key_exists("prepay_id", $UnifiedOrderResult)
        || $UnifiedOrderResult['prepay_id'] == "")
        {
            throw new WxPayException("参数错误");
        }
        $jsapi = new WxPayJsApiPay();
        $jsapi->SetAppid($UnifiedOrderResult["appid"]);
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $parameters = json_encode($jsapi->GetValues());
        return $parameters;
    }

问题有点莫名其妙了 , 我用的 微信浏览器内置方法 js 前端如下:

if (data.pay === 3) {
                        WeixinJSBridge.invoke(
                            'getBrandWCPayRequest', {
                                "appId": data.parameter.appId,
                                "timeStamp": data.parameter.timeStamp,         //时间戳,自1970年以来的秒数
                                "nonceStr": data.parameter.nonceStr, //随机串
                                "package": data.parameter.package,
                                "signType": data.parameter.signType,         //微信签名方式:
                                "paySign": data.parameter.paySign //微信签名
                            },
lokielse commented 7 years ago

你是不是用错接口了,JSAPI返回的应该是 https://github.com/lokielse/omnipay-wechatpay/blob/master/src/Message/CreateOrderResponse.php#L54

你的代码片段里面是刷卡支付里面的 https://github.com/lokielse/omnipay-wechatpay/blob/master/src/Message/CreateMicroOrderResponse.php#L21

getpu commented 7 years ago
/**
 * @return mixed
 */
public function wxpayPay()
{
    $gateway = Omnipay::create('WechatPay_Js');

    $gateway->setApiKey('9c82530e1ee35caebf85381ca64a5073');

    $info = Yii::$app->request->cookies->getValue(BindAccount::COOKIE_INFO);
    $order = [
        'body' => $this->_order->goodsFirstTitle,
        'out_trade_no' => $this->_order->id,
        'total_fee' => $this->_order->price * 100, //=0.01
        'spbill_create_ip' => Yii::$app->request->userIP,
        'openid' => $info['openid'],
        'fee_type' => 'CNY',
    ];

    $request = $gateway->purchase($order);
    $response = $request->send();

    // Yii::getLogger()->log($request->getData(), 1);
    return $response->getJSOrderData();
}
getpu commented 7 years ago

没有吧_

lokielse commented 7 years ago
return $response->getJSOrderData();

这个返回的数据格式里面有timeStamp呢,微信的SDK报缺少参数:timeStamp的错误没道理啊!!

'appId'     => $this->request->getAppId(),
'package'   => 'prepay_id=' . $this->getPrepayId(),
'nonceStr'  => md5(uniqid()),
'timeStamp' => time(),
getpu commented 7 years ago

是的 安卓 iphone5s 都没有 iphone5s 我只测一两遍同事的手机, 但安卓我是测了多遍。 然后 iphone6s 就出现这个问题了

lokielse commented 7 years ago

在前端debug一下吧,把6s和6s Plus的传入支付前数据记录一下: 比如:

alert(JSON.stringify(params));
wx.chooseWXPay(params);
getpu commented 7 years ago

{"status":1,"trade_no":"1490896832241","pay":3,"parameter":

lokielse commented 7 years ago

应该只有这几个参数才对啊,怎么那么多参数???

timestamp
nonceStr
package
signType
paySign
getpu commented 7 years ago

有些是订单参数, parameter 才是 支付参数

lokielse commented 7 years ago

传入wx.chooseWXPay(params);的这个params参数打印一下

getpu commented 7 years ago

这个要引入 weixin-1.0.0.js 我没有引入这个 用的内置浏览器。 前几个项目都是这样干的。这次项目用了Yii2 我才用了你的这个支付插件, 写得很不错啊。算了 时间也早了 我明天再测吧 ,睡觉了。你也早点睡啊。

lokielse commented 7 years ago

我百度了一下WeixinJSBridge,说这个是私有接口。。。,使用有风险。 官方有JSSDK的,请下载后尝试:https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82

wx.chooseWXPay({
    timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: '', // 支付签名随机串,不长于 32 位
    package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
    signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
    paySign: '', // 支付签名
    success: function (res) {
        // 支付成功后的回调函数
    }
});
lokielse commented 7 years ago

你再试一试吧,如果确实表面只是在6s上面有问题,你可以去微信支付那边提提bug。 我看WeixinJSBridge官方文档里面也有写: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 但是里面的timeStamp的值好像是字符串格式,你看看是不是这个数据类型导致的问题。 把服务端返回的timeStamp+''转换成字符串试一试。

getpu commented 7 years ago

是的所以我改了下面的代码 Iphone6s 是可以的了 ,但这次我 update了一下又出现了这个问题 才给你提交一个 issue public function getJSOrderData() { if ($this->isSuccessful()) { $timeStamp = time(); $data = array ( 'appId' => $this->request->getAppId(), 'package' => 'prepay_id=' . $this->getPrepayId(), 'nonceStr' => md5(uniqid()), 'timeStamp' => "$timeStamp", );

        $data['signType'] = 'MD5';
        $data['paySign']  = Helper::sign($data, $this->request->getApiKey());
    } else {
        $data = null;
    }

    return $data;
}
lokielse commented 7 years ago

好吧,那我更新一下吧。