DEV Community

Preecha
Preecha

Posted on

How to Use iPay API for Payment Integration in 2026?

TL;DR

The iPay API enables developers to integrate payment processing, invoicing, and financial transactions programmatically. It uses OAuth 2.0 and API key authentication, RESTful endpoints for payments, refunds, transactions, and reconciliation, with PCI DSS compliance requirements and industry-standard rate limits. This guide covers authentication setup, payment processing, webhook integration, security compliance, and production deployment strategies.

Try Apidog today

Introduction

Digital payment processing handles over $8 trillion annually worldwide. For developers building e-commerce platforms, SaaS applications, or marketplace solutions, payment API integration is essential for accepting customer payments securely and compliantly.

Businesses can lose 5โ€“10% of revenue to failed payments, manual reconciliation, and payment fraud. A solid payment API integration automates payment processing, reduces failures with retry logic, enables automatic reconciliation, and supports fraud detection.

This guide walks through payment API integration end to end: authentication, payment processing, refunds, customer management, webhooks, PCI DSS requirements, and production deployment.

๐Ÿ’ก Apidog simplifies payment API testing. Test payment endpoints in sandbox mode, validate webhook signatures, inspect transaction responses, and debug integration issues in one workspace. Import API specifications, mock responses, and share test scenarios with your team.

Note: This guide covers general payment API integration patterns applicable to iPay and similar payment processors. Specific endpoint URLs and authentication details may varyโ€”always refer to official iPay documentation for implementation details.

What Is the iPay API?

Payment APIs like iPay provide RESTful interfaces for processing financial transactions. Typical capabilities include:

  • Payment authorization and capture
  • Refunds and chargebacks
  • Transaction history and reporting
  • Customer tokenization (vault)
  • Subscription and recurring billing
  • Invoice generation and management
  • Reconciliation and settlement
  • Fraud detection and prevention

Key Features

Feature Description
RESTful API JSON-based endpoints
OAuth 2.0 + API Keys Secure authentication
Webhooks Real-time payment notifications
Tokenization Secure card storage
3D Secure SCA compliance
PCI DSS Level 1 compliance required
Multi-Currency 100+ currencies supported
Fraud Tools Risk scoring and velocity checks

Payment Flow Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Customer  โ”‚โ”€โ”€โ”€โ–ถโ”‚   Merchant  โ”‚โ”€โ”€โ”€โ–ถโ”‚  Payment    โ”‚
โ”‚   (Browser) โ”‚    โ”‚   (Server)  โ”‚    โ”‚  Gateway    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚                    โ”‚                    โ”‚
     โ”‚  1. Enter Card     โ”‚                    โ”‚
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚                    โ”‚
     โ”‚                    โ”‚                    โ”‚
     โ”‚  2. Tokenize       โ”‚                    โ”‚
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚  3. Create Intent  โ”‚
     โ”‚                    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚
     โ”‚                    โ”‚                    โ”‚
     โ”‚                    โ”‚  4. Confirm Paymentโ”‚
     โ”‚                    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚
     โ”‚                    โ”‚                    โ”‚
     โ”‚                    โ”‚  5. Result         โ”‚
     โ”‚                    โ”‚โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
     โ”‚                    โ”‚                    โ”‚
     โ”‚  6. Receipt        โ”‚                    โ”‚
     โ”‚โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                    โ”‚
Enter fullscreen mode Exit fullscreen mode

Keep sensitive card data on the client. Your server should receive a token or payment method ID, then create or confirm the payment through the provider API.

API Environments

Environment URL Use Case
Sandbox https://sandbox.ipay.com/api Development and testing
Production https://api.ipay.com/api Live transactions

Getting Started: Authentication Setup

Step 1: Create an iPay Account

Before accessing the API:

  1. Visit iPay merchant registration.
  2. Complete business verification (KYB).
  3. Submit the required documents:
    • Business registration
    • Bank account details
    • Government ID
  4. Wait for approval, which may take 1โ€“3 business days.

Step 2: Generate API Credentials

In the iPay Merchant Dashboard:

  1. Go to Settings > API Keys.
  2. Create a new API key.
  3. Copy the key and secret into your secret manager or local environment file.
# .env file โ€” NEVER commit this file to git
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"
Enter fullscreen mode Exit fullscreen mode

Use separate credentials for sandbox and production.

Step 3: Choose an Authentication Method

Method Best For Security Level
Basic Auth Server-to-server integrations High
OAuth 2.0 Multi-tenant applications Higher
JWT Microservices High

Step 4: Create a Reusable API Client

