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