当 Controller 被 Authorize.net webhook 调用时,Symfony Request object 中的空数据

Empty data in Symfony Request object when Controller is called by Authorize.net webhook

使用 Authorize.net 沙箱 Web UI,设置一个 webhook 以通过 URL 调用 Symfony 控制器。默认情况下 Auth.net 发送带有 JSON 格式数据的 POST 请求。在 Requestb.in 验证数据已发送:

RAW BODY:

    {"notificationId":"f803dsa2c9-32fa-4f44-8dsd-b9b2324lf9a7",
"eventType":"net.authorize.payment.authcapture.created",
"eventDate":"2017-09-19T09:29:46.9455538Z",
"webhookId":"f2a105zd-drf4-491v-ab31-9cdd4a8ad04a",
"payload":{"responseCode":21,
"authCode":"111",
"avsResponse":"M",
"authAmount":12.5,
"entityName":"transaction",
"id":"45"}
}

然后尝试在 Symfony 控制器中检索 POST 数据并将其写入示例文件,return 实际上什么也没做:

控制器代码:

/**

 * @Route("/webhook")

 * Class DonateController

 * @package AppBundle\Controller
 */

class WebHookController extends Controller


{

    /**

     * @Route("/test", name="webhooktest")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     */

    public function WebHookAction(Request $request){

        set_include_path('/var/www/project/web/');
        $file = 'webhook_test.txt';
        $content = $request->getContent();
        $json = json_decode($content, true);

        $wr = "Request object test 0: " .  $request->request->all() . "\n\n";
        $wr = $wr . "Object : " . $request->__toString() . "\n\n";
        file_put_contents($file, $wr);

        return $this->render('test/webhook.html.twig',
            [
                'wr' => $wr
            ]);
    }

倒霉,$request只包含header,$request->request->all()returns只有空Array

尝试从 FOSRestController 扩展 body_listener 而不是经典的 Symfony 控制器,没有任何区别。

config.xml部分:

param_fetcher_listener: true
body_listener:
  decoders:
    json: fos_rest.decoder.json

还尝试用 symfony-json-request-transformerSymfonyBundlesJsonRequestBundle 处理请求,没有结果。

这是怎么回事?

解决了在 Authorize.net webhook 配置中从 HTTP 切换到 HTTPS 的问题。 默认情况下,带有 POST 数据的 HTTP 请求不会像我预期的那样被识别和处理,并且没有数据在传递。 只是使用 https:// 而不是 http://url,所有的魔法都发生了。

这是一个简单的代码,它有效。我用POST用JSON数据测试过,然后让这个函数返回请求数据来响应。成功了!

/**
 * @Route("/products", name="products", methods={"POST"})
 *
 * @param Request $request
 * @return array|JsonResponse|null|object
 */
public function WebHookAction(Request $request)
{
    $content = $request->getContent();
    $json = json_decode($content, true);
    return new JsonResponse($json);
}