HandyPay
HandyPay

How to Accept Payments on a Website: A Complete Guide

Accepting payments on a website requires integrating a payment processor that securely handles card transactions. This guide covers the technical approaches, implementation steps, and considerations for adding payment functionality to your website.

Whether you are building an e-commerce store, accepting donations, or collecting payments for services, understanding your options helps you choose the right approach.

Overview of Website Payment Options

Websites can accept payments through several methods:

Hosted payment pages redirect customers to a payment provider's secure page. After payment, customers return to your site. This requires minimal technical work.

Embedded payment forms display payment fields directly on your website using the provider's JavaScript library. Card data is handled securely without touching your servers.

Full API integration gives complete control over the payment flow. Your server communicates directly with the payment API to create and manage transactions.

Payment links can be embedded on websites as buttons or included in confirmation emails. Customers click to complete payment on a hosted page.

Each approach involves trade-offs between simplicity and control.

Hosted Payment Pages

Hosted payment pages are the simplest way to accept payments on a website.

How it works:

  1. Customer clicks a payment button on your site
  2. Customer is redirected to the payment provider's hosted page
  3. Customer enters card details on the secure hosted page
  4. After payment, customer is redirected back to your site
  5. Your server receives a webhook confirming the payment

Advantages:

  • Minimal development required
  • Payment provider handles all PCI compliance
  • Works with any website platform
  • Mobile-optimized by default

Disadvantages:

  • Customer leaves your site during checkout
  • Limited customization of payment page appearance
  • May increase cart abandonment due to redirect

Implementation steps:

  1. Create an account with a payment provider
  2. Configure your hosted checkout settings
  3. Add a payment button or link to your website
  4. Set up redirect URLs for success and cancellation
  5. Implement webhook handling to confirm payments

Embedded Payment Forms

Embedded payment forms keep customers on your website while securely collecting card details.

How it works:

  1. Your page loads the payment provider's JavaScript library
  2. The library renders secure input fields for card details
  3. Customer enters card information in the embedded fields
  4. JavaScript tokenizes the card data with the payment provider
  5. Your server uses the token to complete the payment via API

Advantages:

  • Customer stays on your website
  • Customizable appearance to match your brand
  • Better conversion rates than redirects
  • Card data never touches your servers

Disadvantages:

  • Requires JavaScript integration
  • More development work than hosted pages
  • Must handle various card input states and errors

Implementation example:

<!-- Include the payment provider's JavaScript -->
<script src="https://js.paymentprovider.com/v1/"></script>

<form id="payment-form">
  <div id="card-element">
    <!-- Payment fields render here -->
  </div>
  <button type="submit">Pay</button>
  <div id="error-message"></div>
</form>

<script>
  // Initialize the payment library
  const provider = PaymentProvider("your_public_key");
  const elements = provider.elements();
  const cardElement = elements.create("card");
  cardElement.mount("#card-element");

  // Handle form submission
  document
    .getElementById("payment-form")
    .addEventListener("submit", async (e) => {
      e.preventDefault();

      const { token, error } = await provider.createToken(cardElement);

      if (error) {
        document.getElementById("error-message").textContent = error.message;
      } else {
        // Send token to your server to complete payment
        await fetch("/api/charge", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ token: token.id, amount: 5000 }),
        });
      }
    });
</script>

Full API Integration

Full API integration provides maximum control over the payment experience.

How it works:

  1. Your server creates a payment intent via API
  2. The API returns a client secret for the frontend
  3. Your frontend collects card details and confirms the payment
  4. Your server receives webhook notifications of payment status
  5. You update your database and fulfill the order

Advantages:

  • Complete control over payment flow
  • Support for complex scenarios (subscriptions, marketplaces)
  • Can build custom checkout experiences
  • Full access to payment provider features

Disadvantages:

  • Requires significant development effort
  • Must handle error cases and edge conditions
  • Ongoing maintenance as APIs evolve

Server-side implementation example:

// Create a payment intent on your server
app.post("/api/create-payment", async (req, res) => {
  const { amount, currency, description } = req.body;

  const response = await fetch("https://api.paymentprovider.com/v1/payments", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SECRET_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount,
      currency,
      description,
    }),
  });

  const payment = await response.json();

  res.json({
    clientSecret: payment.clientSecret,
    paymentId: payment.id,
  });
});

