Skip to main content

Payment Types

The Easy React SDK supports two types of payment instruments: Payment Cards and Bank Accounts. Each type has specific requirements and use cases.

Payment Cards

Credit and debit cards are the most common payment method.

Type Definition

type PaymentCardParams = {
type: "PAYMENT_CARD";
address?: Address;
// Option 1: Complete card element
cardElement?: RefObject<ICardElement>;
// Option 2: Separate card elements
cardNumberElement?: RefObject<ICardNumberElement>;
cardExpirationDateElement?: RefObject<ICardExpirationDateElement>;
cardVerificationCodeElement?: RefObject<ICardVerificationCodeElement>;
};

Using Complete Card Element

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

function PaymentForm() {
const { checkout } = useEasy();
const cardRef = useRef(null);

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

await checkout({
customer_creation: true,
customer_details: {
first_name: "John",
last_name: "Doe",
email: "[email protected]",
},
source: {
type: "PAYMENT_CARD",
cardElement: cardRef,
name: "Primary Card",
address: {
line1: "123 Main St",
city: "Anytown",
state: "CA",
postal_code: "12345",
country: "US",
},
},
line_items: [{ price_id: "price_123", quantity: 1 }],
});
};

return (
<form onSubmit={handleSubmit}>
<CardElement ref={cardRef} />
<button type="submit">Pay</button>
</form>
);
}

Using Separate Card Elements

import {
useEasy,
CardNumberElement,
CardExpirationDateElement,
CardVerificationCodeElement,
} from "@easylabs/react";
import { useRef } from "react";

function PaymentForm() {
const { checkout } = useEasy();
const cardNumberRef = useRef(null);
const expiryRef = useRef(null);
const cvcRef = useRef(null);

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

await checkout({
customer_creation: true,
customer_details: {
first_name: "Jane",
last_name: "Smith",
email: "[email protected]",
},
source: {
type: "PAYMENT_CARD",
cardNumberElement: cardNumberRef,
cardExpirationDateElement: expiryRef,
cardVerificationCodeElement: cvcRef,
name: "Jane's Card",
},
line_items: [{ price_id: "price_123", quantity: 1 }],
});
};

return (
<form onSubmit={handleSubmit}>
<div>
<label>Card Number</label>
<CardNumberElement ref={cardNumberRef} />
</div>

<div style={{ display: "flex", gap: "1rem" }}>
<div>
<label>Expiry</label>
<CardExpirationDateElement ref={expiryRef} />
</div>
<div>
<label>CVC</label>
<CardVerificationCodeElement ref={cvcRef} />
</div>
</div>

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

Address Field

The address field is optional but recommended for card payments:

interface Address {
line1: string; // Street address
line2?: string; // Apartment, suite, etc. (optional)
city: string; // City
state: string; // State/Province
postal_code: string; // ZIP/Postal code
country: string; // Two-letter country code (e.g., 'US')
}

Bank Accounts

ACH bank account payments for US customers.

Type Definition

type BankAccountParams = {
type: "BANK_ACCOUNT";
accountType: "CHECKING" | "SAVINGS";
routingElement?: RefObject<ITextElement>;
accountElement?: RefObject<ITextElement>;
};

Usage

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

function BankPaymentForm() {
const { checkout } = useEasy();
const routingRef = useRef(null);
const accountRef = useRef(null);

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

await checkout({
customer_creation: true,
customer_details: {
first_name: "Bob",
last_name: "Johnson",
email: "[email protected]",
},
source: {
type: "BANK_ACCOUNT",
accountType: "CHECKING",
routingElement: routingRef,
accountElement: accountRef,
name: "Primary Checking",
},
line_items: [{ price_id: "price_123", quantity: 1 }],
});
};

return (
<form onSubmit={handleSubmit}>
<div>
<label>Routing Number</label>
<TextElement ref={routingRef} placeholder="123456789" />
</div>

<div>
<label>Account Number</label>
<TextElement ref={accountRef} placeholder="0123456789" />
</div>

<div>
<label>Account Type</label>
<select defaultValue="CHECKING">
<option value="CHECKING">Checking</option>
<option value="SAVINGS">Savings</option>
</select>
</div>

<button type="submit">Pay with Bank Account</button>
</form>
);
}

Account Types

  • CHECKING - Checking account
  • SAVINGS - Savings account

Existing Payment Methods

You can also use existing payment instruments by passing the payment instrument ID:

const { checkout } = useEasy();

await checkout({
customer_creation: false,
identity_id: "cust_123",
source: "pi_existing_payment_instrument_id", // Just the ID string
line_items: [{ price_id: "price_123", quantity: 1 }],
});

Comparison

FeaturePayment CardsBank Accounts
Processing TimeInstant1-3 business days
FeesHigher (2-3%)Lower (0.8%)
RefundsInstant5-10 business days
CountriesGlobalUS only
VerificationCVVMicro-deposits
ChargebacksYesLimited

When to Use Each Type

Use Payment Cards When:

  • ✅ You need instant payment confirmation
  • ✅ Selling to international customers
  • ✅ Processing one-time purchases
  • ✅ Customer expects immediate delivery

Use Bank Accounts When:

  • ✅ Processing large transactions (lower fees)
  • ✅ Setting up recurring payments
  • ✅ Customers are US-based
  • ✅ You can wait for payment settlement

Security Considerations

Payment Cards

  • ✅ PCI DSS compliant with secure tokenization
  • ✅ CVV verification required
  • ✅ Address verification recommended
  • ✅ 3D Secure support available

Bank Accounts

  • ✅ Account ownership verification
  • ✅ Micro-deposit verification available
  • ✅ ACH fraud protection
  • ✅ Bank-level encryption

Best Practices

  1. Offer both options: Give customers choice for better conversion
  2. Clear communication: Explain processing times upfront
  3. Save payment methods: Allow customers to save for future use
  4. Verify ownership: Use address verification for cards, micro-deposits for banks
  5. Handle errors gracefully: Provide clear error messages

Error Handling

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

try {
const result = await checkout({
/* ... */
});
console.log("Success:", result);
} catch (error) {
if (error.message.includes("card")) {
console.error("Card error:", error);
// Handle card-specific errors
} else if (error.message.includes("bank")) {
console.error("Bank error:", error);
// Handle bank-specific errors
}
}
};

Next Steps