Stripe: как я могу получить данные для хранения на моей платформе

Я интегрирую Stripe для своей платформы, которая использует Next.js и Laravel.

Я не могу понять, как я могу получить данные и сохранить их в базе данных MY Platform. Например, пользователь покупает клавиатуру за 50 долларов. Как я могу получить эту информацию item_name и price в Laravel.

Ниже мой код. Спасибо.

next.js : страница предметов

<form action = "/api/checkout_sessions/buy" method = "POST">
    <button type = "submit">
        Pay $50
    </button>
</form>

Итак, если пользователь нажмет кнопку «Заплатить 50 долларов», он будет перенаправлен на страницу оформления заказа, размещенную на stript. А ниже pages/api/checkout_sessions/buy.js.

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      // Create Checkout Sessions from body params.
      const session = await stripe.checkout.sessions.create({
        payment_method_types: ["card"],
        line_items: [
          {
              // Provide the exact Price ID (for example, pr_1234) of the product you want to sell
              price: 'price_random',
              quantity: 1,
            },
          ],
        mode: 'payment',
        success_url: `${req.headers.origin}/?success=true`,
        cancel_url: `${req.headers.origin}/?canceled=true`,
      });

      res.redirect(303, session.url);
    } catch (err) {
      res.status(err.statusCode || 500).json(err.message);
    }
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

До сих пор я просто следую этим инструкциям: https://stripe.com/docs/checkout/quickstart.

После заполнения необходимой информации на странице оформления заказа, размещенной на Stript, чтобы проверить, прошел платеж успешно или нет, я написал веб-хуки в своем бэкэнде и протестировал его с помощью stripe cli. А это ниже. Опять же, я просто следую этим инструкциям. https://stripe.com/docs/payments/checkout/fulfill-orders

api.php

Route::post('webhook', function() {

    // Set your secret key. Remember to switch to your live secret key in production.
    // See your keys here: https://dashboard.stripe.com/apikeys
    \Stripe\Stripe::setApiKey('sk_test_');

    function print_log($val) {
        return file_put_contents('php://stderr', print_r($val, TRUE));
    }

    // You can find your endpoint's secret in your webhook settings
    $endpoint_secret = 'whsec_';

    $payload = @file_get_contents('php://input');
    $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
    $event = null;

    try {
        $event = \Stripe\Webhook::constructEvent($payload, $sig_header, $endpoint_secret);
    } 
    catch(\UnexpectedValueException $e) {
        // Invalid payload
        http_response_code(400);
        exit();
    } catch(\Stripe\Exception\SignatureVerificationException $e) {
        // Invalid signature
        http_response_code(400);
        exit();
    }

    function fulfill_order($session) {
        // TODO: fill me in
        print_log("Fulfilling order...");
        print_log($session);
    }

    // Handle the checkout.session.completed event
    if ($event->type == 'checkout.session.completed') {
        $session = $event->data->object;

        Log::info('session----');
        Log::info($session);

        Log::info('payload----');
        Log::info($payload);

        Log::info('event----');
        Log::info($event);

        // Fulfill the purchase...
        fulfill_order($session);
    }

    if ($event->type == 'payment_intent.succeeded') {
        Log::info('payment successful');
    }

    http_response_code(200);
});

Выполняя приведенную ниже команду в Strip cli,

stripe listen --forward-to localhost:3000/api/webhook (which will execute the above function when I clicked pay in stripe-hosted checkout page)

Я получил следующий результат в консоли stript-cli.

payment_intent.created [evt_random]
2022-05-05 21:46:35  <--  [200] POST http://localhost:3000/api/webhook [evt_random]
2022-05-05 21:46:49   --> payment_intent.created [evt_random]
2022-05-05 21:46:49  <--  [200] POST http://localhost:3000/api/webhook [evt_random]
2022-05-05 21:48:50   --> payment_intent.created [evt_random]
2022-05-05 21:48:50  <--  [200] POST http://localhost:3000/api/webhook [evt_random]
2022-05-05 21:50:55   --> payment_intent.created [evt_random]
2022-05-05 21:50:55  <--  [200] POST http://localhost:3000/api/webhook [evt_random]

Я получил следующий результат в консоли laravel.

