# サードパーティーの API エンドポイントにカード情報を転送する

Vault and Forward API を使用して、複数の決済代行業者間でカード詳細を安全に共有します。

> #### 連携を構築せずにサードパーティの PSP で処理を実行
> 
> [Stripe Orchestration](https://docs.stripe.com/payments/orchestration.md) を使用すると、複数の PSP にわたるルーティング、認証、確定、返金、3DS など、代行業者との連携はすべて Stripe が代行します。同じ Payment Intents API を利用でき、PSP 固有のコードは不要です。[アクセスをリクエストするには、メールアドレスを送信してください。](https://docs.stripe.com/payments/vault-and-forward.md#orchestration_preview)

### Orchestration へのアクセスをご希望の場合

Enter your email to request access.

```bash
curl https://docs.stripe.com/preview/register \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Referer: https://docs.stripe.com/payments/vault-and-forward" \
  -d '{"email": "EMAIL", "preview": "orchestration_preview"}'
```

Vault and Forward API を使用すると、カード詳細をトークン化して Stripe の PCI 準拠の Vault に保存し、そのデータをサポート対象の決済代行業者やエンドポイントにルーティングできます。この API は以下の目的で使用します。

- [複数の決済代行業者に対して](https://docs.stripe.com/payments/forwarding-third-party-processors.md) [Payment Element](https://docs.stripe.com/payments/payment-element.md) を使用します。
- Stripe を、決済代行業者間でのカード情報のプライマリボールトとして使用します。
- 自社で構築済みの [PCI 準拠のトークンボールト](https://docs.stripe.com/payments/forwarding-token-vault.md)にカード情報を転送します。

> #### アクセスをリクエストする
> 
> Stripe の転送サービスを使用するには、[Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)にお問い合わせください。

## 送信先エンドポイントにリクエストを転送し、Stripe のボールトからカード詳細を入力する

カード情報を転送する API フロー (See full diagram at https://docs.stripe.com/payments/vault-and-forward)

```text
[サーバー] -- PaymentMethod を作成する --> [Stripe]
[Stripe] -- Stripe は PaymentMethod オブジェクトを返す --> [サーバー]
[サーバー] -- 指定した PaymentMethod で Vault and Forward API を呼び出す --> [Stripe]
[Stripe] -- Stripe がカードデータを含むリクエストを転送する --> [送信先エンドポイント]
[送信先エンドポイント] -- 送信先エンドポイントがレスポンスを返す --> [Stripe]
[Stripe] -- Stripe が特定された PCI 機密データを非表示にしてレスポンスを送信する --> [サーバー]
```

## カード情報を収集して PaymentMethod を作成する

カード情報を収集するには、Payment Element を使用して [PaymentMethod](https://docs.stripe.com/payments/finalize-payments-on-the-server-legacy.md?type=payment#create-pm) を作成します。PaymentMethod を作成すると、カード情報は Stripe の PCI 準拠のボールトに自動的に保存されます。自社で構築済みのフロントエンドがある場合でも、[PaymentMethod を直接作成する](https://docs.stripe.com/api/payment_methods/create.md)ことで Vault and Forward API を使用できます。

通常、PaymentMethods は、顧客に関連付けなければ再利用できません。ただし Vault and Forward API は、顧客に関連付けられていないものも含め、すべての PaymentMethod オブジェクトを受け入れます。

また、Vault and the Forward API は PaymentIntents の[確定](https://docs.stripe.com/api/payment_intents/confirm.md)も、[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)も行いません。そのため、別の決済代行業者ですでにキャプチャーされたものを Stripe での支払いのキャプチャーに誤って使用するおそれがあります。

> #### Link transactions
> 
> Link 取引で保存された消費者の決済用認証情報を決済代行業者間で転送することはできません。Link を通じて保存された認証情報は転送から除外されます。

セキュリティコードは一定の期間が過ぎると自動的に期限切れになり、Vault and Forward API を使用した場合にも期限切れになります。これらの条件のいずれかを満たした後にセキュリティコードが必要な場合は、カード詳細を再収集する必要があります。

### SetupIntents で CVC を保持する

転送前に [SetupIntents](https://docs.stripe.com/api/setup_intents.md) を使用してカード詳細を収集する場合、SetupIntent の確認中のカード検証によって CVC が消費されることがあります。これが発生すると、後続の Forwarding API コールには CVC が含まれなくなり、CVC を必要とする代行業者で失敗が発生する可能性があります。

Forwarding API で SetupIntents を使用する際に CVC の可用性を維持するオプションを利用するには、[Stripe support](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DPreserve%2520CVC%2520with%2520SetupIntents%2520and%2520Forwarding%2520API) に問い合わせる必要があります。

## ForwardingRequest を作成する

Stripe のボールトからカード情報を送信するには、[ForwardingRequest を作成](https://docs.stripe.com/api/forwarding/forwarding_requests/create.md)し、次のパラメーターを含める必要があります。

- `payment_method`: Stripe の Vault に保存されているカード詳細を含むオブジェクトの ID。受け付けられるオブジェクトタイプには、PaymentMethod (`pm_`)、基となるカードを持つ Source (`src_`)、Card (`card_`)、Issuing Card (`ic_`) があります。
- `url`: リクエストの正確な送信先エンドポイント。
- `request.body`: 送信先エンドポイントに送信する API リクエスト本文 (別の決済代行業者に送信する支払いリクエストなど)。通常の場合に顧客のカード情報などを入力するフィールドはすべて空白のままにします。
- `replacements`: Stripe が `request.body` で置き換えるようにするフィールド。常に設定することをお勧めする[使用可能なフィールド](https://docs.stripe.com/api/forwarding/forwarding_requests/create.md#forwarding_request_create-replacements)は、`card_number`、`card_expiry`、`card_cvc`、`cardholder_name` です。たとえば、`replacements` 配列に `card_number` を含めると、`request.body` にある送金先エンドポイントに該当するカード番号フィールドが置き換えられます。

> `request.body` 内の各カードフィールドのプレースホルダー値は、送信先エンドポイントが想定する JSON 型と一致している必要があります。文字列フィールドには `""` を、数値フィールドには `0` を使用します。たとえば、送信先エンドポイントで `expiryMonth` と `expiryYear` に整数が必要な場合は、`""` ではなく `0` に設定します。
> 
> ```json
> "paymentMethod": {"number": "", "expiryMonth": 0, "expiryYear": 0, "cvc": "", "holderName": ""}
> ```

Stripe は、カード保有者名フィールドの検証に関して他の業者よりも寛容な場合があります。`cardholder_name` 置換フィールドを使用する場合は、使用する名前が宛先エンドポイントによって実施される検証に合格することを徹底する責任があります。たとえば、宛先エンドポイントですべての名前に A ～ Z の文字のみを使用し、アクセント記号やその他の表記体系を使用しないことが求められている場合は、転送するカードの詳細がこの要件を満たしていることを確認する必要があります。別の方法としては、`cardholder_name` 置換フィールドを使用せず、リクエスト本文でカード保有者名を直接リクエストに指定する方法があります。

送信先エンドポイントが求めるデータに基づいてリクエストの形式を設定する必要があります。下記の例では、送信先エンドポイントは、`Idempotency-Key` ヘッダーを求め、支払いの詳細が記載された JSON 本文を受け取ります。

API リクエストごとに、送信先エンドポイントの API キーを渡す必要があります。Stripe はお客様が指定した API キーを使用してリクエストを転送し、送信先エンドポイントの API キーのハッシュ化および暗号化されたバージョンのみを保持します。

```curl
curl https://api.stripe.com/v1/forwarding/requests \
  -u "<<YOUR_SECRET_KEY>>:" \
  -H "Idempotency-Key: {{IDEMPOTENCYKEY_ID}}" \
  -d "payment_method={{PAYMENTMETHOD_ID}}" \
  --data-urlencode "url=https://endpoint-url/v1/payments" \
  -d "request[headers][0][name]=Destination-API-Key" \
  -d "request[headers][0][value]={{DESTINATION_API_KEY}}" \
  -d "request[headers][1][name]=Destination-Idempotency-Key" \
  -d "request[headers][1][value]={{DESTINATION_IDEMPOTENCY_KEY}}" \
  --data-urlencode "request[body]={\"amount\":{\"value\":1000,\"currency\":\"usd\"},\"paymentMethod\":{\"number\":\"\",\"expiryMonth\":\"\",\"expiryYear\":\"\",\"cvc\":\"\",\"holderName\":\"\"},\"reference\":\"{{REFERENCE_ID}}\"}" \
  -d "replacements[0]=card_number" \
  -d "replacements[1]=card_expiry" \
  -d "replacements[2]=card_cvc" \
  -d "replacements[3]=cardholder_name"
```

> 同じキーを持つリクエストが 1 つのアウトバウンドリクエストのみを結果として得るように、`Idempotency-Key` を提供できます。Stripe と、基盤となるサードパーティリクエストで提供すべき冪等性キーに対して、異なる一意のキーを使用してください。
> 
> `request.body` または `request.header` フィールドを更新するたびに、新しい `Idempotency-Key` を使用します。古いべき等キーを渡すと、API は以前の検証エラーや送信先エンドポイントエラーなど、古いレスポンスを再生します。送信先エンドポイントに到達する際にエラーが発生したリクエストを再試行するときは、新しいべき等キーを使用して、送信先でリクエストが再試行されるように設定することをお勧めします。

## ウォレットによる決済方法の転送

Vault と Forward API を使用して、Apple Pay と Google Pay の支払い方法を転送することができます。ただし、ウォレットの種類やトークン化のタイプに応じて、ウォレットの認証情報が正しく転送されるために使用される「置換フィールド」が異なります。

### 対応ウォレット

Stripe は、以下のウォレットに対応しています。

- **Apple Pay**: デバイスプライマリーアカウント番号 (DPAN) および加盟店プライマリーアカウント番号 (MPAN)。
- **Google Pay**: Funding Primary Account Numbers (FPAN) と Device Primary Account Numbers (DPAN)。

ウォレット転送にアクセスするには、[Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520wallet%2520forwarding%2520for%2520Vault%2520and%2520Forward%3F)にお問い合わせください。

> Link による決済は現在、Vault and Forward API でサポートされていません。Linkのカード取引には、[PaymentMethod object](https://docs.stripe.com/api/payment_methods/object.md) があり、[type](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) は `card`、[wallet type](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-card-wallet-type) は `link` です。転送リクエストには PaymentMethods を含めないでください。
> 
> 導入で Link を使用している場合は、Linkのカード取引をサードパーティーのエンドポイントに転送するのではなく、Stripe にルーティングして処理する必要があります。

### ウォレットによる決済方法の検出

使用する置換フィールドを判断するには、`PaymentMethod` を取得し、ウォレットの種類とトークン化方法を確認します。

#### Google Pay

`tokenization_type` フィールドが、決済手段で FPAN と DPAN のどちらを使用するかを示します:

```json
{
  "id": "pm_1Q0PsIJvEtkwdCNYMSaVuRz6",
  "object": "payment_method",
  "type": "card",
  "card": {
    "wallet": {
      "type": "google_pay",
      "google_pay": {
        "tokenization_type": "dpan_or_ecommerce_token"  // or "fpan"
      }
    }
  }
}
```

#### Apple Pay

Apple Pay の決済手段では、常に DPAN が使用されます。これは、`tokenization_type` フィールドで示されます:

```json
{
  "id": "pm_1Q0PsIJvEtkwdCNYMSaVuRz6",
  "object": "payment_method",
  "type": "card",
  "card": {
    "wallet": {
      "type": "apple_pay",
      "apple_pay": {
        "tokenization_type": "dpan",
        "cryptogram_type": "emv"
      }
    }
  }
}
```

### ウォレットの置換フィールド

使用する置換フィールドは、ウォレットの種類によって異なります:

- **Google Pay FPAN**: 標準のクレジットカード置換フィールド (`card_number`、`card_expiry`、`card_cvc`、`cardholder_name`) を使用
- **Google Pay DPAN**: ネットワークトークン置換フィールド (`network_token_number`、`network_token_cryptogram`、`network_token_expiry`、`network_token_electronic_commerce_indicator`) を使用
- **Apple Pay DPAN**: ネットワークトークン置換フィールド (`network_token_number`、`network_token_cryptogram`、`network_token_expiry`、`network_token_electronic_commerce_indicator`) を使用

### Google Pay FPAN の転送

Google Pay FPAN では、通常のカード決済と同じ置換フィールドを使用します。

```curl
curl https://api.stripe.com/v1/forwarding/requests \
  -u "<<YOUR_SECRET_KEY>>:" \
  -H "Idempotency-Key: {{IDEMPOTENCYKEY_ID}}" \
  -d "payment_method={{PAYMENTMETHOD_ID}}" \
  --data-urlencode "url=https://endpoint-url/v1/payments" \
  -d "request[headers][0][name]=Destination-API-Key" \
  -d "request[headers][0][value]={{DESTINATION_API_KEY}}" \
  -d "request[headers][1][name]=Destination-Idempotency-Key" \
  -d "request[headers][1][value]={{DESTINATION_IDEMPOTENCY_KEY}}" \
  --data-urlencode "request[body]={\"amount\":{\"value\":1000,\"currency\":\"usd\"},\"paymentMethod\":{\"number\":\"\",\"expiryMonth\":\"\",\"expiryYear\":\"\",\"cvc\":\"\",\"holderName\":\"\"},\"reference\":\"{{REFERENCE_ID}}\"}" \
  -d "replacements[0]=card_number" \
  -d "replacements[1]=card_expiry" \
  -d "replacements[2]=card_cvc" \
  -d "replacements[3]=cardholder_name"
```

### ウォレット DPAN の転送

Google Pay と Apple Pay の DPAN を転送する場合は、ネットワークトークン置換フィールドを使用します。

#### Google Pay

```bash
curl https://api.stripe.com/v1/forwarding/requests \
  -u "sk_test_4eC39HqLyjWDarjtT1zdp7dc:" \
  -H "Idempotency-Key: {{IDEMPOTENCY_KEY}}" \
  -d payment_method="{{PAYMENT_METHOD}}" \
  --data-urlencode url="https://endpoint-url/v1/payments" \
  -d "replacements[0]"=network_token_number \
  -d "replacements[1]"=network_token_cryptogram \
  -d "replacements[2]"=network_token_expiry \
  -d "replacements[3]"=network_token_electronic_commerce_indicator \
  --data-urlencode 'request[body]={"amount":{"value":1000,"currency":"usd"},"paymentMethod":{"networkToken":{"number":"","cryptogram":"","expiryMonth":"","expiryYear":"","electronicCommerceIndicator":""}},"reference":"{{REFERENCE_ID}}"}' \
  -d "request[headers][0][name]"=Destination-API-Key \
  -d "request[headers][0][value]"="{{DESTINATION_API_KEY}}" \
  -d "request[headers][1][name]"=Destination-Idempotency-Key \
  -d "request[headers][1][value]"="{{DESTINATION_IDEMPOTENCY_KEY}}"
```

#### Apple Pay

```bash
curl https://api.stripe.com/v1/forwarding/requests \
  -u "sk_test_4eC39HqLyjWDarjtT1zdp7dc:" \
  -H "Idempotency-Key: {{IDEMPOTENCY_KEY}}" \
  -d payment_method="{{PAYMENT_METHOD}}" \
  --data-urlencode url="https://endpoint-url/v1/payments" \
  -d "replacements[0]"=network_token_number \
  -d "replacements[1]"=network_token_cryptogram \
  -d "replacements[2]"=network_token_expiry \
  -d "replacements[3]"=network_token_electronic_commerce_indicator \
  --data-urlencode 'request[body]={"amount":{"value":1000,"currency":"usd"},"paymentMethod":{"networkToken":{"number":"","cryptogram":"","expiryMonth":"","expiryYear":"","electronicCommerceIndicator":""}},"reference":"{{REFERENCE_ID}}"}' \
  -d "request[headers][0][name]"=Destination-API-Key \
  -d "request[headers][0][value]"="{{DESTINATION_API_KEY}}" \
  -d "request[headers][1][name]"=Destination-Idempotency-Key \
  -d "request[headers][1][value]"="{{DESTINATION_IDEMPOTENCY_KEY}}"
```

## カード情報を含むリクエストを転送する

Stripe は、PaymentMethod からのカード詳細を `request.body` に挿入することで、お客様の代わりに送信先エンドポイントにリクエストを送信します。自動カード更新機能 (CAU) は、有効かつ利用可能な場合は、カード詳細の更新を自動的に試み、リクエストに利用できる最新のカード詳細を提供します。

Stripe は、次にリクエストを送信先エンドポイントに転送します。例:

1. Stripe はエンドポイントに POST リクエストを送信します。

   ```
   POST /v1/payments HTTP/1.1
   User-Agent: Stripe
   Accept: */*
   Host: endpoint-url
   Content-Type: application/json
   Content-Length: 321
   ```

2. Stripe には以下のヘッダーが含まれます。

   ```
   Destination-API-Key: {{DESTINATION_API_KEY}}
   Destination-Idempotency-Key: {{DESTINATION_IDEMPOTENCY_KEY}}
   ```

3. Stripe は、リクエストに以下の JSON 本文を含めます。

   ```
   {
     amount: {
       value: 1000,
       currency: 'usd'
     },
     paymentMethod: {
       number: '4242424242424242',
       expiryMonth: '03',
       expiryYear: '2030',
       cvc: '123',
       holderName: 'First Last',
     },
     reference: '{{REFERENCE_ID}}'
   }
   ```

> Vault and the Forward API を使用してオーソリリクエストを行う場合は、返金や不審請求の申請など、取引後のアクションをサードパーティーの決済代行業者と直接処理する必要があります。複数の決済代行業者の設定で 3DS 認証が必要な場合は、Stripe サポートにお問い合わせください。

## 送信先エンドポイントからのレスポンスに対応する

Vault and Forward API を使用してカード詳細をサードパーティーの決済代行業者に転送する際、Stripe は同時に送信先エンドポイントからのレスポンスを待機します。このレスポンスのタイムアウト期間は 1 分未満です。Stripe は、特定された PCI 機密データを非表示にし、送信先エンドポイントからの非表示のレスポンスを保存し、リクエストとレスポンスに関するデータが含まれた [ForwardingRequest](https://docs.stripe.com/api/forwarding/request/object.md) オブジェクトを返します。

> Vault and Forward API を使用してカード情報をサードパーティーの決済代行業者に転送する際、Stripe は、転送された API リクエストに対して代行業者が特定の応答を行うことを保証できません。サードパーティーの決済代行業者が応答しない場合、問題を解決するには、その決済代行業者に直接連絡する必要があります。

```json
{
  "id": "fwdreq_123",
  "object": "forwarding.request",
  "payment_method": "{{PAYMENT_METHOD}}",
  "request_details": {
    "body": "{ \"amount\": { \"value\": 1000, \"currency\": \"usd\" }, \"paymentMethod\": { \"number\": \"424242******4242\", \"expiryMonth\": \"03\", \"expiryYear\": \"2030\", \"cvc\": \"***\", \"holderName\": \"First Last\" }, \"reference\": \"{{REFERENCE_ID}}\" }",
    "headers": [
      {
        "name": "Content-Type",
        "value": "application/json"
      },
      {
        "name": "Destination-API-Key",
        "value": "{{DESTINATION_API_KEY}}"
      },
      {
        "name": "Destination-Idempotency-Key",
        "value": "{{DESTINATION_IDEMPOTENCY_KEY}}"
      },
      ...
    ]
  },
  "request_context": {
      "destination_duration": 234,
      "destination_ip_address": "35.190.113.80"
  },
  "response_details": {
    "body": "{ // Response from the third-party endpoint goes here ... }",
    "headers": [
      ...
    ],
    "status": 200
  },
  "replacements": [
    "card_number",
    "card_expiry",
    "card_cvc",
    "cardholder_name"
  ]
  ...
}
```

## Vault and Forward API エンドポイントを設定する

Vault and Forward API エンドポイントを設定するには、以下を行う必要があります。

- [送信先エンドポイントがサポートされていることを確認します](https://docs.stripe.com/payments/vault-and-forward.md#confirm-endpoint)。
- [Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)にテストと本番環境用のアカウントを提供します。
- [Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)に送信先エンドポイントの[本番環境の詳細を共有](https://docs.stripe.com/payments/vault-and-forward.md#share-production-details)します。

### 送信先エンドポイントがサポートされていることを確認する

Stripe は、次のエンドポイントへの API リクエストの転送をサポートしています。

- **Accertify**:
  - `icnow01.accertify.net/icNowImport/[path]`
- **Adyen**:
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v68/payments`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v68/storedPaymentMethods`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v69/payments`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v69/storedPaymentMethods`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v70/payments`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v70/storedPaymentMethods`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v71/payments`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v71/storedPaymentMethods`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v72/payments`
  - `[prefix]-checkout-live.adyenpayments.com/checkout/v72/storedPaymentMethods`
- **Basis Theory**:
  - `api.basistheory.com/connections/stripe-forward/tokenize`
- **Braintree**:
  - `payments.braintree-api.com/graphql`
- **CardPointe**:
  - `[prefix].cardconnect.com/cardconnect/rest/auth`
- **Checkout**:
  - `api.checkout.com/tokens`
  - `api.checkout.com/payments`
- **Evervault**:
  - `[prefix].relay.evervault.app`
- **Expedia**:
  - `api.ean.com/v3/itineraries`
- **Fat Zebra**:
  - `gateway.pmnts.io/v1.0/credit_cards`
- **Fiserv**:
  - `prod.api.firstdata.com/gateway/v2/payments`
- **FlexPay**:
  - `api.flexpay.io/v1/gateways/charge`
- **GMO ペイメントゲートウェイ**:
  - `p01.mul-pay.jp/payment/ExecTran.json`
  - `token.mul-pay.jp/payment/ExecTran.json`
- **PaymentsOS**:
  - `api.paymentsos.com/tokens`
- **PCI Vault**:
  - `api.pcivault.io/v1/capture/stripe`
- **ProcessOut**:
  - `api.processout.com/cards`
- **Rewards Network**:
  - `api.rewardsnetwork.com/v2/members/enroll`
  - `api.rewardsnetwork.com/v2/members/*/cards`
- **Shift4**:
  - `api.shift4.com/charges`
- **SoftBank**:
  - `stbfep.sps-system.com/api/xmlapi.do`
- **Spreedly**:
  - `core.spreedly.com/v1/payment_methods.json`
- **TabaPay**:
  - `[prefix]/v1/clients/[ClientID]/accounts`
- **TokenEx**:
  - `tgapi.tokenex.com/Tokenize/Proxy/[ProfileID]`
- **VGS (Very Good Security)**:
  - `[prefix].live.verygoodproxy.com/cards`
- **Worldpay**:
  - `access.worldpay.com/api/payments`
  - `access.worldpay.com/cardPayments/customerInitiatedTransactions`
  - `access.worldpay.com/tokens`
  - `secure.worldpay.com/jsp/merchant/xml/paymentService`
- **Xsolla**:
  - `ps.xsolla.com/forwarding/payments/card`
- **Yuno**:
  - `api-sandbox.y.uno/pci-stripe-forward-webhook/v1/forward`
  - `api.y.uno/pci-stripe-forward-webhook/v1/forward`
- [自社の PCI 準拠のトークンボールト](https://docs.stripe.com/payments/forwarding-token-vault.md)

Stripe では、JSON/XML リクエストを受け付け、JSON/XML レスポンスを返す HTTPS ベースの API をサポートしています。送信先のエンドポイントがサポートされていない場合、または別の API 形式が必要な場合は、エンドポイントの詳細を [Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520Access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)にお知らせください。貴社固有のニーズに合わせてサポートいたします。

### 対応可能な国

Vault and Forward API は、以下の国にのみリクエストを転送できます。

### リクエスト転送機能を使用できる国

- AE
- AG
- AL
- AM
- AO
- AR
- AT
- AU
- AZ
- BA
- BD
- BE
- BG
- BH
- BJ
- BN
- BO
- BS
- BT
- BW
- CA
- CH
- CI
- CL
- CO
- CR
- CY
- CZ
- DE
- DK
- DO
- DZ
- EC
- EE
- EG
- ES
- ET
- FI
- FR
- GA
- GB
- GH
- GI
- GM
- GR
- GT
- GY
- HK
- HR
- HU
- ID
- IE
- IL
- IN
- IS
- IT
- JM
- JO
- JP
- KE
- KH
- KR
- KW
- KZ
- LA
- LC
- LI
- LK
- LT
- LU
- LV
- MA
- MC
- MD
- MG
- MK
- MN
- MO
- MT
- MU
- MX
- MY
- MZ
- NA
- NE
- NG
- NL
- NO
- NZ
- OM
- PA
- PE
- PH
- PK
- PL
- PT
- PY
- QA
- RO
- RS
- RW
- SA
- SE
- SG
- SI
- SK
- SM
- SN
- SV
- TH
- TN
- TR
- TT
- TW
- TZ
- US
- UY
- UZ
- VN
- ZA

加えて、Stripe アカウントが以下のいずれかの国に登録されていることを確認してください。

### Vault and Forward API を利用できる国

- AE
- AT
- AU
- BE
- BG
- BR
- CA
- CH
- CY
- CZ
- DE
- DK
- EE
- ES
- FI
- FR
- GB
- GI
- GR
- HK
- HR
- HU
- ID
- IE
- IT
- JP
- LI
- LT
- LU
- LV
- MT
- MX
- MY
- NL
- NO
- NZ
- PL
- PT
- RO
- SE
- SG
- SI
- SK
- US

### Stripe サポートにテスト用アカウントを提供する

Vault and Forward API にアクセスするには、テスト用アカウントの[アカウント ID](https://dashboard.stripe.com/settings/account) (`acct_xxxx`) を [Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)と共有します。

### 本番環境の詳細を共有する

送信先エンドポイントの本番環境の詳細を [Stripe サポート](https://dashboard.stripe.com/login?redirect=https%3A%2F%2Fsupport.stripe.com%2Fcontact%2Femail%3Fquestion%3Dother%26topic%3Dpayment_apis%26subject%3DHow%2520can%2520I%2520access%2520the%2520Vault%2520and%2520Forward%2520API%3F%26body%3DWhat%2520endpoint%28s%29%2520would%2520you%2520like%2520to%2520forward%2520card%2520details%2520to%3F)と共有します。これには、送信先エンドポイントの URL、HTTP メソッド、ドキュメント、フィールド、リクエストヘッダー、暗号化キーが含まれます。次に Stripe は、本番環境の Vault and Forward API で使用する送信先エンドポイントを設定します。

サードパーティの API キーを共有するには、Vault and Forward API に固有の Stripe 公開鍵を使用して暗号化する必要があります。まず、[GNU Privacy Guard (PGP)](https://gnupg.org) を使用して[公開鍵をインポート](https://www.gnupg.org/gph/en/manual.html#AEN84)します。PGP の基本を理解したら、以下の PGP キーを使用してサードパーティの API キーを暗号化します。

### Vault and Forward API PGP キー

```
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
UraCYX03loNHRxLCyeHR4GA=
=bbos
-----END PGP PUBLIC KEY BLOCK-----
```

Vault and Forward API PGP キーを使用してサードパーティーの API キーを暗号化するには、以下を行います。

1. 以下の内容で `hash_encrypt_key.sh` という名前のファイルを作成します。このスクリプトは、API キーの `SHA256` ハッシュを生成し、それを Stripe の公開キーで暗号化してから `Base64` でエンコードします。

   > #### 必要なユーティリティ
   > 
   > スクリプトを実行するには、まず `sha256sum`、`gpg`、`base64` ユーティリティをそれぞれインストールする必要があります。

   ```bash
   #!/bin/sh
   set -euo pipefail
   fail () { printf "Error: $1\n" >&2 && exit 1; }
   
   STRIPE_PUBLIC_KEY=AE863ADA1603150856C0A853A7B203177D034588
   API_KEY=$(printf "$1" | tr -d '\n' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
   
   [ -x "$(command -v sha256sum)" ]                    || fail "sha256sum is not installed."
   [ -x "$(command -v gpg)" ]                          || fail "gpg is not installed."
   [ -x "$(command -v base64)" ]                       || fail "base64 is not installed."
   [ ! -z "$API_KEY" ]                                 || fail "Please pass in an API key."
   grep -iqv "Basic \|Bearer " <<< "$API_KEY"          || fail "Please omit the Basic/Bearer prefix."
   gpg --list-keys $STRIPE_PUBLIC_KEY > /dev/null 2>&1 || fail "Stripe public key not imported."
   
   printf "$API_KEY" | sha256sum | cut -d " " -f 1 | tr -d '\n' | gpg -e -r $STRIPE_PUBLIC_KEY --always-trust | base64 > encrypted_hashed_key.txt
   printf "Successfully generated encrypted_hashed_key.txt\n"
   ```

2. サードパーティーの API キーを一重引用符で囲んで渡し、`Bearer` または `Basic` プレフィックスを省略してスクリプトを実行します。キーは、宛先エンドポイントへの実際のリクエストに使用する正確なキーである必要があり、プレフィックスは含みません。

   このスクリプトは、`encrypted_hashed_key.txt` という名前のファイルを生成します。

   ```bash
   sh hash_encrypt_key.sh '<THIRD_PARTY_API_KEY>'
   ```

### Vault および Forwardで Stripe の制限された API キーを使用する

[制限された API キー (RAK)](https://docs.stripe.com/keys-best-practices.md#limit-access)を使用して、サーバー側のアクセスを Vault および Forward エンドポイントにのみ許可します。

- 制限されたキーに対する最小限の権限を有効にします。
  - `forwarding_request_write`: ForwardingRequests を[作成](https://docs.stripe.com/api/forwarding/forwarding_requests/create.md)するための必須の権限。
  - `forwarding_request_read`: ForwardingRequests を[取得](https://docs.stripe.com/api/forwarding/forwarding_requests/retrieve.md)または[一覧表示](https://docs.stripe.com/api/forwarding/forwarding_requests/list.md)するための任意の権限。
- サーバーから `/v1/forwarding/requests` を呼び出すときは、制限されたAPIキーを `Authorization: Bearer <rk_...>` という形式の認証情報として使用してください。
- 連携機能で他の API も呼び出す場合は、それらの呼び出しに必要な最小限の権限のみを追加してください。

[制限付き API キーを作成する](https://docs.stripe.com/keys.md#create-restricted-api-key)方法の詳細をご覧ください。

## 構築したシステムをテストする

既存のシステムが送信先エンドポイントで正しく機能することを確認するために、作成した PaymentMethod を使用して ForwardingRequest を開始します。この例では、支払い方法として `pm_card_visa` を使用します。

```curl
curl https://api.stripe.com/v1/forwarding/requests \
  -u "<<YOUR_SECRET_KEY>>:" \
  -H "Idempotency-Key: {{IDEMPOTENCYKEY_ID}}" \
  -d payment_method=pm_card_visa \
  -d "url={{DESTINATION ENDPOINT}}" \
  -d "request[headers][0][name]=Destination-API-Key" \
  -d "request[headers][0][value]={{DESTINATION_API_KEY}}" \
  -d "request[headers][1][name]=Destination-Idempotency-Key" \
  -d "request[headers][1][value]={{DESTINATION_IDEMPOTENCY_KEY}}" \
  --data-urlencode "request[body]={\"amount\":{\"value\":1000,\"currency\":\"usd\"},\"paymentMethod\":{\"number\":\"\",\"expiryMonth\":\"\",\"expiryYear\":\"\",\"cvc\":\"\",\"holderName\":\"\"},\"reference\":\"{{REFERENCE_ID}}\"}" \
  -d "replacements[0]=card_number" \
  -d "replacements[1]=card_expiry" \
  -d "replacements[2]=card_cvc" \
  -d "replacements[3]=cardholder_name"
```

> Vault and Forward API は、送信先エンドポイントからのレスポンスを `success`として扱い、`response.body` 内の送信先エンドポイントのレスポンスコードとともに `200` を返します。たとえば、送信先エンドポイントが `400` のステータスコードを Stripe に返すと、Vault and Forward API は `200` のステータスコードで応答します。 `response.body` には、送信先エンドポイントの `400` レスポンスとエラーメッセージが含まれます。送信先エンドポイントに送信する API リクエストを別途テストして、エラーがないことを確認します。

### ダッシュボードでリクエストログを確認する

Vault and Forward API に関連するリクエストログとエラーを[Workbench](https://docs.stripe.com/workbench/overview.md#request-logs)で表示できます。さらに、[List API](https://docs.stripe.com/api/forwarding/forwarding_requests/list.md)を使用して Stripe からログを取得できます。

> 受信するリクエストの `request.headers` と `request.body` は暗号化され、ダッシュボードで `encrypted_request` と表示されます。
