Get Started Card Payments Check Payments Recurring Payments Gift & Loyalty Payments Fraud Plugins & Integrations Reporting Demo Semi Integrated Fully Integrated Terminals POS Middleware Connectors Portico Gateway Documentation API Overview Gift & Loyalty Bill Pay Payroll Introduction Developer Support Authentication Credit Card Gift Card eCheck & ACH Recurring Reporting Error Handling Semi-Integrated Devices Heartland Profac Global Payments eCommerce Tokenization Demo Testing Knowledge Center GitHub Partnerships
Get sandbox account
Get sandbox account

Card Payments

First create your test API keys by registering for an account, you will have access to them immediately. If you already have an account, sign in and obtain your Sandbox API keys here.

For a more in-depth guide to card payments see our full SDK documentation. View our open source library on Github and the Tokenization Demo for JSFiddle examples.

Accept Card Information

The most secure way to get up and running with Heartland Tokenization is to use our iFrame-hybrid tokenization solution.

Basic HTML Payment Form

<form id="payment-form" action="/Payment/Charge" method="get">
                <!-- Other input fields to capture relevant data -->
                <label for="billing_zip">Billing Zip Code</label>
                <input id="billing_zip" name="billing_zip" value="47150" type="tel" />

                <!-- Target for the credit card form -->
                <div id="credit-card"></div>
</form>
Where are the payment fields?

You may have noticed there are no actual input fields in the HTML above. Congratulations! You’ve discovered how we can reduce your PCI-DSS scope by moving a large portion of the payment acceptance process away from your site.

To achieve this, our JavaScript library inserts tiny iFrames pointed to solitary input fields on our payment gateway into those empty div elements above. Even though the fields themselves are displayed through iFrames and are hosted on our payment gateway, they integrate seemlessly into your existing payment form on your web site, keeping your customers where they should be…on your web site. This can help reduce your PCI scope down to the SAQ-A form (aka the short form) since the customer is inputting their card data onto our servers and all your site has access to is a single-use payment token.

Heartland Tokenization is packaged as a JavaScript library. All you need to do is include the Heartland Tokenization library, and add a few lines of initialization code. It’s that simple!

Necessary JavaScript for Tokenization

<script src="https://js.globalpay.com/v1/globalpayments.js"></script>

<script type="text/javascript">
// Configure account
GlobalPayments.configure({
                publicApiKey: "pkapi_cert_jKc1FtuyAydZhZfbB3"
});

// Create Form
const cardForm = GlobalPayments.creditCard.form("#credit-card");

cardForm.on("token-success", (resp) => {
                // add payment token to form as a hidden input
                const token = document.createElement("input");
                token.type = "hidden";
                token.name = "payment_token";
                token.value = resp.paymentReference;

                // Submit data to the integration's backend for processing
                const form = document.getElementById("payment-form");
                form.appendChild(token);
                form.submit();
});

cardForm.on("token-error", (resp) => {
                // show error to the consumer
});
</script>
Validation

Worried about bad data being entered? Our iFrame-based fields have a set of functions to help your customers during their checkout process. All fields only allow customers to input numbers, preventing the accidental letter and/or symbol from creating a problem, and each one also adds a CSS class of .valid or .invalid to make styling good or bad data easier, pin-pointing problems for your customers as early as possible.

While on the subject of visual cues, the card number field will also add a CSS class of the form .card-type-{card brand}, allowing the card brand logos to be displayed for the customer and adding one more visual validation that the card information is correct.

See It in Action

Head over to the Tokenization Demo to learn more about our JavaScript tokenization solution and to see it in action!

Charge the Token

Once the consumer has entered their card information and submitted the payment form, the next step is to charge the token. Let’s configure the server-side SDK and gather our data together in preparation.

Configure authentication

using GlobalPayments.Api.Services;

ServicesContainer.ConfigureService(new PorticoConfig {
                SecretApiKey = "skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A",
                DeveloperId = "000000",
                VersionNumber = "0000",
                ServiceUrl = "https://cert.api2.heartlandportico.com"
});
<?php
use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig;
use GlobalPayments\Api\ServicesContainer;

$config = new PorticoConfig();
$config->secretApiKey = "skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A";
$config->developerId = "000000";
$config->versionNumber = "0000";
$config->serviceUrl = "https://cert.api2.heartlandportico.com";
ServicesContainer::configureService($config);
import com.global.api.ServicesContainer;
import com.global.api.serviceConfigs.GatewayConfig;

