# レスポンスの拡張 レスポンスでオブジェクトを拡張して、Stripe API へのリクエスト数を削減する方法は以下のとおりです。 このガイドでは、API から追加プロパティをリクエストする方法を説明します。リクエストを変更して以下のプロパティを含める方法について確認できます。 - 関連するオブジェクトから取得されたプロパティ - 関連性の薄いオブジェクトから取得されたプロパティ - リスト内の全オブジェクトの追加プロパティ - デフォルトではレスポンスに含まれないプロパティ ## レスポンスの拡張の仕組み Stripe API は、状態、構成、およびコンテキストの各プロパティを持つオブジェクトで表されるリソースに分類されています。これらのオブジェクトはすべて一意の ID を持ち、この ID はオブジェクトの取得、更新、削除に使用できます。API はこれらの ID を、関連オブジェクトをリンクするためにも使用します。たとえば、[Checkout Session (Checkout セッション)](https://docs.stripe.com/api/checkout/sessions/object.md) は、[顧客 ID](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer) によって [Customer (顧客)](https://docs.stripe.com/api/customers/object.md) にリンクされます。 > 顧客を [Customer](https://docs.stripe.com/api/customers/object.md) オブジェクトではなく顧客設定の [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) オブジェクトとしてモデル化する場合は、`expand` パラメーターの代わりに [include](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-include) パラメーターを使用します。 ```json { "id": "cs_test_KdjLtDPfAjT1gq374DMZ3rHmZ9OoSlGRhyz8yTypH76KpN4JXkQpD2G0", "object": "checkout.session", ..."customer": "cus_HQmikpKnGHkNwW", ... } ``` リンクされたオブジェクトからの情報が必要な場合は、新しい呼び出しでその ID を使用して、リンクされたオブジェクトを取得できます。ただし、このアプローチでは 1 つの値へのアクセスに 2 つの API リクエストが必要になります。複数のリンクされたオブジェクトからの情報が必要な場合、それぞれに別のリクエストが必要になるため、アプリケーションの待ち時間および複雑性が増します。 API には拡張機能があるため、単一の呼び出しでリンクされたオブジェクトを取得し、オブジェクト ID をそのすべてのプロパティおよび値に効率的に置換できます。たとえば、ある Checkout セッションに関連付けられた顧客の詳細にアクセスするとします。Checkout セッションを取得して `expand` 配列に `customer` プロパティを渡すことで、レスポンスに Customer オブジェクト全体を含めるよう Stripe に指示します。 ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=customer" ``` これにより、Checkout セッションで ID の代わりに Customer オブジェクト全体が返されます。 ```json { "id": "cs_test_KdjLtDPfAjT1gq374DMZ3rHmZ9OoSlGRhyz8yTypH76KpN4JXkQpD2G0", "object": "checkout.session", ..."customer": { "id": "cus_HQmikpKnGHkNwW", "object": "customer", ... "metadata": { "user_id": "user_xyz" }, ... } } ``` > すべてのプロパティを拡張できるわけではありません。API リファレンスでは、拡張可能なプロパティを「拡張可能」のラベルでマークしています。 ## 複数のプロパティを拡張する 1 回の呼び出しで複数のプロパティを拡張するには、拡張の配列に項目を追加します。たとえば、ある Checkout セッションで [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 セッションで使用された支払い方法のタイプを知る必要がある場合、最初に Checkout セッションの支払いインテントを取得してから、支払いインテントのリンクされた支払い方法を取得してそのタイプを確認します。`expand` を使用すると、この操作を 1 回の呼び出しで実行できます。 ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{CHECKOUTSESSION_ID}} \ -u "<>:" \ -d "expand[]=payment_intent.payment_method" ``` これにより、Checkout セッションで ID ではなく完全な [PaymentIntent (支払いインテント)](https://docs.stripe.com/api/payment_intents/object.md) オブジェクトおよび [PaymentMethod (支払い方法)](https://docs.stripe.com/api/payment_methods/object.md) オブジェクトが返されます。 ```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" } ``` > 拡張の深さの上限は 4 レベルです。このため、`expand` 文字列には 4 つまでのプロパティ `property1.property2.property3.property4` しか含められません。 ## リスト内のプロパティを拡張する API がオブジェクトのリストを返す際に、`data` キーワードを使用して、リスト内の各オブジェクトの特定のプロパティを拡張できます。たとえば、顧客の 1 人が使用する支払い方法に関する情報が必要であるとします。この情報を入手するため、[顧客の PaymentIntent をリスト](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` キーワードを使用して、拡張カーソルをリスト内に移動できます。 リストの各支払いインテントをループし、リンクされた支払い方法を別の呼び出しで取得する代わりに、`data` キーワードを使用して一度にすべての支払い方法を拡張できます。 ```curl curl -G https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "expand[]=data.payment_method" ``` これにより、リストには各支払いインテントに完全な PaymentMethod オブジェクトが含まれます。 ```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 セッションの [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 ハンドラー内の別の呼び出しでオブジェクトを取得する必要があります。 ## TypeScript を使用した展開 TypeScript で [stripe-node](https://github.com/stripe/stripe-node) SDK を使用する場合、展開可能なフィールドの型は `string | Foo` となります (`Foo` は展開されたオブジェクトの型)。このユニオン型は、フィールドに未展開の ID 文字列、または展開されたオブジェクト全体を含めることができるという事実を反映しています。フィールドの展開後、そのプロパティにアクセスするには、適切なオブジェクト型にキャストする必要があります。コンパイル時にフィールドに ID 文字列と展開されたオブジェクトのどちらが含まれているかを TypeScript が推論できないため、このキャストが必要になります。キャストしない場合、TypeScript によってフィールドが `string | Stripe.Customer | Stripe.DeletedCustomer | null` として処理され、プロパティに直接アクセスできなくなります。 たとえば、`PaymentIntent` の展開された `customer` フィールドのメールアドレスにアクセスするには、次のようにします。 ```typescript const paymentIntent = await stripe.paymentIntents.retrieve( 'pi_123456789', { expand: ['customer'], } ); // Cast the expanded field to the expected object type to access its properties const customerEmail: string | null = (paymentIntent.customer as Stripe.Customer).email; ```