【问题标题】:How to integrate worldpay with angular2如何将worldpay与angular2集成
【发布时间】:2017-03-23 06:14:19
【问题描述】:

我正在尝试将 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 从模板中删除所有标签&lt;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:&lt;div #worldPayScriptElement hidden&gt;&lt;/div&gt;

但是, 由于他们的处理规则,worldpay 将使用名为 CreditCardToken

的字段替换我表单中的敏感数据

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

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

我将非常感谢任何形式的建议。

【问题讨论】:

    标签: angular typescript payment-gateway payment worldpay


    【解决方案1】:

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

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

    对于任何其他细节,请不要犹豫评论/询问:)

    【讨论】:

    • 是的。如果您符合 PCI 标准并且乐于处理信用卡详细信息,那就太好了,否则您将不得不在 iframe 中使用 worldpay 或将用户转到 worldpay 网站。
    • ...无聊...他们还没有为 angular2 实现包装器吗? (按照我上面写的实现解决方案后我没有检查)
    • “他们”我的意思是 worldpay :)
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      这是 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);
        }
      }
      

      【讨论】:

      • 不错的贡献!谢谢@Zymotik
      猜你喜欢
      • 2013-07-21
      • 2011-09-25
      • 1970-01-01
      • 2010-11-03
      • 2012-01-16
      • 2011-04-21
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多