Symfony / Ajax:成功响应时调用函数

Posted

技术标签:

【中文标题】Symfony / Ajax:成功响应时调用函数【英文标题】:Symfony / Ajax : call function on success response 【发布时间】:2021-01-11 16:53:09 【问题描述】:

我正在使用 symfony 5 和 Ajax 调用进行支付开发,当操作结束成功响应时,我想调用另一个操作来生成发票文档并将其保存在公用文件夹中并将其保存到数据库中。

这是我在 php 控制器中所做的:

 /**
     * @Route("/booking/checkout/id", name="booking_checkout")
     * @Security("is_granted('ROLE_USER')")
     * @param Booking $booking
     * @param Request $request
     * @throws ApiErrorException
     */
    public function checkoutAction(Request $request, Booking $booking)
    
        $diff_time = (strtotime($booking->getEndDate()->format('d-m-Y')) - strtotime($booking->getStartDate()->format('d-m-Y'))) / (60 * 60 * 24) + 1;

        $amount = $request->get('amount');
        $carModel = $booking->getCar()->getModel() . " " . $booking->getCar()->getBrand();

        Stripe::setApiKey('sk_test_51HSKmkLhD9FM4Mb7keiF5NmilsUh5rBVzOamXpahjAc6ORYMlnELaroSH8cRwKe4dlEzQqRMgrxDumEQneXyFPQv00JxG2gGCD');

        header('Content-Type: application/json');

        $checkout_session = Session::create([

            'payment_method_types' => ['card'],

            'line_items' => [[

                'price_data' => [

                    'currency' => 'eur',

                    'unit_amount' => $amount * 100,

                    'product_data' => [

                        'name' => $diff_time . " " . "jour(s)" . " " . $carModel,

                    ],

                ],

                'quantity' => 1,

            ]],

            'mode' => 'payment',

            'success_url' => $this->generateUrl('user.profile.bookings', [$booking, $this->addFlash('success', 'vous avéz payé votre réservation avec succes')], UrlGeneratorInterface::ABSOLUTE_URL),

            'cancel_url' => $this->generateUrl('user.profile.bookings', [], UrlGeneratorInterface::ABSOLUTE_URL),


        ]);

        $booking->setStatus("Payée");
        $booking->getCar()->setAvailable(0);
        $this->em->persist($booking);
        $this->em->flush();
        
        return new JsonResponse(['id' => $checkout_session->id], 200);
    

这里是 Ajax 调用:

<script type="text/javascript">
        // Create an instance of the Stripe object with your publishable API key
        var stripe = Stripe("pk_test_51HSKmkLhD9FM4Mb7HbTbsTtzd60BbXnsXpoVGcJT3N7j751XgEeLmraXvzys4DCAYo7ZC1Yjc2nr1PjVdqXsmVg400NVqgnCQH");
        var checkoutButton = document.getElementById("checkout-button");
        checkoutButton.addEventListener("click", function () 

            $.ajax(
                method: "POST",
                url: " path('booking_checkout','id': booking.id) ",
                data: 
                    amount:  total ,
                ,
                success: function (session) 

                    return stripe.redirectToCheckout(sessionId: session.id);
                
            );
           
        );

我定义了一个使用当前 Booking 对象的 Dompdf 库生成发票的方法,但我没有找到在 stripe 重定向成功后更直接地调用它的方法:

  /**
     * @param Booking $booking
     * @Route("/booking/id/invoice", name="booking_invoice")
     * @param Booking $booking
     * @param Request $request
     */

    public function generateInvoice(Booking $booking)
    

        $invoice = new Invoice();
        $invoice->setBooking($booking);
        $invoice->setDate(new \DateTime());
        $invoice->setReference($invoice->generateReference($booking));
        $this->em->persist($invoice);
        $this->em->flush();


        $pdfOptions = new Options();
        $pdfOptions->set('defaultFont', 'Arial');

        // Instantiate Dompdf with our options
        $dompdf = new Dompdf($pdfOptions);

        // Retrieve the html generated in our twig file
        $html = $this->render('admin/ContractInvoice/invoice.html.twig', [
            'invoice' => $invoice
        ]);

        // Load HTML to Dompdf
        $dompdf->loadHtml($html);

        // (Optional) Setup the paper size and orientation 'portrait' or 'portrait'
        $dompdf->setPaper('A4', 'portrait');

        // Render the HTML as PDF
        $dompdf->render();

        // Store PDF Binary Data
        $output = $dompdf->output();

        // In this case, we want to write the file in the public directory
        $publicDirectory = $this->projectDir. '/public/invoices';


        // e.g /var/www/project/public/name.pdf
        $pdfFilepath = $publicDirectory . '/' . $booking->getCar()->getRegistrationNumber() . $booking->getUser()->getName() . '.pdf';

        $invoice->setFilePath($pdfFilepath);
        $this->em->persist($invoice);
        $this->em->flush();

        $filename = $booking->getCar()->getRegistrationNumber() . $booking->getUser()->getName() . '.pdf';


        $dompdf->stream($filename, [
            "Attachment" => true
        ]);
        // Write file to the desired path
        file_put_contents($pdfFilepath, $output);

    

我厌倦了在结帐操作中调用发票操作,但它没有像我想要的那样工作,因为它不会让结帐发送 Stripe 结帐会话!

任何帮助!

【问题讨论】:

【参考方案1】:

您应该将此发票生成放在success_url 中提供的success page 中,您的客户在结帐后到达该处。 “在”redirectToCheckout 之后,您不能做任何事情,因为这涉及完全重定向——您的客户端代码不再运行。

【讨论】:

【参考方案2】:

我认为您需要像downloadAction 这样的东西,因为 AJAX 响应与下载无关。

【讨论】:

我需要的只是在 $.ajax( success: function (session) return stripe.redirectToCheckout(sessionId: session.id); ); 之后调用 generateInvoice 操作跨度>

以上是关于Symfony / Ajax:成功响应时调用函数的主要内容,如果未能解决你的问题,请参考以下文章

jquery ajax响应+不同AppDomain中的函数调用流程

Symfony 安全返回 401 响应而不是重定向

Symfony 5 / 请求响应:使用 Ajax 获取数据

在主页中运行用 AJAX 的调用/响应数据编写的 JavaScript 函数

反应ajax axios没有到达symfony控制器并返回模板

失败时调用的成功回调函数。可能的错误?