GatewayConfig config = new GatewayConfig();
config.setSecretApiKey("skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A");
config.setDeveloperId("000000");
config.setVersionNumber("0000");
config.setServiceUrl("https://cert.api2.heartlandportico.com");
ServicesContainer.configureService(config);
# coming soon
from globalpayments.api import ServicesConfig, ServicesContainer

config = ServicesConfig()
config.secret_api_key = 'skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A'
config.developer_id = '000000'
config.version_number = '0000'
config.service_url = 'https://cert.api2.heartlandportico.com'
ServicesContainer.configure(config)
import { ServicesConfig, ServicesContainer } from "globalpayments-api";

const config = new ServicesConfig();
config.secretApiKey = "skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A";
config.developerId = "000000";
config.versionNumber = "0000";
config.serviceUrl = "https://cert.api2.heartlandportico.com";
ServicesContainer.configure(config);

Prepare to charge a credit card token

using GlobalPayments.Api.Entities;
using GlobalPayments.Api.PaymentMethods;

var card = new CreditCardData {
                Token = "single-use token"
};

var address new Address {
                PostalCode = "12345"
};
<?php
use GlobalPayments\Api\Entities\Address;
use GlobalPayments\Api\PaymentMethods\CreditCardData;

$card = new CreditCardData();
$card->token = "single-use token";

$address = new Address();
$address->postalCode = "12345";
import com.global.api.entities.Address;
import com.global.api.paymentMethods.CreditCardData;

CreditCardData card = new CreditCardData();
card.setToken("single-use token");

Address address = new Address();
address.setCode("12345");
# coming soon
from globalpayments.api.entities import Address
from globalpayments.api.payment_methods import CreditCardData

card = CreditCardData()
card.token = 'single-use token'

address = Address()
address.postal_code = '12345'
import { Address, CreditCardData } from "globalpayments-api";
const card = new CreditCardData();
card.token = "single-use token";

const address = new Address();
address.code = "12345";

With our CreditCardData and Address objects created, we can use them to charge the consumer’s card. Heartland’s server-side SDKs expose the charge action as a method off of the payment objects, including CreditCardData.

Charge a credit card token

var response = card.Charge(10.00m)
                .WithCurrency("USD")
                .WithAddress(address)
                .Execute();
<?php
$response = $card->charge(10)
                ->withCurrency("USD")
                ->withAddress($address)
                ->execute();
import com.global.api.entities.Transaction;
import java.math.BigDecimal;

Transaction response = card.charge(new BigDecimal("10"))
                .withCurrency("USD")
                .withAddress(address)
                .execute();
# coming soon
response = card.charge(10) \
                .with_currency('USD') \
                .with_address(address) \
                .execute()
const response = await card.charge(10)
                .withCurrency("USD")
                .withAddress(address)
                .execute();

All payment transactions, including charge, will return a Transaction object when using our server-side SDKs. Any data exposed on the Transaction object can be stored in your application’s database or displayed to the consumer.

Handle Declines and Errors

Declines from issuing banks and general errors are bound to happen, so it is wise for your application to be prepared. Our server-side SDKs will throw an exception when the issuing bank declines a transaction or if the supplied data fails the SDKs’ built-in validation. The best way to account for this is to wrap your code in a try/catch:

Exception Handling

# coming soon
from globalpayments.api.entities.exceptions import ApiException

try:
                response = card.charge(-5) \
                .with_currency('USD') \
                .with_address(address) \
                .execute()
except ApiException as e:
                // handle error
using GlobalPayments.Api.Entities;

try {
                card.Charge(-5m)
                .WithCurrency("USD")
                .WithAddress(address)
                .Execute();
}

catch (ApiException e) {
                // handle error
}
<?php
use GlobalPayments\Api\Entities\Exceptions\ApiException;

try {
                $card->charge(-5)
                ->withCurrency("USD")
                ->withAddress($address)
                ->execute();
}

catch (ApiException $e) {
                // handle error
}
import com.global.api.entities.exceptions.ApiException;
import java.math.BigDecimal;

try {
                card.charge(new BigDecimal("-5"))
                .withCurrency("USD")
                .withAddress(address)
                .execute();
}

catch (ApiException e) {
                // handle error
}
import { ApiError } from "globalpayments-api";

card.charge(-5)
                .withCurrency("USD")
                .withAddress(address)
                .execute()
                .catch((e) => {
                switch (e.name) {
                case ApiError.constructor.name:
                default:
                // handle error
                break;
                }
});

Please refer to our Error Handling section for more information on specialized types to narrowing the original cause of the exception.

See Also:

Learn more about Heartland Ecommerce card payments with:

Support
Heartland