title: POST request to 3rd party URL from Angular/NodeJS/ExpressJS
body: <p>Option 4.2 seems like the best direction for me. Does anyone have any other suggestions?</p>
  
  <p>Is there a way to access response in any of the below scenarios or I need to rewrite whole logic?</p>
  
  <hr>
  
  <p>I need to perform a form POST to a 3rd party payment provider with Angular Typescript with or without NodeJS/ExpressJS with the redirect. </p>
  
  <p>Flow:</p>
  
  <p><a href="https://i.stack.imgur.com/OhIWO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/OhIWO.png" alt="enter image description here"></a></p>
  
  <p>The problem is that in some cases when I perform URL redirect successfully <strong>I don't receive any response from payment gateway</strong>. <strong>When a user clicks "Pay"</strong> - "Plati" he is redirected to the success page <code>http://example.com/success</code> and in case of error response to page <code>http://example.com/cancel</code>.</p>
  
  <p><a href="https://i.stack.imgur.com/KgiTq.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KgiTq.png" alt="enter image description here"></a></p>
  
  <p><strong>The expected scenario</strong> </p>
  
  <p>The user comes to the website selects the products and clicks on the buy button. At that point, s/he is taken to another page where s/he makes the payment. After successful payment, the user is redirected back to the website and <strong>I get a response</strong> from the server and show the user a related message.</p>
  
  <p><strong>Option 1 - Form Action URL</strong></p>
  
  <p>If I do standard form submit and put payment gateway URL inside <code>[action]="'https://test-wallet.example.com/checkout/'"</code> then the user will be redirected directly to that URL and payment will be processed successfully. But in that case I don't receive a response that is needed for me to know what data to show to the user - success or error message.</p>
  
  <pre><code>&lt;form [action]="'https://test-wallet.example.com/checkout/'" ngNoForm method="POST" target="_blank"&gt;
        &lt;button type="submit"&gt;Pay with card&lt;/button&gt;
        &lt;input name='param1' value='param1'&gt;
        &lt;input name='param2' value='param2'&gt;
        &lt;input name='param3' value='param3'&gt;
        &lt;input name='param4' value='param4'&gt;
        &lt;input name='param5' value='param5'&gt;
        &lt;input name='param6' value='param6'&gt;
        &lt;input name='param7' value='param7'&gt;
        &lt;input name='param8' value='param8'&gt;
        &lt;input name='param9' value='param9'&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p><strong>Option 2 - HttpClient through service</strong> </p>
  
  <p>I've also tried making <a href="https://angular.io/guide/http" rel="nofollow noreferrer">HttpClient</a> POST request inside the Angular app and without NodeJS backend. In that case, I call the Payment Gateway URL directly but with CORS error.</p>
  
  <p>payment.service.ts:</p>
  
  <pre><code>payFunction(parameters: any){
     return this._httpClient.post('https://test-wallet.example.com/checkout/'+ 
        'param1='+parameters.param1+ 
        '&amp;param2='+parameters.param2+
        '&amp;param3='+parameters.param3+ 
        '&amp;param4='+parameters.param4+ 
        '&amp;param5='+parameters.param5+
        '&amp;param6='+parameters.param6+ 
        '&amp;param7='+parameters.param7+
        '&amp;param8='+parameters.param8+
        '&amp;param9='+parameters.param9
        ,parameters
        ,this.httpOptions 
      )
     .catch(err =&gt; {
        console.log(err);
        return Observable.of(err)
     })
  }
  </code></pre>
  
  <p>I call the previous service in component:</p>
  
  <pre><code>async test(form){
    await this._myPaymentService.payFunction(form.value).subscribe(res =&gt; {
          console.log(res);
  })
  </code></pre>
  
  <p>In that case I received only CORS error.</p>
  
  <p><a href="https://i.stack.imgur.com/0j56K.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0j56K.png" alt="enter image description here"></a></p>
  
  <p><strong>Option 3 - jQuery AJAX</strong></p>
  
  <p>I'm calling this inside my Angular component with <a href="https://api.jquery.com/jquery.ajax/" rel="nofollow noreferrer">cross-domain contentType</a>.</p>
  
  <p>But I also received only CORS error as in the case above. I know that using jQuery in the Angular app is not by the book but I had to try.</p>
  
  <pre><code> $.ajax({
     headers: { 
       'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
     },
     url : 'https://test-wallet.example.com/checkout/',
     type: "POST",
     beforeSend: function(xhrObj){
         xhrObj.setRequestHeader('Content-Type':  'application/x-www-form-urlencoded; charset=UTF-8');
     },
     dataType : "json",
     async:true,
     crossDomain:true,
     data: corvusDataObject,
     error: function () {
       alert('Ajax Error');
     },
     onFailure: function () {
       alert('Ajax Failure');
     },
     statusCode: {
       404: function() {
         alert("Ajax 404");
       }   
     },
     success : function (response) {
       alert("Success: " + JSON.stringify(response));
       }
     })
     .done(function( data ) {
     alert("Done: " + JSON.stringify(response));
  });
  </code></pre>
  
  <p><strong>Option 4 - NodeJS/ExpressJS backend</strong></p>
  
  <p>If I use this approach then I received a redirect in the same way as in the first case. But my backend doesn't receive any response from the payment gateway provider.</p>
  
  <p>In Angular app I'm calling my API:</p>
  
  <pre><code>&lt;form [action]="'http://localhost:8080/myPaymentAPI/'" ngNoForm method="POST" target="_blank"&gt;
        &lt;button type="submit"&gt;Pay with card&lt;/button&gt;
        &lt;input name='param1' value='param1'&gt;
        &lt;input name='param2' value='param2'&gt;
        &lt;input name='param3' value='param3'&gt;
        &lt;input name='param4' value='param4'&gt;
        &lt;input name='param5' value='param5'&gt;
        &lt;input name='param6' value='param6'&gt;
        &lt;input name='param7' value='param7'&gt;
        &lt;input name='param8' value='param8'&gt;
        &lt;input name='param9' value='param9'&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>In NodeJS/ExpressJS I've made <code>myPaymentAPI</code> API with 307 redirects (<a href="https://stackoverflow.com/questions/2604530/a-good-way-to-redirect-with-a-post-request/2604893#2604893">from this SO answer</a>).</p>
  
  <pre><code>    var express = require('express');
      var app = express();
      var cors = require('cors')  // CORS
      var bodyParser = require('body-parser'); 
  
      app.use(bodyParser.urlencoded({ extended: true }));
      app.use(bodyParser.json());
      app.use(cors());
  
      var port = process.env.PORT || 8080;
      var apiRoutes = express.Router();
  
      apiRoutes.get('/', function(req, res) {
          res.json({ message: 'API works!' });
      });
  
      app.use('/api', apiRoutes);
  
      app.post('/myPaymentAPI', function(req, res, next) {
  
        let param1 = req.body.param1;
        let param2 = req.body.param2;
        let param3 = req.body.param3;
        let param4 = req.body.param4;
        let param5 = req.body.param5;
        let param6 = req.body.param6;
        let param7 = req.body.param7;
        let param8 = req.body.param8;
        let param9 = req.body.param9;
  
      res.status(200).redirect(307, 'https://test-wallet.example.com/checkout/?param1='+param1 +'&amp;param2='+param2+...)
      //res.end();
  
      });
  </code></pre>
  
  <p>Above redirection transfers the user to URL (see the first image): <code>https://test-wallet.example.com/#/checkout/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx</code> and user on that URL make a payment but I, once again, don't receive any response. </p>
  
  <p><strong>Option 4.1</strong></p>
  
  <p><code>fetch</code> returns HTML page but with blank <code>&lt;body&gt;</code></p>
  
  <pre><code>app.post('/myPaymentAPI', function(req, res, next) {
  
      const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&amp;param2='+param2+'&amp;param3='+param3+'&amp;param4='+param4+'&amp;param5='+param5+'&amp;param6='+param6+'&amp;param7='+param7+'&amp;param8='+param8+'&amp;param9='+param9;
         fetch(url, {
             method : "POST",
             body: res.body
         }).then(
             response =&gt; response.text()
         ).then(
           html =&gt; res.send(html)
        ).catch((err) =&gt; {
           reject(err);
         });
  
  });
  </code></pre>
  
  <p><strong>Option 4.2</strong></p>
  
  <p>In this approach, I successfully get a short version of the URL (see the first image) and then I redirect the user to that URL.</p>
  
  <pre><code>    app.post('/myPaymentAPI', function(req, res, next) {
  
        let param1 = req.body.param1;
        let param2 = req.body.param2;
        let param3 = req.body.param3;
        ...
  
        try{
          var body = JSON.stringify(req.body);
          const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&amp;param2='+param2+...;
          var newData = await fetch(url, {method: "POST", body: body})
          console.log(newData.url)
          res.redirect(307, newData.url);
        }catch(error){
          console.log(error)
        }
  
  });
  </code></pre>
  
  <p>This page is opened after 307 redirects. The message says "Your request cannot be processed. We are sorry, an error occurred."</p>
  
  <p>Do I need in this step once again append FormData before making that redirect?</p>
  
  <p><a href="https://i.stack.imgur.com/i4M2g.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/i4M2g.png" alt="enter image description here"></a></p>
  
  <p><strong>Option 4.3</strong></p>
  
  <p>In this approach, I'm making a call to my API and create an object inside <code>res.send</code> which then I send to my frontend.</p>
  
  <pre><code>try{
       var body = JSON.stringify(req.body);
       const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&amp;param2='+param2+'&amp;param3='+param3+...;
         await fetch(url, {method: "POST", body: body}).then((response) =&gt; {
           const data = response;
           res.send({
             success: true,
             redirectURL: data.url,
             body: req.body
           })
        })
         .catch((error) =&gt; {
           console.error(error);
         })
     }catch(error){
       console.log(error)
  }
  </code></pre>
  
  <p>On frontend I successfully receive <code>redirectURL</code> and <code>body</code> data and try to make a redirect.</p>
  
  <pre><code>this._myPaymentService.payFunction(form.value).subscribe(res =&gt; {
              console.log(res);
              console.log(res.redirectURL);
              window.location.replace(res.redirectURL);
  })
  </code></pre>
  
  <p>The web browser then goes to the following page with blank content.</p>
  
  <p><a href="https://i.stack.imgur.com/YmBu2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YmBu2.png" alt="enter image description here"></a></p>
  
  <p>Because request has become GET. I know that it's not possible to send a POST request this way and I'm looking for way to do it. </p>
  
  <p><a href="https://i.stack.imgur.com/GD6I5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GD6I5.png" alt="enter image description here"></a></p>