Score:0

Stripe doesn't see API key after TrustedRedirectResponse

nl flag

I have a controller that calls the Stripe API using stripe-php to create a checkout session.

  /**
   * Checkout using Stripe.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response.
   */
  public function checkout(Request $request): Response {
    $stripe_settings = $this->config('stripe.settings');
    Stripe::setApiKey($stripe_settings->get('apikey.' . $stripe_settings->get('environment') . '.secret'));

    // Create a Stripe checkout session.
    // https://stripe.com/docs/checkout/quickstart
    $checkout_session = Session::create([
      'line_items' => [
        [
          'price_data' => [
            'currency' => 'usd',
            'unit_amount' => 100,
            'product_data' => [
              'name' => 'Product $1',
              'description' => 'Description',
            ],
          ],
          'quantity' => 1,
        ],
      ],
      'mode' => 'payment',
      'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
      'cancel_url' => 'https://example.com/cancel',
    ]);
    $checkout_url = $checkout_session->baseUrl() . $checkout_session->instanceUrl();

    // In order to avoid errors like this:
    // - LogicException: The controller result claims to be providing relevant
    //   cache metadata, but leaked metadata was detected. Please ensure you are
    //   not rendering content too early. ... TrustedRedirectResponse.
    // Every Url::toString needs to have "->toString(TRUE)->getGeneratedUrl();".
    // See https://www.drupal.org/node/2638686
    $url = Url::fromUri($checkout_url, ['absolute' => TRUE, 'https' => TRUE])->toString(TRUE);
    $headers = [
      'Authorization' => 'Bearer ' . Stripe::getApiKey(),
    ];
    $response = new TrustedRedirectResponse($url->getGeneratedUrl(), Response::HTTP_SEE_OTHER, $headers);
    $response->addCacheableDependency((new CacheableMetadata())->setCacheMaxAge(0));

    // Redirect to Stripe checkout URL.
    return $response;
  }

So I call Stripe::setApiKey, I have my keys correctly set up (the checkout session is created), and the redirect to the external Stripe.com checkout session URL works. But it says the API key is missing from the headers.

I checked using Fiddler, and the header I added is sent correct in the controller's redirect response.

When looking at Stripe's checkout documentation, it doesn't use a controller, and it doesn't seem to need a separate header with the API key. So I'm not really sure what I'm missing. Do I have to do something different to ensure the header stays there after the redirect occurs in the browser or something?

Jaypan avatar
de flag
As far as I know, it's not possible to send headers when redirecting.
4uk4 avatar
cn flag
You could send headers and, as the OP is telling, this was successful. But it's a futile attempt because the browser won't recognize them. See https://stackoverflow.com/questions/7583461/redirect-to-page-and-send-custom-http-headers. If you want to preserve data you set them in a session before redirecting and according to the class name of the PHP library this is what the code is trying to do.
mbomb007 avatar
nl flag
So what you're saying is that, looking at the code at https://stripe.com/docs/checkout/quickstart, it should work without such a header (which isn't possible to send), because the checkout *session* is a session that has been authenticated already.
Score:0
nl flag

The problem was that I used

$checkout_url = $checkout_session->baseUrl() . $checkout_session->instanceUrl();

Because that is https://api.stripe.com/v1/checkout/sessions/cs_test_...

I needed to use

$checkout_url = $checkout_session->url;

Which is https://checkout.stripe.com/c/pay/cs_test_...

So now I just have

$response = new TrustedRedirectResponse($checkout_session->url, Response::HTTP_SEE_OTHER);
$response->addCacheableDependency((new CacheableMetadata())->setCacheMaxAge(0));

return $response;
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.