2

I'm having a problem with loading Square iframes to my form. When I navigate from navbar to payment form iframes are not loading in my inputs fields. The only way to load them is to hit refresh of my payment form. Here is my payment.ts:

import { Component, OnInit, Input, EventEmitter, AfterViewInit } from '@angular/core';
import {AppService} from '../app.service';

declare var SqPaymentForm: any;

@Component({
  selector: 'app-payment',
  templateUrl: './payment.component.html',
  styleUrls: ['./payment.component.css']
})
export class PaymentComponent implements OnInit, AfterViewInit  {

  constructor(private appService: AppService) { }
  paymentForm: any ;
  ngOnInit() {
   this.squarePaymentFunction();
  }
  ngAfterViewInit(): void  {}

  squarePaymentFunction() {
    let vm;
    vm = this;
    // this.calculatePayment();
    const applicationId = '********';

    // Set the location ID
    const locationId = '*********';
    this.paymentForm = new SqPaymentForm({

      // Initialize the payment form elements
      applicationId: applicationId,
      locationId: locationId,
      inputClass: 'sq-input',

      // Customize the CSS for SqPaymentForm iframe elements
      inputStyles: [{
        fontSize: '.9em'
      }],

      // Initialize the credit card placeholders
      cardNumber: {
        elementId: 'sq-card-number',
        placeholder: '•••• •••• •••• ••••'
      },
      cvv: {
        elementId: 'sq-cvv',
        placeholder: 'CVV'
      },
      expirationDate: {
        elementId: 'sq-expiration-date',
        placeholder: 'MM/YY'
      },
      postalCode: {
        elementId: 'sq-postal-code'
      },
      // SqPaymentForm callback functions
      callbacks: {

        /*
         * callback function: methodsSupported
         * Triggered when: the page is loaded.
         */
        methodsSupported: function (methods) {
        },

        /*
         * callback function: createPaymentRequest
         * Triggered when: a digital wallet payment button is clicked.
         */
        createPaymentRequest: function () {

          let paymentRequestJson;
          return paymentRequestJson;

        },

        /*
         * callback function: cardNonceResponseReceived
         * Triggered when: SqPaymentForm completes a card nonce request
         */
        cardNonceResponseReceived: function (errors, nonce, cardData)  {
          if (errors) {
            // Log errors from nonce generation to the Javascript console
            console.log('Encountered errors:');
            errors.forEach(function(error) {
              console.log('  ' + error.message);
            });

            return;
          }

          alert('Nonce received: ' + nonce); /* FOR TESTING ONLY */

          // Assign the nonce value to the hidden form field
          // document.getElementById('card-nonce').value = nonce;
          // needs to be extracted from the
          (<HTMLInputElement>document.getElementById('card-nonce')).value = nonce; // casting so .value will work

          let amount = (<HTMLInputElement>document.getElementById('amountToPay')).value;

          // POST the nonce form to the payment processing page
          // (<HTMLFormElement>document.getElementById('nonce-form')).submit();
          vm.sendSqPayment({'nonce': nonce, 'amountToPay': amount});
        },

        /*
         * callback function: unsupportedBrowserDetected
         * Triggered when: the page loads and an unsupported browser is detected
         */
        unsupportedBrowserDetected: function() {
          alert('Your browser seems to be unsupported for card processing. Please try a different browser.');
        },

        /*
         * callback function: inputEventReceived
         * Triggered when: visitors interact with SqPaymentForm iframe elements.
         */
        inputEventReceived: function(inputEvent) {
          switch (inputEvent.eventType) {
            case 'focusClassAdded':
              /* HANDLE AS DESIRED */
              break;
            case 'focusClassRemoved':
              /* HANDLE AS DESIRED */
              break;
            case 'errorClassAdded':
              document.getElementById('error').innerHTML = 'Please fix card information errors before continuing.';
              /* HANDLE AS DESIRED */
              break;
            case 'errorClassRemoved':
              document.getElementById('error').style.display = 'none';
              /* HANDLE AS DESIRED */
              break;
            case 'cardBrandChanged':
              /* HANDLE AS DESIRED */
              break;
            case 'postalCodeChanged':
              /* HANDLE AS DESIRED */
              break;
          }
        },

        /*
         * callback function: paymentFormLoaded
         * Triggered when: SqPaymentForm is fully loaded
         */
        paymentFormLoaded: function() {
          /* HANDLE AS DESIRED */
          console.log('The form loaded!');
        }
      }
    });
  }

  requestCardNonce(event) {


    // Request a nonce from the SqPaymentForm object
    this.paymentForm.requestCardNonce();
  }
  sendSqPayment(data) {
    this.appService.sendPayment(data).subscribe((data) => {
        if (data.success) {
          console.log('Data success');
        }
        // console.log('data', data);
      },
    );
  }
}

I have setup routing in my app.routing.ts using Routes and RouterModlue

pooh098
  • 201
  • 1
  • 4
  • 15
  • 2
    "The only way to load them is to hit refresh of my payment form." Sounds to me like you should utilize the `autoBuild` parameter of the `SqPaymentForm`. Can you try adding `autoBuild: false`, and then calling `this.paymentForm.build()` when your page is loaded? See more info here: https://docs.connect.squareup.com/api/paymentform#build – sjosey Nov 20 '18 at 22:19
  • Can you solve this issue, please tell me. I am also getting same issue. – Harleen Kaur Arora Jun 11 '19 at 11:05
  • @HarleenKaurArora Please, take a look I posted solution below. I hope it will help. – pooh098 Jun 17 '19 at 14:18

1 Answers1

0

First set autobuild to false

squarePaymentFunction() {
    let vm;
    vm = this;

    this.paymentForm = new SqPaymentForm({

      // Initialize the payment form elements
      applicationId: applicationId,
      locationId: locationId,
      inputClass: 'sq-input',
      autoBuild : false,
)};

Then I created a local variable and set to false

formLoaded: boolean =  false;

Next, I created a function to checked if a form is built and add it to ngOnInit():

loadPaymentForm() {
    if (this.formLoaded === false) {
      this.paymentForm.build();
      this.formLoaded = true;
    }
}

And the last step it was to add it my function to input fields

<input id="property_name" formControlName="property_name"  (focus)="loadPaymentForm()" (input)="checkInputError()" type="text" class="form-control" name="property_name" required/>

This is not the best way but it is working.

pooh098
  • 201
  • 1
  • 4
  • 15