StuartM
StuartM

Reputation: 6813

ASPNET Waiting for a Webhook Response/Result on a WebPage

We have a web page which takes a Stripe payment, once the payment is complete Stripe can call a webhook on our server.

At this point, we can mark an Order as complete and complete any other additional tasks.

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

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

Upvotes: 2

Views: 1863

Answers (3)

Altimus Prime
Altimus Prime

Reputation: 2327

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

No you shouldn't and yes there is a better way. Callback pages/webhooks would make sense if you didn't have an asp.net server handing the transaction, but they aren't necessary here.

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

The stripe payment process only takes a couple seconds to respond with a status code. It's not the same as Paypal where the user is directed to a Paypal site and then back to your site.

The process is supposed to go:

  1. The user enters their payment information into stripe generated elements on your page.

  2. Stripe gives your front end javascript a token that represents the customer's payment data.

  3. You post that information to your server using ajax or even a regular old fashioned form request.

  4. The server side script handling the call uses the asp.net stripe library to send the payment and gets an answer back like the one below.
  5. Save the transaction result to your database as needed.

    a. If the stripe resonse includes "status":"succeeded" then you can serve the customer with a new page with the paid receipt.

    b. If it failed for some reason you can reload the payment page and use the "failure_message" to tell the customer why their card is no good.

Let the user wait until stripe replies with a message regarding the success or failure of the payment and send him because it only takes a second.

    /* 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
    }

Upvotes: 1

Hamit YILDIRIM
Hamit YILDIRIM

Reputation: 4539

Good question, You can handle the stripe payment result to take a new effect on your page

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.

An Ajax example is here but beter way to doing that is the fetch api. You can find out all detail in here

Upvotes: 0

Igor
Igor

Reputation: 62213

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

Most payment engines will redirect the payment session to a URL of your choosing with a result code or a different URL per result code. These can generally be configured at the moment the request is being made or for the entire site in a general configuration. These results should not be relied on for the actual payment as that is the job for the web hook. They can be trusted enough for your site to show a general success/fail error message and let the user continue doing whatever.


Stripe also allows for this, you can specify a success_url (or successUrl in the client integration).

See Create a Checkout Session on your server for how to pass this URL to the request. You can also include a cancel_url. See the last 2 parameters in the code sample below:

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"

See also 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.

And as I stated above do not rely on this as the actual indicator if the payment succeeded. You should use the web hooks for that.

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.

Upvotes: 5

Related Questions