【问题标题】:How can I prevent duplicate charge using Stripe?如何使用 Stripe 防止重复收费?
【发布时间】:2018-05-18 00:27:30
【问题描述】:

我正在使用 Stripe 让我的客户保存信用卡并支付发票(具有唯一 ID)。付款时,我使用表单向我的服务器发送带有卡 ID(由条带提供)的 POST 请求,控制器对其收费。然后我将发票标记为我方已付款。

事实证明,如果我足够快地双击表单的提交按钮,我会发送两个 POST 请求,并且卡最终会被收取两次费用,因为当第二个 POST 请求到达我的服务器时,我的服务器到 Stripe 的 POST 请求API(从第一次点击开始)尚未完成,因此尚未将发票标记为已付款。

我正在考虑在第一次点击后禁用表单提交按钮,但我觉得可能有更简洁的方法。

Stripe 是否可以防止重复收费(可能使用我的发票 ID)?如果不是,我这边最好的后端方法是什么?

【问题讨论】:

  • 在表单的隐藏字段中放置一个唯一的交易 ID(它只需要是用户 ID 和时间戳的哈希值,或类似的东西)并让您的服务器记住交易 ID它被发送到 Stripe 并拒绝发送重复提交。

标签: node.js stripe-payments


【解决方案1】:

在第一次点击后禁用表单提交绝对是最简单的实现方式。

另一种方法是使用记录在 here 中的幂等请求。这个想法是,您在向 Stripe 的 API 发出请求时传递一个唯一标识符,以确保您只能运行此事务一次。如果您使用完全相同的幂等键重新运行查询,您将从第一次调用中获得原始响应,从而确保您永远不会在您的网站上为同一“交易”创建 2 笔费用。

【讨论】:

    【解决方案2】:

    是的,幂等请求是实现这一点的正确方法。

    你可以参考这里

    https://stripe.com/docs/api#idempotent_requests

    您可以实施的另一个简单解决方案是通过跟踪条带 api 调用来使用状态机。

    【讨论】:

      【解决方案3】:

      正如其他答案所述,您可以使用Idempotent Requests 来防止重复收费。以下是我的实现方式:

      checkout.php:

      <?php
      function rand_string( $length ) {
          $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
          return substr(str_shuffle($chars),0,$length);
      }
      $idempotency = rand_string(8);
      ?>
       ...
      <form method="post" action="payment.php">
      <input type="hidden" name="idempotency" id="idempotency" value="<?=$idempotency?>">
      ...
      </form>
      ...
      

      payment.php:

      <?php
      $idempotency = preg_replace('/[^a-z\d]/im', '', $_POST['idempotency']);
      ...
      
      try {
          $charge = \Stripe\Charge::create(
              ["amount" => $price,
              "currency" => $currency,
              "description" => $invoiceid,
              "customer" => $customer->id ], 
          ["idempotency_key" => $idempotency,]);
      }catch(Exception $e) {
          $api_error = $e->getMessage();
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-20
        • 2021-07-29
        • 1970-01-01
        • 2018-06-21
        • 2021-12-30
        • 2022-01-19
        • 2017-06-17
        • 2015-03-13
        • 1970-01-01
        相关资源
        最近更新 更多