// Handle webhook notifications
app.post("/api/webhooks", async (req, res) => {
  const signature = req.headers["x-payment-signature"];

  // Verify webhook signature
  const isValid = verifySignature(
    req.body,
    signature,
    process.env.WEBHOOK_SECRET,
  );

  if (!isValid) {
    return res.status(400).send("Invalid signature");
  }

  const event = req.body;

  if (event.type === "payment.succeeded") {
    // Update order status, send confirmation email, etc.
    await fulfillOrder(event.data.paymentId);
  }

  res.json({ received: true });
});

API Key Management

Secure API integration requires proper key management.

Public keys (also called publishable keys) are safe to include in client-side code. They identify your account but cannot perform sensitive operations.

Secret keys must be kept on your server and never exposed in frontend code. They authenticate requests that create charges, issue refunds, and access sensitive data.

Best practices:

  • Store secret keys in environment variables, not in code
  • Use different keys for test and production environments
  • Rotate keys periodically and after any suspected compromise
  • Restrict key permissions to only what is needed

Webhook Implementation

Webhooks notify your server of payment events asynchronously.

Why webhooks matter:

  • Payments can succeed after the customer leaves your site
  • Network issues may prevent your frontend from receiving confirmation
  • Webhooks provide reliable notification of payment outcomes

Webhook security:

  • Verify webhook signatures to confirm authenticity
  • Use HTTPS endpoints only
  • Respond quickly (within 5 seconds) to avoid timeouts
  • Implement idempotency to handle duplicate deliveries

Common webhook events:

  • payment.succeeded - Payment completed successfully
  • payment.failed - Payment attempt failed
  • payment.refunded - Payment was refunded
  • dispute.created - Customer disputed a charge

Security Considerations

Website payment integration requires attention to security.

PCI DSS compliance applies to any business handling card data. Using hosted payment pages or embedded forms with tokenization minimizes your compliance burden.

HTTPS is required for any page collecting payment information. Obtain an SSL certificate and configure your server to use HTTPS.

Never log card numbers or store them in your database. Use tokens provided by your payment processor instead.

Validate all inputs on both client and server. Never trust data from the frontend without verification.

Implement CSRF protection on payment endpoints to prevent cross-site request forgery attacks.

Testing Your Integration

Test thoroughly before accepting real payments.

Use test mode provided by your payment processor. Test API keys process transactions without moving real money.

Test card numbers simulate various scenarios:

  • Successful payments
  • Declined cards
  • Insufficient funds
  • Expired cards
  • 3D Secure authentication

Test edge cases:

  • Network failures during payment
  • Customer closing browser mid-payment
  • Duplicate form submissions
  • Invalid input handling

Choosing a Payment Provider

Consider these factors when selecting a provider:

Geographic coverage - Does the provider support your target markets?

Supported payment methods - Cards, digital wallets, bank transfers?

Pricing - Per-transaction fees, monthly costs, setup fees?

Developer experience - Quality of documentation, SDKs, and support?

Features - Subscriptions, invoicing, marketplace support?

Popular providers include Stripe, PayPal, Square, and regional options. HandyPay offers both payment links and API integration for businesses in the Caribbean.

Platform-Specific Considerations

Different website platforms have different integration approaches.

WordPress/WooCommerce - Use payment gateway plugins for quick setup

Shopify - Built-in payment processing with Shopify Payments

Custom websites - Direct API integration using the approaches above

Static sites - Use hosted payment pages or serverless functions for API calls

Frequently Asked Questions

Do I need a developer to accept payments on my website?

Hosted payment pages require minimal technical skill. Embedded forms and API integration typically require developer assistance.

How long does it take to set up website payments?

Hosted pages can be operational in hours. Full API integration may take days to weeks depending on complexity.

What are the fees for accepting payments online?

Most providers charge 2.5% to 3.5% plus a fixed fee per transaction. Volume discounts may be available.

Is my website PCI compliant?

Using hosted pages or embedded forms with tokenization handles most PCI requirements. Consult your payment provider's compliance documentation.

Can I accept payments without a business entity?

Some providers allow individual accounts. Requirements vary by provider and jurisdiction.

How do I handle refunds?

Most payment APIs include refund endpoints. Refunds typically return funds to the original payment method within 5-10 business days.

Related Guides