Automated Batch Scheduling

Automated Batch Scheduling

Koard supports automated batch close and re-open scheduling per terminal. Instead of manually closing batches at the end of each day, you can configure a schedule and Koard handles it automatically.

Supported Processors

Processor Supported Notes
TSYS Full support. Batch numbers auto-managed (001-999).
Elavon Full support via ViaConex TC 920/921/929.
Worldpay Full support via 610 settlement interface.
Fiserv Not supported for automated scheduling.
Payroc Not supported for automated scheduling.

How It Works

  1. Configure a schedule on the terminal via PUT /v2/terminals/{terminal_id}
  2. Koard's scheduler runs every minute, checking for terminals due for batch close
  3. When due, Koard closes the current batch and opens a new one
  4. If a close fails, Koard retries up to 10 times with backoff
  5. On persistent failure, a webhook error event is sent

Setting Up a Schedule

Add a batch_schedule field to your terminal update:

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": {
    "timezone": "US/Eastern",
    "is_active": true,
    "schedule": [
      { "day": "MON", "times": ["23:00"] },
      { "day": "TUE", "times": ["23:00"] },
      { "day": "WED", "times": ["23:00"] },
      { "day": "THU", "times": ["23:00"] },
      { "day": "FRI", "times": ["23:00"] },
      { "day": "SAT", "times": ["23:00"] }
    ]
  }
}

Response

The terminal response includes confirmation that the schedule was saved:

{
  "terminal_id": "term-abc123",
  "name": "Front Counter POS",
  "mid": "886000001130",
  "tid": "00000001",
  "processor_config_id": "cfg-tsys-001",
  "status": "active",
  "var_sheet": { "applicationId": "B001" }
}

Schedule Format

Days

Use 3-letter day codes:

Code Day
MON Monday
TUE Tuesday
WED Wednesday
THU Thursday
FRI Friday
SAT Saturday
SUN Sunday

Times

Times are in 24-hour HH:MM format. You can set multiple closes per day:

{
  "day": "WED",
  "times": ["12:00", "18:00", "23:00"]
}

This closes the batch at noon, 6pm, and 11pm on Wednesdays.

No Close on a Day

Simply omit the day from the schedule. If Saturday and Sunday are not listed, no batch close happens on weekends.

Timezones

DST vs Fixed Timezones: Choose carefully between DST-aware and fixed-offset timezones. Most merchants want DST-aware timezones so the batch close follows "wall clock" time.

These follow daylight saving time transitions. 23:00 US/Eastern means 11pm EDT in summer and 11pm EST in winter.

Timezone Description
US/Eastern Eastern Time (New York)
US/Central Central Time (Chicago)
US/Mountain Mountain Time (Denver)
US/Pacific Pacific Time (Los Angeles)
US/Alaska Alaska Time
US/Hawaii Hawaii Time (no DST)
US/Arizona Arizona Time (no DST)

You can also use full IANA zone names like America/New_York, America/Chicago, etc.

Fixed-Offset Timezones

These never change for DST. Use only if you want a fixed UTC offset year-round.

Timezone UTC Offset Notes
EST UTC-5 always Does not switch to EDT in summer
MST UTC-7 always Does not switch to MDT in summer
HST UTC-10 always Same as US/Hawaii
UTC UTC+0 always Universal Coordinated Time

Example: DST Impact

A batch close at 23:00 US/Eastern:

  • Winter (EST): Fires at 04:00 UTC
  • Summer (EDT): Fires at 03:00 UTC

A batch close at 23:00 EST:

  • Always: Fires at 04:00 UTC (even in summer when "wall clock" Eastern time is EDT)

Managing Schedules

Update an Existing Schedule

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": {
    "timezone": "US/Pacific",
    "schedule": [
      { "day": "MON", "times": ["22:00"] },
      { "day": "FRI", "times": ["14:00", "22:00"] }
    ]
  }
}

Pause Scheduling (Keep Config)

Set is_active to false to temporarily disable without losing your schedule:

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": {
    "is_active": false
  }
}

