Stripe.js支付只对某些客户不起作用



我有一个php (Laravel 7)网站,使用Stripe.js接受信用卡支付。集成通常工作得很好,但有时,我有一些客户,他们无法付款。没有错误信息,我从客户那里知道的都是这样的:

我输入了信用卡的详细信息,点击了"支付"。然后是空白区域,什么都没有…">

在stripe后端,我看到付款状态为payment "Incomplete"客户"未输入其付款方式。我认为这意味着客户来到了付款页面,但由于某种原因没有(无法?)完成付款。

请参阅下面的一些代码摘录。第一个代码展示了如何在加载支付页面时创建支付意图。第二个显示支付表单和js代码进行支付。我的怀疑是,不知何故,js代码打破了一些客户…

知道为什么这对某些客户不起作用,或者我如何调试根本原因吗?

谢谢,w .


GNGBookingController.php:

function show_step4($id){
// Create and send payment intent
StripeStripe::setApiKey(env('STRIPE_SECRET'));
$idstr =  '[T#' . sprintf('%04d', $tour->id) . ']';
try{
$intent = StripePaymentIntent::create([
'amount' => round($tour->fees->plat_fee * 100),
'currency' => 'eur',
'payment_method_types' => ['card'],
'description' => $idstr, 
]);
}
catch(Exception $e) {
GNGLogger::qlog('Failed to create payment intent. ' . $e->getFile() . ' ' .  $e->getLine() . $e->getMessage(), GNGLogType::Error);
redirect(route('office.' . app::getLocale() . '.crash.show'));
}
return view('backoffice.booking.ver2.show-step4', [
'tour' => $tour, 
'clientSecret' => $intent->client_secret, 
'date' => $date, 
'time' => $time, 
]);
}

show-step4.blade.php:

@extends('backoffice.layouts.guest')

@section('content')
<script src="https://js.stripe.com/v3/"></script>
<div class="row">
<div class="col-sm-1 col-md-2 col-lg-3 col-xl-4">

</div>
<div class="col">
<h3>{{__('Advance Payment')}}</h3>
<form id="payment-form" method="post" data-secret="{{$clientSecret}}">
<input type="hidden" name="token" />
<div id="payment-form-holder" class="my-4 p-3 border rounded shadow" style="background-color: lightgrey">
@csrf
<div class="form-group">
<input type="hidden" class="form-control" name="ID" id="ID" value="{{$tour->id}}">
</div>
<div class="form-group">
<label>{{__('Card Number')}}</label><br>
<div id="card-number">
</div>
</div>
<div class="form-row">
<div class='col'>
<div class="form-group">
<label>{{__('Expiry Date')}}</label><br>
<div id="card-expiry">
</div>
</div>
</div>
<div class='col'>
<label>{{__('Security Code')}}</label><br>
<div class="form-group">
<div id="card-cvc">
</div>
</div>   
</div>
</div>
<!-- We'll put the error messages in this element -->
<div id="card-errors" role="alert"></div>
<div class="form-row my-3" style="flex-wrap: nowrap">
<div class="spinner-border text-danger" id="spinner" role="status" style="display: none;">
</div>
<div id="spinner-text" class="mx-2" style="display: none;">
{{__('Please wait. This can take up to a minute...')}}
</div>
</div>
<p id="card-error" role="alert"></p>
<p id="result-message" class="result-message" style="display: none;">
{{__('Payment succeeded!')}}  
</p>
<div class="form-row">
<input type="submit" id="pay" name="pay" class="btn btn-primary gng-action-button mr-3 mb-3" style="min-width: 100%" value="{{__('Pay :platFee €', ['platFee' => $tour->fees->plat_fee])}}" >
</div>
</div>

<input type="submit" id="back" name="back" class="btn btn-secondary gng-action-button mr-3 mb-3" value="{{__('Back')}}" >
</form>

</div>
<div class="col-sm-1 col-md-2 col-lg-3 col-xl-4">

</div>
</div>
@endsection
@section('scripts')
<script>
// Create a Stripe client
var stripe = Stripe('{{env('STRIPE_KEY')}}');
// Set up Stripe.js and Elements to use in checkout form
var elements = stripe.elements();
var style = {
base: {
color: "#32325d",
fontSize: "18px",
}
};
var classes = {
base: 'form-control', 
};

var cardNumberElement = elements.create('cardNumber', {
style: style, 
classes: classes, 
});
cardNumberElement.mount('#card-number');
var cardExpiryElement = elements.create('cardExpiry', {
style: style, 
classes: classes,
});
cardExpiryElement.mount('#card-expiry');
var cardCvcElement = elements.create('cardCvc', {
style: style, 
classes: classes,
});
cardCvcElement.mount('#card-cvc');
document.querySelector('#payment-form').addEventListener('submit', function(e) {
if (e.submitter.name == 'pay') {
e.preventDefault();
loading(true);
stripe
.confirmCardPayment('{{$clientSecret}}', {
payment_method: {
card: cardNumberElement, 
billing_details: {
name: '{{$tour->guest->name}}'
}
}
})
.then(function(result) {
if (result.error) {
// Show error to your customer
showError(result.error.message);
} else {
// The payment succeeded!
orderComplete(result.paymentIntent.id);
stripe.createToken(cardNumberElement, options).then(submitToken);
}
});
var options = {
//address_zip: document.getElementById('postal-code').value,
};

}
});
function submitToken(result) {
var form = document.querySelector('#payment-form');
form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
form.submit();
}
/* ------- UI helpers ------- */
// Shows a success message when the payment is complete
var orderComplete = function(paymentIntentId) {
loading(false);
document.querySelector(".result-message").style.display = 'flex';
document.querySelector("#pay").disabled = true;
document.querySelector("#back").disabled = true;
};
// Show the customer the error from Stripe if their card fails to charge
var showError = function(errorMsgText) {
loading(false);
var errorMsg = document.querySelector("#card-error");
errorMsg.textContent = errorMsgText;
setTimeout(function() {
errorMsg.textContent = "";
}, 4000);
};
// Show a spinner on payment submission
var loading = function(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#pay").disabled = true;
document.querySelector("#back").disabled = true;
document.querySelector("#spinner").style.display = 'flex';
document.querySelector("#spinner-text").style.display = 'flex';
document.querySelector("#pay").style.display = 'none';
document.querySelector("#back").style.display = 'none';
} else {
document.querySelector("#pay").disabled = false;
document.querySelector("#back").disabled = false;
document.querySelector("#spinner").style.display = 'none';
document.querySelector("#spinner-text").style.display = 'none';
document.querySelector("#pay").style.display = 'inline-block';
document.querySelector("#back").style.display = 'inline-block';
}
};
</script>
@endsection

如果它只对一些客户中断,我怀疑这是设备/浏览器兼容性问题。当这种情况发生时,一定要询问他们在提交付款时使用的设备和浏览器。然后,您可以验证它们是否使用与stripe.js兼容的浏览器。如果他们正在使用stripe.js兼容的浏览器,我的建议是安装他们正在使用的任何浏览器并测试您的流程(同时检查开发控制台的错误)。

最新更新