【问题标题】:Symfony2 Authorize.net SIM errorSymfony2 Authorize.net SIM 错误
【发布时间】:2016-02-18 15:51:45
【问题描述】:

我想通过 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 

根据我在调用 /prepare 时看到的情况,我们会立即重定向到捕获,这将转到授权表单。然后几秒钟后(填写并提交信用卡数据时)授权(不同的ip)发出post请求以捕获。这是 302 重定向(可能应该是带有 javascript 代码的 SIM 响应以返回我们的页面?)。捕获称为 GET 的秒时间,计算的哈希值不匹配 - 这是 500 响应 - 授权停留在其 url 上并显示错误消息。永远不会调用完成的脚本。

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

我正在使用 http://developer.authorize.net/ 上的帐户在 Internet 可访问的环境中进行测试,并关闭测试模式。

更新:

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

/**
 * @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)"} []

【问题讨论】:

标签: symfony authorize.net omnipay payum


【解决方案1】:

Omnipay 桥接器 0.15.x 没有设置 notifyUrl,而 omnipay gateway uses return url 作为通知之一。当通知到来时(在您被重定向之前),捕获令牌是 invalidated 并且不再可用。

有两种解决方案:

  1. 升级到生成 notifyUrl 的 1.0。顺便说一句,您可以使用omnipay 网关工厂而不是omnipay_offsite

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

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

    $payment->setDetails(['notifyUrl' => $notifyToken->getTargetUrl()]); $storage->update($payment);

【讨论】:

  • 您好,感谢您的回复。我现在选择了第二个选项。我没有那么多时间来调试它,但现在我收到其他错误“不支持请求通知 {model: ArrayObject}”。我更新了问题,详细说明了我如何按照您的说明修改控制器代码以及我得到了什么错误(所以现在的最终结果仍然是相同的)
  • 网桥不会将通知请求代理到内部omnipay 网关的方法。应该实施
  • 是否有任何项目可以通过我可以查看的 authorize.net SIM 桥接器实现此功能?还是文档? PayumBundle:Notify:do 被调用,我知道我必须实现自定义 NotifyAction 应该返回其中一个omnipay/authorize 消息或调用 SIMGateway::completePurchase?
  • 不,没有任何应用程序,至少我不知道它们。是的,您是对的,您必须将 NotifyAction 添加到调用 completePurchase 方法的omnipay 桥接器中。并使用详细信息更新模型,如下所示:github.com/Payum/OmnipayBridge/blob/master/src/Action/…
  • 我添加了动作服务:action.notify.custom: class: AppBundle\Services\NotifyAction tags: - {name: payum.action, prepend: true, all: true } 当我看到do payum:gateway:debug: authorizeGateway (Payum\Core\Gateway): Actions: AppBundle\Services\NotifyAction 但是当授权回到 payum_notify_do 网关时没有附加这个动作(我检查 $this->actions in Payum\Core\Gateway ::findActionSupported),所以我仍然得到 RequestNotSupportedException。我是否正确注册了操作?没有调用 action 可能是什么问题?
猜你喜欢
  • 2019-11-25
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 2015-05-20
  • 2012-05-01
  • 2012-09-05
相关资源
最近更新 更多