【问题标题】:braintree hosted payment fields client undefined Ember 3.25Braintree 托管支付字段客户端未定义 Ember 3.25
【发布时间】:2021-09-04 07:46:36
【问题描述】:

到目前为止,Ember 和 Braintree 托管字段并不是一个很好的组合,Braintree 支持对此没有想法。当表单呈现在页面上时,它会调用操作来创建客户端。客户端未定义。

picture-this-44ac48bef9f8df633632a4d202da2379.js:57 Uncaught TypeError: Cannot read property 'client' of undefined

组件 hbs

<script src="https://js.braintreegateway.com/web/3.81.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.81.0/js/hosted-fields.min.js"></script>
<div class="demo-frame" {{did-insert this.setupBraintreeHostedFields}}>
  <form action="/" method="post" id="cardForm" >
    <label class="hosted-fields--label" for="card-number">Card Number</label>
    <div id="card-number" class="hosted-field"></div>

    <label class="hosted-fields--label" for="expiration-date">Expiration Date</label>
    <div id="expiration-date" class="hosted-field"></div>

    <label class="hosted-fields--label" for="cvv">CVV</label>
    <div id="cvv" class="hosted-field"></div>

    <label class="hosted-fields--label" for="postal-code">Postal Code</label>
    <div id="postal-code" class="hosted-field"></div>

    <div class="button-container">
    <input type="submit" class="button button--small button--green" value="Purchase" id="submit"/>
    </div>
  </form>
</div>

组件类

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { braintree } from 'braintree-web';

export default class CardPaymentComponent extends Component {

  @action
  setupBraintreeHostedFields() {

    alert('booh');
    var form = document.querySelector('#cardForm');
    var authorization = 'sandbox_24nzd6x7_gyvpsk2myght4c2p';

    braintree.client.create({
      authorization: authorization
    }, function(err, clientInstance) {
      if (err) {
        console.error(err);
        return;
      }
      createHostedFields(clientInstance);
    });

    function createHostedFields(clientInstance) {
      braintree.hostedFields.create({
        client: clientInstance,
        styles: {
          'input': {
            'font-size': '16px',
            'font-family': 'courier, monospace',
            'font-weight': 'lighter',
            'color': '#ccc'
          },
          ':focus': {
            'color': 'black'
          },
          '.valid': {
            'color': '#8bdda8'
          }
        },
        fields: {
          number: {
            selector: '#card-number',
            placeholder: '4111 1111 1111 1111'
          },
          cvv: {
            selector: '#cvv',
            placeholder: '123'
          },
          expirationDate: {
            selector: '#expiration-date',
            placeholder: 'MM/YYYY'
          },
          postalCode: {
            selector: '#postal-code',
            placeholder: '11111'
          }
        }
      }, function (err, hostedFieldsInstance) {
        var tokenize = function (event) {
          event.preventDefault();

          hostedFieldsInstance.tokenize(function (err, payload) {
            if (err) {
              alert('Something went wrong. Check your card details and try again.');
              return;
            }

            alert('Submit your nonce (' + payload.nonce + ') to your server here!');
          });
        };

        form.addEventListener('submit', tokenize, false);
      });
    }

  }

}

package.json

...
"ember-cli": "^3.25.2",
"braintree-web": "^3.81.0",
...

** 最终解决方案 **

不需要 NPM 脑树网络。组件类无权访问 Braintree Window 对象。将标签移动到 app/index.html 中,如接受的答案中所述。

组件 hbs

<article class="rental">
  <form action="/" method="post" id="cardForm">
    <label class="hosted-fields--label" for="card-number">Cardholder Name</label>
    <div id="card-holder-name" class="hosted-field payment"></div>

    <label class="hosted-fields--label" for="card-number">Email</label>
    <div id="email" class="hosted-field payment"></div>

    <label class="hosted-fields--label" for="card-number">Card Number</label>
    <div id="card-number" class="hosted-field payment"></div>

    <label class="hosted-fields--label" for="expiration-date">Expiration Date</label>
    <div id="expiration-date" class="hosted-field payment"></div>

    <label class="hosted-fields--label" for="cvv">CVV</label>
    <div id="cvv" class="hosted-field payment"></div>

    <label class="hosted-fields--label" for="postal-code">Postal Code</label>
    <div id="postal-code" class="hosted-field payment"></div>

    <div class="button-container">
    <input type="submit" class="button" value="Purchase" id="submit"/>
    </div>
  </form>
</article>

<script>
var form = document.querySelector('#cardForm');
var authorization = 'sandbox_24nzd6x7_gyvpsk2myght4c2p';

braintree.client.create({
  authorization: authorization
}, function(err, clientInstance) {
  if (err) {
    console.error(err);
    return;
  }
  createHostedFields(clientInstance);
});

function createHostedFields(clientInstance) {
  braintree.hostedFields.create({
    client: clientInstance,
    styles: {
      'input': {
        'font-size': '1.2em',
        'font-family': 'courier, monospace',
        'font-weight': 'lighter',
        'color': '#ccc'
      },
      ':focus': {
        'color': 'black'
      },
      '.valid': {
        'color': '#8bdda8'
      }
    },
    fields: {
      number: {
        selector: '#card-number',
        placeholder: '4111 1111 1111 1111'
      },
      cvv: {
        selector: '#cvv',
        placeholder: '123'
      },
      expirationDate: {
        selector: '#expiration-date',
        placeholder: 'MM/YYYY'
      },
      postalCode: {
        selector: '#postal-code',
        placeholder: '11111'
      }
    }
  }, function (err, hostedFieldsInstance) {
    var tokenize = function (event) {
      event.preventDefault();

      hostedFieldsInstance.tokenize(function (err, payload) {
        if (err) {
          alert('Something went wrong. Check your card details and try again.');
          return;
        }

        alert('Submit your nonce (' + payload.nonce + ') to your server here!');
      });
    };

    form.addEventListener('submit', tokenize, false);
  });
}
</script>

【问题讨论】:

    标签: ember.js braintree braintree-sandbox


    【解决方案1】:

    您可以通过直接脚本标签或在ember-auto-import 的帮助下使用 npm 模块来使用 Braintree SDK。在您的情况下,您同时使用两者。

    为简单起见,让我们使用脚本标签来注入 SDK。您的 sn-p 中的问题是您正在尝试将脚本标签加载到组件车把文件中。把手(.hbs 文件)无法使用 &lt;script&gt; 标签加载脚本。我们需要将脚本标签移动到app 文件夹中的 index.html 文件中。这将正确加载 SDK 以在组件中使用。

    app/index.html:

    <body>
      ...
    
    
      <script src="https://js.braintreegateway.com/web/3.81.0/js/client.min.js"></script>
      <script src="https://js.braintreegateway.com/web/3.81.0/js/hosted-fields.min.js"></script>
    
      {{content-for "body-footer"}}
    </body>
    

    正确注入 SDK 后,您可以毫无问题地使用 braintree 窗口对象。

    【讨论】:

    • 我所指的 HTML 页面是整个 ember 应用程序的单个 HTML (app/index.html) 文件。我不确定您的开发设置。必须有一个 HTML 文件才能启动任何 ember 应用程序。
    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 2023-03-14
    • 2019-03-26
    • 2018-10-15
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    相关资源
    最近更新 更多