[2022-05-05 20:38:58] local.INFO: payment successful  
[2022-05-05 20:38:59] local.INFO: session----  
[2022-05-05 20:38:59] local.INFO: Stripe\Checkout\Session JSON: {
    "id": "cs_test_random",
    "object": "checkout.session",
    "after_expiration": null,
    "allow_promotion_codes": null,
    "amount_subtotal": 50,
    "amount_total": 50,
    "automatic_tax": {
        "enabled": false,
        "status": null
    },
    "billing_address_collection": null,
    "cancel_url": "http://...?canceled=true",
    "client_reference_id": null,
    "consent": null,
    "consent_collection": null,
    "currency": "usd",
    "customer": "cus_",
    "customer_creation": "always",
    "customer_details": {
        "address": {
            "city": null,
            "country": "MM",
            "line1": null,
            "line2": null,
            "postal_code": null,
            "state": null
        },
        "email": "[email protected]",
        "name": "er",
        "phone": null,
        "tax_exempt": "none",
        "tax_ids": []
    },
    "customer_email": null,
    "expires_at": 1651836625,
    "livemode": false,
    "locale": null,
    "metadata": [],
    "mode": "payment",
    "payment_intent": "pi_random",
    "payment_link": null,
    "payment_method_options": [],
    "payment_method_types": [
        "card"
    ],
    "payment_status": "paid",
    "phone_number_collection": {
        "enabled": false
    },
    "recovered_from": null,
    "setup_intent": null,
    "shipping": null,
    "shipping_address_collection": null,
    "shipping_options": [],
    "shipping_rate": null,
    "status": "complete",
    "submit_type": null,
    "subscription": null,
    "success_url": "http:...?success=true",
    "total_details": {
        "amount_discount": 0,
        "amount_shipping": 0,
        "amount_tax": 0
    },
    "url": null
}  
[2022-05-05 20:38:59] local.INFO: payload----  
[2022-05-05 20:38:59] local.INFO: {
  "id": "evt_random",
  "object": "event",
  "api_version": "2018-02-06",
  "created": 1651754338,
  "data": {
    "object": {
      "id": "cs_test_random",
      "object": "checkout.session",
      "after_expiration": null,
      "allow_promotion_codes": null,
      "amount_subtotal": 50,
      "amount_total": 50,
      "automatic_tax": {
        "enabled": false,
        "status": null
      },
      "billing_address_collection": null,
      "cancel_url": "http:...?canceled=true",
      "client_reference_id": null,
      "consent": null,
      "consent_collection": null,
      "currency": "usd",
      "customer": "cus_random",
      "customer_creation": "always",
      "customer_details": {
        "address": {
          "city": null,
          "country": "US",
          "line1": null,
          "line2": null,
          "postal_code": null,
          "state": null
        },
        "email": "[email protected]",
        "name": "er",
        "phone": null,
        "tax_exempt": "none",
        "tax_ids": [

        ]
      },
      "customer_email": null,
      "expires_at": 1651836625,
      "livemode": false,
      "locale": null,
      "metadata": {
      },
      "mode": "payment",
      "payment_intent": "pi_random",
      "payment_link": null,
      "payment_method_options": {
      },
      "payment_method_types": [
        "card"
      ],
      "payment_status": "paid",
      "phone_number_collection": {
        "enabled": false
      },
      "recovered_from": null,
      "setup_intent": null,
      "shipping": null,
      "shipping_address_collection": null,
      "shipping_options": [

      ],
      "shipping_rate": null,
      "status": "complete",
      "submit_type": null,
      "subscription": null,
      "success_url": "http:...?success=true",
      "total_details": {
        "amount_discount": 0,
        "amount_shipping": 0,
        "amount_tax": 0
      },
      "url": null
    }
  },
  "livemode": false,
  "pending_webhooks": 2,
  "request": {
    "id": null,
    "idempotency_key": null
  },
  "type": "checkout.session.completed"
}  
[2022-05-05 23:13:09] local.INFO: event----  
[2022-05-05 23:13:09] local.INFO: Stripe\Event JSON: {
    "id": "evt_random",
    "object": "event",
    "api_version": "2018-02-06",
    "created": 1651763589,
    "data": {
        "object": {
            "id": "cs_test_random",
            "object": "checkout.session",
            "after_expiration": null,
            "allow_promotion_codes": null,
            "amount_subtotal": 50,
            "amount_total": 50,
            "automatic_tax": {
                "enabled": false,
                "status": null
            },
            "billing_address_collection": null,
            "cancel_url": "http:...?canceled=true",
            "client_reference_id": null,
            "consent": null,
            "consent_collection": null,
            "currency": "usd",
            "customer": "cus_random",
            "customer_creation": "always",
            "customer_details": {
                "address": {
                    "city": null,
                    "country": "NL",
                    "line1": null,
                    "line2": null,
                    "postal_code": null,
                    "state": null
                },
                "email": "[email protected]",
                "name": "sample",
                "phone": null,
                "tax_exempt": "none",
                "tax_ids": []
            },
            "customer_email": null,
            "expires_at": 1651849960,
            "livemode": false,
            "locale": null,
            "metadata": [],
            "mode": "payment",
            "payment_intent": "pi_random",
            "payment_link": null,
            "payment_method_options": [],
            "payment_method_types": [
                "card"
            ],
            "payment_status": "paid",
            "phone_number_collection": {
                "enabled": false
            },
            "recovered_from": null,
            "setup_intent": null,
            "shipping": null,
            "shipping_address_collection": null,
            "shipping_options": [],
            "shipping_rate": null,
            "status": "complete",
            "submit_type": null,
            "subscription": null,
            "success_url": "http:...?success=true",
            "total_details": {
                "amount_discount": 0,
                "amount_shipping": 0,
                "amount_tax": 0
            },
            "url": null
        }
    },
    "livemode": false,
    "pending_webhooks": 2,
    "request": {
        "id": null,
        "idempotency_key": null
    },
    "type": "checkout.session.completed"
}  

