条带化克隆客户并在关联帐户上创建直接费用

dldeef67  于 2022-11-03  发布在  Node.js
关注(0)|答案(2)|浏览(190)

我试图在Stripe中的一个连接帐户上创建直接收费。我一直在查看Stripe上的文档和这里的帖子,但似乎无法让它工作。
客户及其支付方式存储在平台账户中。我尝试在关联账户中复制客户,但不想在关联账户中存储其支付方式。根据文档,我可以生成一次性支付意向,但不将其附加到我尝试在关联账户中创建的客户。
在尝试克隆客户时,我收到错误:
StripeInvalidRequestError: The customer must have an active payment source attached.
在下面的代码中,我将确保支付方式与平台客户关联,当我转到控制台时,我会看到他们的支付方式,它被标记为“默认”。
感谢您的帮助!

const customerId = 'cus_xxx'; // platform customer id
const paymentMethod = 'pm_xxxx'; // platform customer payment method

const getDefaultCard = async (customer) => {
  const { invoice_settings } = await stripe.customers.retrieve(customer);
  return invoice_settings ? invoice_settings.default_payment_method : null;
};

const getCards = async (customer) => {
  if (!customer) {
    return [];
  }
  const default_card = await getDefaultCard(customer);
  const { data } = await Stripe.stripe.paymentMethods.list({
    customer,
    type: "card",
  });
  if (!data) return [];
  return data.map(({ id, card: { last4, exp_month, exp_year, brand } }) => ({
    id,
    last4,
    exp_month,
    exp_year,
    brand,
    default: id === default_card,
  }));
};

// check to see if the current payment method is 
// attached to the platform customer
const cards = await getCards(customerId);

let found = cards.filter((card) => card.id === paymentMethod).length > 0;

// if the card is not found, attach it to the platform customer
if (!found) {
  const res = await Stripe.stripe.paymentMethods.attach(paymentMethod, {
    customer: customerId,
  });
}

const defaultCards = cards.filter((card) => card.default);

if (!defaultCards || !defaultCards.length) {
  // attach a default payment source to the user before
  // cloning to the connected account
  await stripe.customers.update(user.cus_id, {
    invoice_settings: {
      default_payment_method: paymentMethod,
    },
  });
}

// Get customer token - Results in ERROR
const token = await stripe.tokens.create(
  {
    customer: customerId,
    card: paymentMethod,
  },
  {
    stripeAccount,
  }
);

/**DOESN'T GET PAST TOKEN CREATION ABOVE**/

// clone customer
const newCustomer = await stripe.customers.create(
  {
    source: token.id,
    card: paymentMethod,
  },
  {
    stripeAccount,
  }
);

const amount = 1000;
const application_fee_amount = 100;

const intent = await Stripe.stripe.paymentIntents.create(
  {
    customer: newCustomer.id,
    amount,
    currency: "usd",
    payment_method_types: ["card"],
    payment_method: paymentMethod,
    description: "Test Connected Direct Charge",
    application_fee_amount,
  },
  {
    stripeAccount,
  }
);

// Now confirm payment
const result = await Stripe.stripe.paymentIntents.confirm(intent.id, {
  payment_method: paymentMethod,
});
9avjhtql

9avjhtql1#

您似乎正在尝试将平台帐户上的支付方式克隆到已连接帐户上的令牌。这是不可能的;支付方法是一个较新的Stripe API,它与令牌(旧的API)不直接兼容。
您应该将平台上的付款方式克隆为关联账户上的付款方式,而不是使用如下代码:

const paymentMethod = await stripe.paymentMethods.create({
  customer: '{{CUSTOMER_ID}}',
  payment_method: '{{PAYMENT_METHOD_ID}}',
}, {
  stripeAccount: '{{CONNECTED_ACCOUNT_ID}}',
});
qpgpyjmq

qpgpyjmq2#

我能够解决这个问题,首先确保用户的支付方式存在于平台上。然后在我的支付意图如下成功克隆客户和支付方式,并成功收费:

// clone payment method
const cloned_pm = await stripe.paymentMethods.create({
        customer,         // platform customer id
        payment_method,   // platform payment method for platform customer
      },{
        stripeAccount
      });

// create token to customer
const token = await stripe.tokens.create({
          customer,              // platform customer id
          card: payment_method,  // platform payment method as above
      },{
          stripeAccount
      });

// clone customer
const newCustomer = await stripe.customers.create({
          source: token.id,
      },{
          stripeAccount
      });

// create intent - used the cloned customer and payment methods
const intent = await stripe.paymentIntents.create(
        {
          customer: newCustomer.id,
          amount: 1000,
          application_fee_amount: 100,
          currency: "usd",
          payment_method_types: ["card"],
          payment_method: cloned_pm.id,    
          ...         
        },
        {
          stripeAccount,
        }
      );

然后在前端客户端上:

const { error, paymentIntent } = await stripe.confirmCardPayment(
      payment_intent_secret,
      { payment_method: cloned_payment_method_id }
    );

相关问题