Hosted Payment Fields

Learn how to implement Hosted Payment Fields for PCI compliance of SAQ-A & maximum flexibility.

If you would like to build your custom checkout flow using the API, but keep your PCI compliance requirements limited to the minimal SAQ-A level, BlueSnap’s Hosted Payment Fields are the ideal solution.

Hosted Payment Fields are iframes that replace sensitive credit card input fields on your checkout page. When the shopper submits the checkout form, BlueSnap binds this payment data to a token. You can then easily process payments or save shopper details by including the token in your BlueSnap API requests.

📘

This setup guide supports the latest version 5 (Web SDK) of Hosted Payment Fields. If you're currently using version 4, visit our Hosted Payment Fields FAQs page to learn how to upgrade.

This guide covers:

To learn about optional styling, customizing accessibility features, and masking, see Customizing the Hosted Payment Fields.

Benefits

  • Control the look and feel of your checkout flow, including the Hosted Payment Fields
  • Simplest level of PCI compliance: SAQ-A
  • Securely capture payment information without your shoppers ever leaving your site
  • Use the Hosted Payment Fields Token to complete a sale, as well as create or update a vaulted shopper
  • Built-in Fraud Prevention with Device Data Check services

How it Works

750

First, you create a Hosted Payment Fields Token for the specific checkout session, using a server-to-server API call. On the checkout form, you call BlueSnap’s Hosted Fields JavaScript file with this Hosted Payment Fields Token. After the shopper completes the form and clicks Submit, the sensitive payment data from the Hosted Payment Fields is saved in BlueSnap’s database and bound to the Hosted Payment Fields Token you provided. This includes Credit Card Number, Expiration Month/Year, CVV. Once the form has been submitted, you can use the Hosted Payment Fields Token to process the purchase, create a shopper, or update a shopper with the new card details provided on the checkout page.

Back to Top

Implementing Hosted Payment Fields in your checkout form

Before Getting Started

  • Authentication: You need a BlueSnap account and API credentials to take advantage of Hosted Payment Fields.
  • Domain: In all steps below, replace the BLUESNAPDOMAINPATH with the relevant domain for either the BlueSnap Sandbox or Production environment, as follows:
    • Sandbox: https://sandpay.bluesnap.com
    • Production: https://pay.bluesnap.com
    • For example, the bluesnap.js script in Step 2 should be downloaded from: https://sandpay.bluesnap.com/web-sdk/5/bluesnap.js on Sandbox and https://pay.bluesnap.com/web-sdk/5/bluesnap.js on Production.
  • Errors: If you encounter any errors while following the steps below, refer to Hosted Payment Fields Errors.
  • Programming Languages: You can use plain JavaScript with Hosted Payment Fields. Though our solution does not require jQuery, you may choose to use jQuery or JS frameworks like AngularJS and React.
  • Hosted Payment Fields Token = pfToken

1. Obtain the Hosted Payment Field Token (pfToken) for the session

Obtain the Hosted Payment Field token by sending a server-to-server POST request to:

Production: https://ws.bluesnap.com/services/2/payment-fields-tokens
Sandbox: https://sandbox.bluesnap.com/services/2/payment-fields-tokens

🚧

Important

Be sure to include the intended URL for the environment you are choosing to use. Including a URL that does not match the environment it is being used in will prevent the solution from working correctly.

Find all the API request details on the Create Hosted Payment Fields Token page. You will need a BlueSnap account in order to generate a Hosted Payment Field token. If you don't have an account yet, you can sign up for one here.

Reusing a pfToken (optional)

For each session, you need to create a new token via the Create Hosted Payment Fields Token request. The token expires 60 minutes after its creation. Within these 60 minutes, you may do the following:

  1. Client-side — Call bluesnap.hostedPaymentFieldsSubmitData to submit the shopper's payment details to BlueSnap and bind them to the token. This function can be called as many times as needed before the 60 minutes are up, and before sending the token in a request from your server to BlueSnap.

  2. Server-side — After the shopper's card details are associated with the token (assuming the token has not yet expired), you may send the token in a request to BlueSnap to either submit the payment for processing or save the payment information to a shopper. After the token is successfully submitted in a request to BlueSnap, it expires and cannot be used again in another request.

