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
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.
Adding Card Elements
Once installed and configured, add the Card Elements to your application.
- JavaScript
- React
<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>
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();
import React, { useRef, useState } from 'react';
import {
PublicSquareProvider,
CardNumberElement,
CardExpirationDateElement,
CardVerificationCodeElement,
usePublicSquare,
} from '@publicsquare/elements-react';
export default function App() {
const { publicsquare } = usePublicSquare();
// Refs to get access to the Elements instance
const cardholderNameRef = useRef(null);
const cardNumberRef = useRef(null);
const cardExpirationRef = useRef(null);
const cardVerificationRef = useRef(null);
return (
<PublicSquareProvider apiKey={apiKey}>
<input
type="text"
id="cardholderName"
placeholder="Cardholder name"
ref={cardholderNameRef}
style={{ display: 'flex', width: '100%' }}
/>
<CardNumberElement
id="cardNumber"
ref={cardNumberRef}
/>
<div style={{ display: 'flex' }}>
<div style={{ width: '100%' }}>
<CardExpirationDateElement
id="cardExpirationDate"
ref={cardExpirationRef}
/>
</div>
<div style={{ width: '100%' }}>
<CardVerificationCodeElement
id="cardVerificationCode"
ref={cardVerificationRef}
cardBrand={cardBrand}
/>
</div>
</div>
</PublicSquareProvider>
);
}
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:
- JavaScript
- React
- cURL
<!-- Form from above -->
<button id="submit">Submit</button>
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();
export default function App() {
const submit = async () => {
try {
const card = await publicsquare.cards.create({
// This can be any string text from the dom
cardholder_name: cardholderNameRef.current.el.value,
card: {
// cardNumberRef.current is the CardNumberElement instance that will be decrypted within the secure
// iFrame on the DOM so that the client never sees the card information.
number: cardNumberRef.current,
expirationMonth: cardExpirationRef.current.month(),
expirationYear: cardExpirationRef.current.year(),
cvc: cardVerificationRef.current,
}
});
// store card.id in your database
} catch (error) {
console.error(error);
}
}
return (
<PublicSquareProvider apiKey={apiKey}>
...
<button onClick={submit}>Submit</button>
</PublicSquareProvider>
);
}
To save a card from your servers, use the Save a Card from Your Servers. It posts the card to https://collect.publicsquare.com with your Publishable Key and needs a PCI-certified organization. To save a card without a CVC, see Saving a card without a CVC.
The created card object contains the non-sensitive information about the card, including the bin:
{
"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"
}
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
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:
| Field | Required | Description |
|---|---|---|
cardholder_name | Yes | Name on the card. |
card.number | Yes | Card number. |
card.expiration_month | Yes | Expiration month, from 1 to 12. |
card.expiration_year | Yes | Four-digit expiration year. The expiration date must be in the future. |
card.cvc | No | Card security code. If you send it, PublicSquare still validates it. |
customer_id | No | ID of an existing customer to associate with the card. |
billing_details | No | Billing 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.
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
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:
{
"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"
}
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: