Reply
Highlighted
Member
Posts: 1
Registered: ‎03-26-2021
Accepted Solution

Accept.js - Receive Address Data in iframe?

We're using Accept.js, specifically the integrated hosted payment information form (https://developer.authorize.net/api/reference/features/acceptjs.html#Integrating_the_Hosted_Payment_...).

 

The general process is:

 

1. we include the Accept.js javascript

2. we set up an html form that has hidden fields for dataValue and dataDescriptor

3. customer clicks the submit button

4. Accept.js shows an iframe in a modal that receives the customer's credit card data

5. If all goes well, Accept.js fills in the dataValue and dataDescriptor fields, and submits the form to our processing script

6. Our processing script passes the data back to Authorize, to capture the payment.

 

**the above is working fine, in general**

 

The problem we're having is with AVS validation. The iframe only shows a zip field, but not an address line 1 field. International customers are having some trouble getting their cards to validate.

 

Is there a way to get the iframe form to show more info, specifically address line 1?


Accepted Solutions
Solution
Accepted by topic author MikeWillis
‎03-31-2021 12:29 PM
Posts: 492
Topics: 0
Kudos: 99
Blog Posts: 0
Ideas: 0
Solutions: 42
Registered: ‎04-28-2017

Re: Accept.js - Receive Address Data in iframe?

Hi Mike,

 

The Hosted Accept.js form only contains the Postal code field. Alternative options include using your own custom Accept.js form or the Accept Hosted method which does contain additional billing address fields.

 

With Hosted Accept.js, you can pass the customer's billing address along with the nonce in your API call. In which case the postal code included in the API call will be used in AVS checks instead. For AVS checks, the postal code used with createTransactionRequest takes precedence over the value in the nonce.

 

Powered by NexWebSites.com -
Certified Authorize.net developers

View solution in original post


All Replies
Solution
Accepted by topic author MikeWillis
‎03-31-2021 12:29 PM
Posts: 492
Topics: 0
Kudos: 99
Blog Posts: 0
Ideas: 0
Solutions: 42
Registered: ‎04-28-2017

Re: Accept.js - Receive Address Data in iframe?

Hi Mike,

 

The Hosted Accept.js form only contains the Postal code field. Alternative options include using your own custom Accept.js form or the Accept Hosted method which does contain additional billing address fields.

 

With Hosted Accept.js, you can pass the customer's billing address along with the nonce in your API call. In which case the postal code included in the API call will be used in AVS checks instead. For AVS checks, the postal code used with createTransactionRequest takes precedence over the value in the nonce.

 

Powered by NexWebSites.com -
Certified Authorize.net developers
Member
Posts: 1
Registered: ‎07-28-2021

Re: Accept.js - Receive Address Data in iframe?


@NexusSoftware slope game wrote:

Hi Mike,

 

The Hosted Accept.js form only contains the Postal code field. Alternative options include using your own custom Accept.js form or the Accept Hosted method which does contain additional billing address fields.

 

With Hosted Accept.js, you can pass the customer's billing address along with the nonce in your API call. In which case the postal code included in the API call will be used in AVS checks instead. For AVS checks, the postal code used with createTransactionRequest takes precedence over the value in the nonce.

 


i got it, thank you for the explanation.

Contributor
Posts: 10
Registered: ‎07-28-2021

Re: Accept.js - Receive Address Data in iframe?

[ Edited ]

Tobie:

 

Originally I had used the hosted form method (AcceptUI) thinking it was the safest and easiest.. I didn't want to spend the time writing that part of the UI.. but the hosted form with its overlay turned out to be the wrong thing for me.. so I took the time and used Accept.js with my own form and honestly it was not that much work. 

 

I will post my code here in case it's helpful.  I'm still prototyping my store so don't consider this the finished product but it does work pretty well as-is.  You can add the additional fields you want...

 

I don't have a lot of form validation because if the entry is wrong.. authorization will fail :)  But I do some basic validation and turn the field border red if I find a problem.  You can expand my tests if you want.  I plan to expand them when I have time (site has not been launched yet so I'm still working on things).

 

The file 'card.js' comes from the following library which makes the card input look quite nice:

 

https://github.com/jessepollak/card

 

 

 

<style>
    .ccform input, .ccform label {
        display: block;
    }
    .ccform label {
        font-size: 9pt;
        margin: 1px;
    }
    .ccform > div > div {
        display: inline-block;
    }
    div.card-form-wrapper {
        text-align: center;
    }
    div.card-form-wrapper > div {
        display: inline-block;
        text-align: left;
    }
    .payment_footer {
        text-align: center;
        text-transform: uppercase;
        font-size: 12px;
        border: 1px solid;
        margin-top: 10px;
    }
    </style>
    
    
    
    <form id="payment_form" method="POST" action="/checkout/preview/">
    <input type="hidden" name="dataDescriptor" id="id_dataDescriptor">
