Skip to main content

Batch Payments

Process multiple payments at once - perfect for subscriptions, memberships, and recurring billing. Creates multiple payment orders in a single request.
POST /payment-orders/batch
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Why Use Batch Payments?

Faster Processing

Process hundreds of payments in a single API call

Subscription Renewals

Charge all subscribers at once each billing cycle

Bulk Invoicing

Process multiple invoices simultaneously

Automatic Retries

Built-in retry logic for failed payments

Ideal Use Cases

Monthly Subscription Renewals

Charge all your subscribers at once:
const subscribers = [
  { customerId: "cus_123", amount: 9900, plan: "basic" },
  { customerId: "cus_456", amount: 19900, plan: "pro" },
  { customerId: "cus_789", amount: 49900, plan: "enterprise" }
];

Membership Fee Collection

Process monthly gym, club, or association fees:
const members = [
  { memberId: "mem_001", amount: 50000, membershipType: "gold" },
  { memberId: "mem_002", amount: 30000, membershipType: "silver" }
];

Scheduled Billing Runs

Automate recurring billing for services:
  • SaaS subscriptions
  • Hosting renewals
  • License renewals
  • Maintenance contracts

Request Format

{
  "batchId": "batch_monthly_2025_10",
  "payments": [
    {
      "externalId": "sub_123_2025_10",
      "customerId": "cus_xyz789",
      "paymentMethodId": "pm_abc123",
      "amount": 9900,
      "currency": "MXN",
      "description": "Basic plan - October 2025",
      "metadata": {
        "subscriptionId": "sub_123",
        "planType": "basic"
      }
    },
    {
      "externalId": "sub_456_2025_10",
      "customerId": "cus_def456",
      "paymentMethodId": "pm_ghi789",
      "amount": 19900,
      "currency": "MXN",
      "description": "Pro plan - October 2025",
      "metadata": {
        "subscriptionId": "sub_456",
        "planType": "pro"
      }
    }
  ]
}

Required Fields

FieldTypeDescription
batchIdstringUnique identifier for this batch
paymentsarrayArray of payment objects (max 100)
payments[].externalIdstringUnique payment identifier
payments[].customerIdstringCheqpay customer ID
payments[].paymentMethodIdstringSaved payment method ID
payments[].amountintegerAmount in cents
payments[].currencystringISO currency code
You can process up to 100 payments in a single batch request.

Response Format

{
  "batchId": "batch_monthly_2025_10",
  "status": "processing",
  "totalPayments": 2,
  "processed": 0,
  "successful": 0,
  "failed": 0,
  "createdAt": "2025-10-30T10:00:00.000Z",
  "estimatedCompletionTime": "2025-10-30T10:05:00.000Z"
}

Monitor Batch Progress

Get Batch Status

GET /payment-orders/batches/:batchId
Authorization: Bearer YOUR_API_KEY
{
  "batchId": "batch_monthly_2025_10",
  "status": "completed",
  "totalPayments": 2,
  "processed": 2,
  "successful": 1,
  "failed": 1,
  "results": [
    {
      "externalId": "sub_123_2025_10",
      "status": "COMPLETED",
      "paymentOrderId": "ord_abc123"
    },
    {
      "externalId": "sub_456_2025_10",
      "status": "FAILED",
      "error": {
        "code": "DECLINED",
        "message": "Insufficient funds"
      }
    }
  ]
}

Batch Statuses

StatusDescription
processingBatch is being processed
completedAll payments have been attempted
partialSome payments succeeded, some failed

Handle Failed Payments

Failed payments in a batch don’t stop other payments from processing:
1

Identify Failures

Check the batch results to see which payments failed.
2

Notify Customers

Send email or SMS to customers with failed payments.
3

Update Payment Methods

Allow customers to update their payment information.
4

Retry

Create a new batch with just the failed payments.

Example: Retry Failed Payments

async function retryFailedPayments(batchId) {
  const batch = await getBatchStatus(batchId);
  
  const failedPayments = batch.results
    .filter(p => p.status === 'FAILED')
    .map(p => ({
      externalId: `${p.externalId}_retry`,
      customerId: p.customerId,
      paymentMethodId: p.paymentMethodId,
      amount: p.amount,
      currency: p.currency
    }));
  
  if (failedPayments.length > 0) {
    await createBatchPayment({
      batchId: `${batchId}_retry`,
      payments: failedPayments
    });
  }
}

Webhook Notifications

Receive notifications for batch completion and individual payment results:

Batch Completed

{
  "eventType": "batch.completed",
  "data": {
    "batchId": "batch_monthly_2025_10",
    "totalPayments": 100,
    "successful": 95,
    "failed": 5
  }
}

Individual Payment Updates

You’ll also receive standard payment webhooks for each payment in the batch:
{
  "eventType": "payment.completed",
  "data": {
    "paymentOrderId": "ord_abc123",
    "externalId": "sub_123_2025_10",
    "batchId": "batch_monthly_2025_10"
  }
}

Configure Webhooks

Learn how to set up webhook notifications

Best Practices

Include date and identifier in batch IDs: batch_subscriptions_2025_10_30
Schedule batch jobs during low-traffic hours to minimize impact on customers.
Include subscription IDs, plan types, or other relevant data in metadata for easier reconciliation.
Track failure patterns. High failure rates may indicate expired cards or other issues.
Create a retry strategy for failed payments (e.g., retry after 3 days, then 7 days).

Limits and Performance

Batch Limits

  • Maximum payments per batch: 100
  • Maximum batches per hour: Contact support for high-volume needs
  • Processing time: ~2-5 seconds per payment

Expected Performance

For a batch of 100 payments:
  • Processing time: 3-8 minutes
  • Success rate: 85-95% (varies by customer base)
Need higher limits? Contact [email protected] to discuss your requirements.

Testing Batch Payments

Test in sandbox with multiple test payments:
{
  "batchId": "test_batch_001",
  "payments": [
    {
      "externalId": "test_pay_001",
      "amount": 10000,
      "paymentMethod": {
        "type": "card",
        "options": {
          "card": {
            "number": "4000000000002503",
            "expiryMonth": "12",
            "expiryYear": "2025",
            "cvc": "123"
          }
        }
      }
    }
  ]
}
Use test cards to simulate different scenarios:
  • 4000000000002503 - Success
  • 4000000000000002 - Decline

Next Steps