web-dev-qa-db-ja.com

ストライプアカウントを接続する金額を転送できません

BackGround:

私がやろうとしていることは、顧客が売り手のサービスを取得できる市場を設定することです。正確には、プロジェクトはMERNスタックトラベルアプリケーションです。私が望むのは、顧客がホテルの部屋などのサービスを取得したいときに、プラットフォーム(Stripeに接続された私のウェブサイト)を支払うことです。顧客は割り当てられた時間ホテルに滞在し、チェックアウト時にプラットフォームは顧客の一部をアプリケーション料金として保持し、残りをサービスプロバイダー(この場合はホテル)に転送します。

現在の努力:

必要な機能を実現するためにSTRIPE CONNECTを使用しました。

Note:下のコードをすべて見る必要はありません。見出しと説明だけで、私がやったことと私が尋ねようとしていることがわかりますが、 issueセクション)

彼が私のウェブサイトにサインアップするときに、売り手のためにConnect accountを作成します

接続アカウントの作成

const express = require("express");
const router = express.Router();
  router.post("/createAccount", async (req, res) => {
  const { name, email } = req.body; //Data Passed from the FrontEnd
  stripe.accounts.create(
    {
      type: "custom",
      country: "US",
      email: email,
      requested_capabilities: ["card_payments", "transfers"],
    },
    function (err, account) {
      res.json({ account: account });
    }
  );
});

Seller Portalにログインした後、売り手が残りの必要な詳細(銀行口座を含む)を提供する場合、bank_accountを作成し、すでに作成済みのConnect Accountを更新して、bank_accountConnect Account(うまくいけば、それは何とか理にかなっています)

銀行口座の作成

  router.post("/createBankAccount", async (req, res) => {
  const { account_holder_name, routing_number, account_number } = req.body;
  stripe.tokens.create(
    {
      bank_account: {
        country: "US",
        currency: "USD",
        account_holder_name,
        account_holder_type: "individual",
        routing_number,
        account_number,
      },
    },
    function (err, token) {
      res.send(token);
    }
  );
});

アカウントの更新:

  router.post("/updateAccount", async (req, res) => {
      const {
        AccountID,
        Day,
        Month,
        Year,
        first_name,
        last_name,
        email,
        BankAccountID,
      } = req.body;

      const FrontFilePath = fs.readFileSync("PathToFileHere");
      const FrontPhotoIDUpload = await stripe.files.create({
        file: {
          data: FrontFilePath,
          name: "FrontPhotoID.jpg",
          type: "application.octet-stream",
        },
        purpose: "identity_document",
      });

      const BackFilePath = fs.readFileSync("PathToFileHere");
      const BackPhotoIDUpload = await stripe.files.create({
        file: {
          data: BackFilePath,
          name: "BackPhotoID.jpg",
          type: "application.octet-stream",
        },
        purpose: "identity_document",
      });

      stripe.accounts.update(
        AccountID,
        {
          business_type: "individual",
          individual: {
            dob: { day: Day, month: Month, year: Year },
            first_name: first_name,
            last_name: last_name,
            id_number: "006-20-8311",
            phone: "605-628-6049",
            address: {
              city: "Half Way",
              line1: "2467  Twin House Lane",
              postal_code: "65663",
              state: "MO",
            },
            email,
            ssn_last_4: "8311",
            verification: {
              document: {
                front: FrontPhotoIDUpload.id,
                back: BackPhotoIDUpload.id,
              },
            },
          },
          business_profile: {
            mcc: "4722",
            url: "http://www.baoisne.com",
          },
          tos_acceptance: {
            date: Math.floor(Date.now() / 1000),
            ip: req.connection.remoteAddress, 
          },
        },
        function (err, account) {
          console.log(err);
          console.log(account);
        }
      );
     //Connect External Account
      stripe.accounts.createExternalAccount(
        AccountID,
        {
          external_account: BankAccountID,
        },
        function (err, bankAccount) {
          console.log(err);
          res.send(bankAccount);
        }
      );
    });

次に、顧客がアカウントの詳細を提供すると、私は顧客に請求し、いくらかのお金をアプリケーション料金として保管し、残りをService Providers Connectアカウントに移動します。

顧客の請求

  router.post("/charge", async (req, res) => {
  const { TokenID, CustomerID, Amount, AccountID } = req.body;
  let PaymentAmount = Amount * 100;
  let application_fee_amount = 400;
  try {
    const payment = await stripe.paymentIntents.create({
      amount: PaymentAmount,
      currency: "USD",
      description: "We did it boss",
      payment_method_data: {
        type: "card",
        card: {
          token: TokenID,
        },
      },
      receipt_email: "[email protected]",
      customer: CustomerID,
      application_fee_amount,
      transfer_data: {
      destination: AccountID,
      },
      confirm: true,
    });
    return res.status(200).json({
      confirm: "Payment Succeeded",
    });
  } catch (error) {
    console.log(error);
    return res.status(400).json({
      message: error.message,
    });
  }
});

上記の手順を実行すると、接続アカウントが作成され、金額が接続アカウントに移動します。

問題

上記の手順は正しく機能しますが、顧客に請求された直後に接続サービスプロバイダーアカウントに金額を移動します。私が望むのは、顧客がプラットフォームに支払い、サービスプロバイダーがサービスを提供した後、プラットフォームが支払います。サービスプロバイダー、削除を考えた

  application_fee_amount,
  transfer_data: {
  destination: AccountID,
  }

ChargeまたはStripe.paymentIntents.createエンドポイントの上記のパラメーター、およびサービスプロバイダーがサービスを完了した後、Stripe Transfer APIを使用して金額を転送します

router.post("/transfer", async (req, res) => {
  try {
    console.log("TRANSFER=");
    const { AccountID, amount } = req.body;
    const transfer = await stripe.transfers.create({
      amount,
      currency: "USD",
      destination: AccountID,
    });
    res.send(transfer);
  } catch (error) {
    res.send(error);
  }
});

ここでの問題は、転送エンドポイントが「」を返すことです。転送先アカウントでは、次の機能の少なくとも1つを有効にする必要があります:transfers、legacy_payments "、私はチェックしましたストライプダッシュボードと機能セクションの接続されたアカウントCard_PaymentTransfersはどちらもアクティブに設定されており、支払いと支払いはどちらも有効になっており、接続アカウントのステータスは「完了」です

だから誰かが正しい方向に向けることができれば私はそれを本当に感謝します、乾杯:)

4
Abdullah Abid

以下を含むWebhook(Stripe config)を作成します。

  • Webhookに送信されたイベント:この場合はcustomer.createdcustomer.source.createdcustomer.source.updated
  • URL =イベントが到着したときに処理するルート

したがって、まず保留中の支払いをDBに保存する必要があります。次に、WebhookでDBからそれを見つけて、転送を完了します。

0
Miro Lehtonen