Updating/Replacing a pfToken (optional)

If the token expires (expiration occurs after 60 minutes, see error code event 14040), you can update it by creating a new token (see Obtain the Hosted Payment Field token for the session) and update the solution accordingly:

bluesnap.hostedPaymentFieldsUpdateToken(new token string);

2. Add the BlueSnap JavaScript file to your checkout form

In your checkout page, call the BlueSnap Hosted Payment Fields JavaScript file by adding the following script:

<script type="text/javascript" src="BLUESNAPDOMAINPATH/web-sdk/5/bluesnap.js"></script>

3. Add the Hosted Payment Fields to your checkout form

Replace the credit card number, expiration date, and CVV input fields in your checkout form with the following <div> elements.

🚧

Important!

The values for the data-bluesnap attributes must be typed exactly as they appear in the below code in order for your implementation to work.

<div data-bluesnap="ccn"></div>
			
<div data-bluesnap="exp"></div>
			
<div data-bluesnap="cvv"></div>

4. Add a script to initiate the Hosted Payment Fields with your Hosted Fields token

In order to call the Hosted Payment Fields script, add the following script to your checkout page, below the <div> elements.

<script>
  var bsObj = {
    token: " HOSTEDFIELDTOKENID ",
    onFieldEventHandler: {
      /*OPTIONAL*/ setupComplete: function () {
        console.warn("setupComplete");
      },
      /*OPTIONAL*/ threeDsChallengeExecuted: function () {
        console.warn("threeDsChallengeExecuted");
      },
      // tagId returns: "ccn", "cvv", "exp"
      onFocus: function (tagId) {}, // Handle focus
      onBlur: function (tagId) {}, // Handle blur
      onError: function (tagId, errorCode /*, errorDescription, eventOrigin*/) {}, // Handle a change in validation
      /*errorCode returns:
              "10" --> invalid | empty where errorDescription will return invalid if input field invalid or empty if input field is empty (tagId will indicate which input);
              "22013" --> "CC type is not supported by the merchant"; 
              "14040" --> " Token is expired";
              "14041" --> " Could not find token";
              "14042" --> " Token is not associated with a payment method, please verify your client integration or contact BlueSnap support";
              "400" --> "Session expired please refresh page to continue";
              "403", "404", "500" --> "Internal server error please try again later"; 
          */

      /* errorDescription is optional. Returns BlueSnap's standard error description */
      /* eventOrigin is optional. Returns BlueSnap's event origin: onBlur | onSubmit */

      onType: function (tagId, cardType /*, cardData*/) {
        /* cardType will give card type, and only applies to ccn: AMEX, VISA, MASTERCARD, AMEX, DISCOVER, DINERS, JCB */
        if (null != cardData) {
          /* cardData is an optional parameter which will provide ccType, last4Digits, issuingCountry, isRegulatedCard, cardSubType, binCategory and ccBin details (only applies to ccn) in a JsonObject */
          console.log(cardData);
        }
      },
      onEnter: function(tagId) {} // Will trigger when shopper presses enter while inside one of the inputs
    
      onValid: function (tagId) {} // Handle a change in validation
    },
    /* example:
          style: {
          "Selector": {
          "Property": "Value",
          "Property2": "Value2"
          },                                                                                                                                                             
          "Selector2": {
          "Property": "Value"
          } 
      }, */
    style: {
      ":focus": {
        //style for all input elements on focus event
        color: "orange"
      },
      input: {
        //style for all input elements
        color: "blue"
      },
      ".invalid": {
        //style for all input elements when invalid
        color: "red"
      }
    },
    ccnPlaceHolder: "1234 5678 9012 3456", //for example
    cvvPlaceHolder: "123", //for example
    expPlaceHolder: "MM/YY", //for example
  };

  //Run the following command after Document Object Model (DOM) is fully loaded
  bluesnap.hostedPaymentFieldsCreate(bsObj);
</script>

Notes

  • Replace HOSTEDFIELDTOKENID with the token you obtained in Step 1.
  • If you're using the Complete fraud prevention level, include enterpriseId set to your Kount ID within bsObj.
