【发布时间】:2020-07-04 16:59:40
【问题描述】:
选项 4.2 对我来说似乎是最好的方向。有人有其他建议吗?
有没有办法在以下任何一种情况下访问响应,或者我需要重写整个逻辑?
我需要使用带有或不带有重定向的 NodeJS/ExpressJS 的 Angular Typescript 向 3rd 方支付提供商执行表单 POST。
流程:
问题是在某些情况下,当我成功执行 URL 重定向时我没有收到来自支付网关的任何响应。 当用户点击“支付”时 - “Plati”他被重定向到成功页面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>
选项 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+
'¶m2='+parameters.param2+
'¶m3='+parameters.param3+
'¶m4='+parameters.param4+
'¶m5='+parameters.param5+
'¶m6='+parameters.param6+
'¶m7='+parameters.param7+
'¶m8='+parameters.param8+
'¶m9='+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 错误。
选项 3 - jQuery AJAX
我在我的 Angular 组件中使用 cross-domain 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));
});
选项 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 中,我制作了 myPaymentAPI API 和 307 次重定向 (from this SO answer)。
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 +'¶m2='+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+'¶m2='+param2+'¶m3='+param3+'¶m4='+param4+'¶m5='+param5+'¶m6='+param6+'¶m7='+param7+'¶m8='+param8+'¶m9='+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+'¶m2='+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?
选项 4.3
在这种方法中,我调用我的 API 并在 res.send 中创建一个对象,然后我将其发送到我的前端。
try{
var body = JSON.stringify(req.body);
const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'¶m2='+param2+'¶m3='+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)
}
在前端我成功接收到redirectURL 和body 数据并尝试进行重定向。
this._myPaymentService.payFunction(form.value).subscribe(res => {
console.log(res);
console.log(res.redirectURL);
window.location.replace(res.redirectURL);
})
Web 浏览器随后会转到以下页面,但内容为空白。
因为请求已经变成了GET。我知道以这种方式发送 POST 请求是不可能的,我正在寻找方法。
【问题讨论】:
-
支付服务如何发送错误或成功响应?只是使用查询字符串中的参数重定向到callbak url?
-
@David 我在回调 URL 中没有收到任何响应,这是我最大的问题。文档指出成功 URL 应该是这样的
http://example.com/success?order_number=1233,但我只收到http://example.com/success。我正在等待他们的支持部门对回调 URL 中的参数做出回应。 -
@David 据称,POST 参数位于消息正文中。他们说,URL 保持不变,我需要期待 POST。
-
您在问题中说,用户在成功付款后被重定向到“example.com/success”(example.com 是第 3 方支付网关)。因此,用户必须从该成功页面按下另一个按钮,该按钮将执行发布请求以返回您的网站?
-
@David
example.com/success是我的网站,用户在test-wallet.example.com(支付网关的地址)上成功付款后会被重定向到该页面。
标签: node.js angular express post payment-gateway