Проверка Stripe API с несколькими элементами

У меня проблема с методом Checkout Session в Stripe API. Когда я жестко запрограммировал значения для цены и количества, 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",
      ]);

Может ли кто-нибудь заметить ошибку, которую я делаю? Я полагаю, что я не помещаю значения в массив соответствующим образом.

4 ответа

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

и

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

Я столкнулся с этим несколько недель назад. Служба поддержки Stripe не была заинтересована в помощи.

Обзор:

  • Создайте то, что вы хотите, с помощью кода внешнего интерфейса.
  • т.е.: массив объектов с такими ключами, как: product, quantity, так далее.
  • Передайте этот массив объектов (через JSON.stringify()) на серверную часть PHP.
  • Прокрутите его в PHP и поместите в массив.
  • Передайте этот массив в line_items ключ \Stripe\Checkout\Session::create().

Это довольно просто, но было сложно понять, потому что я не привык к 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]);

Возможно, сейчас немного поздно отвечать, но в любом случае после долгих испытаний и проб и ошибок вот что сработало для меня.

Я обнаружил, что передача списка массивов была серьезной проблемой, поэтому мне пришлось заново собрать массив, как только я получил его из ввода как json, перед передачей его в Stripe Create, который даже тогда, казалось, работал правильно только тогда, когда я использовал eval для массив при его передаче. В основном размещаю это, чтобы помочь кому-либо избежать боли, через которую я прошел :), я уверен, что есть способы сделать это лучше, но в то время я не мог найти нигде примеров, и это работает нормально уже почти год, поэтому я пока не пытался улучшить или изменить.

      <?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;    

Я не уверен, но вы пытались удалить скобки в:'line_items' => [$line_items_array],

чтобы это выглядело так?'line_items' => $line_items_array,

У меня такое ощущение, что в исходных двойных скобках 'line_items' => [[внутренняя скобка объявляет массив, а внешняя скобка служит чем-то похожим на push или [] = array (для создания нового индекса для каждого элемента строки .

Итак, если вы передаете готовый массив, у меня такое чувство, что скобок не должно быть. Но я не знаю.

Другие вопросы по тегам