DEV Community

Cover image for 2Checkout API: Complete Integration Guide for Payment Processing (2026)
Preecha
Preecha

Posted on

2Checkout API: Complete Integration Guide for Payment Processing (2026)

TL;DR

The 2Checkout API (now Verifone) lets you process payments, manage subscriptions, and automate e-commerce workflows through REST endpoints for orders, customers, products, and webhooks.

Try Apidog today

This implementation guide covers authentication, payment and subscription flows, webhook verification, error handling, sandbox testing, and production readiness.

Introduction

Payment processing directly affects conversion and revenue. The 2Checkout API, now part of Verifone Digital Commerce, supports payment processing for merchants globally.

Payment friction matters: 67% of shoppers abandon carts due to payment issues. A reliable API integration helps reduce failures across checkout, renewals, refunds, and customer management.

By the end of this guide, you will have a practical implementation plan for:

  • Authenticating API requests
  • Creating one-time orders
  • Managing customers and subscriptions
  • Handling 3D Secure and multi-currency pricing
  • Verifying and processing webhooks
  • Testing in sandbox before production

Apidog can simplify API integration testing. Use it to test 2Checkout endpoints, validate webhook payloads, mock responses, and share test scenarios with your team.

What Is the 2Checkout API?

2Checkout, now operating as Verifone Digital Commerce, provides a RESTful API for payment processing and subscription management.

You can use it for:

  • One-time and recurring payments
  • Customer and product management
  • Order lifecycle tracking
  • Refund and dispute handling
  • Tax and compliance automation
  • Multi-currency support across 100+ currencies

Key Features

Feature Description
RESTful design Standard GET, POST, PUT, and DELETE methods with JSON payloads
Sandbox environment Test payments without processing real transactions
Webhook support Receive real-time notifications for order events
Tokenization Handle payment data without storing card details
Global compliance PCI DSS Level 1, GDPR, PSD2, and 3D Secure 2.0 support

API Architecture

2Checkout uses versioned REST API paths:

https://api.2checkout.com/1/
https://api.2checkout.com/2/
Enter fullscreen mode Exit fullscreen mode

Version 2 is the current recommended version, with improved subscription management and webhook handling.

Getting Started: Authentication Setup

Step 1: Create a Merchant Account

Before calling the API:

  1. Visit the 2Checkout or Verifone signup page.
  2. Complete business verification.
  3. Wait for account approval, typically 24–48 hours.
  4. Open the Control Panel and retrieve your API credentials.

Step 2: Retrieve API Keys

In the Control Panel, go to Integrations > API Keys.

You need:

  • Private API Key: Server-side authentication. Keep this secret.
  • Public API Key: Client-side tokenization. Safe to expose in the browser.
  • Webhook Secret: Verifies webhook signatures.

Store secrets in environment variables rather than source code:

# .env
TWOCHECKOUT_PRIVATE_KEY="your_private_key_here"
TWOCHECKOUT_PUBLIC_KEY="your_public_key_here"
TWOCHECKOUT_WEBHOOK_SECRET="your_webhook_secret_here"
Enter fullscreen mode Exit fullscreen mode

Add .env files to .gitignore and configure equivalent secrets in your deployment platform.

Step 3: Choose Sandbox or Production

Environment Base URL Use case
Sandbox https://sandbox.2checkout.com/api/ Development and testing
Production https://api.2checkout.com/ Live transactions

Use sandbox credentials during development. Switch both the base URL and credentials when you are ready to accept real payments.

Step 4: Authenticate Requests

2Checkout supports API key authentication and HMAC request signing.

Method 1: API Key Authentication

Send the private key in the request headers:

const response = await fetch('https://api.2checkout.com/1/orders', {
  method: 'GET',
  headers: {
    'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
    'Content-Type': 'application/json',
    Accept: 'application/json'
  }
});
Enter fullscreen mode Exit fullscreen mode

Method 2: HMAC Signature Authentication

For enhanced security, sign request payloads with HMAC-SHA256:

const crypto = require('crypto');