Centralize authentication, JSON headers, idempotency keys, and error handling in one function.

const IPAY_BASE_URL = process.env.IPAY_SANDBOX
  ? 'https://sandbox.ipay.com/api'
  : 'https://api.ipay.com/api';

const ipayRequest = async (endpoint, options = {}) => {
  const apiKey = process.env.IPAY_API_KEY;
  const apiSecret = process.env.IPAY_API_SECRET;

  // Basic authentication (Base64 encoded)
  const authHeader = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');

  const response = await fetch(`${IPAY_BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      Authorization: `Basic ${authHeader}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': options.idempotencyKey || generateIdempotencyKey(),
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`iPay API Error: ${error.message}`);
  }

  return response.json();
};

function generateIdempotencyKey() {
  return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}

// Usage
const account = await ipayRequest('/account');
console.log(`Merchant: ${account.business_name}`);
Enter fullscreen mode Exit fullscreen mode

Payment Processing

Create a Payment Intent

Create payments from your server, using amounts in the smallest currency unit. For USD, $29.99 becomes 2999.

const createPayment = async (paymentData) => {
  const payment = {
    amount: paymentData.amount,
    currency: paymentData.currency || 'USD',
    customer: paymentData.customerId,
    payment_method: paymentData.paymentMethodId,
    confirm: true,
    description: paymentData.description,
    metadata: {
      orderId: paymentData.orderId,
      customerId: paymentData.customerId
    },
    capture_method: paymentData.captureMethod || 'automatic',
    statement_descriptor: paymentData.statementDescriptor || 'MYCOMPANY'
  };

  return ipayRequest('/payments', {
    method: 'POST',
    body: JSON.stringify(payment),
    idempotencyKey: paymentData.idempotencyKey
  });
};

// Usage
const payment = await createPayment({
  amount: 2999, // $29.99
  currency: 'USD',
  customerId: 'cus_12345',
  paymentMethodId: 'pm_67890',
  description: 'Order #ORD-001',
  orderId: 'ORD-001',
  statementDescriptor: 'MYCOMPANY INC'
});

console.log(`Payment status: ${payment.status}`);
console.log(`Payment ID: ${payment.id}`);
Enter fullscreen mode Exit fullscreen mode

Generate and persist one idempotency key per checkout attempt. Reuse it if your application retries the same payment request.

Payment Status Flow

requires_payment_method โ†’ requires_confirmation โ†’ requires_action
                         โ†’ processing โ†’ requires_capture โ†’ succeeded
                                                        โ†’ failed
                                                        โ†’ canceled
Enter fullscreen mode Exit fullscreen mode

Your application should treat payment status as asynchronous. Do not mark an order as paid only because the initial API request returned successfullyโ€”use the resulting payment status and verified webhook events.

Payment Methods

Method Type Use Case
card Credit/Debit Standard payments
bank_transfer ACH, SEPA Low-fee transfers
digital_wallet Apple Pay, Google Pay Mobile checkout
buy_now_pay_later Klarna, Afterpay Installment payments

Tokenize Card Details

Do not send raw card details to your server. Tokenize payment details in the browser or mobile app, then send only the resulting token ID to your backend.

