Stripe:如何获取数据以存储在我的平台中

Stripe : How can I get data to store in my platform

我正在为我的平台集成 Stripe,该平台使用 Next.js 和 Laravel。

我不知道如何获取数据并将其存储在 MY Platform 数据库中。 例如,用户购买了 50 美元的键盘。如何在 Laravel.

中获取 item_nameprice 信息

下面是我的代码。谢谢。

next.js : 项目页面

<form action="/api/checkout_sessions/buy" method="POST">
    <button type="submit">
        Pay 
    </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": "sample@gm.com",
        "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": "sample@gm.com",
        "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": "sample@gm.com",
                "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"
}  

问题:

支付成功!但是,我怎样才能将这些 keyboard50 保存到我的数据库中以及在哪里编写这些代码,以便我知道用户已经以该价格购买了该商品。

在事件的处理程序代码中(checkout.session.completed 或 payment_intent.succeeded),您可以从事件对象中获取所需的字段并将它们存储到变量中。然后,您可以使用 Laravel 数据库库并将该数据插入到事件处理程序代码块内的数据库中。

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 to use product and prices when creating Checkout Session)。这是回答你问题的关键:

how can I get those keyboard and 50

那么,您应该如何获取价格 ID?常见的方法是从您的表单中提交 lookup_key。在服务器端,您可以使用此键搜索价格:

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

并使用正确的价格 ID 创建结帐会话:

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