Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stripe events: How to capture the product that was successfully paid with Stripe events and a webhook?

My website's users will buy credits using Stripe's single-payment workflow with a checkout session. They can buy single credits or credit packages, like 10 credits package at discount price. After a successfully payment I want to capture the event with a webhook and update the user balance according to the product and quantity paid by the user.

I'm currently tracking payment_intent.succeeded events and I can see payment and charge information however I can't find any information related to the product ordered. What am I missing? Thank you.

This is an example of the payment intent event I'm capturing:

{
  "amount": 5250,
  "amount_capturable": 0,
  "amount_received": 5250,
  "application": null,
  "application_fee_amount": null,
  "canceled_at": null,
  "cancellation_reason": null,
  "capture_method": "automatic",
  "charges": {
    "data": [
      {
        "amount": 5250,
        "amount_captured": 5250,
        "amount_refunded": 0,
        "application": null,
        "application_fee": null,
        "application_fee_amount": null,
        "balance_transaction": "txn_1HUSonCfZ37XLQD8mLERR2YR",
        "billing_details": {
          "address": {
            "city": null,
            "country": "JP",
            "line1": null,
            "line2": null,
            "postal_code": null,
            "state": null
          },
          "email": "[email protected]",
          "name": "asd",
          "phone": null
        },
        "calculated_statement_descriptor": "XXX XXXX",
        "captured": true,
        "created": 1600847712,
        "currency": "jpy",
        "customer": "cus_I4c27DIUQuvAHQ",
        "description": null,
        "destination": null,
        "dispute": null,
        "disputed": false,
        "failure_code": null,
        "failure_message": null,
        "fraud_details": {},
        "id": "ch_1HUSomCfZ37XLQD8d133buOK",
        "invoice": null,
        "livemode": false,
        "metadata": {},
        "object": "charge",
        "on_behalf_of": null,
        "order": null,
        "outcome": {
          "network_status": "approved_by_network",
          "reason": null,
          "risk_level": "normal",
          "risk_score": 39,
          "seller_message": "Payment complete.",
          "type": "authorized"
        },
        "paid": true,
        "payment_intent": "pi_1HUSoWCfZ37XLQD82vnE1yQT",
        "payment_method": "pm_1HUSolCfZ37XLQD8gSn0oy4x",
        "payment_method_details": {
          "card": {
            "brand": "visa",
            "checks": {
              "address_line1_check": null,
              "address_postal_code_check": null,
              "cvc_check": "pass"
            },
            "country": "US",
            "exp_month": 11,
            "exp_year": 2050,
            "fingerprint": "uaJa23vzDgA7fnSC",
            "funding": "credit",
            "installments": null,
            "last4": "4242",
            "network": "visa",
            "three_d_secure": null,
            "wallet": null
          },
          "type": "card"
        },
        "receipt_email": null,
        "receipt_number": null,
        "receipt_url": "https://pay.stripe.com/receipts/acct_1HU77uCfZ37XLQD8/ch_1HUSomCfZ37XLQD8d133buOK/rcpt_I4c233eGeSYOaN9cPvncC4AcU2Sm4s7",
        "refunded": false,
        "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,
    "object": "list",
    "total_count": 1,
    "url": "/v1/charges?payment_intent=pi_1HUSoWCfZ37XLQD82vnE1yQT"
  },
  "client_secret": "pi_1HUSoWCfZ37XLQD82vnE1yQT_secret_XXX",
  "confirmation_method": "automatic",
  "created": 1600847696,
  "currency": "jpy",
  "customer": "cus_I4c27DIUQuvAHQ",
  "description": null,
  "id": "pi_1HUSoWCfZ37XLQD82vnE1yQT",
  "invoice": null,
  "last_payment_error": null,
  "livemode": false,
  "metadata": {},
  "next_action": null,
  "object": "payment_intent",
  "on_behalf_of": null,
  "payment_method": "pm_1HUSolCfZ37XLQD8gSn0oy4x",
  "payment_method_options": {
    "card": {
      "installments": null,
      "network": null,
      "request_three_d_secure": "automatic"
    }
  },
  "payment_method_types": [
    "card"
  ],
  "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
}
like image 834
Veilkrand Avatar asked Oct 23 '25 09:10

Veilkrand


1 Answers

Assuming you've put the product details in the line_items of the Checkout session you created (see guide step), then what you're looking for is how to "fulfill the order" (see guide step), which you can do by listening to checkout.session.completed events.

When you receive an event, the event data will be a Checkout session by id, and you can then retrieve that session and specify expand\[\]=line_items to be able to inspect the line_items for the session.

Update: I modified the above to reflect that line_items is not included by default. You must retrieve the session and include it in an expand.

like image 121
Nolan H Avatar answered Oct 27 '25 02:10

Nolan H



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!