4

我正在尝试将 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()方法中的页面中注入一些脚本(就像我在第一步中所做的那样)

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模板中 div 的 ViewChild 在哪里:<div #worldPayScriptElement hidden></div>

但是,由于他们的处理规则,worldpay 将用一个名为CreditCardToken的字段替换我表单中的敏感数据

来自源:最后,在 Worldpay.formBuilder() 中,所有敏感的卡数据都从表单中删除,替换为令牌,然后才将表单提交回您的服务器。 来源:https ://developer.worldpay.com/jsonapi/docs/own-form

如何继续整合这个......无法理解。
如果他们有一个基于GET/POST请求返回 CreditCardToken 的 API,那将是完美的,但从文档中我还没有找到合适的方法......

我将非常感谢任何建议。

4

3 回答 3

3

我已经决定考虑另一种方法:)

我已经使用 Worldpay 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)

我如何在 angular2 中调用 worldpay API?

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#tokens

有关任何其他详细信息,请随时发表评论/询问:)

于 2016-12-14T09:15:30.003 回答
3

如果您可以使用 API,则接受的答案很好,但如果您不符合 PCI-DSS,则不应使用 API。

对于在 Angular 2+ 中使用模板表单或您自己的表单,我使用的步骤如下:

  1. 以某种方式包括Worldpay.js

    • 作为脚本的本地副本.angular-cli.json
    • 通过在您的组件中导入的本地副本,例如import '../../libs/worldpay';
    • index.html在从 CDN 加载它的 main 中包含一个 script 标签:
      <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,这涉及自我评估过程(冗长的文书工作)。

于 2017-09-16T11:34:38.693 回答
1

这是 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);
  }
}
于 2017-11-02T12:59:20.437 回答