如何通过 Stripe 中的 Webhooks 从 payment_intent.succeeded 事件中获取产品和数量信息?

How to get Product and Quantity information from payment_intent.succeeded event via Webhooks in Stripe?

这是我在 Node.js 中初始化结帐流程的方式。

 let email = req.body.email
 let product_id = req.body.product_id
 let YOUR_DOMAIN = 'http://localhost:8000'

 const session = await stripe.checkout.sessions.create({

                line_items: [{
                    price: product_id,
                    adjustable_quantity: {
                      enabled: true,
                      minimum: 1,
                      maximum: 5,
                    },
                    quantity: 1,
                }],
                customer_email: email, 
                mode: 'payment',
                success_url: `${YOUR_DOMAIN}/payment-success`,
                cancel_url: `${YOUR_DOMAIN}/payment-failure`,
              });

这是我在 Webhooks 中订阅的事件

payment_intent.succeeded

checkout.session.completed

成功收到付款意向中的对象

{
    "id": "evt_1KEqIxI5cib7rtVMoKMkak96",
    "object": "event",
    "api_version": "2020-03-02",
    "created": 1641453754,
    "data": {
        "object": {
            "id": "pi_1KEqIeI5cib7rtVMcz8zsXys",
            "object": "payment_intent",
            "amount": 59700,
            "amount_capturable": 0,
            "amount_received": 59700,
            "application": null,
            "application_fee_amount": null,
            "automatic_payment_methods": null,
            "canceled_at": null,
            "cancellation_reason": null,
            "capture_method": "automatic",
            "charges": {
                "object": "list",
                "data": [{
                    "id": "ch_1KEqIvI5cib7rtVMYUVn5gfQ",
                    "object": "charge",
                    "amount": 59700,
                    "amount_captured": 59700,
                    "amount_refunded": 0,
                    "application": null,
                    "application_fee": null,
                    "application_fee_amount": null,
                    "balance_transaction": "txn_1KEqIwI5cib7rtVMGfJlEahg",
                    "billing_details": {
                        "address": {
                            "city": "NY",
                            "country": "US",
                            "line1": "sada",
                            "line2": "asd",
                            "postal_code": "10001",
                            "state": "NY"
                        },
                        "email": "test@gmail.com",
                        "name": "John Doe",
                        "phone": null
                    },
                    "calculated_statement_descriptor": "VIDEOFORM",
                    "captured": true,
                    "created": 1641453753,
                    "currency": "usd",
                    "customer": "cus_KufeYc1hifvZGA",
                    "description": null,
                    "destination": null,
                    "dispute": null,
                    "disputed": false,
                    "failure_code": null,
                    "failure_message": null,
                    "fraud_details": {},
                    "invoice": null,
                    "livemode": false,
                    "metadata": {},
                    "on_behalf_of": null,
                    "order": null,
                    "outcome": {
                        "network_status": "approved_by_network",
                        "reason": null,
                        "risk_level": "normal",
                        "risk_score": 25,
                        "seller_message": "Payment complete.",
                        "type": "authorized"
                    },
                    "paid": true,
                    "payment_intent": "pi_1KEqIeI5cib7rtVMcz8zsXys",
                    "payment_method": "pm_1KEqIuI5cib7rtVMYPWlLV8S",
                    "payment_method_details": {
                        "card": {
                            "brand": "visa",
                            "checks": {
                                "address_line1_check": "pass",
                                "address_postal_code_check": "pass",
                                "cvc_check": "pass"
                            },
                            "country": "US",
                            "exp_month": 1,
                            "exp_year": 2023,
                            "fingerprint": "QaiTi5PATFO8ZoC3",
                            "funding": "credit",
                            "installments": null,
                            "last4": "4242",
                            "mandate": null,
                            "network": "visa",
                            "three_d_secure": null,
                            "wallet": null
                        },
                        "type": "card"
                    },
                    "receipt_email": null,
                    "receipt_number": null,
                    "receipt_url": "https://pay.stripe.com/receipts/acct_1GhUSuI5cib7rtVM/ch_1KEqIvI5cib7rtVMYUVn5gfQ/rcpt_KufeysPW3LD8Yu47q14iYOIIlcGth9h",
                    "refunded": false,
                    "refunds": {
                        "object": "list",
                        "data": [],
                        "has_more": false,
                        "total_count": 0,
                        "url": "/v1/charges/ch_1KEqIvI5cib7rtVMYUVn5gfQ/refunds"
                    },
                    "review": null,
                    "shipping": null,
                    "source": null,
                    "source_transfer": null,
                    "statement_descriptor": null,
                    "statement_descriptor_suffix": null,
                    "status": "succeeded",
                    "transfer_data": null,
                    "transfer_group": null
                }],
                "has_more": false,
                "total_count": 1,
                "url": "/v1/charges?payment_intent=pi_1KEqIeI5cib7rtVMcz8zsXys"
            },
            "client_secret": "pi_1KEqIeI5cib7rtVMcz8zsXys_secret_uZwm3uziwfaWePgTHENYXeraD",
            "confirmation_method": "automatic",
            "created": 1641453736,
            "currency": "usd",
            "customer": "cus_KufeYc1hifvZGA",
            "description": null,
            "invoice": null,
            "last_payment_error": null,
            "livemode": false,
            "metadata": {},
            "next_action": null,
            "on_behalf_of": null,
            "payment_method": "pm_1KEqIuI5cib7rtVMYPWlLV8S",
            "payment_method_options": {
                "card": {
                    "installments": null,
                    "mandate_options": null,
                    "network": null,
                    "request_three_d_secure": "automatic"
                }
            },
            "payment_method_types": ["card"],
            "processing": null,
            "receipt_email": null,
            "review": null,
            "setup_future_usage": null,
            "shipping": null,
            "source": null,
            "statement_descriptor": null,
            "statement_descriptor_suffix": null,
            "status": "succeeded",
            "transfer_data": null,
            "transfer_group": null
        }
    },
    "livemode": false,
    "pending_webhooks": 3,
    "request": {
        "id": "req_Y87umQuitz9WCc",
        "idempotency_key": "a4b6af76-73d8-49b4-8393-9017e673af7e"
    },
    "type": "payment_intent.succeeded"
}

