Решено — Полосатый Клонирует клиента и Создает Прямую плату за Подключенный аккаунт

#node.js #stripe-payments

Вопрос:

Я пытаюсь создать прямую плату за подключенную учетную запись в 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,
});
 

Ответ №1:

Похоже, вы пытаетесь клонировать Способ оплаты в своей учетной записи платформы на токен в подключенной учетной записи. Это невозможно; Способы оплаты-это более новый API Stripe, который напрямую не совместим с токенами (более старый API).

Вместо этого вы должны клонировать способ оплаты на платформе в Способ оплаты на подключенной учетной записи, используя код, подобный этому:

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

Комментарии:

1. Спасибо! Я подходил к нему с клиентом платформы, у которого не было способа оплаты, и сохранял/прикреплял его во время процесса намерения платежа, а затем пытался клонировать его. Поскольку я загружаю интерфейс stripe js на странице, используя идентификатор подключенной учетной записи, я не могу подтвердить новый способ оплаты в своем намерении настройки. Как только я создал способ оплаты в учетной записи клиента платформы и начал оттуда, все работало, как указано в моем ответе выше. Мне просто нужно будет создать отдельный рабочий процесс для добавления способа оплаты до того, как пользователь выпишется.

Ответ №2:

Я смог решить эту проблему, сначала убедившись, что на платформе существует способ оплаты для пользователя. Затем в моем намерении оплаты следующее успешно клонирует клиента и способ оплаты и успешно взимает плату:

 // 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 }
    );