var bsObj = {
  // ...
  enterpriseId: "KOUNT_ID"
};
bluesnap.hostedPaymentFieldsCreate(bsObj);
  • Use onFieldEventHandler to handle focus, blur, validation events, and to get the card type. For example, you can use this to identify when the user has entered a Visa card and then show the relevant icon for Visa. If you want to use BlueSnap icons for each card type, choose the appropriate URL path and add it to the end of the URL below:

URL: https://pay.bluesnap.com/web-sdk/5/assets/cards/

URL Paths:

  • AMEX: amex.png

  • DINERS: diners.png

  • DISCOVER: discover.png

  • JCB: jcb.png

  • MASTERCARD: mastercard.png

  • VISA: visa.png

  • Optionally, use these to define what placeholder appears in each Hosted Payment Field input:

    • ccnPlaceHolder
    • cvvPlaceHolder
    • expPlaceHolder
  • Styling, customizing accessibility features, and masking are all optional. For more details about these capabilities, see Customizing the Hosted Payment Fields.

👍

Add 3D Secure for increased checkout security

Visit the 3D Secure guide to learn how to add 3D Secure to your configuration.

5. Add a script to submit credit card, expiration date, and CVV data

Add the script below to your checkout form:

<script>
    function do_when_clicking_submit_button(){
    bluesnap.hostedPaymentFieldsSubmitData( function(callback){
        if (null != callback.cardData) {
            var fraudSessionId = callback.transactionFraudInfo.fraudSessionId;

            console.log('card type: ' + callback.cardData.ccType +
                ', last 4 digits: ' + callback.cardData.last4Digits +
                ', exp: ' + callback.cardData.exp +
                ', issuing Country: ' + callback.cardData.issuingCountry +
                ', isRegulatedCard: ' + callback.cardData.isRegulatedCard +
                ', cardSubType: ' + callback.cardData.cardSubType +
                ', binCategory: ' + callback.cardData.binCategory +
                ', cardCategory: ' + callback.cardData. cardCategory +
                ', ccBin: ' + callback.cardData.ccBin +
                ', issuing bank: ' + callback.cardData.ccIssuingBank +
                ' and fraudSessionId: ' + fraudSessionId +
                ', after that I can call final submit');
            // submit the form 
        } else {
            var errorArray = callback.error;
            for (i in errorArray) {
                console.log("Received error: tagId= " +
                    errorArray[i].tagId + ", errorCode= " +
                    errorArray[i].errorCode + ", errorDescription= " +
                    errorArray[i].errorDescription);
            }
        }
    });
}                                             
</script>

This function should be activated when the shopper clicks the Submit button. This submits the credit card number, expiration date, and CVV data to BlueSnap, where it is associated with the Hosted Payment Fields Token.

