Symfony2 Authorize.net SIM错误

时间:2015-11-17 10:09:35

标签: symfony authorize.net omnipay payum

我想使用payum.org在Symfony中使用Authorize.net SIM付款方式。 它没有官方网关,但在omnipay中有一个:omnipay-authorizenet。 payum中还有omnipay-bridge,因此可以在payum中使用omnipay网关。

所以我使用此设置,在提交authorize.net表单后,我收到错误:

[date] request.CRITICAL: Uncaught PHP Exception Omnipay\Common\Exception\InvalidRequestException: "Incorrect hash" at .../authorize/vendor/omnipay/authorizenet/src/Message/SIMCompleteAuthorizeRequest.php line 42 {"exception":"[object] (Omnipay\\Common\\Exception\\InvalidRequestException(code: 0): Incorrect hash at .../authorize/vendor/omnipay/authorizenet/src/Message/SIMCompleteAuthorizeRequest.php:42)"} []

但这不是,因为生成的哈希值不正确 - 这是因为第二次调用了捕获URL而没有POST数据。

使用3个软件包进行干净的Symfony2安装:

composer.json:

"payum/payum-bundle": "0.15.*",
"omnipay/authorizenet": "~2.0",
"payum/omnipay-bridge": "*@stable"

config.yml:

payum:
    security:
        token_storage:
            AppBundle\Entity\PaymentToken: { doctrine: orm }

    storages:
        AppBundle\Entity\Payment: { doctrine: orm }

    gateways:
        authorizeGateway:
            omnipay_offsite:
                type: AuthorizeNet_SIM
                options:
                    hashSecret: 'Simon'
                    ApiLoginId: 'xxx'
                    transactionkey: 'xxx'
                    testMode: false
                    developerMode: true

控制器:

/**
 * @Route("/prepare", name="prepare")
 */
public function prepareAction()
{
    $gatewayName = 'authorizeGateway';

    $storage = $this->get('payum')->getStorage('AppBundle\Entity\Payment');

    $payment = $storage->create();
    $payment->setNumber(uniqid());
    $payment->setCurrencyCode('USD');
    $payment->setTotalAmount(1);
    $payment->setDescription('A description');
    $payment->setClientId('anId');
    $payment->setClientEmail('foo@example.com');
    $storage->update($payment);

    $captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
        $gatewayName,
        $payment,
        'done' // the route to redirect after capture
    );

    return $this->redirect($captureToken->getTargetUrl());
}

/**
 * @Route("/done", name="done")
 */
public function doneAction(Request $request)
{
    ...
}

转到/ prepare显示重定向到authorize.net页面一秒钟,我被重定向到外部test.authorize.net/gateway/transact.dll(在https上)页面,我指定了卡号(测试卡号) )和未来的到期日。 提交此表单即可:

An error occurred while trying to report this transaction to the merchant. An e-mail has been sent to the merchant informing them of the error. The following is the result of the attempt to charge your credit card.

This transaction has been approved.

It is advisable for you to contact the merchant to verify that you will receive the product or service.

我收到有关商家电子邮件收据的电子邮件以及有关错误的电子邮件:

Authorize.Net Developer Center Merchant,

Your script timed out while we were trying to post transaction results to it.
Transaction ID: XXX

Transaction Result: This transaction has been approved.

正确处理事务,调用捕获脚本,哈希匹配,然后再次调用捕获而不发布数据 - 然后哈希不匹配并授权显示错误。

来自symfony profiler的请求:

Token   IP                  Method  URL                                                                 Time                                Status
fe39ec  198.241.162.104     GET     .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk     Tue, 17 Nov 2015 09:47:36 +0100     500
bba47c  198.241.162.104     GET     .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk     Tue, 17 Nov 2015 09:47:36 +0100     200
c95b83  198.241.162.104     POST    .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk     Tue, 17 Nov 2015 09:47:36 +0100     302
a87347  myip                GET     .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk     Tue, 17 Nov 2015 09:47:30 +0100     200
c95d57  myip                GET     .../prepare                                                         Tue, 17 Nov 2015 09:47:29 +0100     302 

