Symfony 5 条带 v3 找不到 CHECKOUT_SESSION_ID
Symfony 5 stripe v3 can't find CHECKOUT_SESSION_ID
我正在尝试使用 stripe 处理每月订阅:
我创建了一个带有操作的支付控制器:
创建结帐会话操作:
/**
* @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);
}
})
});
});
付款正常,但我在重定向到成功后收到此错误
Invalid checkout.session id: {CHECKOUT_SESSION_ID}
如何修复此错误以及如何在我的项目中处理每月付款?
您将该确切值作为 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.
我认为您的反馈在 post 正文中,基于您在 stripe 上的配置。做这样的事情应该会给你你想要的。
首先,从 success_url
中删除会话 ID
'success_url' => $this->generateUrl('success', UrlGeneratorInterface::ABSOLUTE_URL),
接下来,更改您的成功 url 逻辑以使用 post 正文。
/**
* @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(您创建的)。
Leroy 是正确的,但我建议您确认您正在生成的 success_url
实际上看起来像它应该的那样 - 即没有对这些 {} 进行 urlencoded - 因为那可能是这是怎么回事。
除此之外,我相信您的方法是正确的,而 Leroy 的方法不正确 - 我认为您没有为 Stripe 提供未编码的 URL,因此它不会将 {CHECKOUT_SESSION_ID}
识别为模板字符串,因为它应该是。
我遇到了同样的问题。我只是添加:
$this->router->generate('my_confirm_route', ['myrouteparam' => $myRouteParam], UrlGeneratorInterface::ABSOLUTE_URL).'?session_id={CHECKOUT_SESSION_ID}';
在控制器中:
$request->query->get('session_id')
我正在尝试使用 stripe 处理每月订阅:
我创建了一个带有操作的支付控制器:
创建结帐会话操作:
/**
* @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);
}
})
});
});
付款正常,但我在重定向到成功后收到此错误
Invalid checkout.session id: {CHECKOUT_SESSION_ID}
如何修复此错误以及如何在我的项目中处理每月付款?
您将该确切值作为 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.
我认为您的反馈在 post 正文中,基于您在 stripe 上的配置。做这样的事情应该会给你你想要的。
首先,从 success_url
中删除会话 ID'success_url' => $this->generateUrl('success', UrlGeneratorInterface::ABSOLUTE_URL),
接下来,更改您的成功 url 逻辑以使用 post 正文。
/**
* @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(您创建的)。
Leroy 是正确的,但我建议您确认您正在生成的 success_url
实际上看起来像它应该的那样 - 即没有对这些 {} 进行 urlencoded - 因为那可能是这是怎么回事。
除此之外,我相信您的方法是正确的,而 Leroy 的方法不正确 - 我认为您没有为 Stripe 提供未编码的 URL,因此它不会将 {CHECKOUT_SESSION_ID}
识别为模板字符串,因为它应该是。
我遇到了同样的问题。我只是添加:
$this->router->generate('my_confirm_route', ['myrouteparam' => $myRouteParam], UrlGeneratorInterface::ABSOLUTE_URL).'?session_id={CHECKOUT_SESSION_ID}';
在控制器中:
$request->query->get('session_id')