Search code examples
angularhttp-redirectasp.net-web-apipayment-gatewayopayo

How to redirect a user to an external site though a POST request


How to redirect a user to an external site though a POST request,which is better using backend-asp.net core web api or frontend- angular?

I am working with a payment gateway. For confirming 3D secure I need to redirect the user to a new-url.

The docs says that use like this a form,

<form
  id="pa-form"
  method="post"
  action="https://test.sagepay.com/mpitools/accesscontroler?action=pareq"
>
  <input
    type="hidden"
    name="PaReq"
    value="eJxVUstugzAQvPcrEB+AHwTiRBtHaXMIqlrRJlJ7tYzVoIIhBgL5+9oJNK1PM+PV7HrWsB7Kwjsr0+SVXvkkwP6aP8DhaJTa7pXsjOLwoppGfCkvz1Y+xSQO53GIWcgYwTHDM59DunlXJw6jD7c2AQE0UWtg5FHoloOQp8fklc8WdIExoJFCqUyy5SSibL5geDyAbjJoUSqe7g5GnFXRir4yRXasijwTgK53IKtOt+bCGY0BTQQ6U/C+7wM3fC0ugayC7huQkwHdZ0o7hxprM+QZT98SfaBVHX0878PPbBeJ4YI2eggZXgFyFZCJVnGKKSGEhh4mSzpfEgboqoMoXX8eR/Z5Nwi167C563852IyN0nIafmKghrrSylZQQL8YMtVIvnfbSMXFe0kT29ZJgO7PeNq5oGXrInUZX5Hzy20qNMQ3Q0cAuVo0rg+Ni7bo3wf4AWyps7I="
  />
  <input
    type="hidden"
    name="TermUrl"
    value="http://localhost:4200/payment"
  />
  <input type="hidden" name="MD" value="FAD0DBBA-FC72-2D9A-F09F-D4D6FFFCB2CD" />
</form>

// in index.html  
<script>document.addEventListener("DOMContentLoaded",function(){var b=document.getElementById("pa-form");b&&b.submit()})</script>

But I tried this form in angular. I got Cannot POST / response.

So I search about this, someone said angular is not able to handle third-party responses. So Then How can I do this? How to do above form with asp .net core or angular.

I am not clear What I should I do?

Please guide me. How can I use asp .net core and angular


Solution

  • Brief overview: With a single-page application(Angular), you should not handle the third-party response on the client side if you are redirecting the user. Because each time the application redirects to a third party, all the context is lost and upon coming back, the Angular app will get bootstrapped again.

    Solution 1: In terms of architecture, you can use the following approach:

    1. Get all the gateway-related keys like PaReq, TermUrl etc when a user clicks on the pay now button on your website (HttpClient request can call your backend API to get the gateways configs). Example:

         {
            keys: [
              {
                name: "PaReq",
                value: "eJxVUstugzAQvPcrEB+AHwTiRBtHaXMIqlrRJ",
              },
              //... Rest of the keys
            ],
          };
      
    2. Create a dynamic form after getting gateway config

      let f = document.createElement("form");
      f.setAttribute("method", "post");
      f.setAttribute(
        "action",
        "https://test.sagepay.com/mpitools/accesscontroler?action=pareq"
      ); //Your action URL
      
      //create hidden input elements
      config.keys.forEach((item) => {
        let i = document.createElement("input");
        i.type = "hidden";
        i.name = item.name;
        i.value = item.value;
        f.appendChild(i); //Add it to the form
      });
      
      document.body.appendChild(f);//Add the form to the body
      f.submit(); //Submit it immediately
      
    3. Now the user will be redirected to the payment gateway. Payment gateways ask for a callback URL which they use to pass the result of payment to your backend. Create an API (let's say api/callback) that would handle the payment response from the gateway.

    4. Finally in api/callback you can store the response in the database and based upon payment success/failure, redirect the user back to your Angular application with payment id as a parameter. https://youapp.com/payment/123456/success

    Here, we have a route defined in Angular application named payment that takes 2 route parameters

        path: 'payment/:paymentId/:result'
    

    Solution 2: Some payment gateways provide a Javascript plugin(script) that you can use. They allow payment transaction to happen without redirection. They open the payment page in a modal within the Angular's context.

    1. You get the payment related keys from your backend API when user clicks on checkout button.

    2. Instead of submitting a form, you pass the keys to the JS plug-in provided by the gateway.

    3. The transaction modal opens up in same window. The plug-in usually takes in a callback function to be invoked when transaction is successful/ failed.

    With this solution, you never loose Angular(or other SPA framework) context. It is better performant because your app doesn't get downloaded and bootstrapped again