【问题标题】:Stripe API Checkout WIth Multiple Items带多个项目的 Stripe API 结帐
【发布时间】:2020-10-26 09:43:57
【问题描述】:

我在 Stripe API 中遇到了 Checkout Session 方法的问题。当我硬编码价格和数量的值时,Stripe 将允许我在结帐时使用多个项目,但是当我尝试动态加载这些值时,它只会列出购物车中的第一个产品。以下是硬编码值的示例:

          $product = \Stripe\Product::create([
            'name' => "{$row['product_title']}",
            'images' => [
              "https://moto-d.net/wp-content/uploads/2018/01/webshop.jpg"
              ]
          ]);
          
          $price_100 = $row['product_price'] * 100;

          $price = \Stripe\Price::create([
            'product' => "{$product['id']}",
            'unit_amount' => "{$price_100}",
            'currency' => 'eur'
          ]);
  
      $session = \Stripe\Checkout\Session::create([
        'payment_method_types' => ['card'],
        'line_items' => [[
          'price' => 'price_1H1qQRAvwpgnxaFsFErrYUQs',
          'quantity' => 1
        ], [
          'price' => 'price_1H1qQSAvwpgnxaFsXR3XO8Sg',
          'quantity' => 1
        ], [
          'price' => 'price_1H1qQTAvwpgnxaFsfAAn8FMI',
          'quantity' => 1
        ], [
          'price' => 'price_1H1qQUAvwpgnxaFsX9KRfDPE',
          'quantity' => 1
        ]],
        'mode' => 'payment',
        'success_url' => "http://localhost/e-com-master/public/thank_you.php",
        'cancel_url' => "http://localhost/e-com-master/public/index.php",
     ]);
    }
   }
  }
      return $session['id'];

使用此代码,它可以完美运行。但是,问题就在这里(我使用数组来存储这些值):

         $line_items_array = array(
           "price" => $price['id'],
           "quantity" => $value
          );

      $session = \Stripe\Checkout\Session::create([
        'payment_method_types' => ['card'],
        'line_items' => [$line_items_array],
        'mode' => 'payment',
        'success_url' => "http://localhost/e-com-master/public/thank_you.php",
        'cancel_url' => "http://localhost/e-com-master/public/index.php",
      ]);

有人能注意到我犯的错误吗?我想我没有以适当的方式在数组中推送值。

