Skip to main content

Hosted Checkout Integration

The Payment Gateway provides a fully-hosted, PCI-compliant checkout page that handles card collection and payment processing. This eliminates your PCI compliance burden and provides a secure, optimized payment experience.
Checkout URL: https://checkout-page-amber.vercel.appBuilt with Next.js 15, React 19, and TypeScript

Why Use Hosted Checkout?

Zero PCI Compliance Burden

Card data never touches your serverNo PCI-DSS compliance requirements for your infrastructure

Enterprise-Grade Security

Client-side validation with Luhn algorithmHTTPS enforcement, input sanitization, automatic expiration

Optimized Conversion

Mobile-first responsive designReal-time validation, clear error messages, smooth animations

Zero Maintenance

Fully managed and updatedWorks across all modern browsers, automatic security patches

Security Features

PCI-DSS Compliance

Card Data Isolation: Card numbers, CVV, and expiry dates never touch your server. All sensitive data is collected directly by the checkout page and sent to the Payment API over encrypted connections.
Card Validation:
  • Luhn algorithm validation (detects typos)
  • Expiry date validation (rejects expired cards)
  • CVV format validation (3-4 digits)
  • Real-time error feedback
Input Sanitization:
  • Special characters blocked
  • Paste prevention on CVV field
  • Numeric-only inputs for card numbers
HTTPS Enforcement:
  • TLS 1.3 encryption for all requests
  • Strict-Transport-Security headers
  • Content-Security-Policy enforcement
Authentication:
  • Client secret validation (not API keys)
  • One-time use secrets per payment intent
  • Automatic expiration after 1 hour
Expiration Handling:
  • Payment intents expire after 1 hour
  • Automatic redirect on expiration
  • Clear expiration messaging
Attempt Limiting:
  • Maximum 5 payment attempts per intent
  • Progressive delay between attempts
  • Automatic intent invalidation after max attempts
No Data Persistence:
  • Card data never logged or stored client-side
  • Tokenization happens server-side immediately
  • Only last 4 digits stored for receipts
Error Handling:
  • Generic error messages (no sensitive data exposed)
  • No card details in error logs
  • Rate limiting on validation failures

How It Works

Payment Flow


Integration Steps

1

Create Payment Intent (Server-Side)

Create a payment intent with your API key:
2

Redirect Customer to Checkout

Use the checkout_url from the response:
Checkout URL format:
3

Customer Completes Payment

The checkout page:
  • Validates payment intent hasn’t expired
  • Displays order summary (amount, currency)
  • Collects card details with real-time validation
  • Submits payment to API with client_secret
  • Shows success animation or error message
  • Redirects to your success/cancel URL
4

Handle Customer Return

Verify payment on your server:

Checkout Page Features

User Experience

Responsive Design

Mobile-first layout optimized for all screen sizesTouch-friendly inputs, large tap targets

Real-Time Validation

Instant feedback on card input errorsClear, actionable error messages

Smart Card Detection

Automatic brand detection (Visa, Mastercard, etc.)Dynamic card logo display

Accessibility

WCAG 2.1 AA compliantScreen reader friendly, keyboard navigation

Payment Summary Display

The checkout page automatically displays:

Supported Payment Methods

Visa
  • All Visa cards supported
  • Test card: 4242 4242 4242 4242
Mastercard
  • All Mastercard types supported
  • Test card: 5555 5555 5555 4444
Card Requirements:
  • 13-19 digit card number
  • Valid expiry date (MM/YY format)
  • 3-4 digit CVV/CVC code
  • Cardholder name

Error Handling

Payment Intent Errors

Displayed Message:
Action:
  • Automatic redirect to cancel_url after 5 seconds
  • “Return to Merchant” button shown immediately
Cause: Payment intent created more than 1 hour ago
Displayed Message:
Action:
  • Show support contact information
  • Log error for merchant review
Cause:
  • Tampered client_secret parameter
  • Client secret from different payment intent
Displayed Message:
Action:
  • Redirect to success_url immediately
Cause:
  • Customer refreshed page after successful payment
  • Attempting to pay twice with same intent
Displayed Message:
Action:
  • Redirect to cancel_url
  • Show “Contact Support” button