function generateSignature(payload, privateKey) {
  return crypto
    .createHmac('sha256', privateKey)
    .update(JSON.stringify(payload))
    .digest('hex');
}

const payload = {
  order_id: '12345',
  amount: 99.99
};

const signature = generateSignature(
  payload,
  process.env.TWOCHECKOUT_PRIVATE_KEY
);

const response = await fetch('https://api.2checkout.com/1/orders', {
  method: 'POST',
  headers: {
    'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
    'X-Signature': signature,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
});
Enter fullscreen mode Exit fullscreen mode

Image

Processing Payments: Core Endpoints

Create a One-Time Order

Use the /orders endpoint to create a payment order. Tokenize card details client-side and send only the resulting token from your server.

const createOrder = async (customerData, productData) => {
  const payload = {
    currency: 'USD',
    customer: {
      email: customerData.email,
      first_name: customerData.firstName,
      last_name: customerData.lastName,
      phone: customerData.phone,
      billing_address: {
        address1: customerData.address,
        city: customerData.city,
        state: customerData.state,
        zip: customerData.zip,
        country: customerData.country
      }
    },
    items: [
      {
        name: productData.name,
        quantity: productData.quantity,
        price: productData.price,
        product_code: productData.sku
      }
    ],
    payment_method: {
      type: 'card',
      card_token: customerData.cardToken
    }
  };

  const response = await fetch('https://api.2checkout.com/1/orders', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  });

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Expected Response

{
  "order_id": "ORD-2026-001234",
  "status": "approved",
  "amount": 99.99,
  "currency": "USD",
  "customer_id": "CUST-789456",
  "transaction_id": "TXN-9876543210",
  "created_at": "2026-03-20T10:30:00Z"
}
Enter fullscreen mode Exit fullscreen mode

Handle Payment Errors

Check both API-level failures and payment-specific error responses.

try {
  const result = await createOrder(customer, product);

  if (result.error) {
    switch (result.error.code) {
      case 'CARD_DECLINED':
        // Ask the customer to use another payment method.
        break;

      case 'INSUFFICIENT_FUNDS':
        // Show an appropriate payment failure message.
        break;

      case 'INVALID_CVV':
        // Ask the customer to re-enter their CVV.
        break;

      default:
        console.error('Payment failed:', result.error);
    }
  }
} catch (error) {
  // Network, timeout, or server error.
  console.error('API request failed:', error);
}
Enter fullscreen mode Exit fullscreen mode

Common Error Codes

Error code HTTP status Description Resolution
CARD_DECLINED 402 Card was declined Ask for another payment method
INVALID_CARD 400 Invalid card number Validate card input
EXPIRED_CARD 400 Card has expired Request updated expiration
INVALID_CVV 400 CVV verification failed Re-request CVV
INSUFFICIENT_FUNDS 402 Not enough funds Suggest an alternative payment method
DUPLICATE_ORDER 409 Order already processed Check idempotency and duplicate submissions
INVALID_CURRENCY 400 Unsupported currency Verify the currency code
API_KEY_INVALID 401 Authentication failed Check the API key

Customer Management

Customer records are useful for repeat purchases and subscription billing.

Create a Customer

const createCustomer = async (customerData) => {
  const payload = {
    email: customerData.email,
    first_name: customerData.firstName,
    last_name: customerData.lastName,
    phone: customerData.phone,
    company: customerData.company,
    billing_address: {
      address1: customerData.address,
      address2: customerData.address2 || '',
      city: customerData.city,
      state: customerData.state,
      zip: customerData.zip,
      country: customerData.country
    },
    shipping_address: customerData.shippingAddress || null,
    tax_exempt: false,
    language: 'en'
  };

  const response = await fetch('https://api.2checkout.com/1/customers', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  });

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Customer Response

{
  "customer_id": "CUST-2026-123456",
  "email": "john.doe@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "created_at": "2026-03-20T10:00:00Z",
  "updated_at": "2026-03-20T10:00:00Z",
  "payment_methods": [],
  "subscriptions": [],
  "order_history": []
}
Enter fullscreen mode Exit fullscreen mode

Retrieve a Customer

const getCustomer = async (customerId) => {
  const response = await fetch(
    `https://api.2checkout.com/1/customers/${customerId}`,
    {
      method: 'GET',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      }
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Update a Customer

const updateCustomer = async (customerId, updates) => {
  const response = await fetch(
    `https://api.2checkout.com/1/customers/${customerId}`,
    {
      method: 'PUT',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(updates)
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Delete a Customer

const deleteCustomer = async (customerId) => {
  const response = await fetch(
    `https://api.2checkout.com/1/customers/${customerId}`,
    {
      method: 'DELETE',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY
      }
    }
  );

  return response.status === 204;
};
Enter fullscreen mode Exit fullscreen mode

Note: Deleting a customer with active subscriptions or outstanding balances will fail. Cancel subscriptions first.

Advanced Integration Patterns

Use Idempotency Keys for Safe Retries

Payment requests must be safe to retry. Include a unique idempotency key for each order:

const createIdempotentOrder = async (payload, idempotencyKey) => {
  const response = await fetch('https://api.2checkout.com/1/orders', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
      'Content-Type': 'application/json',
      'X-Idempotency-Key': idempotencyKey
    },
    body: JSON.stringify(payload)
  });

  return response.json();
};

// Generate once per order and store it in your database.
const idempotencyKey = `order_${userId}_${Date.now()}`;
Enter fullscreen mode Exit fullscreen mode

If a request times out after 2Checkout processes it, retry with the same key. The API should return the original result instead of creating a duplicate charge.

Handle 3D Secure 2.0

For European customers, 3D Secure 2.0 is mandatory under PSD2.

const createOrderWith3DS = async (payload) => {
  const response = await fetch('https://api.2checkout.com/1/orders', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      ...payload,
      three_ds: {
        enabled: true,
        challenge_required: 'preferred',
        notification_url: 'https://your-site.com/3ds-callback'
      }
    })
  });

  const result = await response.json();

  if (result.three_ds_redirect_url) {
    // Redirect the customer to their bank for authentication.
    res.redirect(result.three_ds_redirect_url);
  }

  return result;
};
Enter fullscreen mode Exit fullscreen mode

