Как интегрировать worldpay с angular2
Я пытаюсь интегрировать Worldpay в приложение angular2.
Я использую собственный подход формы ( own-form), где необходимо включить их скрипт на странице: <script src="https://cdn.worldpay.com/v1/worldpay.js"></script>
Добавьте конкретные атрибуты для некоторых входов: data-worldpay
и присоединить логику Worldpay.js к форме...
Мне удалось сделать шаги:
1. Включите Worldpay.js на свою страницу
2. Создайте форму оплаты с соответствующими атрибутами
Как я могу продолжать делать следующие шаги... Я застрял на этой проблеме:
5. Прикрепите Worldpay.js к вашей форме:
<script type="text/javascript">
var form = document.getElementById('paymentForm');
Worldpay.useOwnForm({
'clientKey': 'your-test-client-key',
'form': form,
'reusable': false,
'callback': function(status, response) {
document.getElementById('paymentErrors').innerHTML = '';
if (response.error) {
Worldpay.handleError(form, document.getElementById('paymentErrors'), response.error);
} else {
var token = response.token;
Worldpay.formBuilder(form, 'input', 'hidden', 'token', token);
form.submit();
}
}
});
</script>
Зачем?
angular2 удаляет все теги <script
из шаблонов.
Предположим, что с помощью обходного пути можно внедрить некоторые сценарии на странице в ngAfterViewInit()
метод (как я сделал для 1-го шага)
ngAfterViewInit(): void {
let s = document.createElement("script");
s.type = "text/javascript";
s.src = "https://cdn.worldpay.com/v1/worldpay.js";
this.worldPayScriptElement.nativeElement.appendChild(s);
}
где this.worldPayScriptElement
является ViewChild div из шаблона: <div #worldPayScriptElement hidden></div>
Но, согласно их правилам обработки, worldpay заменит конфиденциальные данные из моей формы на поле с именем CreditCardToken
Из источника: Наконец, в Worldpay.formBuilder() все конфиденциальные данные карты удаляются из формы, заменяются токеном, и только после этого форма отправляется обратно на ваш сервер. источник: https://developer.worldpay.com/jsonapi/docs/own-form
Как продолжить интеграцию этого... Не могу понять.
Если бы у них был API, возвращающий CreditCardToken на основе GET/POST
запрос был бы идеальным, но из документации я пока не нашел подходящий метод для этого...
Я буду очень признателен за любые предложения.
3 ответа
Я решил, что с учетом другого подхода:)
Я использовал Worldpay API для получения токена.
URL API: https://api.worldpay.com/v1/tokens
Конечная точка ожидает POST
запрос в форме:
'{
"reusable": true/false,
"paymentMethod": {
"name": "name",
"expiryMonth": 2,
"expiryYear": 2015,
"issueNumber": 1,
"startMonth": 2,
"startYear": 2013,
"cardNumber": "4444 3333 2222 1111",
"type": "Card",
"cvc": "123"
},
"clientKey": "T_C_client_key"
}'
где Header
должен содержать эти параметры: "Content-type: application/json"
Имея это, больше не нужно включать worldpay.js
на странице
Кроме того, больше не нужно включать в форму оплаты определенные атрибуты worldpay (например, data-worldpay=""
)
Просто следует вызвать API, дождаться ответа, который будет иметь вид:
{
"token": "UUID of token",
"reusable": true/false,
"paymentMethod": {
"type" : "ObfuscatedCard",
"name": "name",
"expiryMonth": 2,
"expiryYear": 2015,
"issueNumber": 1,
"startMonth": 2,
"startYear": 2013,
"cardType": "VISA_CREDIT",
"maskedCardNumber": "xxxx xxxx xxxx 1111",
"cardSchemeType": "consumer",
"cardSchemeName": "VISA CREDIT",
"cardProductTypeDescNonContactless": "Visa Credit Personal",
"cardProductTypeDescContactless": "CL Visa Credit Pers",
"cardIssuer": "LLOYDS BANK PLC",
"countryCode": "GBR",
"cardClass": "credit",
"prepaid": "false"
}
}
Из ответа вы готовы использовать response.token
чтобы перейти к следующему шагу: оплата.
Вы должны убедиться, что будут отправлены определенные атрибуты WorldPay (CreditCardToken, Enrolled)
Как я вызывал worldpay API в angular2?
public getWorldpayToken(request: any): Observable<any>{
let worldPayApiUrl = `https://api.worldpay.com/v1/tokens`;
let body = JSON.stringify(request);
let headers = new Headers({ 'Content-Type':'application/json;charset=UTF-8'});
let options = new RequestOptions({ headers: headers });
return this.http.post(worldPayApiUrl, body, options)
.map(response => response.json())
.catch(this.handleError);
}
Документация: https://developer.worldpay.com/jsonapi/api
Для любых других деталей, не стесняйтесь комментировать / спрашивать:)
Принятый ответ будет хорошим, если вы можете использовать API, но если вы не совместимы с PCI-DSS, вам не следует использовать API.
Для использования формы шаблона или вашей собственной формы в Angular 2+ я использовал следующие шаги:
Включают
Worldpay.js
так или иначе:- Локальная копия как скрипт в
.angular-cli.json
- Локальная копия через импорт в вашем компоненте, например
import '../../libs/worldpay';
- Включить тег сценария в основной
index.html
загрузка его из cdn:<script src="https://cdn.worldpay.com/v1/worldpay.js"></script>
- Локальная копия как скрипт в
Удовлетворить Typescript, что он доступен в вашем компоненте:
declare var Worldpay: any;
Используйте ViewChild, чтобы получить ссылку на форму:
@ViewChild('paymentForm') form;
и в HTML:
<form #paymentForm>
Реализуйте обратный вызов, например:
worldpayCallback(status, response) { if (response.error) { this.handleError(response.error.object); } else { this.token = response.token; } }
Инициализируйте Worldpay подходящим способом, например:
ngOnInit(): void { Worldpay.useTemplateForm({ 'clientKey': this.worldpayKey, 'form': this.form.nativeElement, 'callback': (status, response) => this.worldpayCallback(status, response) }); }
Теперь вы должны иметь токен, доступный вам после отправки формы.
Обратите внимание, что если вы используете свою собственную форму, вам необходимо стать совместимым с PCI SAQ A-EP, что предполагает процесс самооценки (длительные документы).
Это рабочий пример в Angular 4/5. Пожалуйста, добавьте ваш ключ API клиента в Worldpay.component.ts
https://plnkr.co/edit/vz6YX68ykyBuHGiwGBVx
Шаблон:
<form #paymentForm *ngIf="!token">
<div id="paymentSection"></div>
</form>
<h2 *ngIf="token">Token from WorldPay {{ token }}</h2>
Составная часть:
import { Component, OnInit, ViewChild } from '@angular/core';
declare var Worldpay: any;
@Component({
selector: 'app-worldpay',
templateUrl: './worldpay.component.html'
})
export class WorldpayComponent implements OnInit {
@ViewChild('paymentForm') form;
readonly worldpayClientKey = 'ADD_YOUR_KEY_HERE';
token: string = null;
constructor() { }
ngOnInit() {
this.loadScript('https://cdn.worldpay.com/v1/worldpay.js', this.init);
}
init = (): void => {
Worldpay.useTemplateForm({
'clientKey': this.worldpayClientKey,
'form': this.form.nativeElement,
'paymentSection': 'paymentSection',
'display': 'inline',
'type': 'card',
'callback': this.worldpayCallback
});
}
worldpayCallback = (status): void => {
this.token = status.token;
}
private loadScript(url: string, callbackFunction: (any) = undefined) {
const node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
node.onload = callbackFunction;
document.getElementsByTagName('body')[0].appendChild(node);
}
}