Stripe: Можно ли создать прямую зарядку с идемпотентностью

Я пытаюсь напрямую списать средства с учетной записи, подключенной к полосе, и могу сделать это с помощью следующих

const charge = {
  amount,
  currency,
  source} ;

return stripe.charges.create(
  charge ,
  {stripe_account: stripeVendorAccount});

Вопрос: есть ли способ включить параметр идемпотентности в объект заряда? Если нет, как лучше всего избежать дублирования платежей?

Я пробовал это, но это не работает

const charge = {
  amount,
  currency,
  source} ;

return stripe.charges.create(
  charge ,
  {stripe_account: stripeVendorAccount},
  {idempotency_key });

ИЗМЕНИТЬ: это моя функция

exports.stripeCharge = functions.database
                                .ref('/payments/{userId}/{paymentId}')
                                .onWrite( (change,context) => {
const payment = change.after.val();
const userId = context.params.userId;
const paymentId = context.params.paymentId;
const stripeVendorAccount = 'xx'
// checks if payment exists or if it has already been charged
if (!payment || payment.charge) return;
return admin.database()
              .ref(`/users/${userId}`)
              .once('value')
              .then(snapshot => {
return snapshot.val();
               })
               .then(async customer => {
const amount = payment.amount;
const idempotency_key = paymentId;  // prevent duplicate charges
const source = payment.token.id;
const currency = payment.currency;
const application_fee = payment.application_fee;
const description = payment.description;



//-------- destination charges
// const transfer_data = {destination: stripeVendorAccount};
// const charge = {
//   amount,
//   currency,
//   description,
//   transfer_data,
//   source};
// return stripe.charges.create(charge , { idempotency_key });
//                })
//                .then(charge => {
// admin.database()
//                         .ref(`/payments/${userId}/${paymentId}/charge`)
//                         .set(charge);
//                         return true;
//                   })
//-------- destination charges

//-------- DIRECT charges
const charge = {
  amount,
  currency,
  description,
  application_fee,
  source} ;

return stripe.charges.create(charge ,{stripe_account: stripeVendorAccount});
               })
               .then(charge => {
admin.database()
                        .ref(`/payments/${userId}/${paymentId}/charge`)
                        .set(charge);
                        return true;
                  })

});

person mactrix    schedule 03.11.2019    source источник


Ответы (1)


Что ж, я предполагаю, что создание заряда не идемпотентно по определению, поскольку заряд обычно связан с одной покупкой. (Если пользователь инициирует покупку одного и того же товара три раза подряд, это приведет к трем различным заказам / расходам). Я не знаю вашей текущей реализации бизнес-логики, лежащей в основе вашей интеграции с электронной коммерцией. Но если вы просто хотите избежать создания нескольких списаний для одного заказа, вам следует идентифицировать свои заказы с помощью уникального идентификатора и сохранять его в базе данных. В вашем методе начисления запросите из базы данных, если уже есть плата за эту покупку, если не создайте ее.

person widdy    schedule 03.11.2019
comment
Я просто хотел бы избежать того, чтобы несколько запросов POST к этим ресурсам не повлияли на результат - другими словами, чтобы предотвратить дублирование списаний с карты. Я разместил свой код, где вы можете видеть, что я передаю paymentId как объект идемпотентности в случае платы за назначение, однако я не могу сделать то же самое для прямых сборов, поскольку плата принимает только один объект option, и я должен передать stripeId - person mactrix; 05.11.2019