【问题标题】:Symfony 5 stripe v3 can't find CHECKOUT_SESSION_IDSymfony 5 stripe v3 找不到 CHECKOUT_SESSION_ID
【发布时间】:2021-05-16 10:27:02
【问题描述】:

我正在尝试使用条纹处理每月订阅:

我创建了一个带有操作的支付控制器:

创建结帐会话操作:

 /**
     * @Route ("/create-checkout-session", name="checkout")
     */
    public function checkout(Request $request)
    {
        $data = json_decode($request->getContent());
        \Stripe\Stripe::setApiKey('sk_test_...');
        try {
            $checkout_session = \Stripe\Checkout\Session::create([
                'payment_method_types' => ['card'],
                'line_items' => [[
                    'price' => $data->priceId,
                    // For metered billing, do not pass quantity
                    'quantity' => 1,
                ]],
                'mode' => 'subscription',
                'success_url' => $this->generateUrl('success', ["session_id" => "{CHECKOUT_SESSION_ID}"], UrlGeneratorInterface::ABSOLUTE_URL),
                'cancel_url' => $this->generateUrl('error', [], UrlGeneratorInterface::ABSOLUTE_URL),
            ]);
        } catch (\Exception $e) {
            return new JsonResponse(["error" => ['message' => $e->getMessage()]]);

        }
        return new JsonResponse(["sessionId" => $checkout_session['id']]);
    }

成功行动:

  /**
     * @Route(
     *     "/{_locale}/success/{session_id}",
     *      name="success",
     *      defaults={"_locale"="en"},
     *      requirements={"_locale"="en|fr"}
     * )
     * @param Request $request
     * @return Response
     */
    public function success(Request $request): Response
    {

        $locale = $request->getLocale();

        // Get current user
        $user = $this->getUser();

        \Stripe\Stripe::setApiKey('sk_test_...');

        $session = \Stripe\Checkout\Session::retrieve($request->get('session_id'));
        $customer = \Stripe\Customer::retrieve($session->customer);

        return $this->render('payment/success.html.twig', [
            'current_language' => $locale,
            'user' => $user,
            'session' => $session,
            'customer' => $customer,
        ]);
    }

我创建了一个脚本:

// Create an instance of the Stripe object with your publishable API key
const stripe = Stripe('pk_test_..');

const createCheckoutSession = function (priceId) {
    return fetch("/create-checkout-session", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            priceId: priceId
        })
    }).then(function (result) {
        return result.json();
    });
};


$(".subscription-btn").click(function (e) {
    e.preventDefault();
    let PRICE_ID = $(this).data('priceCode');
    console.log(PRICE_ID);
    createCheckoutSession(PRICE_ID).then(function (data) {
        // Call Stripe.js method to redirect to the new Checkout page
        stripe
            .redirectToCheckout({
                sessionId: data.sessionId
            })
            .then(function (result) {
                // If `redirectToCheckout` fails due to a browser or network
                // error, you should display the localized error message to your
                // customer using `error.message`.
                if (result.error) {
                    alert(result.error.message);
                }
            })
    });
});

付款工作,但重定向成功后出现此错误

无效的 checkout.session id:{CHECKOUT_SESSION_ID}

我该如何解决这个错误以及如何在我的项目中处理每月付款?

【问题讨论】:

    标签: symfony stripe-payments


    【解决方案1】:

    我遇到了同样的问题。我只是添加:

    $this->router->generate('my_confirm_route', ['myrouteparam' => $myRouteParam], UrlGeneratorInterface::ABSOLUTE_URL).'?session_id={CHECKOUT_SESSION_ID}';
    

    在控制器中:

    $request->query->get('session_id')
    

    【讨论】:

      【解决方案2】:

      Leroy 是正确的,但我建议您确认您生成的 success_url 实际上看起来像它应该的样子 - 即没有对那些 {} 进行 urlencoded - 因为这可能是这里发生的事情.

      除此之外,我认为您的方法是正确的,而 Leroy 的方法则不是——我认为您没有向 Stripe 提供未编码的 URL,因此它没有将 {CHECKOUT_SESSION_ID} 识别为应有的模板字符串。

      【讨论】:

      • 感谢您的回答,我正在使用 generateUrl 生成带有参数的路由,但它不起作用,我使用了一个简单的链接:'success_url' => 'localhost/'.$locale.'/success?session_id={CHECKOUT_SESSION_ID}' ,
      【解决方案3】:

      您将确切的值作为 success_url 传递给您的 PSP。

      'success_url' => $this->generateUrl('success', ["session_id" => "{CHECKOUT_SESSION_ID}"], UrlGeneratorInterface::ABSOLUTE_URL),
      

      然后您将返回该重定向 url,作为文字:/en/success/{CHECKOUT_SESSION_ID}

      接下来,您从某个 api 中查找确切的值 {CHECKOUT_SESSION_ID}

      $session = \Stripe\Checkout\Session::retrieve($request->get('session_id'));
      

      我不确定,但我认为您需要从 success_url 的正文而不是 $request 对象中获取会话 ID。

      我也认为你可以跳过success_url中的session_id,因为那是用户的回调url。当用户被重定向回您的应用程序时,用户仍处于登录状态,您不想将会话 ID 发送到您的 PSP。

      我认为您的反馈在帖子正文中,基于您在 stripe 中的配置。做这样的事情应该会给你你想要的。

      首先,从success_url中去掉session id

      'success_url' => $this->generateUrl('success', UrlGeneratorInterface::ABSOLUTE_URL),
      

      接下来,更改您的成功 url 逻辑以使用帖子正文。

      /**
           * @Route(
           *     "/{_locale}/success",
           *      name="success",
           *      defaults={"_locale"="en"},
           *      requirements={"_locale"="en|fr"}
           * )
           * @param Request $request
           * @return Response
           */
          public function success(Request $request): Response
          {
              ...
              $body = $request->getContent();
              $feedback = json_decode($body, true);
      
              $session = \Stripe\Checkout\Session::retrieve($feedback['id']);
              ...
          }
      

      PS,请记住,我还没有阅读有关 Stripe 的文档。但我坚信他们会以某种形式将会话 ID(您创建的)发回给您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        • 2021-05-02
        • 2020-07-11
        • 2021-09-21
        • 2021-09-03
        • 2013-11-05
        • 2019-07-12
        相关资源
        最近更新 更多