Вопрос:

Платеж прошел успешно! Но как я могу сохранить эти keyboard и 50 в моей базе данных и где написать этот код, чтобы я знал, что пользователь купил этот товар по этой цене.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
49
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В коде обработчика события (либо checkout.session.completed, либо payment_intent.succeeded) вы можете получить нужные поля из объекта события и сохранить их в переменных. Затем вы можете использовать свою библиотеку базы данных Laravel и вставить эти данные в свою базу данных в блоке кода обработчика событий.

Я добавил объект event из вебхука в вопрос.

Ms. Siri 06.05.2022 06:21
Ответ принят как подходящий

Till now, I'm just following these instructions: https://stripe.com/docs/checkout/quickstart.

Если да, то в методе stripe.checkout.sessions.create следует

// Provide the exact Price ID (for example, pr_1234) of the product you want to sell

как предполагает пример для вашей среды (вместе с документом Как использовать продукт и цены при создании сеанса оформления заказа). Это ключ к ответу на ваш вопрос:

how can I get those keyboard and 50

Итак, что вы должны сделать, чтобы получить идентификатор цены? Обычный способ — отправить lookup_key из вашей формы. На стороне сервера вы можете искать цену, используя этот ключ:

$priceSearchResult = \Stripe\Price::search([
  "query" => "lookup_key:'" . $priceLookupKey . "'"
]);

и создайте сеанс оформления заказа с правильным идентификатором цены:

"line_items" => [
  [
    "price"    => $priceSearchResult->data[0]->id,
    "quantity" => 1,
  ]
]

Спасибо. Я последовал вашим инструкциям и создал цену на панели инструментов Stripe, взял идентификатор цены и жестко закодировал его в next.js. Теперь это нормально. Но что такое $priceLookupKey в вашем первом блоке кода. Кстати, я добавил объект event из вебхука в вопрос.

Ms. Siri 06.05.2022 06:11

Я добавил lookup_key: 'keyboard' после line_items (не в line_items), но получил Received unknown parameter: lookup_key.

Ms. Siri 06.05.2022 06:17

Отправьте ключ поиска от клиента вместо жестко заданного идентификатора цены. На стороне сервера присвойте его значение (например, $_POST["key"]) $priceLookupKey. Однако нет возможности добавить lookup_key на панель инструментов Stripe. Используйте Stripe CLI или другой API-способ для обновления ценового объекта.

seeker 06.05.2022 12:34

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