📖

Stripe APIのPersonはアカウントリンク生成後にアクセスできない

2023/02/06に公開

概要

  • Stripe ConnectでExpressアカウントを作成する
  • アカウントリンクを発行し、ユーザーの入力が終わった後にStripe APIのPersonから入力情報を取得してDBに保存したい
  • テスト環境の標準キーでPersonにアクセスするとmore_permissions_required のエラーがでる
{
  "error": {
    "code": "more_permissions_required",
    "message": "The provided key '***' does not have the required permissions for this endpoint on account '****'. Having more permissions would allow this request to continue.",
    "request_log_url": "https://dashboard.stripe.com/test/logs/****",
    "type": "invalid_request_error"
  }
}
  • 標準キーでは権限が足りなかったので、すべてのConnectリソースに読み取り権限を持つ制限付きの API シークレットキーを作成して、Personにアクセスする
  • account_invalidのエラーがでる
{
  "error": {
    "code": "account_invalid",
    "doc_url": "https://stripe.com/docs/error-codes/account-invalid",
    "message": "The provided key '****' does not have access to account '****' (or that account does not exist). Application access may have been revoked.",
    "type": "invalid_request_error"
  }
}

Stripe APIのPersonにはアカウントリンク生成後にアクセスできない

API Referenseには以下のように書いてあり、そもそもStripeのアカウントリンクで入力した情報を取得することはできなかった

プラットフォームは、アカウントのアカウントリンクを生成した後など、アカウントがオンボーディングを開始した後に、StandardまたはExpressアカウントの人物にアクセスすることはできません。

Stripe API Reference - Persons

WebhookでPersonオブジェクトを取得できるか

StripeのWebhookでperson.updated イベントを監視できるので、ユーザーがアカウント情報を入力したときのWebhookであればPersonオブジェクトを取得できるのか確認します。

API を利用した確認処理 | Stripe のドキュメント

StripeではStripe CLIを使うことでWebhookのテストをすることができます。

homebrew で Stripe CLI をインストールするには、以下を実行します。

brew install stripe/stripe-cli/stripe

Stripeにログインをする

stripe login

Stripe CLI を使ってみる | Stripe のドキュメント

Webhook エンドポイントビルダーでWebhookエンドポイントを作成する

const stripe = require('stripe')('***');

const endpointSecret = '***';
const express = require('express');
const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
  let event = request.body;
  // Only verify the event if you have an endpoint secret defined.
  // Otherwise use the basic event deserialized with JSON.parse
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = request.headers['stripe-signature'];
    try {
      event = stripe.webhooks.constructEvent(
        request.body,
        signature,
        endpointSecret
      );
    } catch (err) {
      console.log(`⚠️  Webhook signature verification failed.`, err.message);
      return response.sendStatus(400);
    }
  }

  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log(`PaymentIntent for ${paymentIntent.amount} was successful!`);
      // Then define and call a method to handle the successful payment intent.
      // handlePaymentIntentSucceeded(paymentIntent);
      break;
    case 'payment_method.attached':
      const paymentMethod = event.data.object;
      // Then define and call a method to handle the successful attachment of a PaymentMethod.
      // handlePaymentMethodAttached(paymentMethod);
      break;
    default:
      // Unexpected event type
      console.log(`Unhandled event type ${event.type}.`);
  }

  // Return a 200 response to acknowledge receipt of the event
  response.send();
});

app.listen(8080, () => console.log('Running on port 8080'));

Stripe CLI で Webhook の組み込みをテストする | Stripe のドキュメント

-forward-to フラグを使用して、テスト環境のすべての Stripe イベントをローカルの Webhook エンドポイントに送信する。

stripe listen --forward-to localhost:8000/webhook

アカウントリンクで情報を入力してWebhookで取得できる情報の中身を見ると以下のようになります。入力した情報を取得することはできませんでした。

{
  id: '****',
  object: 'event',
  account: '****',
  api_version: '2020-03-02',
  created: 1675639014,
  data: {
    object: {
      id: 'transfers',
      object: 'capability',
      account: '****',
      future_requirements: [Object],
      requested: true,
      requested_at: 1675638907,
      requirements: [Object],
      status: 'inactive'
    },
    previous_attributes: { requirements: [Object] }
  },
  livemode: false,
  pending_webhooks: 2,
  request: {
    id: '****',
    idempotency_key: '****'
  },
  type: 'capability.updated'
}

このWebhookはrequirementsハッシュで顧客確認 (KYC) のためのユーザーに関する必要な情報が揃っているかを確認し、必要に応じて、追加情報をユーザに問い合わせるために使うみたいです。

Stripeに登録する情報をDBに保存する

結論、Stripeに登録する情報をDBに保存する場合は、アカウントリンクを生成する前に行う必要がありました。具体的にはStripeアカウントを作成するタイミングです。

Stripe API reference – Accounts – Node

Stripeアカウントを作成する際は、以下のように記述していましたが、

const account = await stripe.accounts.create({
  country: 'JP',
  type: 'express',
  capabilities: {
    transfers: { requested: true },
  },
});

createメソッドの引数で必要な確認情報を含めることができます。createメソッドに含めた内容は、アカウントリンクでは自動入力されるためユーザーは同じ内容を登録する必要はありません。

const account = await stripe.accounts.create({
  country: 'JP',
  type: 'express',
  capabilities: {
    transfers: { requested: true },
  },
  business_type: 'company',
  company: {
    name: 'てすと',
    name_kana: 'テスト',
    name_kanji: 'てすと',
});

なので、アカウントリンクを生成する前のStripeアカウントを作成するタイミングでDBにユーザー情報を保存しておけば良いことになります。

Stripeアカウント作成に必要な情報はこちらで確認できます。

必要な確認情報 | Stripe のドキュメント

Discussion