Search code examples
javascripthtmlpolymerbraintreepolymer-starter-kit

Braintree Hosted Fields not rendering on Polymer


I'm attempting to use braintree's hosted fields on a polymer application and am running into an issue where the input boxes representing the hosted fields are not rendering. No errors are appearing, and iFrame that would normally contain the input boxes are rendering properly.

Here is part of my code, which is fairly similar the the basic example code provided by braintree on their webisite here, just modified so that it functions properly within a custom polymer element.

<script src="https://js.braintreegateway.com/web/3.5.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.5.0/js/hosted-fields.min.js"></script>

<dom-module id="my-view1">
  <template>
    <style include="shared-styles">
    </style>
    <form action="/" method="post" id="cardForm" >
      <div class="horizontal layout center-justified card-container">
        <div class="vertical layout center-justified">
          <paper-card id="creditCardDetails" heading="Credit Card Information" class="card-content" elevation="2" style="">
            <div class="field-label">
              <label class="hosted-field-braintree--label" for="card-number">Card Number</label>
              <div id="card-number" class="hosted-field-braintree"></div>
            </div>
            <div class="field-label">
              <label class="hosted-field-braintree--label" for="expiration-date">Expiration Date</label>
              <div id="expiration-date" class="hosted-field-braintree"></div>
            </div>
            <div class="field-label">
              <label class="hosted-field-braintree--label" for="cvv">CVV</label>
              <div id="cvv" class="hosted-field-braintree"></div>
            </div>
            <div>
              <paper-button id="creditButton" raised class="custom-color" on-click="_onCreditButtonClick">Submit</paper-button>
            </div>
          </paper-card>
        </div>
      </div>
    </form>
  </template>

  <script>
    Polymer({
    is: 'payment'
    ...
    });

    var form = document.querySelector("*/deep/#cardForm");
    braintree.client.create({
    authorization: 'sandbox_g42y39zw_348pk9cgf3bgyw2b'
    }, function (clientErr, clientInstance) {
      if (clientErr) {
        console.error(clientErr);
        return;
      }

      braintree.hostedFields.create({
        client: clientInstance,
        styles: {
          'input': {
            'font-size': '14px'
          },
          'input.invalid': {
            'color': 'red'
          },
          'input.valid': {
            'color': 'green'
          }
        },
        fields: {
          number: {
            selector: '*/deep/#card-number',
            placeholder: '4111 1111 1111 1111'
          },
          cvv: {
            selector: '*/deep/#cvv',
            placeholder: '123'
          },
          expirationDate: {
            selector: '*/deep/#expiration-date',
            placeholder: '10/2019'
          }
        }
      }, function (hostedFieldsErr, hostedFieldsInstance) {
           if (hostedFieldsErr) {
             console.error(hostedFieldsErr);
             return;
           }
           console.log(hostedFieldsInstance)
         });
       });           
     }); 
   });
  </script>

Any help in the right direction is appreciated.


Solution

  • Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.

    At the moment, the Polymer library and the Braintree Javascript library are incompatible. We're starting a conversation with the Polymer team in hopes of finding a way they can work together.

    Braintree's Hosted Fields inserts iFrames in each selector that you name in the setup. To initialize these frames and communicate with them, it relies on the created iframes being referenced in the window.frames property on the merchant's page.

    Polymer's Shadow DOM abstracts and hides many things in the DOM, and part of that work prevents iframes in the Shadow DOM from being included in window.frames. This means that when running alongside Polymer, the Braintree Javascript SDK cannot access the iframes that it created, leaving them rendered, but uninitialized and useless.