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.
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>
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>
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.
Head over to the Tokenization Demo to learn more about our JavaScript tokenization solution and to see it in action!
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.
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:
- See our Javascript tokenization solution in action
- Full SDK Documentation for Card Payments
- Github
- Portico Gateway Documentation
- A whitepaper detailing PCI-DSS benefits of our tokenization library