Stripe: Как добавить и сохранить дополнительные элементы формы с javascript? - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь сохранить данные из дополнительных входов в форме, а не только данные кредитной карты.

Вот как выглядит форма: изображение формы

Оплата работает, и бронирование сохраняется в базе данных. Я изо всех сил пытаюсь выяснить, как также получить дополнительные входные данные формы "ссылку на ваш проект" и "дополнительную информацию", которые также хранятся в БД.

Вот что код любит на сервере:

router.route('/pay')
 .post(async (req, res, next) => {
   let artist = req.session.artist;
   let price = req.session.price;
   let user = req.session.user;
   let email = req.session.userEmail;

   price *= 100;

   const {
     paymentMethodId,
     paymentIntentId,
     currency,
     useStripeSdk
   } = req.body;

   try {
     let intent;
     if (paymentMethodId) {
       // Create new PaymentIntent with a PaymentMethod ID from the client.
       intent = await stripe.paymentIntents.create({
         amount: price,
         currency: currency,
         receipt_email: email,
         payment_method: paymentMethodId,
         confirmation_method: 'manual',
         confirm: true,
         // If a mobile client passes `useStripeSdk`, set `use_stripe_sdk=true`
         // to take advantage of new authentication features in mobile SDKs
         use_stripe_sdk: useStripeSdk
       });
       // After create, if the PaymentIntent's status is succeeded, fulfill the order.
     } else if (paymentIntentId) {
       // Confirm the PaymentIntent to finalize payment after handling a required action
       // on the client.
       intent = await stripe.paymentIntents.confirm(paymentIntentId);
       // After confirm, if the PaymentIntent's status is succeeded, fulfill the order.
     }

     let newBooking = await Booking.create({
       artist,
       user,
       price,
       projectLink: req.body.projectLink,
       additionalInfo: req.body.additionalInfo
     });
     console.log(newBooking)

     let data = {
       intent: generateResponse(intent)
     };

     res.send(data);
   } catch (e) {
     // Handle "hard declines" e.g. insufficient funds, expired card, etc
     // See https://stripe.com/docs/declines/codes for more
     res.send({
       error: e.message
     });
   }
 });

А вот как это выглядит на клиенте:

var stripe = Stripe('pk_test_ycz...');
// A reference to Stripe.js
var stripe;

var orderData = {
  items: [{
    id: "photo-subscription"
  }],
  currency: "usd"
};

// Disable the button until we have Stripe set up on the page
document.querySelector(".disable").disabled = true;

fetch("/stripe-key")
  .then(function (result) {
    return result.json();
  })
  .then(function (data) {
    return setupElements(data);

  })
  .then(function ({
    stripe,
    card,
    clientSecret
  }) {
    document.querySelector(".disable").disabled = false;
    var form = document.getElementById("payment-form");
    form.addEventListener("submit", function (event) {
      event.preventDefault();
      const projectLink = document.getElementById('projectLink').value;
      const additionalInfo = document.getElementById('additionalInfo').value;

      pay(stripe, card, clientSecret, projectLink, additionalInfo);
      console.log(projectLink, additionalInfo)


    });
  });

var setupElements = function (data) {
  stripe = Stripe(data.publishableKey);
  /* ------- Set up Stripe Elements to use in checkout form ------- */
  var elements = stripe.elements();
  var style = {
    base: {
      color: "#32325d",
      fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
      fontSmoothing: "antialiased",
      fontSize: "16px",
      "::placeholder": {
        color: "#aab7c4"
      }
    },
    invalid: {
      color: "#fa755a",
      iconColor: "#fa755a"
    }
  };

  var card = elements.create("card", {
    style: style
  });
  card.mount("#card-element");

  return {
    stripe: stripe,
    card: card,
    clientSecret: data.clientSecret
  };
};

var handleAction = function (clientSecret, projectLink, additionalInfo) {
  stripe.handleCardAction(clientSecret).then(function (data) {
    if (data.error) {
      showError("Your card was not authenticated, please try again");
    } else if (data.paymentIntent.status === "requires_confirmation") {
      fetch("/pay", {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            paymentIntentId: data.paymentIntent.id
          })

        })
        .then(function (result) {
          return result.json();
        })
        .then(function (json) {
          if (json.error) {
            showError(json.error);
          } else {
            orderComplete(clientSecret);
          }
        });
    }

  });
};

/*
 * Collect card details and pay for the order
 */
var pay = function (stripe, card) {
  changeLoadingState(true);

  // Collects card details and creates a PaymentMethod
  stripe
    .createPaymentMethod("card", card)
    .then(function (result) {
      if (result.error) {
        showError(result.error.message);
      } else {
        orderData.paymentMethodId = result.paymentMethod.id;


        return fetch("/pay", {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify(orderData)
        });
      }
    })
    .then(function (result) {
      return result.json();

    })
    .then(function (response) {
      if (response.intent.error) {
        showError(response.intent.error);
      } else if (response.intent.requiresAction) {
        // Request authentication
        handleAction(response.intent.clientSecret);
      } else {
        orderComplete(response.intent.clientSecret);
      }
    });
};





На стороне сервера я использовал req.body для обоих входов в Booking.create (... ) но я не уверен, как получить это от клиента, используя код Stripe. На стороне клиента я пытался добавить данные формы в вызов API fetch для / pay, но не мог понять, как заставить его работать. Если у кого-то есть идеи, это было бы здорово. Спасибо

1 Ответ

0 голосов
/ 20 апреля 2020

Вы не передаете дополнительную информацию, которую хотите, как часть body из fetch("/pay"), то есть как она будет поступать на серверную часть. Вы должны добавить их в качестве аргументов в свою pay() функцию на стороне клиента, а затем передать их в теле этого fetch запроса.

...