从我所看到的呼叫/准备时,我们被重定向到捕获,这将转到授权的形式。然后在几秒钟后(当信用卡数据被填写并提交时)授权(不同的ip)使得发布请求被捕获。这是302重定向(可能应该是带有javascript代码的SIM响应返回到我们的页面?)。使用GET将捕获称为secod时间,并且计算的哈希值不匹配 - 这是500响应 - 授权保留在其URL上并显示错误消息。永远不会调用完成脚本。

可能是什么问题?这很难进一步调试,因为有payum,omnipay-bridge,omnipay,authorize combined。

我在可通过互联网访问的环境中使用http://developer.authorize.net/帐户关闭测试模式对此进行测试。

更新

如果我将通知令牌添加到控制器,如下所示:

/**
 * @Route("/prepare", name="prepare")
 */
public function prepareAction()
{
    $gatewayName = 'authorizeGateway';

    $storage = $this->get('payum')->getStorage('AppBundle\Entity\Payment');

    $payment = $storage->create();
    $payment->setNumber(uniqid());
    $payment->setCurrencyCode('USD');
    $payment->setTotalAmount(1); // 1.23 EUR
    $payment->setDescription('A description');
    $payment->setClientId('anId');
    $payment->setClientEmail('foo@example.com');
    $storage->update($payment);
    $captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
        $gatewayName,
        $payment,
        'done' // the route to redirect after capture
    );

    $tokenFactory = $this->get('payum.security.token_factory');
    $notifyToken = $tokenFactory->createNotifyToken($gatewayName, $payment);
    $payment->setDetails(['notifyUrl' => $notifyToken->getTargetUrl()]);
    $storage->update($payment);

    return $this->redirect($captureToken->getTargetUrl());
}

我收到错误“不支持请求通知{model:ArrayObject}。”:

[2015-11-17 17:46:50] request.INFO: Matched route "payum_notify_do". {"route_parameters":{"_controller":"Payum\\Bundle\\PayumBundle\\Controller\\NotifyController::doAction","payum_token":"Lv5ovrC-8vikIB9ItDVLcNfuRzjjaD_pPiE3-6VIV8Y","_route":"payum_notify_do"},"request_uri":".../payment/notify/Lv5ovrC-8vikIB9ItDVLcNfuRzjjaD_pPiE3-6VIV8Y"} []
[2015-11-17 17:46:50] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2015-11-17 17:46:50] request.CRITICAL: Uncaught PHP Exception Payum\Core\Exception\RequestNotSupportedException: "Request Notify{model: ArrayObject} is not supported." at .../authorize/vendor/payum/core/Payum/Core/Exception/RequestNotSupportedException.php line 29 {"exception":"[object] (Payum\\Core\\Exception\\RequestNotSupportedException(code: 0): Request Notify{model: ArrayObject} is not supported. at .../authorize/vendor/payum/core/Payum/Core/Exception/RequestNotSupportedException.php:29)"} []

1 个答案:

答案 0 :(得分:0)

Omnipay bridge 0.15.x未设置notifyUrl,omnipay gateway uses return url为通知。当通知到来时(重定向之前),捕获令牌为invalidated且不再可用。

有两种解决方案:

  1. 升级到1.0,生成notifyUrl。顺便说一句,您可以使用function sum($carry, $item){ return $carry + $item['count']; } array_reduce($item_arr, "sum"); 网关工厂而不是omnipay

  2. 或者您必须自己生成通知网址,并将其设置为omnipay_offsite

    $ tokenFactory = $ this-> get('payum.security.token_factory'); $ notifyToken = $ tokenFactory-> createNotifyToken($ gatewayName,$ payment);

    $ payment-> setDetails(['notifyUrl'=> $ notifyToken-> getTargetUrl()]); $存储 - >更新($付款);