# 扩展响应 通过扩展响应中的对象,减少向 Stripe API 发出请求的数量。 本指南介绍了如何从 API 请求额外属性。您将学习如何修改请求,以包含以下内容: - 来自相关对象的请求 - 来自远处相关对象的请求 - 列表中所有对象的额外属性 - 响应中默认未包含的属性 ## 运作机制 Stripe API 以代表对象的资源来组织,具有状态、配置及上下文属性。这些对象都有唯一 ID,可用于检索、更新和删除对象。API 还用这些 ID 把对象关联在一起。例如 [Checkout Session](https://docs.stripe.com/api/checkout/sessions/object.md),可通过 [Customer ID](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer) 关联到 [Customer](https://docs.stripe.com/api/customers/object.md)。 ```json { "id": "cs_test_KdjLtDPfAjT1gq374DMZ3rHmZ9OoSlGRhyz8yTypH76KpN4JXkQpD2G0", "object": "checkout.session", ..."customer": "cus_HQmikpKnGHkNwW", ... } ``` 在需要某个关联对象的信息时,可以用它的 ID 在一个新调用中检索关联的对象。但是,使用这种方法时,用两个 API 请求只能访问一个值。如果需要多个关联对象的信息,则每个对象还都要求独立的请求,从而会增加您的应用程序的延迟和复杂性。 API 有一个 Expand 功能,可通过该功能用一次调用检索关联的对象,可将对象 ID 有效替换为它的属性和值。例如,加入您想访问特定 Checkout Session 所涉及的客户的详情。则便可以检索 Checkout Session,并向 `expand` 数组传递 `customer` 属性,从而告诉 Stripe 将整个 Customer 对象包含到响应中: ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=customer" ``` 它返回的 Checkout Session 中就会包含完整的 Customer 对象,而不是它的 ID: ```json { "id": "cs_test_KdjLtDPfAjT1gq374DMZ3rHmZ9OoSlGRhyz8yTypH76KpN4JXkQpD2G0", "object": "checkout.session", ..."customer": { "id": "cus_HQmikpKnGHkNwW", "object": "customer", ... "metadata": { "user_id": "user_xyz" }, ... } } ``` > 并非所有属性都可扩展。API 参考中通过“可扩展”标签对可扩展的属性进行了标记。 ## 扩展多个属性 在一次调用中扩展多个属性时,向扩展数组添加额外项目。例如,如果您想扩展某个特定 Checkout Session 的 [customer](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer) 和 [payment_intent](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-payment_intent),则向 `expand` 中传递的数组应包含 `customer` 和 `payment_intent` 这两个字串: ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=customer" \ -d "expand[]=payment_intent" ``` ## 扩展多个级别 如果您想要的值嵌套在多个关联的资源中,则可以利用圆点记法递归方式来找到它。例如,如果您需要知道特定 Checkout Session 中使用的支付方式的类型,则需要先检索 Checkout Session 的 Payment Intent,然后再通过检索 Payment Intent 的关联支付方式来获取它的类型。通过 `expand`,您在一个调用中就可以实现: ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=payment_intent.payment_method" ``` 它返回的 Checkout Session 中就会包含完整的 [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) 和 [PaymentMethod](https://docs.stripe.com/api/payment_methods/object.md) 对象,而不是它们的 ID: ```json { "id": "cs_test_KdjLtDPfAjT1gq374DMZ3rHmZ9OoSlGRhyz8yTypH76KpN4JXkQpD2G0", "object": "checkout.session", ... "mode": "payment","payment_intent": { "id": "pi_1GkXXDLHughnNhxyLlsnvUuY", "object": "payment_intent", "amount": 100, ... "charges": {...}, "client_secret": "pi_1GkXXDLHughnNhxyLlsnvUuY_secret_oLbwpm0ME0ieJ9Aykz2SwKzj5", ... "payment_method": { "id": "pm_1GkXXuLHughnNhxy8xpAdGtf", "object": "payment_method", "billing_details": {...}, "card": {...}, "created": 1589902798, "customer": "cus_HQmikpKnGHkNwW", "livemode": false, "metadata": {}, "type": "card" }, "payment_method_options": {...}, "payment_method_types": [ "card" ], "receipt_email": "jenny.rosen@gmail.com", "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 }, "payment_method_types": [ "card" ], "setup_intent": null, "shipping": null, "shipping_address_collection": null, "submit_type": null, "subscription": null, "success_url": "http://localhost:5000" } ``` > 扩展的最大深度为四个级别。即,一个 `expand` 字串所能包含的属性不能超过四个:`property1.property2.property3.property4`。 ## 扩展列表中的属性 API 返回一个对象列表时,您可以用 `data` 关键词来扩展该列表中每个对象的特定属性。例如,假设您需要您的某个客户所用支付方式的信息。要获取该信息,您需要[列出客户的 PaymentIntents](https://docs.stripe.com/api/payment_intents/list.md#list_payment_intents-customer),返回一个具有以下结构的对象: ```json { "object": "list","data": [ { "id": "pi_1GrvBKLHughnNhxy6N28q8gt", "object": "payment_intent", "amount": 1000, ..."payment_method": "pm_1GrvBxLHughnNhxyJjtBtHcc", ... }, { "id": "pi_1Grv8tLHughnNhxyflPG4bMG", "object": "payment_intent", "amount": 4000, ..."payment_method": "pm_1Grv9zLHughnNhxyv6uMNomv", ... } ], "has_more": false, "url": "/v1/payment_intents" } ``` > API 中返回的所有列表都具有上述结构,其中 `data` 属性包含所列对象的数组。您可以在扩展字串内的任意位置使用 `data` 关键词,将扩展光标移动到列表。 不需要在列表中的每个 Payment Intent 间循环并在单独的调用中检索关联的支付方式,年您可以用 `data` 关键词一次性扩展所有支付方式。 ```curl curl -G https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "expand[]=data.payment_method" ``` 然后列表会包含每个 Payment Intent 上的完整支付方式对象: ```json { "object": "list", "data": [ { "id": "pi_1GrvBKLHughnNhxy6N28q8gt", "object": "payment_intent", "amount": 1000, ..."payment_method": { "id": "pm_1GrvBxLHughnNhxyJjtBtHcc", "object": "payment_method", "billing_details": {...}, "card": { "brand": "visa", ... "country": "US", "exp_month": 2, "exp_year": 2022, "fingerprint": "1212u2LvSFqEHu3h", "funding": "credit", "last4": "4242", ... }, "created": 1591661989, "customer": "cus_HQmikpKnGHkNwW", "livemode": false, "metadata": {...}, "type": "card" }, ... }, { "id": "pi_1Grv8tLHughnNhxyflPG4bMG", "object": "payment_intent", "amount": 4000, ..."payment_method": { "id": "pm_1Grv9zLHughnNhxyv6uMNomv", "object": "payment_method", "billing_details": {...}, "card": { "brand": "visa", "checks": {...}, "country": "US", "exp_month": 2, "exp_year": 2025, "fingerprint": "1212u2LvSFqEHu3h", "funding": "credit", "generated_from": null, "last4": "0341", "three_d_secure_usage": {...}, "wallet": null }, "created": 1591661989, "customer": "cus_HQmikpKnGHkNwW", "livemode": false, "metadata": {...}, "type": "card" }, ... } ], "has_more": false, "url": "/v1/payment_intents" } ``` > 扩展响应对性能有影响。要保持请求快速响应,尽可能多地限制列表请求中嵌套的扩展。 ## 用扩展请求未包含的属性 某些情况下,资源中会包含默认不能包含的属性。其中就有 Checkout Session 的 [line_items](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-line_items) 属性,只有用 `expand` 参数请求时才会包含在响应中,例如: ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=line_items" ``` > 与其他可扩展属性一样,API 参考会用“可扩展”标签标记可包含的属性。 ## 通过 Webhook 使用扩展 您不能接收包含自动扩展属性的 *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) 事件。事件中发送的对象始终会以其最小形式出现。要访问可扩展属性中的嵌套值,必须在您的 Webhook 处理程序中单独调用该对象。