Cause:
  • 5 failed payment attempts on this intent

Card Validation Errors

Invalid Card Number

Error: “Invalid card number”Triggers:
  • Luhn check fails
  • Less than 13 or more than 19 digits
  • Non-numeric characters

Expired Card

Error: “Card has expired”Triggers:
  • Expiry date in the past
  • Invalid month (>12)

Invalid CVV

Error: “Invalid security code”Triggers:
  • Less than 3 digits
  • Non-numeric characters

Missing Name

Error: “Cardholder name required”Triggers:
  • Empty field
  • Less than 3 characters

Payment Declined Errors

User-Friendly Messages:

Customization Options

URL Configuration

string
required
Where to redirect customer after successful paymentPlaceholder: Use {CHECKOUT_SESSION_ID} to include payment intent IDExample:
Result:
string
Where to redirect customer on cancellation or failureExample:
Triggers:
  • Customer clicks “Cancel” button
  • Payment intent expires
  • Maximum attempts reached

Metadata

Pass custom data that appears on receipts and webhooks:
Metadata is:
  • Returned in webhook events
  • Visible in payment dashboard
  • Searchable for reporting
  • Limited to 50 keys, 500 chars per value

Best Practices

Never trust client-side redirects alone.
Implement both success and cancel handlers.
Cancel reasons:
  • Customer clicked “Cancel” button
  • Payment declined after max attempts
  • Payment intent expired
  • Customer abandoned checkout
Don’t rely solely on redirect for order fulfillment.Redirects can be missed (browser crash, network issue). Use webhooks as the primary fulfillment trigger:
Use redirects for user feedback only.
One payment intent = one order.
Help customers recognize charges.
Appears on:
  • Checkout page header
  • Customer bank statement
  • Payment receipts

Browser Support

Desktop Browsers

Chrome/Edge: 88+Firefox: 85+Safari: 14+

Mobile Browsers

iOS Safari: 14+Chrome Mobile: 88+Samsung Internet: 13+
Features:
  • ES6+ JavaScript
  • CSS Grid & Flexbox
  • Fetch API
  • Web Crypto API (for validation)

FAQ

Currently: No, the checkout page uses a standard design for all merchants.Future: We’re working on customization options:
  • Custom logo upload
  • Brand color selection
  • Custom success messages
Contact sales for enterprise customization.
Short answer: Nothing is charged.Details:
  • Payment intent remains in created status
  • Customer can return to same checkout URL (if not expired)
  • Intent auto-expires after 1 hour
  • No money is held or charged
Currently: No, checkout collects card details only.Workaround: Collect billing address on your order form before redirecting to checkout. Pass it in metadata:
Use test cards (see Test Cards section).All test cards work in production environment without charging real money. Results are simulated based on card number.
Currently: No, each payment requires new card entry.Future: Card-on-file and subscription features are planned for Q2 2026.

Troubleshooting

Causes:
  • Payment intent ID in URL doesn’t exist
  • Client secret doesn’t match intent
  • Intent was created for different merchant
Solution:
  • Verify checkout_url from payment intent response is used exactly
  • Don’t modify URL parameters
  • Check API key belongs to correct merchant
Cause: Payment intent created more than 1 hour ago.Solution:
  • Create new payment intent
  • Reduce time between intent creation and checkout redirect
  • Consider creating intent when customer clicks “Checkout” button, not when cart is created
Causes:
  • Customer clicked browser back button before completing payment
  • Payment was declined but customer was redirected to success_url (shouldn’t happen)
Solution:
  • Always verify payment status server-side (see Best Practices)
  • Check for status: 'authorized' or status: 'captured' before fulfilling
Causes:
  • Using real card number in test mode
  • Incorrect expiry format
  • Test card not in supported list
Solution:
  • Use exact test card numbers (4242 4242 4242 4242 for success)
  • Use any future expiry date (e.g., 12/2027)
  • Use any 3-digit CVV

Next Steps

Payment API Reference

Complete Payment Intent API documentation

Quick Start Guide

Create your first payment in 5 minutes

Webhooks Guide

Implement webhook handlers

CLI Tool

Test payments from command line

Questions? Contact support at [email protected]