0

我想使用 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)"} []

但这不是因为生成的哈希不正确 - 这是因为在没有 POST 数据的情况下第二次调用捕获 url。

在带有 3 个软件包的 Symfony2 的全新安装中:

作曲家.json:

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

配置.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)"} []
4

1 回答 1

0

Omnipay bridge 0.15.x 没有设置notifyUrl,omnipay 网关使用return url作为notify one。当通知到来时(在您被重定向之前),捕获令牌将失效并且不再可用。

有两种解决方案:

  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()]); $存储->更新($支付);

于 2015-11-17T15:05:40.447 回答