DEVELOPER

iFrame JavaScript SDK



Products

iFrame JavaScript SDK Integration Guide


EnvironmentBase URL
Sandboxhttps://proxy.payanywhere.dev
Productionhttps://proxy.payanywhere.com



How To Start

  1. Sign up for a free North Developer account.
  2. Contact us for Sandbox credentials that can be used to try out this product in a test environment. We will ask that you provide us with the Domain Names (DNS) for the website which will be used to develop and test the integration.
  3. Use the guide below or the Postman Collection to build your app. Resources to assist with development are provided here.
  4. When logged in, you can use the Integration Tracker to view the status of your integration, notes from meetings with Integration Engineers, resources related to your solution, and more by clicking the User profile icon in the top right corner of the screen and selecting Integrations.
  5. When development is complete, contact us to certify your integration. Once certified, the merchant or an authorized contact will be able to retrieve Production credentials from the API Access page of your Production Payments Hub account. For more information about using Payments Hub, visit the Help Center.


Server Requirements

Any connections must be made over TLS v1.2 or higher. The following are the supported ciphers:

  • ECDHE-ECDSA-AES128-GCM-SHA256
  • ECDHE-RSA-AES128-GCM-SHA256
  • ECDHE-ECDSA-AES256-GCM-SHA384
  • ECDHE-RSA-AES256-GCM-SHA384

iFrame JavaScript SDK Setup

1. Place the following JavaScript in a file named "ph.js" (or your preferred name):

// this file contains all the JavaScript needed to initialize the iFrame JavaScript SDK and tokenize a card.
// you can customize the styling of the iFrame fields, adjust the error handling logic, and more by editing this file.

const PayNowSdk = PayNow.default;

// call this function on page load
function initialize_sdk(mid, gateway_public_key)
{
  const options = {
    cardFieldId: 'card-number',
    cvvFieldId: 'card-cvv',
    //comment out the next three lines if you do not want the customer to enter their billing street and zip for AVS
    addressFieldId: 'address',
    zipFieldId: 'zipFirst5',
    zipPlusFourFieldId: 'zipPlus4'
  };

  // triggered when credentials are validated and iframes loaded:
  PayNowSdk().on('ready', () => {
    // set styling for the iframe fields
    const numberStyling = 'border: 1px solid black; width: 160px; height: 20px;';
    const cvvStyling = 'border: 1px solid black; width: 38px; height: 20px;';
    //comment out the next three lines if you do not want the customer to enter their billing street and zip for AVS
    const streetStyling = 'border: 1px solid black; width: 200px; height: 20px;';
    const zipStyling = 'border: 1px solid black; width: 90px; height: 20px;';
    const zip4Styling = 'border: 1px solid black; width: 80px; height: 20px;';

    PayNowSdk().setStyle('number', numberStyling);
    PayNowSdk().setStyle('cvv', cvvStyling);
    //comment out the next three lines if you do not want the customer to enter their billing street and zip for AVS
    PayNowSdk().setStyle('address', streetStyling);
    PayNowSdk().setStyle('zip', zipStyling);
    PayNowSdk().setStyle('zipPlusFour', zip4Styling);

    // set number format for card (optional)
    // can be 'plainFormat', 'prettyFormat', or 'maskedFormat'
    PayNowSdk().setNumberFormat('maskedFormat');

    console.log('ready!');
  });

  // triggered after addCard, checks valid field entries only
  PayNowSdk().on('validation', (inputProperties) => {
    console.log('validation', inputProperties);
  });

  // triggered after getCardToken
  // can be type: "validation" for missing fields or type: "server"
  PayNowSdk().on('errors', (errors) => {
    console.log('error', errors);
    // add your preferred error handling here
  });

  PayNowSdk().init(gateway_public_key, mid, options);
}

// call this function before submitting the payment form
const getToken = async () => {
  document.getElementById('card-token').value = "";

  //document.getElementById('alert_message').innerHTML = "Verifying...";

  //in addition to the fields listed here, the addCard method will also validate the credit card number, CVV, and AVS fields if present
  await PayNowSdk().addCard({
      month: document.getElementById('card-month').value,
      year: document.getElementById('card-year').value,    
  });

  const cardToken = PayNowSdk().getCardToken();

  if (cardToken == null)
  {
    console.log('unable to tokenize the card');
    //document.getElementById('alert_message').innerHTML = "Please verify the card information or use a different card.";
  }
  else
  {
    document.getElementById('card-token').value = cardToken;
    console.log('cardToken', cardToken);

    //document.getElementById('alert_message').innerHTML = "Processing...";
    
    //optional return of AVS fields
    //comment out the next three lines if you do not want the customer to enter their billing street and zip for AVS
    const avsFields = PayNowSdk().getAVSFields();
    const json_string = JSON.stringify(avsFields);
    document.getElementById('avs-fields-data').value = json_string;

    //replace 'pay' below with the id of your form
    document.getElementById('pay').submit();
  }
}

  • addressFieldId: This field is required if zip or zip+4 are present.
  • zipFieldId: This field is required if address or zip+4 are present.
  • zipPlusFourFieldId: If this field is set, the data in it will be added to the zip value to send the 9-digit zip.



2. Add references to the JavaScript SDK file, https://sdk.paymentshub.dev/pay-now.min.js, and your local JavaScript file from Step 1, ph.js, on your checkout page. For example:

