从Angular / NodeJS / ExpressJS向第三方URL的POST请求

问题描述 投票:5回答:2

选项4.2对我来说似乎是最好的方向。有人还有其他建议吗?

在以下任何一种情况下是否都可以访问响应,或者我需要重写整个逻辑?


我需要使用Angular Typescript向具有或不带有NodeJS / ExpressJS且具有重定向功能的第三方付款提供商执行POST表格。

当前流量:

enter image description here

问题是,在某些情况下,我成功执行了URL重定向我没有从支付网关收到任何响应[当用户单击“付款”时-“ Plati”,他将重定向到成功页面http://example.com/success,并且在对页面http://example.com/cancel作出错误响应的情况下。

enter image description here

预期情况

用户进入网站选择产品,然后点击购买按钮。此时,他/他被带到他/她进行付款的另一页。付款成功后,用户将被重定向回网站,并从服务器我得到答复并向用户显示相关消息。

选项1-表单操作URL

如果我使用标准表格提交并在[action]="'https://test-wallet.example.com/checkout/'"中放置了付款网关URL,那么用户将直接重定向到该URL,并且付款将成功处理。但是在那种情况下,我不会收到需要知道要显示给用户的数据-成功或错误消息的响应。

<form [action]="'https://test-wallet.example.com/checkout/'" ngNoForm method="POST" target="_blank">
      <button type="submit">Pay with card</button>
      <input name='param1' value='param1'>
      <input name='param2' value='param2'>
      <input name='param3' value='param3'>
      <input name='param4' value='param4'>
      <input name='param5' value='param5'>
      <input name='param6' value='param6'>
      <input name='param7' value='param7'>
      <input name='param8' value='param8'>
      <input name='param9' value='param9'>
</form>

选项2-通过服务的HttpClient

我也尝试过在Angular应用中发出HttpClient POST请求,并且没有NodeJS后端。在这种情况下,我会直接调用支付网关URL,但会出现CORS错误。

payment.service.ts:

payFunction(parameters: any){
   return this._httpClient.post('https://test-wallet.example.com/checkout/'+ 
      'param1='+parameters.param1+ 
      '&param2='+parameters.param2+
      '&param3='+parameters.param3+ 
      '&param4='+parameters.param4+ 
      '&param5='+parameters.param5+
      '&param6='+parameters.param6+ 
      '&param7='+parameters.param7+
      '&param8='+parameters.param8+
      '&param9='+parameters.param9
      ,parameters
      ,this.httpOptions 
    )
   .catch(err => {
      console.log(err);
      return Observable.of(err)
   })
}

我在组件中调用先前的服务:

async test(form){
  await this._myPaymentService.payFunction(form.value).subscribe(res => {
        console.log(res);
})

在那种情况下,我仅收到CORS错误。

enter image description here

选项3-jQuery AJAX

我正在cross-domain contentType的Angular组件中调用它。

但是如上所述,我也只收到了CORS错误。我知道在Angular应用程序中使用jQuery并不是本书所必需的,但我不得不尝试。

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

选项4-NodeJS / ExpressJS后端

如果我使用这种方法,那么我会收到与第一种情况相同的重定向。但是我的后端没有收到付款网关提供商的任何响应。

在Angular应用中,我正在调用我的API:

<form [action]="'http://localhost:8080/myPaymentAPI/'" ngNoForm method="POST" target="_blank">
      <button type="submit">Pay with card</button>
      <input name='param1' value='param1'>
      <input name='param2' value='param2'>
      <input name='param3' value='param3'>
      <input name='param4' value='param4'>
      <input name='param5' value='param5'>
      <input name='param6' value='param6'>
      <input name='param7' value='param7'>
      <input name='param8' value='param8'>
      <input name='param9' value='param9'>
</form>

在NodeJS / ExpressJS中,我制作了具有307个重定向(myPaymentAPI)的from this SO answer API。

  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 +'&param2='+param2+...)
    //res.end();

    });

以上重定向将用户转移到URL(请参见第一张图片):https://test-wallet.example.com/#/checkout/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx,该URL上的用户付款了,但是我再也没有收到任何回复。

选项4.1

[fetch返回HTML页面,但空白<body>

app.post('/myPaymentAPI', function(req, res, next) {

    const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&param2='+param2+'&param3='+param3+'&param4='+param4+'&param5='+param5+'&param6='+param6+'&param7='+param7+'&param8='+param8+'&param9='+param9;
       fetch(url, {
           method : "POST",
           body: res.body
       }).then(
           response => response.text()
       ).then(
         html => res.send(html)
      ).catch((err) => {
         reject(err);
       });

});

选项4.2

通过这种方法,我成功获得了URL的简短版本(请参见第一个图像),然后将用户重定向到该URL。

    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+'&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)
      }

});

此页面在307重定向后打开。消息显示“无法处理您的请求。很抱歉,发生错误。”

在进行此重定向之前,我是否需要在此步骤中再次附加FormData?

enter image description here

选项4.3

在这种方法中,我要调用我的API并在res.send中创建一个对象,然后将其发送到前端。

try{
     var body = JSON.stringify(req.body);
     const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&param2='+param2+'&param3='+param3+...;
       await fetch(url, {method: "POST", body: body}).then((response) => {
         const data = response;
         res.send({
           success: true,
           redirectURL: data.url,
           body: req.body
         })
      })
       .catch((error) => {
         console.error(error);
       })
   }catch(error){
     console.log(error)
}

在前端,我成功接收了redirectURLbody数据,并尝试进行重定向。

this._myPaymentService.payFunction(form.value).subscribe(res => {
            console.log(res);
            console.log(res.redirectURL);
            window.location.replace(res.redirectURL);
})

然后,Web浏览器转到带有空白内容的下一页。

enter image description here

因为请求已成为GET。我知道不可能以这种方式发送POST请求,而我正在寻找做到这一点的方法。

enter image description here

node.js angular express post payment-gateway
2个回答
1
投票

哇,听起来您很想编写代码,但实际上缺少一些基本知识。您想拥有SPA还是旧学校的POST?当然,当您尝试发送直接API请求时会收到CORS错误。

我非常担心此结果,因为您实际上正在处理付款,并且似乎对体系结构了解不多-也许我错了。您听说过OWASP或CSRF吗?您是否考虑过存储事务以防万一发生不良情况?您是否防止用户发送带有负数的错误请求?那>>

[让自己和用户的口袋放松一下,并在编写代码之前先阅读,至少要讲一些示例,例如,英雄的Angular Tour。

以下是基本外观。

后端是这里的翻译器。它提供了一个API,可将用户发送的数据(经过验证后)转换为支付提供商所需的请求。得到结果后,它将答案转换为对Angular应用程序的已定义响应-这将是成功或错误消息。然后,Angular应用程序可以决定要执行的操作:向用户显示确定或错误消息。

然后!您总是会从付款服务提供商处收到一条消息,如果确实没有收到,则应该实施超时并向用户显示错误消息。

祝您好运,我真的祈祷您了解并实施一些安全措施。

enter image description here


0
投票

这两种方法似乎是正确的:

© www.soinside.com 2019 - 2024. All rights reserved.