const tokenizeCard = async (cardData) => {
  // NEVER send raw card data to your server.
  // Use client-side tokenization instead.

  const response = await fetch(`${IPAY_BASE_URL}/tokens`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${CLIENT_PUBLISHABLE_KEY}`
    },
    body: JSON.stringify({
      card: {
        number: cardData.number,
        exp_month: cardData.expMonth,
        exp_year: cardData.expYear,
        cvc: cardData.cvc
      }
    })
  });

  const token = await response.json();
  return token; // Send token.id to your server
};
Enter fullscreen mode Exit fullscreen mode

On the server, exchange the token for a payment method:

const createPaymentMethod = async (tokenId, customerId) => {
  return ipayRequest('/payment_methods', {
    method: 'POST',
    body: JSON.stringify({
      type: 'card',
      token: tokenId,
      customer: customerId
    })
  });
};
Enter fullscreen mode Exit fullscreen mode

Handle 3D Secure Authentication

For Strong Customer Authentication (SCA), your server may need to return a client secret and let the client complete the challenge.

const createPaymentWith3DS = async (paymentData) => {
  const payment = await createPayment({
    ...paymentData,
    confirmation_token: true // Return client secret for 3DS
  });

  if (payment.status === 'requires_action') {
    return {
      requiresAction: true,
      clientSecret: payment.client_secret,
      nextAction: payment.next_action
    };
  }

  return { success: true, payment };
};
Enter fullscreen mode Exit fullscreen mode

On the client, use iPay.js or the mobile SDK to present the authentication challenge when requiresAction is true.

Refund Management

Process a Full Refund

Use the original payment ID when creating a refund.

const refundPayment = async (paymentId, reason = null) => {
  const refund = {
    payment: paymentId,
    reason: reason || 'requested_by_customer'
  };

  return ipayRequest('/refunds', {
    method: 'POST',
    body: JSON.stringify(refund),
    idempotencyKey: `refund_${paymentId}_${Date.now()}`
  });
};

// Usage
const refund = await refundPayment('pay_12345', 'duplicate');
console.log(`Refund status: ${refund.status}`);
console.log(`Refund ID: ${refund.id}`);
Enter fullscreen mode Exit fullscreen mode

Process a Partial Refund

Include an amount when refunding only part of a payment.

const partialRefund = async (paymentId, amount, reason = null) => {
  const refund = {
    payment: paymentId,
    amount, // Smallest currency unit
    reason: reason || 'requested_by_customer'
  };

  return ipayRequest('/refunds', {
    method: 'POST',
    body: JSON.stringify(refund),
    idempotencyKey: `refund_${paymentId}_${amount}_${Date.now()}`
  });
};

// Usage โ€” refund $15.00 of a $29.99 payment
const refund = await partialRefund('pay_12345', 1500, 'partial_ship');
console.log(`Refunded: $${refund.amount / 100}`);
Enter fullscreen mode Exit fullscreen mode

Refund Reasons

Reason Code Description
duplicate Duplicate charge
fraudulent Fraudulent transaction
requested_by_customer Customer request
order_canceled Order cancellation
product_not_received Item not delivered
product_not_as_described Item differs from description

Customer Management

Create a Customer

Store customer records so you can support recurring payments and saved payment methods.

const createCustomer = async (customerData) => {
  const customer = {
    email: customerData.email,
    name: customerData.name,
    phone: customerData.phone,
    metadata: {
      internalId: customerData.internalId,
      tier: customerData.tier
    }
  };

  return ipayRequest('/customers', {
    method: 'POST',
    body: JSON.stringify(customer)
  });
};

// Usage
const customer = await createCustomer({
  email: 'customer@example.com',
  name: 'John Doe',
  phone: '+1-555-0123',
  internalId: 'USR-12345',
  tier: 'premium'
});

console.log(`Customer created: ${customer.id}`);
Enter fullscreen mode Exit fullscreen mode

Attach a Payment Method

const attachPaymentMethod = async (paymentMethodId, customerId) => {
  return ipayRequest(`/payment_methods/${paymentMethodId}/attach`, {
    method: 'POST',
    body: JSON.stringify({
      customer: customerId
    })
  });
};

// Usage
await attachPaymentMethod('pm_67890', 'cus_12345');
Enter fullscreen mode Exit fullscreen mode

List Saved Payment Methods

const getCustomerPaymentMethods = async (customerId) => {
  return ipayRequest(`/customers/${customerId}/payment_methods`);
};

// Usage
const methods = await getCustomerPaymentMethods('cus_12345');

methods.data.forEach((method) => {
  console.log(`${method.card.brand} ending in ${method.card.last4}`);
  console.log(`Expires: ${method.card.exp_month}/${method.card.exp_year}`);
});
Enter fullscreen mode Exit fullscreen mode

Webhooks

Configure Webhooks

In the iPay Dashboard:

  1. Go to Developers > Webhooks.
  2. Click Add Endpoint.
  3. Enter your HTTPS endpoint URL.
  4. Select the events your integration needs.
  5. Store the webhook signing secret in your environment configuration.

Webhook Events

Event Trigger
payment.succeeded Payment completed
payment.failed Payment declined
payment.refunded Refund processed
payment.disputed Chargeback filed
customer.created New customer
customer.subscription.updated Subscription changed

Verify and Handle Webhooks

Use the raw request body for signature verification. Parsing JSON before verification can change the payload and invalidate the signature.

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

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

    const isValid = verifyWebhookSignature(
      payload,
      signature,
      process.env.IPAY_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 'payment.succeeded':
        await handlePaymentSucceeded(event.data);
        break;
      case 'payment.failed':
        await handlePaymentFailed(event.data);
        break;
      case 'payment.refunded':
        await handlePaymentRefunded(event.data);
        break;
      case 'payment.disputed':
        await handlePaymentDisputed(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

Update your internal order state from webhook events:

async function handlePaymentSucceeded(data) {
  console.log(`Payment succeeded: ${data.id}`);

  await db.orders.update(data.metadata.orderId, {
    status: 'paid',
    paymentId: data.id,
    paidAt: new Date()
  });

  await sendOrderConfirmation(data.metadata.orderId);
}

async function handlePaymentFailed(data) {
  console.log(`Payment failed: ${data.id} - ${data.failure_code}`);

  await sendPaymentFailedEmail(data.customer, data.failure_message);

  await db.orders.update(data.metadata.orderId, {
    status: 'payment_failed',
    failureReason: data.failure_message
  });
}
Enter fullscreen mode Exit fullscreen mode

Make webhook handlers idempotent as well. Payment providers can retry an event when your endpoint times out or returns a non-success response.

Security and Compliance

PCI DSS Requirements

Requirement Implementation
Secure Network Use HTTPS, firewalls, and secure configurations
Cardholder Data Protection Never store CVV; encrypt PAN
Vulnerability Management Apply regular security updates and anti-virus
Access Control Use least privilege, MFA, and unique IDs
Monitoring Enable logging and intrusion detection
Security Policy Maintain documented policies and regular training

Security Practices to Implement

// 1. Use tokenization โ€” NEVER handle raw card data
const token = await tokenizeCard(cardData); // Client-side

// 2. Add idempotency to every payment operation
const idempotencyKey = `pay_${orderId}_${Date.now()}`;

// 3. Validate amounts on the server
if (req.body.amount !== calculatedAmount) {
  throw new Error('Amount mismatch - possible tampering');
}

// 4. Log payment operations without sensitive data
logger.info('Payment attempted', {
  orderId,
  amount,
  currency,
  customerId,
  timestamp: new Date().toISOString()
  // NEVER log card numbers, CVV, or full payment method details
});

// 5. Load secrets from environment variables
const apiKey = process.env.IPAY_API_KEY;

// 6. Rate-limit payment endpoints
const paymentLimiter = rateLimit({
  windowMs: 60000,
  max: 10 // 10 payment attempts per minute
});
Enter fullscreen mode Exit fullscreen mode

Production Deployment Checklist

Before processing live payments:

  • [ ] Complete the PCI DSS Self-Assessment Questionnaire.
  • [ ] Use HTTPS for all endpoints.
  • [ ] Store API keys in secure secret management.
  • [ ] Implement webhook signature verification.
  • [ ] Add idempotency for all payment operations.
  • [ ] Set up comprehensive logging without sensitive data.
  • [ ] Configure fraud detection rules.
  • [ ] Test refund and dispute flows.
  • [ ] Create a runbook for payment failures.
  • [ ] Set up monitoring and alerting.
  • [ ] Implement a backup payment processor.

Real-World Use Cases

E-commerce Checkout

An online retailer integrates payments:

  • Challenge: Manual payment processing and high abandonment.
  • Solution: One-page checkout with tokenized cards.
  • Result: 35% conversion increase and instant payments.

SaaS Subscription Billing

A software company automates billing:

  • Challenge: Manual invoice generation and collection.
  • Solution: Recurring payments with automatic retry.
  • Result: 95% on-time payment and 80% admin time savings.

Marketplace Escrow

A platform handles multi-party payments:

  • Challenge: Complex split payments between vendors.
  • Solution: Payment intents with transfer scheduling.
  • Result: Automated vendor payouts and reduced fraud.

Conclusion

Payment API integration requires careful attention to security, compliance, and error handling. The implementation priorities are:

  • Never handle raw card dataโ€”use tokenization.
  • Add idempotency to every payment operation.
  • Verify webhook signatures before processing events.
  • Comply with PCI DSS requirements.
  • Test payment, refund, dispute, and failure paths in sandbox before production.
  • Use Apidog to streamline API testing and team collaboration.

FAQ Section

How do I authenticate with iPay API?

Use Basic authentication with an API key and secret, or OAuth 2.0 for multi-tenant applications.

Can I store customer card details?

Yes, but you must be PCI DSS compliant. Use tokenization to store cards securely in iPayโ€™s vault.

How do I handle failed payments?

Implement retry logic with exponential backoff, notify customers, and provide alternative payment methods.

What is idempotency and why is it important?

Idempotency ensures duplicate requests with the same key produce the same result, preventing duplicate charges.

How do I test payments without charging cards?

Use sandbox mode with test card numbers provided in iPay documentation.

What are webhook signatures?

They are cryptographic signatures that verify webhooks came from iPay rather than a malicious actor.

Top comments (0)