ASPNET 正在等待网页上的 Webhook Response/Result

ASPNET Waiting for a Webhook Response/Result on a WebPage

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

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

我们怎样才能让 update/move 用户的订购网页完成订购?

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

Q: How can we have the order webpage update/move the user onto to order complete?

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


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

When your customer successfully completes their payment or initiates a subscription using Checkout, Stripe redirects them to the URL that you specified in the success_url parameter (or successUrl in the client integration). Typically, this is a page on your website that informs your customer that their payment was successful.

正如我上面所说,如果付款成功,请不要依赖此作为实际指标。您应该为此使用网络挂钩。

Do not rely on the redirect to the success_url alone for fulfilling purchases as:

  • Malicious users could directly access the success_url without paying and gain access to your goods or services.
  • Customers may not always reach the success_url after a successful payment. It is possible they close their browser tab before the redirect occurs.

好问题, 您可以处理条纹支付结果,让您的页面焕然一新

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
    }
  });
});

Should we consistently hit the server in AJAX to check if it's now complete, or is there a better way of doing this.

一个 Ajax 例子是 here but beter way to doing that is the fetch api. You can find out all detail in here

Should we consistently hit the server in AJAX to check if it's now complete, or is there a better way of doing this.

不,你不应该,是的,有更好的方法。如果您没有 asp.net 服务器处理事务,回调 pages/webhooks 会有意义,但这里不需要它们。

How can we have the order webpage update/move the user onto to order complete?

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

流程应该进行:

  1. 用户输入自己的支付信息生成stripe 页面上的元素。

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

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

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

    一个。如果条纹响应包括 "status":"succeeded" 那么您可以为客户提供带有已付款收据的新页面。

    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
    }