Skip to main content

Save Cards

A saved card has an id that starts with card_. You use it to create payments and payouts, and to charge the customer later. Save a card in one of two ways:

  • Credova Elements captures the card in your web app. Card data never touches your servers, so you avoid PCI requirements.
  • The Direct API posts the card from your servers. Your organization must be PCI certified.

Before you start​

Credova account
Sign up or sign in to the Credova Portal.
Publishable Key
Loads Credova Elements in the browser. It is safe to put in frontend code.

Save a Card with Credova Elements​

Configuring Credova Elements​

Credova Elements are available for the following technologies. Click below for detailed instructions on how to install and configure them.

Javascript
React

Adding Card Elements​

Once installed and configured, add the Card Elements to your application.

index.html
<input
type="text"
id="cardholderName"
placeholder="Cardholder name"
style={{ display: 'flex', width: '100%' }}
/>

<div id="cardNumber"></div>

<div style="display: flex;">
<div id="cardExpirationDate" style="width: 100%;"></div>
<div id="cardVerificationCode" style="width: 100%;"></div>
</div>
index.js
import { PublicSquare } from '@publicsquare/elements-js';

let publicsquare;
let cardNumberElement;
let cardExpirationDateElement;
let cardVerificationCodeElement;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

// Creates Elements instances
cardNumberElement = publicsquare.createCardNumberElement();
cardNumberElement.mount('#cardNumber');

cardExpirationDateElement = publicsquare.createCardExpirationDateElement();
cardExpirationDateElement.mount('#cardExpirationDate');

cardVerificationCodeElement = publicsquare.createCardVerificationCodeElement();
cardVerificationCodeElement.mount('#cardVerificationCode');
}

init();

Storing Cards​

Now that you are capturing cardholder data in your web application, it is time to store the card in your account.

To do this, we will call the create card method from the SDK, passing the Card Elements as data points in the payload.

Add a submit function along with a button to trigger it:

index.html
<!-- Form from above -->
<button id="submit">Submit</button>
index.js
async function init () {
...
document.getElementById("submit").addEventListener("click", submit);
}

async function submit (e: FormEvent<HTMLFormElement>,) {
try {
const formData = new FormData(e.currentTarget)

const card = await publicsquare.cards.create({
cardholder_name: formData.cardholderName,
card: {
number: cardNumberElement,
expirationMonth: cardExpirationDateElement.month(),
expirationYear: cardExpirationDateElement.year(),
cvc: cardVerificationCodeElement,
}
});
// store card.id in your database
} catch (error) {
console.error(error);
}
}

init();

The created card object contains the non-sensitive information about the card, including the bin:

card.json
{
"id": "card_AjkCFKAYiTsjghXWMzoXFPMxj",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"cardholder_name": "John Smith",
"last4": "4242",
"bin": "424242",
"exp_month": "12",
"exp_year": "2030",
"brand": "visa",
"fingerprint": "CC2XvyoohnqecEq4r3FtXv6MdCx4TbaW1UUTdCCN5MNL",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
Displaying the card's first 6 digits (bin) alongside the last 4 (last4) is PCI compliant per PCI DSS Requirement 3.3.

You can safely store the card's id value in your database to link it with the appropriate payment or customer association.

To charge a stored card later without the customer present, see Card on File and Recurring Payments.

You can optionally pass in a customer_id to associate with an existing Created Customer and billing_details to remove the requirement to pass them when Creating a Payment.

Save a Card from Your Servers​

Accepting or transmitting cardholder data requires the merchant to be PCI certified. If you are unsure, please contact support. To keep card data out of your servers, use Credova Elements.

Save a Card​

Send the card in a POST request to https://collect.publicsquare.com:

curl -L 'https://collect.publicsquare.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-API-KEY: <PUBLISHABLE_API_KEY>' \
-d '{
"cardholder_name": "John Smith",
"card": {
"number": "4242424242424242",
"expiration_month": 12,
"expiration_year": 2030,
"cvc": "123"
}
}'

The request body accepts these fields:

FieldRequiredDescription
cardholder_nameYesName on the card.
card.numberYesCard number.
card.expiration_monthYesExpiration month, from 1 to 12.
card.expiration_yearYesFour-digit expiration year. The expiration date must be in the future.
card.cvcNoCard security code. If you send it, PublicSquare still validates it.
customer_idNoID of an existing customer to associate with the card.
billing_detailsNoBilling address for the card.

Saving a card without a CVC​

The cvc field is optional. Leave it out when you save a card that you will charge later without the customer present, for example a card on file or a card that you move from another vault.

A card saved without a CVC can decline more often on its first charge. Its cvv2_reply cannot show a match (M), so do not use a missing CVV as a reason to decline these payments. See Fraud Details and Prevention.
curl -L 'https://collect.publicsquare.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-API-KEY: <PUBLISHABLE_API_KEY>' \
-d '{
"cardholder_name": "John Smith",
"card": {
"number": "4242424242424242",
"expiration_month": 12,
"expiration_year": 2030
}
}'

Test Mode​

To test card collection in test mode, use the https://collect-test.publicsquare.com endpoint instead of https://collect.publicsquare.com, along with your test mode Publishable Key. This lets you exercise the collect card flow without submitting live cardholder data. See Testing for every test hostname.
curl -L 'https://collect-test.publicsquare.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-API-KEY: <TEST_PUBLISHABLE_API_KEY>' \
-d '{
"cardholder_name": "John Smith",
"card": {
"number": "4242424242424242",
"expiration_month": 12,
"expiration_year": 2030,
"cvc": "123"
}
}'

Card Response​

The created card object contains the non-sensitive information about the card, including the bin:

card.json
{
"id": "card_AjkCFKAYiTsjghXWMzoXFPMxj",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"cardholder_name": "John Smith",
"last4": "4242",
"bin": "424242",
"exp_month": "12",
"exp_year": "2030",
"brand": "visa",
"fingerprint": "CC2XvyoohnqecEq4r3FtXv6MdCx4TbaW1UUTdCCN5MNL",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
Displaying the card's first 6 digits (bin) alongside the last 4 (last4) is PCI compliant per PCI DSS Requirement 3.3.

You can safely store the card's id value in your database to link it with the appropriate payment or customer association.

To charge a stored card later without the customer present, see Card on File and Recurring Payments.

You can optionally pass in a customer_id to associate with an existing Created Customer and billing_details to remove the requirement to pass them when Creating a Payment.

Conclusion​

You have saved a customer's card. To use it, follow these guides: