Вариант 4.2 кажется мне лучшим направлением. У кого-нибудь есть другие предложения?
Есть ли способ получить ответ в любом из нижеприведенных сценариев ios или мне нужно переписать весь лог c?
I необходимо выполнить форму POST для стороннего поставщика платежей с Angular Typescript с или без NodeJS / ExpressJS с перенаправлением.
Поток:
Проблема заключается в том, что в некоторых случаях при успешном выполнении перенаправления 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>
Вариант 2 - HttpClient через службу
Я также пытался сделать запрос HttpClient POST внутри приложения Angular и без 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 компонента с кросс-доменным contentType .
Но я также получил только ошибку CORS, как в случае выше. Я знаю, что использование jQuery в приложении Angular не по книге, но мне пришлось попробовать.
$.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 Backend
Если я использую этот подход, то я получаю перенаправление так же, как и в первом случае. Но мой бэкэнд не получает ответа от провайдера платежного шлюза.
В приложении 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 перенаправлениями ( из этого ответа 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 +'¶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);
})
Затем веб-браузер переходит к следующему страница с пустым содержимым.
Поскольку запрос стал GET. Я знаю, что отправить запрос POST таким способом невозможно, и я ищу способ сделать это.