Skip to main content

Payment Instruments API

The Payment Instruments API allows you to manage customer payment methods including credit cards and bank accounts.

Methods

getCustomerPaymentInstruments

Retrieve all payment instruments for a customer.

const { getCustomerPaymentInstruments } = useEasy();

const result = await getCustomerPaymentInstruments("cust_123");
const instruments = result.data;

Parameters

  • customerId (string, required): The ID of the customer

Returns

ApiResponse<PaymentInstrumentData[]>;

Example

import { useEasy } from "@easylabs/react";
import { useState, useEffect } from "react";

function PaymentMethodList({ customerId }) {
const { getCustomerPaymentInstruments } = useEasy();
const [instruments, setInstruments] = useState([]);

useEffect(() => {
const fetchInstruments = async () => {
try {
const result = await getCustomerPaymentInstruments(customerId);
setInstruments(result.data);
} catch (error) {
console.error("Failed to fetch payment methods:", error);
}
};

fetchInstruments();
}, [customerId, getCustomerPaymentInstruments]);

return (
<ul>
{instruments.map((instrument) => (
<li key={instrument.id}>
{instrument.name} -
{instrument.type === "PAYMENT_CARD" ? (
<span>
{instrument.details?.card?.brand} ****
{instrument.details?.card?.last4}
</span>
) : (
<span>
{instrument.details?.bank?.account_type} ****
{instrument.details?.bank?.last4}
</span>
)}
</li>
))}
</ul>
);
}

createPaymentInstrument

Create a new payment instrument for a customer.

Payment Card

const { createPaymentInstrument } = useEasy();
const cardRef = useRef(null);

const result = await createPaymentInstrument({
type: "PAYMENT_CARD",
customerId: "cust_123",
cardElement: cardRef,
address: {
line1: "123 Main St",
city: "Anytown",
state: "CA",
postal_code: "12345",
country: "US",
},
name: "My Primary Card",
});

Bank Account

const { createPaymentInstrument } = useEasy();
const routingRef = useRef(null);
const accountRef = useRef(null);

const result = await createPaymentInstrument({
type: "BANK_ACCOUNT",
customerId: "cust_123",
accountType: "CHECKING",
routingElement: routingRef,
accountElement: accountRef,
name: "My Checking Account",
});

Parameters

  • params (required): Payment instrument details
    • type ('PAYMENT_CARD' | 'BANK_ACCOUNT'): Type of payment instrument
    • customerId (string, required): The ID of the customer
    • name (string, required): Display name for the payment method
    • For cards: cardElement or separate card elements, optional address
    • For bank accounts: accountType, routingElement, accountElement

Returns

ApiResponse<PaymentInstrumentData>;

Example

import { useEasy, CardElement } from "@easylabs/react";
import { useRef, useState } from "react";

function AddCardForm({ customerId }) {
const { createPaymentInstrument } = useEasy();
const cardRef = useRef(null);
const [name, setName] = useState("");
const [address, setAddress] = useState({
line1: "",
city: "",
state: "",
postal_code: "",
country: "US",
});

const handleSubmit = async (e) => {
e.preventDefault();

try {
const result = await createPaymentInstrument({
type: "PAYMENT_CARD",
customerId,
cardElement: cardRef,
address,
name,
});
console.log("Card added:", result.data.id);
} catch (error) {
console.error("Failed to add card:", error);
}
};

return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Card Nickname"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>

<CardElement ref={cardRef} />

<input
type="text"
placeholder="Street Address"
value={address.line1}
onChange={(e) => setAddress({ ...address, line1: e.target.value })}
required
/>

<input
type="text"
placeholder="City"
value={address.city}
onChange={(e) => setAddress({ ...address, city: e.target.value })}
required
/>

<input
type="text"
placeholder="State"
value={address.state}
onChange={(e) => setAddress({ ...address, state: e.target.value })}
required
/>

<input
type="text"
placeholder="ZIP Code"
value={address.postal_code}
onChange={(e) =>
setAddress({ ...address, postal_code: e.target.value })
}
required
/>

<button type="submit">Add Card</button>
</form>
);
}

updatePaymentInstrument

Update a payment instrument's metadata, name, or enabled status.

const { updatePaymentInstrument } = useEasy();

const result = await updatePaymentInstrument("pi_123", {
name: "Updated Card Name",
metadata: {
primary: true,
},
});

Parameters

  • instrumentId (string, required): The ID of the payment instrument
  • params (required)
    • name (string, optional): New display name
    • enabled (boolean, optional): Set to false to disable the payment instrument
    • metadata (object, optional): Updated metadata

Returns

ApiResponse<PaymentInstrumentData>;
info

You cannot update card numbers, expiration dates, or bank account numbers. To change these details, create a new payment instrument.

Disabling Payment Instruments

Instead of deleting payment instruments, set enabled: false to disable them. This preserves the payment history while preventing future use.

Example

import { useEasy } from "@easylabs/react";
import { useState } from "react";

function UpdatePaymentMethodName({ instrumentId, currentName }) {
const { updatePaymentInstrument } = useEasy();
const [name, setName] = useState(currentName);

const handleSubmit = async (e) => {
e.preventDefault();

try {
await updatePaymentInstrument(instrumentId, { name });
console.log("Payment method updated");
} catch (error) {
console.error("Failed to update:", error);
}
};

const handleDisable = async () => {
try {
await updatePaymentInstrument(instrumentId, { enabled: false });
console.log("Payment method disabled");
} catch (error) {
console.error("Failed to disable:", error);
}
};

return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit">Save</button>
</form>
<button onClick={handleDisable} style={{ color: "orange" }}>
Disable Payment Method
</button>
</div>
);
}

Type Definitions

PaymentInstrumentData

interface PaymentInstrumentData {
id: string;
identity_id: string;
name: string;
type: "PAYMENT_CARD" | "BANK_ACCOUNT";
details?: {
card?: {
last4: string;
brand: string;
exp_month: number;
exp_year: number;
};
bank?: {
last4: string;
bank_name?: string;
account_type: "CHECKING" | "SAVINGS";
};
};
created_at: string;
updated_at: string;
}

PaymentCardParams

interface PaymentCardParams {
type: "PAYMENT_CARD";
customerId: string;
name: string;
address?: Address;
cardElement?: RefObject<ICardElement>;
cardNumberElement?: RefObject<ICardNumberElement>;
cardExpirationDateElement?: RefObject<ICardExpirationDateElement>;
cardVerificationCodeElement?: RefObject<ICardVerificationCodeElement>;
}

BankAccountParams

interface BankAccountParams {
type: "BANK_ACCOUNT";
customerId: string;
name: string;
accountType: "CHECKING" | "SAVINGS";
routingElement?: RefObject<ITextElement>;
accountElement?: RefObject<ITextElement>;
}

Address

interface Address {
line1: string;
line2?: string;
city: string;
state: string;
postal_code: string;
country: string;
}

Security

PCI Compliance

The SDK uses secure form elements to tokenize payment data. Your application never has access to raw card numbers or bank account numbers, ensuring PCI compliance.

  • ✅ Card data is tokenized before transmission
  • ✅ Bank account numbers are encrypted
  • ✅ No sensitive data touches your servers
  • ✅ Automatic CVV verification

Best Practices

  1. Allow multiple payment methods: Customers appreciate having backup options
  2. Show card brands: Display card logos for better UX
  3. Verify addresses: Use address verification to reduce fraud
  4. Handle expired cards: Notify customers when cards are expiring
  5. Disable instead of delete: Set enabled: false to preserve payment history while preventing future use

Next Steps