我正在向我们的网络应用程序添加会员资格,并正在测试不同的卡是否能够处理错误。我注意到,在使用他们的一张测试卡(例如通用拒绝测试卡)从 stripe 收到错误拒绝响应后,我无法重新提交他们卡信息所在的表单,似乎 JS 停止运行,因为它甚至没有不再触发按钮元素上的点击事件。
相关代码如下:
支付元素加载到的刀片文件:
<!DOCTYPE html>
<html>
<head>
@include('layouts.redesign.head')
<script src="https://js.stripe.com/v3/"></script>
<style>
#overlay {
position: fixed;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
display: none;
background: rgba(0, 0, 0, 0.6);
}
.cv-spinner {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.spinner {
width: 40px;
height: 40px;
border: 4px #ddd solid;
border-top: 4px #2e93e6 solid;
border-radius: 50%;
animation: sp-anime 0.8s infinite linear;
}
@keyframes sp-anime {
100% {
transform: rotate(360deg);
}
}
.is-hide {
display: none;
}
</style>
</head>
<body class="mad-body--scheme-brown">
<div id="mad-page-wrapper" class="mad-page-wrapper">
@include('layouts.redesign.header')
<!--================ Page Title ================-->
<div class="mad-breadcrumb with-bg-img with-overlay light bg-alignright"
data-bg-image-src="{{asset('/images/banner-service-consultations.jpg')}}">
<div class="container wide">
<h1 class="mad-page-title">Sign up</h1>
</div>
</div>
<div class="container my-3">
<form method="GET" id="signupForm" class="mad-contact-form mad-form type-2 item-col-1 m-auto"
style="max-width: 500px">
<div class="mad-form-item">
<label for="email">Name:</label>
<input type="text" id="name" name="name" required placeholder="Name"/>
</div>
<div class="mad-form-item">
<label for="email">Email:</label>
<input type="text" id="email" name="email" required placeholder="Email"/>
</div>
<div class="mad-form-item">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required placeholder="Password"/>
</div>
<div class="mad-form-item">
<label for="password_confirmation">Confirm Password:</label>
<input type="password" id="password_confirmation" name="password_confirmation" required
placeholder="Confirm Password"/>
</div>
<div class="mad-col full-width">
<div class="mad-row full-width row">
<span id="errors"></span>
<div class="mad-form-item align-center">
<button type="submit" class="btn btn-big g-recaptcha create_user"
>{{__('contact_form.submit')}}
</button>
</div>
</div>
</div>
</form>
<div class="stripe_lmnts mad-contact-form mad-form type-2 item-col-1 m-auto"
style="display: none; max-width: 500px">
<!-- Stripe Elements Placeholder -->
<div id="payment-element"></div>
<button id="card-button" class="btn btn-primary py-3" data-secret="{{$client_secret}}">
Sign up
</button>
</div>
</div>
<div id="overlay">
<div class="cv-spinner">
<span class="spinner"></span>
</div>
</div>
<script>
$(document).ready(function () {
let user_id;
$('.create_user').on('click', function (e) {
e.preventDefault()
$.ajax({
url: '{{route('create_user')}}',
type: 'GET',
data: {
name: $('input[name="name"]').val(),
email: $('input[name="email"]').val(),
password: $('input[name="password"]').val(),
password_confirmation: $('input[name="password_confirmation"]').val(),
},
success: function (data) {
let response = JSON.parse(data)
if (!response.error) {
user_id = response.user_id
$('.stripe_lmnts').css('display', 'block')
$('#signupForm').css('display', 'none')
} else {
$('#errors').html(response.message)
if (response.for === 'email') {
$('input[name="email"]').css('border-color', '#dc3545')
}
if (response.for === 'password') {
$('input[name="password"]').css('border-color', '#dc3545')
$('input[name="password_confirmation"]').css('border-color', '#dc3545')
}
}
}
})
})
const stripe = Stripe('{{env('STRIPE_KEY')}}');
const cardButton = $('#card-button');
const clientSecret = cardButton.data('secret');
const options = {layout: 'accordion', /* options */};
const appearance = {
theme: 'flat',
variables: {colorPrimaryText: '#262626'}
};
const elements = stripe.elements({clientSecret, appearance});
const paymentElement = elements.create('payment', options);
paymentElement.mount('#payment-element');
cardButton.on('click', function () {
$(this).prop('disabled', true)
$(this).addClass('btn-secondary')
$(this).removeClass('btn-primary')
$("#overlay").fadeIn(300);
stripe.confirmSetup({
elements,
confirmParams: {
// Return URL where the customer should be redirected after the PaymentIntent is confirmed.
return_url: `http://localhost:8080/create-subscription?user_id=${user_id}`,
},
})
.then(function (result) {
if (result.error) {
$(this).prop('disabled', false)
$(this).removeClass('btn-secondary')
$(this).addClass('btn-primary')
$("#overlay").fadeOut(300);
}
});
})
})
</script>
</div>
@include('layouts.redesign.footer')
</body>
</html>
我建议您重点调试
then
之后的错误处理 confirmSetup
块:
.then(function (result) {
if (result.error) {
$(this).prop('disabled', false)
$(this).removeClass('btn-secondary')
$(this).addClass('btn-primary')
$("#overlay").fadeOut(300);
}
});
您也可以在调用
confirmSubmit
之前删除该处理来验证是否从您自己的覆盖/禁用中验证此操作。评论出来:
$(this).prop('disabled', true)
$(this).addClass('btn-secondary')
$(this).removeClass('btn-primary')
$("#overlay").fadeIn(300);