Braintree Angular and Ionic custom integration iframe issues

Viewed 648

I'm attempting to integrate Braintree - Hosted Fields into an ionic application. Currently my implementation works fine on browsers through ionic serve but as soon as I run it on iOS simulator / device I get the following error:

Blocked a frame with origin "https://assets.braintreegateway.com" from accessing
a frame with origin "file://".  The frame requesting access has a protocol of "https",
the frame being accessed has a protocol of "about". Protocols must match.

I understand that braintree isn't fully supported on hybrid apps due to it relying on iframes (which is what seems to be causing my issue), but I think it's worth looking for help here.


Background:

I based the implementation on Jeff Carpenter's Braintree Angular repo (a developer @ Braintree). I forked the repo, updated the braintree-web dependency and included a new directive to implement my custom integration of Braintree:

braintree-angular.js

// ...

braingular.directive('braintreeCustom', function() {
  return {
    restrict: 'A',
    scope: {
      options: '=braintreeCustom',
    },
    controller: function($scope, $braintree) {
      var options = $scope.options || {};
      $braintree.setupCustom(options);
    }
  }
});

// ...

$braintree.setupCustom = function(options) {
  $braintree.getClientToken().then(function(token) {
    braintree.setup(token, 'custom', options);
  }, function(error) {
    console.error('error fetching client token at '+clientTokenPath, error);
  });
}

And then for setting up the client, I have the following code in my controller:

controller.js

vm.braintree = {
    options: {
        enableCORS: true,
        id: "bt-form",
        hostedFields: {
            styles: {
                'input': {
                  'font-size': '16pt',
                  'color': '#ffc900'
                },
            },
            onFieldEvent: _handleBraintreeEvents,
            number: {
                selector: '#hosted-fields-number',
            },
            expirationMonth: {
                selector: '#hosted-fields-expiration-month',
            },
            expirationYear: {
                selector: '#hosted-fields-expiration-year',
            },
            cvv: {
                selector: '#hosted-fields-cvv'
            }
        }
    }
};

//////////////////////////////////////////////


function _handleBraintreeEvents(event) {
    switch(event.type) {
        // case 'focus':
        case 'blur':
            console.log(event);
        case 'fieldStateChange':
            switch(event.target.fieldKey) {
                case 'number':
                    vm.btNumberValid = event.isValid;
                    break;
                case 'expirationMonth':
                    vm.btExpirationMonthValid = event.isValid;
                    break;
                case 'expirationYear':
                    vm.btExpirationYearValid = event.isValid;
                    break;
                case 'cvv':
                    vm.btCvvValid = event.isValid;
                    break;
                default:
                    break;
            }
            if (event.card) {
                console.log(event.card);
                vm.braintree.cardCode = event.card.code.name || 'CVV';
            }
            break;
        default:
            break;
    }

    $scope.$digest();
}

And finally my payment form:

payment.html

<form id="bt-form" braintree-custom="vm.braintree.options">
  <ion-list>
    <div class="row">
      <div class="col col-67">
        <ion-item class="dir-rtl splash-input-label item-input item-stacked-label item-icon-left">
          <i ng-if="!vm.btNumberValid" class="icon ion-alert-circled assertive"></i>
          <span class="input-label">Card Number</span>
          <div id="hosted-fields-number" class="bt-hosted-field"></div>
        </ion-item>
      </div>
      <div class="col col-33">
        <ion-item class="dir-rtl splash-input-label item-input item-stacked-label item-icon-left">
          <i ng-if="!vm.btCvvValid" class="icon ion-alert-circled assertive"></i>
          <span class="input-label">{{vm.braintree.cardCode}} *</span>
          <div id="hosted-fields-cvv" class="bt-hosted-field"></div>
        </ion-item>
      </div>
    </div>
    <div class="row">
      <div class="col">
        <ion-item class="dir-rtl splash-input-label item-input item-stacked-label item-icon-left">
          <i ng-if="!vm.btExpirationYearValid" class="icon ion-alert-circled assertive"></i>
          <span class="input-label">Exp. Year</span>
          <div id="hosted-fields-expiration-year" class="bt-hosted-field"></div>
        </ion-item>
      </div>
      <div class="col">
        <ion-item class="dir-rtl splash-input-label item-input item-stacked-label item-icon-left">
          <i ng-if="!vm.btExpirationMonthValid" class="icon ion-alert-circled assertive"></i>
          <span class="input-label">Exp. Month</span>
          <div id="hosted-fields-expiration-month" class="bt-hosted-field"></div>
        </ion-item>
      </div>
    </div>

  </ion-list>
</form>

I'm not quite sure how to tackle this , so any advice or suggestions will be highly appreciated.

0 Answers
Related