If the data submission to BlueSnap is successful, a cardData object is passed to the function(callback) { // callback.cardData}. Otherwise, if there is a client or server error in the submission, callback.error receives an array and each item contains errorArray[i].tagId, errorArray[i].errorCode, errorArray[i].errorDescription.

📘

Card Validation

The card is validated when you send it in a transaction or you save it to a shopper.

cardData object

PropertyTypeDescription
ccBinStringThe first 6 digits of the credit card.
binCategoryStringPossible Values:
BUSINESS
CLASSIC
COMPANY
CONSUMER,
CORPORATE
EXECUTIVE
GOLD
PERSONAL
PLATINUM
PREPAID
WORLD
cardSubTypeStringPossible Values: CREDIT or DEBIT
ccTypeStringPossible Values:
VISA
MASTERCARD
AMERICAN EXPRESS
JCB
CHINA UNION PAY
last4DigitsStringThe last 4 digits of the credit card.
isRegulatedCardStringPossible Values: Y or N
issuingCountryStringISO 3166-1 alpha-2 code of the country where the credit card was issued.
ccIssuingBankStringThe bank that issued the card.
expStringThe expiration date of the card.
cardCategoryStringPossible Values:
STANDARD/ENHANCED
TRAVEL
GOLD BUSINESS
ATM CARD

Back to Top

Example Forms

Below are two examples of checkout forms that use BlueSnap's Hosted Payment Fields. Click the HTML/CSS/JS tabs to view the code.

with Bootstrap styling

with Material styling


Back to Top

Process Payments and Vault Shoppers with pfToken

Once you have implemented Hosted Payment Fields in your checkout form, you can process payments and save shopper information by including the Hosted Payment Fields Token in your API requests.

Keep in mind, the Hosted Payment Fields Token can only be used once- either to process a transaction or to save shopper payment info. If you want to use Hosted Payment Fields to vault a shopper and then process a charge, please contact BlueSnap implementation to enable a multi-use token for improved conversions.

Learn how to process payments and vault shoppers with either the Payment API or the Extended Payment API below.

In the Payment API

Process Payment

To use the Hosted Payment Fields Token to process a payment, send the token within the pfToken property in your Auth Capture, Auth Only, or Create Subscription.

Vault Shoppers

To save the card information from the Hosted Payment Fields in a new or existing vaulted shopper, send the token within the pfToken property in your Create Vaulted Shopper or Update Vaulted Shopper request.

Example Request Body

{
    "amount": 11,
    "softDescriptor": "DescTest",
    "cardHolderInfo": {
        "firstName": "test first name",
        "lastName": "test last name", 
        "zip": "123456"
    },
    "currency": "USD",
    "cardTransactionType": "AUTH_CAPTURE",
    "pfToken": "abcde12345**********"
}
{
    "paymentSources": {"creditCardInfo": [{"pfToken": "9688f4f6945f615b1ab6954ceb5dbf67f63d6b41fa27dbff6ac342cff9bf50fc_"}]},
    "firstName": "FirstName",
    "lastName": "LastName"
}
{
    "firstName": "FirstName",
    "lastName": "LastName",
    "paymentSources": {"creditCardInfo": [{
         "pfToken": "9688f4f6945f615b1ab6954ceb5dbf67f63d6b41fa27dbff6ac342cff9bf50fc_"
    }]}
}

In the Extended Payment API

Process Payment for New Shopper

To use the Hosted Payment Fields Token to process a payment for a new shopper, you can send the token within the pf-token property in your Create Order and New Shopper or Create Shopping Context request.

Example Request Body

<batch-order xmlns="http://ws.plimus.com">
  <shopper>
    <web-info>
      <ip>62.219.121.253</ip>
    </web-info>
    <shopper-info>
      <shopper-currency>USD</shopper-currency>
      <store-id>4677</store-id>
      <locale>en</locale>
      <shopper-contact-info>
        <title>Mr.</title>
        <first-name>John</first-name>
        <last-name>Doe</last-name>
        <email>[email protected]</email>
        <company-name>JohnDoeAndSons</company-name>
        <address1>138 Market st</address1>
        <city>San Francisco</city>
        <zip>756543</zip>
        <state>CA</state>
        <country>US</country>
        <phone>1413555666</phone>
        <fax>1413555666789</fax>
      </shopper-contact-info>
      <payment-info>
        <credit-cards-info>
          <credit-card-info>
            <billing-contact-info>
              <first-name>John</first-name>
              <last-name>Doe</last-name>
              <address1>138 Market st</address1>
              <city>San Francisco</city>
              <zip>756543</zip>
              <state>CA</state>
              <country>US</country>
            </billing-contact-info>
            <pf-token>c7c69ff853ab784ef35a0c78ffec08e78cf1d1b5b4bb9e2644c2bcc73f3f818f_1</pf-token>
          </credit-card-info>
        </credit-cards-info>
      </payment-info>
    </shopper-info>
  </shopper>
  <order>
    <ordering-shopper>
      <web-info>
        <ip>62.219.121.253</ip>
        <remote-host>www.merchant.com</remote-host>
        <user-agent>Mozilla/5.0 (Linux; X11)</user-agent>
      </web-info>
    </ordering-shopper>
    <cart>
      <cart-item>
        <sku>
          <sku-id>2152762</sku-id>
        </sku>
        <quantity>1</quantity>
      </cart-item>
    </cart>
    <expected-total-price>
      <amount>15.00</amount>
      <currency>USD</currency>
    </expected-total-price>
  </order>
</batch-order>
<shopping-context xmlns="http://ws.plimus.com">
  <web-info>
    <ip>62.219.121.253</ip>
    <remote-host>
    bzq-219-121-253.static.bezeqint.net.reinventhosting.com</remote-host>
    <user-agent>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
    SV1; GTB6.3; .NET CLR 2.0.50727)</user-agent>
    <accept-language>en-us</accept-language>
  </web-info>
  <shopper-details>
    <shopper>
      <shopper-info>
        <shopper-contact-info>
          <title>Mr</title>
          <first-name>shopper first name</first-name>
          <last-name>shopper last name</last-name>
          <email>[email protected]</email>
          <company-name>JS Company</company-name>
          <address1>123 Oxford</address1>
          <address2 />
          <city>London</city>
          <state>ny</state>
          <zip>54321</zip>
          <country>us</country>
          <phone>1800808080</phone>
          <fax>1800808080</fax>
        </shopper-contact-info>
        <shipping-contact-info>
          <first-name>Shipping first name</first-name>
          <last-name>Shipping last name</last-name>
          <address1>123 Oxford</address1>
          <address2 />
          <city>London</city>
          <state>ny</state>
          <zip>54321</zip>
          <country>us</country>
        </shipping-contact-info>
        <invoice-contacts-info>
          <invoice-contact-info>
            <default>true</default>
            <company-name>BlueSnap UK</company-name>
            <vat-code></vat-code>
            <title>Mrs.</title>
            <first-name>John</first-name>
            <last-name>Black</last-name>
            <address1>5 star drive</address1>
            <address2>3rd entrance</address2>
            <city>Purchase</city>
            <state>NY</state>
            <zip>34645</zip>
            <country>us</country>
            <phone>1800400500</phone>
            <fax>1800400500</fax>
            <email>[email protected]</email>
          </invoice-contact-info>
        </invoice-contacts-info>
        <payment-info>
          <credit-cards-info>
            <credit-card-info>
              <billing-contact-info>
                <first-name>John</first-name>
                <last-name>Doe</last-name>
                <address1>138 Market st</address1>
                <city>San Francisco</city>
                <zip>756543</zip>
                <state>CA</state>
                <country>US</country>
              </billing-contact-info>
              <pf-token>c7c69ff853ab784ef35a0c78ffec08e78cf1d1b5b4bb9e2644c2bcc73f3f818f_1</pf-token>
            </credit-card-info>
          </credit-cards-info>
        </payment-info>
        <store-id>12700</store-id>
        <vat-code></vat-code>
        <shopper-currency>USD</shopper-currency>
        <locale>en</locale>
      </shopper-info>
    </shopper>
  </shopper-details>
  <order-details>
    <order>
      <cart>
        <cart-item>
          <sku>
            <sku-id>2178316</sku-id>
            <sku-charge-price>
              <charge-type>initial</charge-type>
              <amount>50.00</amount>
              <currency>USD</currency>
            </sku-charge-price>
          </sku>
          <quantity>1</quantity>
        </cart-item>
      </cart>
      <expected-total-price>
        <amount>50.00</amount>
        <currency>USD</currency>
      </expected-total-price>
    </order>
  </order-details>
</shopping-context>

Process Payment for Existing Shopper

To use the Hosted Payment Fields Token to process a payment for an existing shopper, first update the existing shopper with the information from the Hosted Payment Fields by sending the token within the pf-token property in your Update Shopper request.

You can then process the payment as usual, by including the relevant shopper ID in the Create Order with Existing Shopper or Create Shopping Context request.

Example Request Body

<shopper xmlns="http://ws.plimus.com">
  <web-info>
    <ip>62.219.121.253</ip>
  </web-info>
  <shopper-info>
    <store-id>4677</store-id>
    <payment-info>
      <credit-cards-info>
        <credit-card-info>
          <billing-contact-info>
            <first-name>John</first-name>
            <last-name>Doe</last-name>
            <address1>138 Market st</address1>
            <city>San Francisco</city>
            <zip>756543</zip>
            <state>CA</state>
            <country>US</country>
          </billing-contact-info>
          <pf-token>c7c69ff853ab784ef35a0c78ffec08e78cf1d1b5b4bb9e2644c2bcc73f3f818f_1</pf-token>
        </credit-card-info>
      </credit-cards-info>
    </payment-info>
  </shopper-info>
</shopper>

Back to Top