来自 Angular/NodeJS/ExpressJS 的 3rd 方 URL POST 请求

Tom*_*vic 5 post payment-gateway node.js express angular

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

有没有办法在以下任何一种情况下访问响应,或者我需要重写整个逻辑?


我需要使用带有或不带有重定向的 NodeJS/ExpressJS 的 Angular Typescript 向第 3 方支付提供商执行表单 POST。

流动:

在此处输入图片说明

问题是,在某些情况下,当我成功执行 URL 重定向时,我没有收到来自支付网关的任何响应当用户点击“支付” -“普拉蒂”时,他将被重定向到成功页面http://example.com/success,如果出现错误响应页面http://example.com/cancel

在此处输入图片说明

预期的场景

用户来到网站选择产品并点击购买按钮。那时,他/她会被带到另一个页面,他/她在那里付款。成功付款后,用户被重定向回网站,我收到服务器的响应并向用户显示相关消息。

选项 1 - 表单操作 URL

如果我执行标准表单提交并将支付网关 URL 放在里面,[action]="'https://test-wallet.example.com/checkout/'"那么用户将被直接重定向到该 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>
Run Code Online (Sandbox Code Playgroud)

选项 2 - HttpClient 通过服务

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

付款.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)
   })
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

在此处输入图片说明

选项 3 - jQuery AJAX

我在我的 Angular 组件中使用跨域 contentType调用它。

但我也只收到了上述案例中的 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));
});
Run Code Online (Sandbox Code Playgroud)

选项 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>
Run Code Online (Sandbox Code Playgroud)

在 NodeJS/ExpressJS 中,我制作了myPaymentAPI带有 307 个重定向的 API(来自这个 SO 答案)。

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

    });
Run Code Online (Sandbox Code Playgroud)

以上重定向将用户转移到 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);
       });

});
Run Code Online (Sandbox Code Playgroud)

选项 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)
      }

});
Run Code Online (Sandbox Code Playgroud)

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

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

在此处输入图片说明

选项 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)
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

在此处输入图片说明

因为请求变成了GET。我知道不可能以这种方式发送 POST 请求,我正在寻找这样做的方法。

在此处输入图片说明

Sun*_*ary 1

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

  • 选项1
  • 选项4(使用nodejs服务器-4.1之前支付成功)

然而,有一种流动似乎缺失了。付款完成后,付款 API 服务器会向http://example.com/success或发出 post 请求http://example.com/cancel,并在正文中找到参数。因此,您不能直接使用 url 在屏幕(客户端浏览器)上向用户显示信息。


你需要做的是:

  • 让节点服务器(或者你的后端 API 服务器也可以工作),并使用 app.post 处理服务器上的 url - 就像你为app.post('/myPaymentAPI',).
  • 更新您的数据库或从 req.body 等获取相关付款详细信息或 ID。
  • 创建一个新网址,例如https://yourwebsite.com/payment?status=SUCCESS&other-infohttps://yourwebsite.com/payment/id
  • 将用户重定向到浏览器上的特定 URL
  • 该特定 url 将包含详细信息或 ID。您可以根据需要显示相关详细信息或获取 id 并进行 API 调用
app.post("http://example.com/success", function(req, res){
  //get the req.body/params here which Payment Server will post to success url
  //update your backend etc about payment status etc
  //redirect to your custom page from here https://yourwebsite.com/payment?status=success&id=id or similar
})

app.post("http://example.com/cancel", function(req, res){
  //get the req.body/params here which Payment Server will post to cancel url
  //update your backend etc about payment status etc
  //redirect to your custom page from here https://yourwebsite.com/payment?status=failure&id=id
})
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。如有任何疑问/澄清,请回复