<input type="hidden" name="dataValue" id="id_dataValue">
<input type="hidden" name="cardNumber" id="id_cardNumber">
<input type="hidden" name="expDate" id="id_expDate">
<input type="hidden" name="fullName" id="id_fullName">
<input type="hidden" name="zip" id="id_zip"> </form> <div class="card-wrapper"></div> <div id="card-form-wrapper" class="card-form-wrapper"> <div> <form class="ccform" id="ccform"> <div> <div> <label for="number">Card Number</label> <input id="number" type="text" name="number" style="width:170px; " /> </div> <div> <label for="expiry">Expiration</label> <input id="expiry" type="text" name="expiry" style="width:80px;" /> </div> </div> <div> <label for="name">Name on Card</label> <input id="name" type="text" name="name" style="width:254px"/> </div> <div> <div> <label for="cvc">CVC</label> <input id="cvc" type="text" name="cvc" style="width: 4em;" /> </div> <div> <label for="zip">Billing Zip</label> <input id="zip" type="text" name="zip" maxlength="5" style="width: 5em;" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" /> </div> <div style="float: right;"> <label for="continue">&nbsp;</label> <input id="continue" type="button" class="btn btn-primary" value="Continue" /> </div> </div> </form> </div> </div> <div class="payment_footer"> You will have the opportunity to review your order before this card is charged. </div> <script src="/static/checkout/js/card/card.js"></script> <script type="text/javascript" src="https://jstest.authorize.net/v1/Accept.js" charset="utf-8"></script> <script> var card = new Card({ // a selector or DOM element for the form where users will // be entering their information form: '.ccform', // *required* // a selector or DOM element for the container // where you want the card to appear container: '.card-wrapper', // *required* formSelectors: { //numberInput: 'input#number', // optional — default input[name="number"] //expiryInput: 'input#expiry', // optional — default input[name="expiry"] //cvcInput: 'input#cvc', // optional — default input[name="cvc"] //nameInput: 'input#name' // optional - defaults input[name="name"] }, //width: 200, // optional — default 350px formatting: true, // optional - default true // Strings for translation - optional messages: { validDate: 'valid\ndate', // optional - default 'valid\nthru' monthYear: 'mm/yyyy', // optional - default 'month/year' }, // Default placeholders for rendered fields - optional placeholders: { number: '•••• •••• •••• ••••', name: 'Full Name', expiry: '••/••', cvc: '•••' }, masks: { cardNumber: '•' // optional - mask card number }, // if true, will log helpful messages for setting up Card debug: true // optional - default false }); function response_handler(response) {
// This is just code from the authorize.net example that
// will log errors to the browser console, I should warn the
// user when this happens but the code is just not done yet.
// However a failure here will be rare. try { if (response.messages.resultCode === "Error") { var i = 0; while (i < response.messages.message.length) { console.log( response.messages.message[i].code + ": " + response.messages.message[i].text ); i = i + 1; } } else { var od = response.opaqueData; document.getElementById("id_dataDescriptor").value = od.dataDescriptor; document.getElementById("id_dataValue").value = od.dataValue; document.getElementById("payment_form").submit(); } } catch (error) { console.log(error); } } document.getElementById('continue').onclick = function() { var name = document.getElementById("name"); var expiry = document.getElementById("expiry"); var number = document.getElementById("number"); var cvc = document.getElementById("cvc"); var zip = document.getElementById("zip"); var errcount = 0; // if any fields are blank or unparseable, indicate to customer for(const f of [name, number, cvc, expiry, zip]) { if(!f.value) { f.style.borderColor = 'red'; errcount++; } else { f.style.borderColor = 'black'; } } // parse date var m; if(m = expiry.value.match(/\s*(\d+)\s*\/\s*(\d+)/)) { var month = m[1], year = m[2].slice(-2); } else {
// browser saved credit card comes in a different format if(m = expiry.value.match(/\s*(\d+)\s*-\s*(\d+)/)) { var month = m[2], year = m[1].slice(-2); } } // We do not validate the month and year value right now, authorize will // do that when we authorize if(!m) { expiry.style.borderColor = "red"; errcount++; } if(errcount) { return; } var secureData = { authData: { clientKey: "34Ph7Z6Etd5k4eeUm2KB5EkjX7K4394KLg7Qjzjw3EkFxEceh6qGSFujDJAMy4U8", apiLoginID: "4NsNS2d6TMuG" }, cardData: { cardNumber: number.value, month: month, year: year, cardCode: cvc.value, fullName: name.value, zip: zip.value } }; console.log(secureData); document.getElementById("id_cardNumber").value = number.value.replace(/\d(?=\d{4})/g, "X"); document.getElementById("id_expDate").value = month + '/' + year; document.getElementById("id_fullName").value = name.value; document.getElementById("id_zip").value = zip.value; Accept.dispatchData(secureData, response_handler); } </script>

 

Hope this helps.

As I said I tried to avoid doing this work and just use the hosted form but now that I've done it I'm glad I did.

 

PS:  The ecommerce system into which I embedded this form already uses bootstrap and stylesheets set up which make the fields, buttons etc look pretty nice.  If you just paste this into your own existing page it may need some styling.  And obviously if your back end is expecting different input field names than mine you would have to change those both in the form and in the javascript.