Resume Scheduling

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": {
    "is_active": true,
    "schedule": [
      { "day": "MON", "times": ["23:00"] },
      { "day": "TUE", "times": ["23:00"] }
    ]
  }
}

Important: An active schedule must have at least one day with times configured. Setting is_active: true with an empty schedule will return an error.

Remove Schedule Entirely (Back to Manual)

Set batch_schedule to null:

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": null
}

After removal, the terminal returns to manual batch management.

Updates Without batch_schedule

Updating other terminal fields (name, MID, var_sheet, etc.) does not affect the schedule:

PUT /v2/terminals/{terminal_id}
{
  "name": "New Terminal Name"
}

The existing batch schedule is preserved.

Switching Between Auto and Manual

Switching from Auto to Manual

To switch a terminal back to manual batch management, remove the schedule:

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": null
}

Important: When switching to manual, the current open batch stays open. You are now responsible for:

  • Closing the current batch manually (POST /v1/batches/{batch_id}/close)
  • Opening new batches manually (POST /v1/batches/open)
  • Closing all future batches — they will no longer auto-close

Switching from Manual to Auto

Enable a schedule on an existing terminal:

PUT /v2/terminals/{terminal_id}
{
  "batch_schedule": {
    "timezone": "US/Central",
    "is_active": true,
    "schedule": [
      { "day": "MON", "times": ["22:00"] },
      { "day": "TUE", "times": ["22:00"] },
      { "day": "WED", "times": ["22:00"] },
      { "day": "THU", "times": ["22:00"] },
      { "day": "FRI", "times": ["22:00"] }
    ]
  }
}

If the terminal already has an open batch, the scheduler will close it at the next scheduled time and open a new one automatically.

Closing a Batch Early

You can always close a batch early, even when automated scheduling is enabled:

POST /v1/batches/{batch_id}/close

You must open a new batch immediately after an early close. Transactions cannot be processed without an open batch. Call POST /v1/batches/open right after the early close.

When the scheduler fires later at its scheduled time:

  • If it finds an open batch with transactions, it closes and reopens normally
  • If it finds an open batch with no transactions (e.g., you just opened it), it cancels the empty batch and opens a fresh one
  • If it finds no open batch (e.g., you closed early and didn't reopen), it opens a new one

This means early closes are safe and the scheduler self-heals on the next run.

Example: Early Close at 3pm, Scheduled Close at 11pm

  1. 3:00 PM — You close the batch early via API
  2. 3:01 PM — You open a new batch via API
  3. 3:01 PM – 11:00 PM — Transactions accumulate in the new batch
  4. 11:00 PM — Scheduler fires, closes the batch (with transactions), opens a new one

If you forget to reopen at step 2, the scheduler at 11pm will detect no open batch and open one for you — but any transactions between 3:01 PM and 11:00 PM will have failed because there was no open batch.

TSYS-Specific Behavior

Batch Number Auto-Management

TSYS batch numbers must be between 001-999 and cannot be reused within 5 consecutive days. Koard handles this automatically:

  1. On open: Queries the last closed batch for the terminal and increments
  2. On close: Verifies no conflicting batch number, auto-increments if needed
  3. On duplicate (QD): Automatically retries with the next batch number (up to 10 attempts)

Batch Number Wrapping

When the batch number reaches 999, it wraps around to 001.

Error Handling

Scenario Koard's Response
Processor unavailable Retries up to 10 times with backoff
Duplicate batch number (TSYS QD) Auto-increments and retries
All retries exhausted Sends webhook error event, logs error
No open batch to close Skips close, opens a new batch

Webhook Events

When using automated scheduling, you'll receive the standard batch webhook events:

Event When
batch.submitted Batch sent to processor
batch.accepted Processor accepted the batch
batch.rejected Processor rejected the batch
batch.opened New batch opened after close
batch.error Scheduler failed after all retries

Permissions

The following roles can view and manage batch schedules:

Role View Create/Edit Delete
Admin
PSP
Partner
Merchant

See also