Use mandatory when required for EU flows.

Retrieve Multi-Currency Prices

You can display a localized price while settling in your base currency:

const getLocalizedPrice = async (basePrice, targetCurrency) => {
  const response = await fetch(
    `https://api.2checkout.com/1/rates?from=USD&to=${targetCurrency}`,
    {
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY
      }
    }
  );

  const rates = await response.json();
  return basePrice * rates.rate;
};

const eurPrice = await getLocalizedPrice(99.99, 'EUR');

console.log(`Price: EUR ${eurPrice.toFixed(2)}`);
Enter fullscreen mode Exit fullscreen mode

Apply Proration for Subscription Upgrades

When a customer changes plans mid-cycle, use proration settings to calculate the difference:

const upgradeSubscription = async (subscriptionId, newPlanId) => {
  const response = await fetch(
    `https://api.2checkout.com/1/subscriptions/${subscriptionId}/upgrade`,
    {
      method: 'POST',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        plan_id: newPlanId,
        proration: 'immediate',
        invoice_proration: true
      })
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Subscription Management

2Checkout supports recurring billing workflows, including trials, renewals, upgrades, and cancellations.

Create a Subscription

const createSubscription = async (customerId, planId) => {
  const payload = {
    customer_id: customerId,
    plan_id: planId,
    start_date: new Date().toISOString(),
    billing_cycle: 'monthly',
    payment_method: {
      type: 'card',
      card_token: 'tok_card_tokenized'
    },
    options: {
      trial_days: 14,
      auto_renew: true
    }
  };

  const response = await fetch(
    'https://api.2checkout.com/1/subscriptions',
    {
      method: 'POST',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Subscription Response

{
  "subscription_id": "SUB-2026-567890",
  "status": "active",
  "plan_id": "PLAN-PREMIUM-MONTHLY",
  "customer_id": "CUST-789456",
  "current_period_start": "2026-03-20T00:00:00Z",
  "current_period_end": "2026-04-20T00:00:00Z",
  "trial_end": "2026-04-03T00:00:00Z",
  "amount": 29.99,
  "currency": "USD"
}
Enter fullscreen mode Exit fullscreen mode

Update a Subscription

Use PUT to change plans, quantities, or payment methods:

const updateSubscription = async (subscriptionId, updates) => {
  const payload = {
    ...updates
    // Example values:
    // plan_id: 'PLAN-ENTERPRISE-MONTHLY',
    // quantity: 5,
    // payment_method: { card_token: 'new_token' }
  };

  const response = await fetch(
    `https://api.2checkout.com/1/subscriptions/${subscriptionId}`,
    {
      method: 'PUT',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Cancel a Subscription

const cancelSubscription = async (subscriptionId, reason = '') => {
  const payload = {
    cancel_at_period_end: false,
    reason
  };

  const response = await fetch(
    `https://api.2checkout.com/1/subscriptions/${subscriptionId}/cancel`,
    {
      method: 'POST',
      headers: {
        'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    }
  );

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Set cancel_at_period_end to true to preserve customer access through the current billing period.

Webhook Integration: Real-Time Event Handling

Webhooks notify your application about payment and subscription events without polling. They are essential for renewals, failed payments, refunds, and access control.

Step 1: Configure a Webhook Endpoint

In the 2Checkout Control Panel:

  1. Go to Integrations > Webhooks.
  2. Add an HTTPS endpoint URL.
  3. Select the events your application needs.
  4. Save the configuration.
  5. Store the generated webhook secret securely.

Step 2: Implement a Webhook Handler

Use the raw request body for signature verification.

const express = require('express');
const crypto = require('crypto');

const app = express();

app.post(
  '/webhooks/2checkout',
  express.raw({ type: 'application/json' }),
  async (req, res) => {
    const signature = req.headers['x-webhook-signature'];
    const payload = req.body;

    const isValid = verifyWebhookSignature(
      payload,
      signature,
      process.env.TWOCHECKOUT_WEBHOOK_SECRET
    );

    if (!isValid) {
      console.error('Invalid webhook signature');
      return res.status(401).send('Unauthorized');
    }

    const event = JSON.parse(payload.toString());

    switch (event.type) {
      case 'order.created':
        await handleOrderCreated(event.data);
        break;

      case 'order.approved':
        await handleOrderApproved(event.data);
        break;

      case 'order.declined':
        await handleOrderDeclined(event.data);
        break;

      case 'subscription.created':
        await handleSubscriptionCreated(event.data);
        break;

      case 'subscription.renewed':
        await handleSubscriptionRenewed(event.data);
        break;

      case 'subscription.cancelled':
        await handleSubscriptionCancelled(event.data);
        break;

      case 'refund.processed':
        await handleRefundProcessed(event.data);
        break;

      default:
        console.log('Unhandled event type:', event.type);
    }

    return res.status(200).send('OK');
  }
);

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}
Enter fullscreen mode Exit fullscreen mode

Critical Webhook Events

Event type Trigger Recommended action
order.created New order placed Send a confirmation email
order.approved Payment successful Fulfill the order or grant access
order.declined Payment failed Notify the customer and apply retry logic
subscription.renewed Recurring payment completed Extend the access period
subscription.payment_failed Renewal failed Start a dunning sequence
subscription.cancelled Customer canceled Revoke access at period end
refund.processed Refund issued Update user balance
chargeback.received Dispute filed Gather evidence

Webhook Best Practices

  • Verify signatures: Prevent spoofed webhook requests.
  • Return 200 OK quickly: Non-200 responses can trigger retries.
  • Process asynchronously: Queue heavy work instead of blocking the webhook response.
  • Make handlers idempotent: Duplicate deliveries can happen.
  • Log every event: Include event IDs, timestamps, payload metadata, and processing status.

Testing Your Integration

Use the Sandbox Environment

Use sandbox endpoints and keys before processing real payments:

const BASE_URL = 'https://sandbox.2checkout.com/api/1';

const TEST_CARDS = {
  APPROVED: '4111111111111111',
  DECLINED: '4000000000000002',
  INSUFFICIENT_FUNDS: '4000000000009995',
  EXPIRED_CARD: '4000000000000069'
};

const TEST_ADDRESS = {
  country: 'US',
  zip: '90210'
};
Enter fullscreen mode Exit fullscreen mode

Test success paths and failure paths before production:

  • Approved payments
  • Declined cards
  • Invalid CVV values
  • Insufficient funds
  • Expired cards
  • Subscription renewals and cancellation
  • Webhook retries and duplicate deliveries

Test Webhooks Locally

Use ngrok to expose a local webhook handler:

# Install ngrok
npm install -g ngrok

# Start your application
node server.js

# Expose local port 3000
ngrok http 3000
Enter fullscreen mode Exit fullscreen mode

Copy the generated HTTPS URL into the 2Checkout webhook settings.

Test With Apidog

Apidog can streamline testing for a 2Checkout integration:

  • Import the OpenAPI specification
  • Create endpoint-specific test scenarios
  • Mock API responses without calling the live API
  • Validate webhook payload structures
  • Share collections and environments with your team

Create separate sandbox and production environments, then switch API base URLs and credentials without changing requests.

Troubleshooting Common Issues

Webhooks Are Not Arriving

Symptoms: Orders process successfully, but your application state does not update.

Check webhook delivery logs in the 2Checkout dashboard for failed attempts and non-200 responses.

Fixes:

  • Return 200 OK within five seconds.
  • Confirm the endpoint uses HTTPS.
  • Validate the SSL certificate.
  • Whitelist 2Checkout IP ranges in your firewall.
  • Review signature verification logic.
  • Test the endpoint with a webhook simulator before production.

Sandbox Payments Fail

Symptoms: All test cards decline in sandbox.

Check the following:

  • Use sandbox API keys, not production keys.
  • Use the sandbox base URL: https://sandbox.2checkout.com/api/.
  • Use supported test card numbers.
  • Verify that the sandbox account is active.

Subscription Renewals Fail Silently

Symptoms: A subscription remains active, but renewal payments do not process.

Query payment history:

const history = await fetch(
  `https://api.2checkout.com/1/subscriptions/${subId}/payments`,
  {
    headers: {
      'X-Api-Key': privateKey
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

Then verify:

  • The customer payment method has not expired.
  • Dunning settings are enabled in the Control Panel.
  • Your application receives subscription.payment_failed events.
  • The subscription has auto_renew enabled.

Currency Conversion Does Not Match Expected Values

Symptoms: The charged amount differs from a locally calculated conversion.

2Checkout uses daily exchange rates, which fluctuate.

Recommended approach:

  • Display conversion amounts as approximate.
  • Lock rates at cart creation with a 15-minute expiry.
  • Store transactions in the customer’s local currency.

AVS Failures

Symptoms: Valid cards fail because the billing address does not match.

Possible improvements:

  • Add address autocomplete with tools such as Google Places or Lob.
  • Require ZIP or postal code during checkout.
  • Use soft AVS warnings instead of immediate declines.
  • Let customers update their billing address easily.

Production Deployment Checklist

Before going live:

  • [ ] Switch from sandbox to production API keys.
  • [ ] Update the base URL to https://api.2checkout.com/.
  • [ ] Enable webhook signature verification.
  • [ ] Monitor failed payments.
  • [ ] Add retry handling for transient failures.
  • [ ] Test refund and chargeback flows.
  • [ ] Verify PCI DSS compliance by using tokenization.
  • [ ] Enable 3D Secure 2.0 for EU customers.
  • [ ] Create timestamped audit logs.
  • [ ] Write a runbook for payment incidents.

Monitor Payment Health

Track payment success rates and error-code trends.

const successRate = (approvedOrders / totalOrders) * 100;

if (successRate < 95) {
  sendAlert('Payment success rate dropped below 95%');
}

const errorBreakdown = errors.reduce((acc, err) => {
  acc[err.code] = (acc[err.code] || 0) + 1;
  return acc;
}, {});

if (errorBreakdown.CARD_DECLINED > threshold) {
  sendAlert('Spike in card declines detected');
}
Enter fullscreen mode Exit fullscreen mode

Useful production metrics include:

  • Approval rate
  • Checkout error rate
  • Webhook delivery failures
  • Subscription renewal success rate
  • Refund volume
  • Chargeback volume
  • Error-code distribution

Real-World Use Cases

E-Commerce Store Integration

A fashion retailer integrated 2Checkout for global payments and reported:

  • Support for 100+ currencies
  • A 23% reduction in cart abandonment
  • Automated EU VAT compliance
  • More than $2M processed in the first year

The team started with 2Checkout hosted checkout pages, then moved to direct API integration for a custom checkout experience. Implementation took three weeks.

SaaS Subscription Business

A project-management SaaS used 2Checkout subscriptions to:

  • Manage more than 5,000 active subscriptions
  • Apply proration for plan upgrades
  • Automate dunning for failed renewals
  • Reduce churn by 15% through smart retries

The key pattern was webhook-driven access control:

  • On subscription.renewed, extend user access immediately.
  • On subscription.cancelled, schedule access revocation.

Conclusion

The 2Checkout API provides the core building blocks for payment processing and subscription management.

For a production-ready integration:

  • Develop and test in sandbox first.
  • Keep API keys and webhook secrets out of source control.
  • Use tokenization instead of handling raw card data.
  • Add idempotency to payment requests and webhook handlers.
  • Verify webhook signatures with HMAC-SHA256.
  • Test trial, renewal, cancellation, refund, and failure flows.
  • Monitor payment success rates and error-code spikes.
  • Use Apidog to organize API tests, mock responses, and validate webhook payloads.

FAQ

What is the 2Checkout API?

The 2Checkout API, now Verifone, is a RESTful interface for processing payments, managing subscriptions, handling refunds, and automating e-commerce transactions. It supports JSON payloads, HMAC authentication, and real-time webhooks.

Is 2Checkout the same as Verifone?

Yes. Verifone acquired 2Checkout in 2020 and rebranded it as Verifone Digital Commerce. API endpoints and functionality remain the same, although some documentation uses Verifone branding.

How do I get a 2Checkout API key?

Log in to the 2Checkout Control Panel, go to Integrations > API Keys, and generate a key. You receive a private key for server-side calls and a public key for client-side tokenization.

Does 2Checkout have a sandbox environment?

Yes. Use https://sandbox.2checkout.com/api/ for testing. Create a separate sandbox account and use sandbox API keys to process test transactions without real charges.

What payment methods does 2Checkout support?

2Checkout supports credit cards including Visa, Mastercard, Amex, and Discover; PayPal; Apple Pay; Google Pay; bank transfers; and local payment methods across 100+ countries.

How do I handle webhooks securely?

Verify the X-Webhook-Signature header with HMAC-SHA256 and your webhook secret. Process events asynchronously and return 200 OK immediately to avoid unnecessary retries.

What happens when a subscription payment fails?

2Checkout sends a subscription.payment_failed webhook. Implement retry logic, typically three attempts over seven days, and handle subscription.cancelled if all retries fail.

Is 2Checkout PCI DSS compliant?

Yes. 2Checkout is PCI DSS Level 1 certified. Use client-side tokenization to avoid handling raw card data and reduce your PCI compliance scope.

Can I test subscriptions in sandbox?

Yes. Sandbox supports subscription lifecycle testing, including trials, renewals, upgrades, downgrades, and cancellations. Use test card 4111111111111111 for successful payments.

How do I handle refunds through the API?

Send a POST request to /refunds with the order ID and refund amount. 2Checkout supports partial and full refunds and sends a refund.processed webhook when processing completes.

Top comments (0)