Как интегрировать 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+ я использовал следующие шаги:

  1. Включают Worldpay.js так или иначе:

    • Локальная копия как скрипт в .angular-cli.json
    • Локальная копия через импорт в вашем компоненте, например import '../../libs/worldpay';
    • Включить тег сценария в основной index.html загрузка его из cdn:
      <script src="https://cdn.worldpay.com/v1/worldpay.js"></script>
  2. Удовлетворить Typescript, что он доступен в вашем компоненте:

    declare var Worldpay: any;   
    
  3. Используйте ViewChild, чтобы получить ссылку на форму:

    @ViewChild('paymentForm') form;
    

    и в HTML:

    <form #paymentForm>
    
  4. Реализуйте обратный вызов, например:

    worldpayCallback(status, response) {        
      if (response.error) {
        this.handleError(response.error.object);
      } else {
        this.token = response.token;
      }
    }
    
  5. Инициализируйте 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);
  }
}
Другие вопросы по тегам