【问题讨论】:

    标签: php checkout stripe-payments


    【解决方案1】:
         $line_items_array = array(
           'price' => "{$price['id']}",
           'quantity' => "{$value}"
          ); 
    

    'line_items' => [[$line_items_array]],
    

    【讨论】:

      【解决方案2】:

      几周前我刚刚遇到了这个问题。 Stripe 支持没有兴趣提供帮助。

      概述:

      • 通过前端代码构造您想要的line_items
      • 即:对象数组,其键如下:productquantity 等。
      • 将该对象数组(通过JSON.stringify())传递给后端PHP。
      • 在 PHP 中循环遍历它并将其推送到一个数组中。
      • \Stripe\Checkout\Session::create()line_items 键中传递该数组。

      这很简单,但是因为我不习惯 PHP,所以很难正确。

      作为 PHP 新手,这些对我很有帮助:

      我为您的create-checkout-session.php 文件包含所有内容。不仅仅是foreach()

      <?php
      
      
      /* Standard Stripe API stuff */
      require 'vendor/autoload.php';
      \Stripe\Stripe::setApiKey("STRIPE_LIVE_SECRET_KEY_HERE");
      header('Content-Type: application/json');
      $YOUR_DOMAIN = 'http://localhost:4242';
      
      
      /* Read in the JSON sent via the frontend */
      $json_str = file_get_contents('php://input');
      
      
      /*
       * Convert to PHP object
       * - NOT setting `json_decode($json_str, TRUE)` because having the data decoded into an *object* seems to work well. Also, Stripe's own sample code, for custom flows, does not set to `TRUE`.
       * - https://www.php.net/manual/en/function.json-decode.php
       */
      $data = json_decode($json_str);
      
      
      /* Create array to accept multiple `line_item` objects */
      $lineItemsArray = [];
      
      
      /*
       * [OPTIONAL] Create array to combine multiple keys from each`line_item` into a single one for `payment_intent_data.description`
       * - Only required if you want to pass along this type of description that's either provided by the user or by your frontend logic.
       * - IOW: It was useful to me, but it might not be to you.
       */
      $descriptionInternal = [];
      
      
      /* Convert the incoming JSON key/values into a PHP array() that the Stripe API will accept below in `\Stripe\Checkout\Session::create()` */
      foreach($data as $key => $value) {
      
        /*
         * Swap frontend `price` for backend Stripe `price id`
         * - If you have Products/Prices that you created in the Stripe Dashboard, you might want to keep those Ids secret (although I don't know if that matters).
         * - So you'll need to convert whatever you define them as on the frontend (public), to the Stripe PriceId equivalents (private).
         * - This switch statement does that.
         */
        switch ($value->price) {
          case 50:
            $value->price = "price_1Iaxxxxxxx";
            break;
          case 100:
            $value->price = "price_1Ibxxxxxxx";
            break;
          case 150:
            $value->price = "price_1Icxxxxxxx";
            break;
          default:
            $value->price = "price_1Iaxxxxxxx";
        }
      
      
        /* `array_push` this object shape, for each `line_item` entry, into the array created outside of this `foreach()` loop. */
        array_push($lineItemsArray, 
          [
            "price" => $value->price, 
            "quantity" => $value->quantity,
            "customerName" => $value->customer_name,
            "recipientName" => $value->recipient_name,
            "description" => $value->description /* Customer facing on the Stripe "Pay" page */
            /*
             * Add whatever else you want to include, with each `line_item`, here.
             * - Stripe API allows:
             * - https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-line_items
            */
          ]);
      
      
        /*
         * [OPTIONAL] `array_push` some or all of the `line_item` key values in a combined form.
         * - Handy (in some cases) if you want to see a quick readout of the entire purchase in your Stripe Dashboard "Purchases" listing (i.e.: Saves you from having click into it to see the details).
         * - Or you could construct this via your frontend code and pass it as a string.
         * - But I'm including this here, in case you want to do it, or something like it, in in PHP.
         * - Example final result: "[Axl: 3 Guns N' Roses for Duff] [Slash: 6 Guns N' Roses for Izzy]"
         */
        array_push(
          $descriptionInternal, 
          ("[" . $value->customerName . ": " . $value->quantity . " Guns N' Roses for " . $value->recipientName) . "]");
      
      }
      
      
      /* [OPTIONAL] `payment_intent_data.description` takes a string, not an array. */
      $descriptionInternal = implode(" ", $descriptionInternal);
      
      
      /* https://stripe.com/docs/api/checkout/sessions/create */
      $checkout_session = \Stripe\Checkout\Session::create([
        'payment_method_types' => ['card'],
      
        /* Takes in the array from above */
        'line_items' => $lineItemsArray,
      
        /* [OPTIONAL] Single `payment_intent_data.description` */
        'payment_intent_data' => [
          'description' => $descriptionInternal, /* This version of "Description" is displayed in the Dashboard and on Customer email receipts. */
      
        ],
      
        'mode' => 'payment',
      
        'success_url' => $YOUR_DOMAIN . '/success.html',
        'cancel_url' => $YOUR_DOMAIN . '/cancel.html',
      ]);
      
      echo json_encode(['id' => $checkout_session->id]);
      

      【讨论】:

        【解决方案3】:

        现在回复可能有点晚了,但无论如何经过大量测试和反复试验,这对我有用。

        我发现传递数组列表是一件很痛苦的事情,所以一旦我从输入作为 json 接收到数组后,我必须重新组装数组,然后再将其传递给 Stripe Create,即便如此,它似乎只有在我使用时才能正常工作传递数组时对数组进行评估。主要是为了帮助任何人避免我所经历的痛苦:),我相信有更好的方法可以做到这一点,但我当时在任何地方都找不到任何例子,而且这已经运行了将近一年,所以我还没有改进或修改。

        <?php
        
        header("Content-Type: application/json");
        
        require_once('stripe/vendor/autoload.php');
        
        // Set your secret key. Remember to switch to your live secret key in production!
        // See your keys here: https://dashboard.stripe.com/account/apikeys
        \Stripe\Stripe::setApiKey('whateveryouroneis');
        
        // grab the json data from the cart, sent via php input
        $data = (array) json_decode(file_get_contents("php://input"), TRUE);
        
        //get the current webpage URL
        $returnToPage = $_COOKIE["whateveryoursis"];
        
        /**
        * recursive read though what we recieved, try to get it to pass by rebuilding it
        */
        function displayArrayRecursively($arr) {
        if ($arr) {
            foreach ($arr as $key => $value) {
                if (is_array($value)) {
        
                  $arrs .= displayArrayRecursively($value);
        
                 } else {
                    //  Output
                     if ( $key == 'name' ) {
                        $arrs .= " [ \"$key\" => '$value', \n";
                        }
                     elseif ( $key == 'quantity' ) {
                        $arrs .= " \"$key\" => $value , ], \n";
                        }
                     elseif ( in_array($key, ['description','currency'], true )) {
                        $arrs .= " \"$key\" => '$value', \n";
                        }
                     elseif ( $key == 'amount' ) {
                        $arrs .= " \"$key\" => " . $value * 100 . ", \n";
                        }
                     else {
                        $arrs .= " \"$key\" => ['$value'], \n";
                         }
                     }
                }
           }
        
        return $arrs;
          }
        
        $line_items_str = displayArrayRecursively($data);
        
        $createSession_str = (
              "'payment_method_types' => ['card']," .
              "'success_url' => '" . $returnToPage . "?success=1'," .
              "'cancel_url' => '" . $returnToPage . "'," .
              "'shipping_address_collection' => [" .
              "'allowed_countries' => ['GB'], ]," .
              "'line_items' => [" . $line_items_str . " ], ");
        
        // create the checkout session on Stripe
        eval ( $session = "\$session = \Stripe\Checkout\Session::create( [ " . 
        $createSession_str . " ] );" );
        
        $stripeSession = array($session);
        // test while working on it :-
        // var_dump($stripeSession);
        $sessId = ($stripeSession[0]['id']);
        
        echo $sessId;    
        

        【讨论】:

          【解决方案4】:

          已编辑:我使用 Stripe PHP 库及其示例代码进行了一些测试。我认为您的错误是您将括号留在:

          'line_items' => [$line_items_array],
          

          它应该看起来像这样。

          'line_items' => $line_items_array,
          

          line_items 参数的现成数组应该是数字索引,带有嵌套的多维关联数组。

          //Here is a functional example that returns a successful checkout session:
          <pre>
          <?php
          
          $currency = 'eur';
          
          $products = array (
              array (
                  'unit_amount' => 1000,
                  'name' => 'product 1',
                  'images' => 'https://i.imgur.com/EHyR2nP.png',
                  'quantity' => '1'
              ),
              array (
                  'unit_amount' => 2000,
                  'name' => 'product 2',
                  'images' => 'https://i.imgur.com/EHyR2nP.png',
                  'quantity' => '2'
              ),
          );
          
          foreach ($products as $product) {
              $line_items_array[] = array(
                  'price_data' => array(
                      'currency' => $currency,
                      'unit_amount' => $product['unit_amount'],
                      'product_data' => array(
                          'name' => $product['name'],
                          'images' => array($product['images']),
                      ),
                  ),
                  'quantity' => $product['quantity'],
              );
          }
          print_r ($line_items_array);
          ?>
          </pre>
          
          
          //the output
          Array
          (
              [0] => Array
                  (
                      [price_data] => Array
                          (
                              [currency] => eur
                              [unit_amount] => 1000
                              [product_data] => Array
                                  (
                                      [name] => product 1
                                      [images] => Array
                                          (
                                              [0] => https://i.imgur.com/EHyR2nP.png
                                          )
                                  )
                          )
                      [quantity] => 1
                  )
          
              [1] => Array
                  (
                      [price_data] => Array
                          (
                              [currency] => eur
                              [unit_amount] => 2000
                              [product_data] => Array
                                  (
                                      [name] => product 2
                                      [images] => Array
                                          (
                                              [0] => https://i.imgur.com/EHyR2nP.png
                                          )
                                  )
                          )
                      [quantity] => 2
                  )
          )
          

          【讨论】:

            猜你喜欢
            • 2021-12-02
            • 2014-11-26
            • 2022-01-01
            • 2015-01-28
            • 1970-01-01
            • 2014-06-20
            • 1970-01-01
            • 2015-10-24
            • 1970-01-01
            相关资源
            最近更新 更多