javascript - Stripe 支付总是成功,paymentIntent 的金额不能更改
问题描述
我为在我的 Laravel 应用程序中实现 Stripe 苦苦挣扎了很长一段时间,但我遇到了很多问题。我确实以某种方式实现了逻辑,但我不能或者我不知道如何发送当前订单总额来创建 paymentIntent,所有付款都存储在控制器中设置的默认金额 500。我不得不提一下,在 stripe 的成功响应之后,当前订单应该存储在数据库中,其中包含在第一个表单中找到的用户运输详细信息,并且所有订购的产品都存储在会话中。让我给你一个更好的理解。
这是视图 (revieworder.blade.php),其中我有 2 个表单,一个包含用户的运输详细信息,以及 Stripe 支付表单,以及会话中的购物车产品列表:
<ul class="list-group mb-3">
<?php $total = 0 ?>
@if(session('cart'))
@foreach(session('cart') as $id => $details)
<?php $total += $details['price'] * $details['quantity'] ?>
<li class="list-group-item d-flex justify-content-between lh-condensed">
<img src="../img/{{ $details['image'] }}" alt="{{ $details['name'] }}" width="60" height="60">
<div>
<h6 class="my-0">{{ $details['name'] }}</h6>
<small class="text-muted">{{ __('Quantity') }}: {{ $details['quantity'] }}</small><br>
<small class="text-muted">{{ __('Unit price') }}: {{ $details['price'] }} RON</small>
</div>
<span class="text-muted">{{ $details['price'] * $details['quantity'] }} RON</span>
</li>
@endforeach
@endif
<li class="list-group-item d-flex justify-content-between">
<span>Total (RON)</span>
<strong id="total">{{ $total.' RON' }}</strong>
</li>
</ul>
<form id="payment-form">
@csrf
<div id="card-element"><!--Stripe.js injects the Card Element--></div>
<button id="submit" class="submit-id">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay now</span>
</button>
<p id="card-error" role="alert"></p>
<p class="result-message hidden">
</p>
</form>
<script>
//Stripe script
var stripe = Stripe("pk_test_XXX");
// The items the customer wants to buy
var purchase = {
items: [{id: "prod"}] //sessions cart
};
console.log(purchase);
var elements = stripe.elements();
var style = {
base: { //some styling },
invalid: {
fontFamily: 'Arial, sans-serif',
color: "#fa755a"
}
};
var card = elements.create("card", { style: style });
// Stripe injects an iframe into the DOM
card.mount("#card-element");
card.on("change", function (event) {
// Disable the Pay button if there are no card details in the Element
document.querySelector("button").disabled = event.empty;
document.querySelector("#card-error").textContent = event.error ? event.error.message : "";
});
// Disable the button until we have Stripe set up on the page
document.getElementsByClassName("submit-id").disabled = true;
$('#payment-form').submit(function(){
fetch("{{ url(app()->getLocale().'/revieworder') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
'X-CSRF-TOKEN': "{{ csrf_token() }}"
},
body: JSON.stringify(purchase)
})
.then(function(data) {
$('#payment-form').submit(function(event) {
event.preventDefault();
// Complete payment when the submit button is clicked
payWithCard(stripe, card, data.clientSecret);
});
});
// Calls stripe.confirmCardPayment
var payWithCard = function(stripe, card, clientSecret) {
loading(true);
stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: card
}
})
.then(function(result) {
if (result.error) {
// Show error to your customer
showError(result.error.message);
} else {
// The payment succeeded!
// The order should be stored in the database
orderComplete(result.paymentIntent.id);
}
});
};
// Shows a success message when the payment is complete
var orderComplete = function(paymentIntentId) {
loading(false);
document
.querySelector(".result-message a")
.setAttribute(
"href",
"https://dashboard.stripe.com/test/payments/" + paymentIntentId
);
document.querySelector(".result-message").classList.remove("hidden");
document.getElementsByClassName("submit-id").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.getElementsByClassName("submit-id").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.getElementsByClassName("submit-id").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
};
});
</script>
然后这是处理秘密客户端密钥和 paymentIntent (CheckoutController.php) 的控制器:
public function create(){
\Stripe\Stripe::setApiKey('sk_test_XXX');
header('Content-Type: application/json');
try {
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => "500",
'currency' => 'ron',
]);
$output = [
'clientSecret' => $paymentIntent->client_secret,
];
echo json_encode($output);
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}
因此,其中一个问题是,每当我为订单付款时,无论我通过什么信用卡号,它总是成功,这是一个重大错误。第二个,我需要传递当前订单的总额,否则所有订单都会得到总额 500,默认值。我试图将会话购物车项目传递给 fetch,但它没有用。即使我无法将购物车中的所有物品都发送到意图,但至少总价格应该对应。
如果我对任何事情不够清楚,请告诉我。我真的很感激任何建议。谢谢 !
解决方案
推荐阅读
- python - 如何在 Python Flask 应用程序的服务员服务器上进行反向代理
- html - sematic ui react ,是否可以将标签分成两部分?
- mysql - 使用 Navicat 聚合年初至今的收入
- javascript - Javascript 聊天室:如何确定我向谁发送消息?
- react-native - 我可以避免 TextInput 在其父状态更改时失去焦点吗?
- r - 将两个向量合并到数据框中的函数,保持其向量名称
- python - 将文本文件中的列拆分为python中的列表
- go - 提取特定域的所有 TXT 记录
- npm - bower.json 可以链接到 package.json 中的 npm install 吗?
- r - 在 R 中跟踪库存和损失