lokielse / omnipay-alipay

Alipay driver for the Omnipay PHP payment processing library
MIT License
565 stars 155 forks source link

Alipay_AopWap手机网页支付 签名验证失败 #122

Closed WuRongzong closed 6 years ago

WuRongzong commented 6 years ago
public function indexAction()
{
    $gateway = Omnipay::create('Alipay_AopWap');
    $gateway->setSignType('RSA2');
    $gateway->setAppId('appid');
    $gateway->setPrivateKey('app_private_key');
    $gateway->setAlipayPublicKey('alipay_public_key');
    $gateway->setReturnUrl('alipay/index');
    $gateway->setNotifyUrl('alipay/notify');
    $gateway_request = $gateway->completePurchase();
    $gateway_request->setParams($_GET); 
    try {
        $response = $gateway_request->send();
        if($response->isPaid()) {
            die('success');
        } else {
            die('fail');
        }
    } catch (Exception $e) {
        die('fail');
    }
    return false;
}

public function purchaseAction()
{
    $request = $this->getRequest();
    $out_trade_no = $request->getQuery('out_trade_no');
    $subject = $request->getQuery('subject');
    $total_fee = $request->getQuery('total_fee');
    $extra_common_param = $request->getQuery('extra_common_param', null);

    $gateway = Omnipay::create('Alipay_AopWap');
    $gateway->setSignType('RSA2');
    $gateway->setAppId('appid');
    $gateway->setPrivateKey('app_private_key');
    $gateway->setAlipayPublicKey('alipay_public_key');
    $gateway->setReturnUrl('alipay/index');
    $gateway->setNotifyUrl('alipay/notify');

    $gateway_request = $gateway->purchase();
    $gateway_request->setBizContent([
        'out_trade_no' => $out_trade_no,
        'total_amount' => $total_fee,
        'subject'      => $subject,
        'product_code' => 'QUICK_WAP_PAY',
    ]);
    $response = $gateway_request->send();
    $this->redirect($response->getRedirectUrl());
}

public function notifyAction()
{
    $request = $this->getRequest();

    if ($request->isPost()) {

        $out_trade_no = $request->getPost('out_trade_no'); // 商户订单号
        $trade_no = $request->getPost('trade_no'); // 支付宝交易号
        $trade_status = $request->getPost('trade_status'); // 交易状态
        $total_amount = $request->getPost('total_amount'); // 订单金额

        $gateway = Omnipay::create('Alipay_AopWap');
        $gateway->setSignType('RSA2');
        $gateway->setAppId('appid');
        $gateway->setPrivateKey('app_private_key');
        $gateway->setAlipayPublicKey('alipay_public_key');
        $gateway->setReturnUrl('alipay/index');
        $gateway->setNotifyUrl('alipay/notify');
        $gateway_request = $gateway->completePurchase();
        $gateway_request->setParams($_POST); 
        try {
            $response = $gateway_request->send();
            if ($response->isPaid()) {
                self::$_logger->info(__METHOD__, ['SUCCESS']);
                die('success');
            }
        } catch (Exception $e) {
            self::$_logger->info( __METHOD__, (array)$e);
            throw $e;
        }
    }
}

支付宝同步通知签名验证成功 支付宝异步通知 异常:“The signature is not match”

怎么回事?

yunshang commented 6 years ago

我也遇到同样问题

deloz commented 6 years ago

同遇到..

lokielse commented 6 years ago

这个是一个被询问得非常频繁的问题,经验告诉我们这很可能是配置错误,例如公钥,私钥配置错误(格式错误,不匹配,失效等),具体请见FAQ自查一下。

https://github.com/lokielse/omnipay-alipay/wiki/FAQs

解决了的同志请跟帖回复一下具体的问题点和解决办法,以帮助后人。。。

iwillhappy1314 commented 5 years ago

和 @WuRongzong 遇到的问题一样,同步通知验证成功。在反复确认了各种钥都没错的情况下,异步通知一直出现 “The signature is not match” 的错误。后来在支付宝官方论坛里面找到了问题。

支付宝发出的通知里面有一个 fund_bill_list 参数,这个参数的值是一个 JSON 数组,有些 PHP 环境或框架会自动转义 JSON 数组,于是,通过 $request->setParams(array_merge($_POST, $_GET)); 获取到的参数就是这个样子的:

[fund_bill_list] => [{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]

其实支付宝异步通知发出的参数是这个样子的:

[fund_bill_list] => [{"amount":"0.01","fundChannel":"ALIPAYACCOUNT"}]

设置请求参数的时候,把这个转义字符去掉就可以通过验证了。参考下面的代码:

$request->setParams(array_map('stripslashes', array_merge($_POST, $_GET)));

@lokielse 是否有必要把取消转义的功能添加到$request->setParameter方法里?以避免这种意外的发生?