结帐会话中收到的对象已完成

 {
        "id": "evt_1KEqQOI5cib7rtVMRwAHWDvV",
        "object": "event",
        "api_version": "2020-03-02",
        "created": 1641454214,
        "data": {
            "object": {
                "id": "cs_test_a1AQ9EKIaxi8dXFAJzZ86xYm5meRkWb9Vu0eLowfkiKgUO4cyToooBzSTd",
                "object": "checkout.session",
                "after_expiration": null,
                "allow_promotion_codes": null,
                "amount_subtotal": 59700,
                "amount_total": 59700,
                "automatic_tax": {
                    "enabled": false,
                    "status": null
                },
                "billing_address_collection": null,
                "cancel_url": "http://localhost:8000/payment-failure",
                "client_reference_id": null,
                "consent": null,
                "consent_collection": null,
                "currency": "usd",
                "customer": "cus_Kuflo6N0n4HTzL",
                "customer_details": {
                    "email": "test@gmail.com",
                    "phone": null,
                    "tax_exempt": "none",
                    "tax_ids": []
                },
                "customer_email": "test@gmail.com",
                "expires_at": 1641540596,
                "livemode": false,
                "locale": null,
                "mode": "payment",
                "payment_intent": "pi_1KEqQ4I5cib7rtVMyND6NhQG",
                "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://localhost:8000/payment-success",
                "total_details": {
                    "amount_discount": 0,
                    "amount_shipping": 0,
                    "amount_tax": 0
                },
                "url": null
            }
        },
        "livemode": false,
        "pending_webhooks": 4,
        "request": {
            "id": null,
            "idempotency_key": null
        },
        "type": "checkout.session.completed"
    }

我不知道如何获取产品 ID 和数量。有人可以在这里提出正确的方法吗?

您可以使用 expand on the line_items 属性 从结帐会话中查找产品和数量。代码应如下所示。

// In "checkout.session.completed" event handler, get the ID of the Checkout Session
const id = event.data.object.id; // "cs_xxx"

// Retrieve the Checkout Session with expand
const session = await stripe.checkout.sessions.retrieve(id, {
   expand: [ "line_items" ]
});

// Get the quantity
console.log(session.line_items[0].quantity);

// Get the product ID
console.log(session.line_items[0].price.product);