HTML
<head>
<script src="https://sdk.paymentshub.dev/pay-now.min.js"></script>
<script src="ph.js"></script>
<link rel="stylesheet" href="ph.css">
<title>Checkout</title>
</head>



3. Add code to initialize the SDK when the checkout page loads, and be sure to replace the placeholders with your credentials. For example:

HTML
<body onload="initialize_sdk('Your MID','Your Gateway Public Key')">



4. Build your form to collect payment data, including any fields necessary for the way that your business wants to process payments. For example, you might include fields for customer name, address, and the card expiration date. A few fields need to be created in a special way to work with the SDK. See below for how to create these fields:

HTML
<label>Card Number:</label>
<div id="card-number" class="form-field" />
</div>
<label>CVV:</label>
<div id="card-cvv" class="form-field" />
</div>
<!-- comment out or remove the below section if you do not want the customer to enter their billing street and zip for AVS -->
<label>Street:</label>
<div id="address" class="form-field" />
</div>
<label>Zip:</label>
<div id="zipFirst5" class="form-field" />
</div>
<label>Zip+4:</label>
<div id="zipPlus4" class="form-field" />
</div>
<input type="hidden" id="avs-fields-data" />
<!-- end of AVS section -->
<input type="hidden" id="card-token" />
<input type="button" onclick="getToken()" name="tokenize_and_pay" value="Submit Payment" />

The SDK will turn these divs into iFrames when the page loads. The hidden card-token field will be populated by the SDK when the user clicks the button to "Submit Payment."

Either set your form's id to "pay", or adjust the JavaScript at the very bottom of the file from Step 1 to use your desired form id.


5. If you would like to customize the appearance of the iFrame fields, place CSS similar to the following in a file named "ph.css" (or your preferred name):

.form-field {
  height: 50px;
  width: 200px;
}



6. When the user clicks the button to "Submit Payment," the browser will make a call to the getToken() JavaScript function defined in the ph.js file. This function uses the SDK to run validation checks and tries to tokenize the card. If either the validation or tokenization step fails, the payment form is not submitted. In these cases, you should notify the user so they can correct the card information on the current page or try another card. When card tokenization is successful, the getToken() function will populate the "card-token" field in your form, right before programmatically submitting the payment form.


7. When the POSTed form is received by your server, you will need to make two calls to API endpoints.

The first call is to authenticate. You can make this call using a variety of server-side languages or libraries of your choice. Here are the details for this request:

Method: POST
Request URL: https://proxy.payanywhere.com/auth

Headers:

NameValueDescription
Content-Typeapplication/jsonRequired. Content type of message. For most messages, this will be the default.
Content-Length1234Required. This value should be set to the exact length of the message body you are sending.
x-nabwss-appsourcepa_isv_1234567890abcRequired. This value is specific to each individual API account. For example, ISVs selling an application to multiple companies would use a different value for each company. Similarly, if a user has multiple accounts (MIDs) with us, the value for the x-nabwss-appsource header would be different for each MID.

Request body:

{
  "mid": "Your MID",
  "developerKey": "Your Developer Key",
  "password": "Your Auth Password"
}

JSON response:

{
  "accountId": "Account ID",
  "mid": "Your MID",
  "token": "JWT"
}

When authentication is successful, you will receive a JSON response which includes a "token" field. The value in this field will be used in the next step.


8. The second API call is to submit the payment. Pass in the information from your payment form including the hidden card-token field. Include the token (JWT) received in the previous call.

Method: POST
Request URL: https://proxy.payanywhere.com/mids/YourMID/gateways/payment

Headers:

NameValueDescription
Content-Typeapplication/jsonRequired. Content type of message. For most messages, this will be the default.
Content-Length1234Required. This value should be set to the exact length of the message body you are sending.
AuthorizationBearer Required. should be replaced with the JSON web token received from the latest authorization.
x-nabwss-appsourcepa_isv_1234567890abcRequired. This value is specific to each individual API account. For example, ISVs selling an application to multiple companies would use a different value for each company. Similarly, if a user has multiple accounts (MIDs) with us, the value for the x-nabwss-appsource header would be different for each MID.

Body:

{
  "token": "Use the value from the posted card-token field",
  "amount": "Amount to charge",
  "gateway_public_key": "Your Gateway Public Key",
  "transaction_source": "PA-JS-SDK"
}



9. Your site will receive a response with details of the attempted payment. Below is a sample response:

{
  "uniq_id": "ccs_329574",
  "response_code": "APR",
  "status_code": "00",
  "status_message": "00 - Approval",
  "last4": "1111",
  "exp_date": "2027-11-01",
  "network": "Mastercard",
  "cc_type": "Keyed",
  "sold_by": "account owner's email address",
  "is_duplicate": false,
  "requested_amt": "1.26",
  "authorized_amt": "1.26"
}

Based on the response (approval, decline, partial auth, etc.), your site can present any relevant information to the user and continue your desired user experience. The uniq_id field can be parsed to get a transaction identifier which can be used for a void or refund of that same transaction. For more details, see the Server Functions page.

©2025 North is a registered DBA of NorthAB, LLC. All rights reserved. North is a registered ISO of BMO Harris Bank N.A., Chicago, IL, Citizens Bank N.A., Providence, RI, The Bancorp Bank, Philadelphia, PA, FFB Bank, Fresno, CA, Wells Fargo Bank, N.A., Concord, CA, and PNC Bank, N.A.