【问题标题】:ASPNET Waiting for a Webhook Response/Result on a WebPageASPNET 等待网页上的 Webhook 响应/结果
【发布时间】:2019-12-20 04:53:35
【问题描述】:

我们有一个接受 Stripe 付款的网页,一旦付款完成,Stripe 可以调用我们服务器上的 webhook。

此时,我们可以将订单标记为完成并完成任何其他附加任务。

我们如何让订单网页更新/将用户移动到订单完成?

我们是否应该一直在 AJAX 中访问服务器以检查它现在是否已完成,或者是否有更好的方法来执行此操作。

【问题讨论】:

  • 我对 Stripe 不太熟悉,但是 webhook 功能是否允许您根据付款状态处理带有成功/失败标志的订单?
  • 问题更多是关于等待来自 webhook 的结果/更新的响应的网页。由于这将是主订单表,因此我认为定期轮询结果不是一个好主意,因为它可能会导致性能问题,因此请寻找有关整体处理的其他建议。
  • 如果您担心性能问题,您可以每 30 秒左右轮询一次端点?一旦条带付款到达 webhook,订单状态就会更新,在您等待 30 秒后,订单状态将反馈给客户
  • @StuartM Use signalR。发出请求后,转发到条带并返回您的响应。在服务器上调用 webhook 时,让 signalR 将响应传递给客户端。完毕。无需等待或轮询
  • 目前发生的事情是我们从条带调用中获取结果,如果成功,我们将它们传递到成功页面,该页面反过来完成后端的订单。但是,对于极少数客户,订单未完成并处于待付款状态。我们还遇到有人在处理付款页面时离开付款页面,因此没有更新订单以完成的问题。所以我们需要做的就是把 webhook 当作封面来处理。

标签: asp.net-mvc asp.net-mvc-4 stripe-payments webhooks asp.net-webhooks


【解决方案1】:

问:我们如何让订单网页更新/将用户移动到订单完成?

大多数支付引擎会将支付会话重定向到您选择的带有结果代码的 URL 或每个结果代码的不同 URL。这些通常可以在发出请求时进行配置,也可以在一般配置中针对整个站点进行配置。实际付款不应依赖这些结果,因为这是网络挂钩的工作。他们可以得到足够的信任,让您的网站显示一般的成功/失败错误消息并让用户继续执行任何操作。


Stripe 也允许这样做,您可以在客户端集成中指定success_url(或successUrl)。

请参阅Create a Checkout Session on your server,了解如何将此 URL 传递给请求。您还可以添加cancel_url。请参阅下面代码示例中的最后 2 个参数:

curl https://api.stripe.com/v1/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -d payment_method_types[]=card \
  -d line_items[][name]=T-shirt \
  -d line_items[][description]="Comfortable cotton t-shirt" \
  -d line_items[][images][]="https://example.com/t-shirt.png" \
  -d line_items[][amount]=500 \
  -d line_items[][currency]=usd \
  -d line_items[][quantity]=1 \
  -d success_url="https://example.com/success" \
  -d cancel_url="https://example.com/cancel"

另见Checkout Purchase Fulfillment

当您的客户成功完成付款或使用 Checkout 启动订阅时,Stripe 会将他们重定向到您在 success_url 参数中指定的 URL(或客户端集成中的 successUrl)。通常,这是您网站上的一个页面,用于通知您的客户他们的付款已成功。

如上所述,如果付款成功,请不要将此作为实际指标。您应该为此使用网络挂钩。

不要仅仅依靠重定向到success_url 来完成购买:

  • 恶意用户无需付费即可直接访问success_url,并获得您的商品或服务的访问权限。
  • 成功付款后,客户可能无法始终联系到success_url。他们可能会在重定向发生之前关闭浏览器选项卡。

【讨论】:

  • 因此,无论付款是否完成,我们都应将客户引导至订单完成/succes_url。然后 webhook 处理完成订单
  • @StuartM - 如果这里的答案之一与您所要求的相符,您可以将其标记为答案吗?通过不标记答案或仅奖励 1/2 的赏金,赏金将奖励给最重要的问题(但是,整个赏金金额仍会从您的帐户中扣除)。提前致谢(另请参阅bounty)。
【解决方案2】:

好问题, 您可以处理条带支付结果在您的页面上产生新的效果

var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = cardButton.dataset.secret;

cardButton.addEventListener('click', function(ev) {
  stripe.handleCardPayment(
    clientSecret, cardElement, {
      payment_method_data: {
        billing_details: {name: cardholderName.value}
      }
    }
  ).then(function(result) {
    if (result.error) {
      // Display error.message in your UI.
    } else {
      // The payment has succeeded. update your front-end
    }
  });
});

我们是否应该一直在 AJAX 中访问服务器以检查它是否现在 完成,或者有更好的方法。

here 是一个 Ajax 示例,但更好的方法是 fetch api。您可以在here 中找到所有详细信息

【讨论】:

    【解决方案3】:

    我们是否应该一直在 AJAX 中访问服务器以检查它现在是否已完成,或者是否有更好的方法来执行此操作。

    不,您不应该这样做,是的,有更好的方法。如果您没有处理事务的 asp.net 服务器,回调页面/webhook 将是有意义的,但在这里它们不是必需的。

    我们如何让订单网页更新/将用户移动到订单 完成了吗?

    条带支付过程只需几秒钟即可响应状态码。这与将用户定向到 Paypal 网站然后返回您的网站的 Paypal 不同。

    这个过程应该去:

    1. 用户将他们的支付信息输入到生成的条带中 页面上的元素。

    2. Stripe 为您的前端 javascript 代表客户支付数据的令牌。

    3. 您使用 ajax 甚至是常规的老式表单请求将该信息发布到您的服务器。

    4. 处理呼叫的服务器端脚本使用asp.net stripe library 发送付款并获得如下回复。
    5. 根据需要将交易结果保存到您的数据库中。

      一个。如果条带响应包括“状态”:“成功”,那么您可以为客户提供带有已付款收据的新页面。

      b.如果由于某种原因失败,您可以重新加载支付页面并使用“failure_message”告诉客户他们的卡为什么不好。

    让用户等到 stripe 回复一条关于支付成功或失败的消息后再发送给他,因为这只需要一秒钟。

        /* SAMPLE RESPONSE FROM STRIPE
        {
        "id": "ch_1D658SDJ46dzUiasdfsdfaDq",
        "object": "charge",
        "amount": 2125,
        "amount_refunded": 0,
        "application": null,
        "application_fee": null,
        "balance_transaction": "txn_1D658SDJ46dzUilftNXRCz64",
        "captured": true,
        "created": 1565431460,
        "currency": "usd",
        "customer": null,
        "description": "856 addresses",
        "destination": null,
        "dispute": null,
        "failure_code": null,
        "failure_message": null,
        "fraud_details": {},
        "invoice": null,
        "livemode": false,
        "metadata": {},
        "on_behalf_of": null,
        "order": null,
        "outcome": {
          "network_status": "approved_by_network",
          "reason": null,
          "risk_level": "normal",
          "seller_message": "Payment complete.",
          "type": "authorized"
        },
        "paid": true,
        "receipt_email": null,
        "receipt_number": null,
        "refunded": false,
        "refunds": {
           "object": "list",
           "data": [],
           "has_more": false,
           "total_count": 0,
           "url": "/v1/charges/ch_1D658SDJ46dzUilfalFFraDq/refunds"
         },
         "review": null,
         "shipping": null,
         "source": {
           "id": "card_1D658RDJ46dzUilfbkLSOIwp",
           "object": "card",
           "address_city": "test",
           "address_country": "US",
           "address_line1": "123 test",
           "address_line1_check": "pass",
           "address_line2": "",
           "address_state": null,
           "address_zip": "32121",
           "address_zip_check": "pass",
           "brand": "Visa",
           "country": "US",
           "customer": null,
           "cvc_check": "pass",
           "dynamic_last4": null,
           "exp_month": 12,
           "exp_year": 2033,
           "fingerprint": "fNMgYIntTkOnLVzk",
           "funding": "credit",
           "last4": "4242",
           "metadata": {},
           "name": "Test",
           "tokenization_method": null
        },
        "source_transfer": null,
        "statement_descriptor": null,
        "status": "succeeded",
        "transfer_group": null
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 2012-08-12
      相关资源
      最近更新 更多