[英]How to ensure an online payment is executed only once?
我为我的一个有在线支付的客户开发并维护了一个网站。
大多数情况下,它使用客户的墨西哥银行 Banorte 提供的支付网关。 我遇到的问题是,在某些情况下,付款会执行两次。 我不确定用户是否双击或存在其他问题,目前仍在尝试找出发生了什么,但最后一次发生这种情况的时间间隔约为 2 分钟。 与此相关的另一个问题是,该产品仅限于每人 1 个,因为它是一个事件访问。
我有一个获取卡信息的表格,单击时我执行以下操作(使用 Foundation 6):
var cardSubmit = false;
$(document).on("submit", "#card-form", function(e) {
e.preventDefault();
if(cardSubmit) {
$("#process").addClass("loading");
$("#card-form button[type='submit']").prop("disabled", true).html("Processing...");
setTimeout(function() {
e.currentTarget.submit();
}, 2500);
}
})
$(document).on("formvalid.zf.abide", "#card-form", function() {
cardSubmit = true;
})
$(document).on("forminvalid.zf.abide", "#card-form", function() {
cardSubmit = false;
})
.loading
class 添加了一个::after
元素,该元素位于所有内容之上,此外我禁用了该按钮。 这是为了确保用户不能再次单击该按钮。 我不确定在这种情况下是否可以双击。
提交后(由于明显的原因减少了代码),我执行以下操作:
$client = new \GuzzleHttp\Client(['base_uri' => 'https://via.banorte.com:443']);
$parametros = [...]; // information required for the payment
$postQuery = http_build_query($parametros);
$contentLength = strlen($postQuery);
$resultadoPago = $client->post('/payw2', [
'query' => $parametros,
]);
$headersPago = $resultadoPago->getHeaders();
if ($headersPago['RESULTADO_PAYW'][0] == 'A') {
// This runs if the response is Authorized
// The first thing I do here is create the new transaction and mark it as paid
// Then I do some more stuff and finally redirect to a thank you page
}
然后,如果用户访问该产品,我会检查是否已经有具有相同产品的交易,这样我就不允许用户再次尝试购买它。 所以这让我相信双重支付发生在同一个 window 并且在这个过程中失败了。
有没有办法保证我只执行一次? 还是我总是依赖支付网关的响应? 我正在考虑添加与上一段中提到的相同的检查,但不确定页面是否正在刷新或用户是否正在刷新页面。
我会考虑将 true 或 false 添加到数据属性并确保目标是实际表单。 我不相信 e.currentTarget 在 2.5 秒后仍然保持不变
$(document).on("submit", "#card-form", function(e) {
e.preventDefault();
if (!$(this).data("cardSubmit")) return ;
let DOMForm = this;
$("#process").addClass("loading");
$("button[type='submit']",this).prop("disabled", true).html("Processing...");
setTimeout(function() {
DOMForm.submit();
$(DOMForm).data("cardSubmit",false);
}, 2500);
})
$(document).on("formvalid.zf.abide", "#card-form", function() {
$(this).data("cardSubmit",true);
})
$(document).on("forminvalid.zf.abide", "#card-form", function() {
$(this).data("cardSubmit",false);
})
我认为更深层次的问题是您对产品是否已购买的验证。 如果您跟踪数据库中的购买和产品,我看不出双击会使产品被购买两次的原因。
如果您确实管理数据库,您可以自己跟踪购买情况,并在每次调用时根据数据库验证产品是否可用。 如果可用,则处理付款并使用付款服务响应相应地更新您的数据库。 最后,将购买状态返回到您的前端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.