Элемент Stripe JS card не разрешает пользовательский ввод в Flask

#javascript #stripe-payments

#javascript #stripe-платежи

Вопрос:

Я использовал пример элемента Stripe 1, найденный здесь:https://jsfiddle.net/ywain/2qyamjga для тестирования элементов Stripe с помощью Flask. В моем приложении поля имени и номера телефона разрешают пользовательский ввод, а поле card — нет.

Вот мой код для функции views:

 @billing.route('/charge', methods=['GET', 'POST'])
def charge():
    if request.method == 'POST':
        customer = stripe.Customer.create(
            email='customer@example.com',
            source=request.form['stripeToken']
        )

        charge = stripe.Charge.create(
            customer=customer.id,
            amount=request.form['amountInCents'],
            currency='usd',
            description='Flask Charge'
        )
    return render_template('billing/charge.html')
  

После просмотра веб-консоли я получаю эту ошибку:

Error: The selector you specified (#card-element) applies to no DOM elements that are currently on the page.
Make sure the element exists on the page before calling mount().

Как бы мне это сделать? Любые предложения будут высоко оценены. Исходный код stripe можно найти здесь:https://github.com/stripe/elements-examples/#example-1

Ответ №1:

После отладки я обнаружил, что ошибка заключалась в том, что мой Javascript был до html. Javascript должен быть размещен под html для корректной работы полей формы:

 <script src="https://js.stripe.com/v3/"></script>
<body>
  <form>
    <div class="group">
      <label>
        <span>Name</span>
        <input name="cardholder-name" class="field" placeholder="Jane Doe" />
      </label>
      <label>
        <span>Phone</span>
        <input class="field" placeholder="(123) 456-7890" type="tel" />
      </label>
    </div>
    <div class="group">
      <label>
        <span>Card</span>
        <div id="card-element" class="field"></div>
      </label>
    </div>
    <button type="submit">Pay $25</button>
    <div class="outcome">
      <div class="error"></div>
      <div class="success">
        Success! Your Stripe token is <span class="token"></span>
      </div>
    </div>
  </form>
</body>

<script>
var stripe = Stripe('pk_test_XXXXXXXXXXXXXXXX');
var elements = stripe.elements();

// Custom styling can be passed to options when creating an Element.
var style = {
  base: {
    // Add your base input styles here. For example:
    fontSize: '16px',
    color: "#32325d",
  }
};

var card = elements.create('card', {
  style: {
    base: {
      iconColor: '#666EE8',
      color: '#31325F',
      lineHeight: '40px',
      fontWeight: 300,
      fontFamily: 'Helvetica Neue',
      fontSize: '15px',

      '::placeholder': {
        color: '#CFD7E0',
      },
    },
  }
});
card.mount('#card-element');

function setOutcome(result) {
  var successElement = document.querySelector('.success');
  var errorElement = document.querySelector('.error');
  successElement.classList.remove('visible');
  errorElement.classList.remove('visible');

  if (result.token) {
    // Use the token to create a charge or a customer
    // https://stripe.com/docs/charges
    successElement.querySelector('.token').textContent = result.token.id;
    successElement.classList.add('visible');
  } else if (result.error) {
    errorElement.textContent = result.error.message;
    errorElement.classList.add('visible');
  }
}

card.on('change', function(event) {
  setOutcome(event);
});

document.querySelector('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var form = document.querySelector('form');
  var extraDetails = {
    name: form.querySelector('input[name=cardholder-name]').value,
  };
  stripe.createToken(card, extraDetails).then(setOutcome);
});

</script>