0

I'm trying to incorporate balanced payment processing into my site, however, their solution assumes a standard HTML form is in use and retrieves it with jQuery. Since I'm using knockout.js to power my forms, the inputs are referenced differently which means I had to modify my form. For this example, I manually set the value of the credit card data rather than take it from the $(#credit-card-form)

When I open up the network tab to check for errors it says "Uncaught TypeError: Property '0' of object # is not a function" which I'm thinking is in reference to the input attribute being appended to creditCardData

This fiddle is the example that Balanced gives to show how it works. In the javascript area, you must create a new request bin and copy that bin into the code. Then when you update the code and click "tokenize", visit that request bin URL and you'll see the request was submitted.

I created this fiddle which properly tokenizes the card, but I'm getting errors and can't quite pin it down to where they're coming from. Remember, you must create your own requestbin and copy/paste that URL into the code. Just a heads up, that "tokenize" button won't do anything. I just left the HTML there, it really doesn't do anything considering the function is called as soon as the fiddle opens.

The main difference between my version and Balanced's is in the initial call to balanced.js functions.

//paidForItems is a button set with knockout.js
self.paidForItems = function() {

      //responseCallbackHandler here, see fiddle for details

     var creditCardData = {
        card_number: '4111111111111111',
        expiration_month: '01',
        expiration_year: '2020',
        security_code: '123'
    };

    balanced.card.create(creditCardData, responseCallbackHandler);
}

Whereas balanced does it upon submitting a form

 //responseCallbackHandler here, see fiddle for details

var tokenizeInstrument = function(e) {
   e.preventDefault();

   var $form = $('#credit-card-form');
   var creditCardData = {
        card_number: $form.find('.cc-number').val(),
        expiration_month: $form.find('.cc-em').val(),
        expiration_year: $form.find('.cc-ey').val(),
        security_code: $form.find('cc-csc').val()
    };

    balanced.card.create(creditCardData, responseCallbackHandler);
};
$('#credit-card-form').submit(tokenizeInstrument);
user1406951
  • 454
  • 1
  • 10
  • 28
  • Do you have this running on open or on pageload? JQuery really wants to wait for pageload for things like this. – Ben Barden Jul 12 '13 at 19:24
  • I don't see anything different between .val() and hard coding a string value in. I think there's something else going on – Andrew Walters Jul 12 '13 at 19:27
  • @BenBarden I'm not quite sure what you mean. I thought I explained how the functions are called pretty clearly, unless you're referring to something else. – user1406951 Jul 12 '13 at 19:29
  • @AndrewWalters did you look at the two fiddles and try them out? The balanced fiddle works and the one I made doesn't. My fiddle will tokenize the card value as shown by the popup, but it throws an error following that. – user1406951 Jul 12 '13 at 19:31
  • @BenBarden Sorry, just had looked at yours and the code snippets. Yours was erroring out due to permissions. I'll check out the balanced fiddle now – Andrew Walters Jul 12 '13 at 19:33
  • On second read-through, I see I had misunderstood what you meant. Mind you, it is still somewhat difficult to understand exactly what you are describing. If you could be clearer about where things are actually breaking down, that might help. I take it the "balanced" version works fine, and your version is producing the described error when run? – Ben Barden Jul 12 '13 at 19:36
  • @AndrewWalters I assume that that was intended for the OP - and I think that the erroring out due to permissions is why the OP said to create a new request bin to run it in. – Ben Barden Jul 12 '13 at 19:38
  • @AndrewWalters the reason why I said create a new Request Bin is because on that request bin it shows where the IP request came from. I could have used one, but anytime someone posts to it, their IP would be available for everyone to see. – user1406951 Jul 12 '13 at 19:42
  • I tried to make a new one & paste the URL in. But still have some permissions errors. Do you have to supply any user/pass to get their example to work? – Andrew Walters Jul 12 '13 at 19:43
  • @AndrewWalters Hmm, it should work fine. It's publically available on their site [here](https://docs.balancedpayments.com/current/overview.html#collecting-credit-card-information) – user1406951 Jul 12 '13 at 19:44
  • Hm, I'll try to take a look when I get off work. Maybe our network is messing with things – Andrew Walters Jul 12 '13 at 20:05

1 Answers1

1

Going to put into an answer since the comments are getting a bit lengthy.

I am not getting permissions errors anymore so I guess something was blocked at work.

The main difference is they're submitting an HTML form and you're (trying to) submitting a javascript object.

I'm pretty sure you can't call .submit() on any random object.

You'll need to do it like this:

http://jsfiddle.net/sKjPF/2/

case 201:
            console.log(response.data);
            var cardTokenURI = response.data['uri'];

            // append the token as a hidden field to submit to the server
              var form = $("#credit-card-form");
            $('<input>').attr({
               type: 'hidden',
               value: cardTokenURI,
               name: 'balancedCreditCardURI'
            }).appendTo(form);
            form.attr({action: requestBinURL});
            form.submit();

Let me know if that doesn't help out.

Andrew Walters
  • 4,763
  • 6
  • 35
  • 49
  • Thank you so much. I do have one question though. Considering I'm using knockout.js and acquire my form inputs and not jQuery, won't form always be null for me? This clearly works, but I'm a bit confused as to what happens to "var form"'s value since it's not actually being set. – user1406951 Jul 13 '13 at 03:45
  • You should still have a form using knockout. Worst case you dynamically inject a form into the DOM then submit that – Andrew Walters Jul 13 '13 at 03:53
  • While there are forms with knockout, it masks them so you don't explicitly declare form names, at least that I'm aware of. For example, a given input you just bind the value and knockout does the rest. When you say dynamically inject a form, do I just create a "fake" form and not assign anything to it? – user1406951 Jul 13 '13 at 04:03
  • Ya, but you still should have a form tag somewhere on the page, if not you can do something like this and dynamically create the credit card inputs they're expecting to be posted: http://stackoverflow.com/questions/6964927/how-to-create-a-form-dynamically-via-javascript – Andrew Walters Jul 13 '13 at 12:54
  • I'm not sure how familiar you are with knockout, or maybe you're so familiar with it that you understand how it works behind the scenes. [Here is a fiddle](http://jsfiddle.net/c6bxE/) for a very basic knockout.js form. As far as I can tell there is no explicit form name declaration. From what it looks like, knockout does that for you behind the scenes. – user1406951 Jul 13 '13 at 18:30
  • I've been using it a decent amount recently in .net pages which are wrapped with a form tag by default. You can drop in a
    tag around your inputs without any issue I imagine
    – Andrew Walters Jul 14 '13 at 19:03
  • thanks for your help! I need to stop being so unimaginative and just try things out. Sorry for bugging you, and I really appreciate your help. – user1406951 Jul 14 '13 at 21:44