Gateway API · v1 · REST + JSON

Build on the Koi Pay Gateway

One REST API for transactions, tokenization, the customer vault, recurring billing, invoicing, fraud and settlement. Authenticate with a single key, send JSON, get JSON back. Start in the sandbox and go live without changing a line of integration code.

Getting started

Quick Start

Make your first live-shaped request in under five minutes. Every Koi Pay API call is an HTTPS POST or GET to the gateway, authenticated with your secret key, carrying a JSON body and returning a JSON envelope.

1. Get your keys

From the portal, open Settings → API keys. You'll find a sandbox secret key for testing and a live secret key for production. Treat both like passwords — they authorize money movement.

2. Send a sale

Charge a card by posting a sale to the Transactions endpoint. Amounts are always in cents, so $10.00 is 1000.

POST/api/transactionCopy
# charge $10.00 to a test card
curl https://sandbox.example.com/api/transaction \
  -H "Authorization: YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "sale",
    "amount": 1000,
    "payment_method": {
      "card": {
        "number": "4111111111111111",
        "expiration": "12/29",
        "cvc": "123"
      }
    }
  }'

3. Read the response

Every response is the same envelope: a status, a human-readable msg, and a data object with the details.

200responseCopy
{
  "status": "success",
  "msg": "Approved",
  "data": {
    "id": "txn_8Fp2k9",
    "response_code": 100,
    "amount": 1000,
    "auth_code": "A1B2C3",
    "card": { "last4": "1111", "brand": "visa" }
  }
}
Response code 100 means approved. See the Quick reference for the full list of codes.

4. Go live

When you're ready, swap the sandbox host for your production host and the sandbox key for your live key. Nothing else changes — the contract is identical between environments.

Getting started

Integration paths

There's more than one way to embed Koi Pay. Pick the path that matches how much of the payment surface you want to own.

PathBest forPCI scope
Tokenizer / WalletJS (client-side)Web checkouts that want full design control with no card data touching your serverLowest (SAQ A)
Simple Payments (hosted)Fastest launch — a hosted, brandable payment page or buttonLowest (SAQ A)
Direct API (server-side)Platforms processing card-present, MOTO or stored credentials end-to-endHigher (SAQ D)
Plugins (WooCommerce, Magento, Gravity Forms)Existing storefronts that want a drop-in extensionLowest (SAQ A)
Gateway EmulatorMigrating merchants off a legacy gateway with no rewriteMatches existing
Most embedded platforms combine Tokenizer on the client (to keep card data out of scope) with the Transactions API on the server (to charge the resulting token).
Getting started

Authentication

Authenticate every request with your secret key in the Authorization header. There is no Bearer prefix — send the key directly.

HEADERAuthorizationCopy
Authorization: YOUR_SECRET_KEY
Content-Type: application/json
Never expose a secret key in client-side code, a mobile app bundle, or a public repository. For browser payments use the Tokenizer public key instead.
Getting started

Request conventions

  • All requests and responses use Content-Type: application/json.
  • Amounts are integers in cents. $25.50 is sent as 2550.
  • Every response shares the same envelope: { "status", "msg", "data" }.
  • status is "success" or "error"; the numeric processor result lives in data.response_code.
  • Timestamps are ISO 8601 in UTC. IDs are opaque strings — don't parse them.
Core API

Transactions

The Transactions API moves money: authorize, capture, sale, refund and void. Send a type and the gateway routes it to the processor.

TypeWhat it does
authorizeReserve funds without capturing — finalize later with a capture.
captureSettle a previous authorization, in full or partial.
saleAuthorize and capture in one step.
refundReturn funds for a settled transaction.
voidCancel an authorization or unsettled sale.
POST/api/transactionCopy
{
  "type": "sale",
  "amount": 4999,
  "payment_method": { "customer_vault_id": "cv_72ab" }
}
POST/api/transactionCopy
// 1) reserve the funds
{ "type": "authorize", "amount": 4999,
  "payment_method": { "card": { "number": "4111111111111111", "expiration": "12/29" } } }

// 2) capture later, by transaction id
{ "type": "capture", "transaction_id": "txn_8Fp2k9", "amount": 4999 }
POST/api/transactionCopy
{
  "type": "refund",
  "transaction_id": "txn_8Fp2k9",
  "amount": 4999
}

Level 3 data

For B2B and B2G cards, attach line-item detail to qualify for the lowest interchange. Koi Pay assembles the Level 3 fields for you — pass the items and we format the rest.

Core API

Customer Vault

Store cards and bank accounts as tokens so you never re-handle raw credentials. Vault records are referenced by customer_vault_id anywhere a payment method is accepted.

OperationEndpoint
Create recordPOST /api/vault with "action":"add"
Update recordPOST /api/vault with "action":"update"
Delete recordPOST /api/vault with "action":"delete"
POST/api/vaultCopy
{
  "action": "add",
  "customer": { "first_name": "Ada", "email": "ada@acme.co" },
  "payment_method": { "card": { "number": "4111111111111111", "expiration": "12/29" } }
}
Account Updater keeps stored cards fresh automatically, refreshing numbers and expiry dates before recurring charges fail.
Core API

Recurring Billing

Define a plan, attach a customer (typically a vault record), and the gateway charges on schedule — with retries, proration and dunning handled for you.

POST/api/recurringCopy
{
  "plan": {
    "amount": 2900,
    "interval": "month",
    "day_of_month": 1
  },
  "customer_vault_id": "cv_72ab",
  "start_date": "2026-07-01"
}
FieldNotes
intervalday, week, month or year.
amountPer-cycle charge in cents.
start_dateFirst billing date; omit to start immediately.
trial_daysOptional free trial before the first charge.
Other API

Invoices

Create, send and track invoices. Each invoice generates a hosted, brandable pay link your customer can settle by card or ACH.

POST/api/invoiceCopy
{
  "customer": { "email": "ada@acme.co" },
  "items": [ { "description": "Design retainer", "amount": 150000 } ],
  "due_date": "2026-07-15",
  "send": true
}
Other API

Batch

Submit many transactions in a single request for high-volume billing runs. The gateway processes the batch and returns a per-row result set you can reconcile against.

POST/api/batchCopy
{
  "transactions": [
    { "type": "sale", "amount": 1000, "customer_vault_id": "cv_72ab" },
    { "type": "sale", "amount": 2500, "customer_vault_id": "cv_91cd" }
  ]
}
Other API

BIN Lookup

Identify a card's brand, type, issuing bank and country from its first digits — before you authorize. Use it to route smarter, screen risk, or surface fees.

GET/api/bin/411111Copy
{
  "status": "success",
  "data": {
    "brand": "visa",
    "type": "credit",
    "issuer": "Example Bank",
    "country": "US"
  }
}
Other API

Settlement Batches

Inspect every settlement batch and its line items. Reconcile deposits, fees and refunds against your ledger, and offer same-day (T+0) payout visibility.

GET/api/settlement/{batch_id}Copy
{
  "data": {
    "batch_id": "set_20260622",
    "funded_amount": 482310,
    "fees": 11240,
    "transactions": 214
  }
}
Other API

Terminals

Provision, pair and send transactions to card-present (EMV) terminals. Push an amount to a registered terminal and collect a chip, tap or swipe.

POST/api/terminal/saleCopy
{
  "terminal_id": "trm_4410",
  "amount": 3200
}
Other API

Custom Fields

Attach your own metadata to transactions, customers and invoices — order IDs, location codes, sales-rep tags — and filter or report on them later in the portal and API.

POST/api/transactionCopy
{
  "type": "sale", "amount": 1000,
  "custom_fields": { "order_id": "A-8841", "location": "store-12" }
}
Other API

Cart

Build server-side carts with itemized lines, tax and shipping, then hand off to checkout. Cart data flows into Level 3 detail and receipts automatically.

POST/api/cartCopy
{
  "items": [ { "sku": "TEE-01", "qty": 2, "unit_price": 1800 } ],
  "tax": 300, "shipping": 500
}
Service

Tokenizer

A drop-in JavaScript library that turns card fields into single-use tokens in the browser, so raw card data never touches your server and your PCI scope stays at SAQ A. Style the iframe fields to match your checkout.

HTMLcheckout.htmlCopy
<!-- 1) drop in the library with your PUBLIC key -->
<script src="https://sandbox.example.com/tokenizer/tokenizer.js"
        data-public-key="YOUR_PUBLIC_KEY"></script>

<!-- 2) mount the secure card field -->
<div id="koi-card"></div>
JSon submitCopy
// returns a one-time token you POST to your server
KoiTokenizer.tokenize().then(function(t) {
  fetch("/charge", { method: "POST", body: JSON.stringify({ token: t.token }) });
});

On your server, charge the token exactly like a card via the Transactions API by passing "payment_method": { "token": "..." }.

Service

Simple Payments

The fastest way to get paid: a hosted, fully brandable payment page or button with no front-end build. Create a payment link, share it, get notified by webhook when it's paid.

POST/api/payment-linkCopy
{
  "amount": 5000,
  "description": "Deposit — Order A-8841",
  "redirect_url": "https://yourshop.com/thanks"
}
Service

Webhooks

Subscribe to events and the gateway POSTs a signed JSON payload to your endpoint. Delivery is idempotent — verify the signature, ack with 200, and dedupe on the event id.

EventFires when
transaction.approvedA sale or capture succeeds.
transaction.declinedA charge is declined by the issuer.
settlement.fundedA settlement batch is funded.
vault.updatedA stored card is refreshed by Account Updater.
recurring.chargedA recurring cycle is billed.
POSTyour endpointCopy
{
  "id": "evt_5kP1",
  "event": "transaction.approved",
  "data": { "id": "txn_8Fp2k9", "amount": 1000 }
}
Service

Fraud Protection — Koi Guard™

Rules, velocity filters and ML scoring tuned per merchant, not generic internet traffic. Configure sensitivity per MID, opt into network-wide Community Rules, and review held transactions in the portal.

  • Rules & velocity — block or hold by amount, BIN, geo, AVS/CVV result, or attempt frequency.
  • ML scoring — every transaction gets a risk score; you choose the threshold to hold or decline.
  • Community Rules — a coordinated attack on one merchant becomes a shield for the whole portfolio.
Pair BIN Lookup with Koi Guard to screen card type and country before authorization.
Service

WalletJS

Add Apple Pay and Google Pay to any checkout with a single script. WalletJS handles the wallet sheet, decrypts the network token, and returns a Koi Pay token you charge like any other.

HTMLcheckout.htmlCopy
<script src="https://sandbox.example.com/wallet/wallet.js"></script>
<div id="koi-wallet" data-amount="1000"></div>
Service

Fee programs

Pass on the cost of acceptance compliantly. Configure per merchant; the gateway applies the program at authorization and discloses it on receipts.

ProgramHow it works
Cash DiscountPatented DTI model that holds up across card-present, online and virtual terminal.
Dual PricingShow a cash price and a card price at the POS, difference handled and disclosed automatically.
SurchargingCompliant credit-card surcharging with caps, disclosures and exemptions enforced by the gateway.
Reference

Integration workflows

A typical embedded checkout stitches a few APIs together. Here's the canonical flow for a tokenized web payment with a stored customer.

1

Tokenize

Tokenizer turns card fields into a one-time token in the browser.

2

Vault

Optionally store the token in the Customer Vault for reuse.

3

Charge

POST a sale to the Transactions API with the token or vault id.

4

Confirm

Receive a webhook, reconcile the settlement batch, and fulfill.

Reference

E-Commerce plugins

Drop Koi Pay into an existing storefront with a maintained extension — no API code required. See Integrations for install guides.

WooCommerce

WordPress checkout, subscriptions and refunds, powered by the Tokenizer for SAQ A scope.

Magento / Adobe Commerce

Native payment method with vault, capture and partial refund support.

Gravity Forms

Take one-time and recurring payments directly from any Gravity Form.

Reference

Testing

Point your integration at the sandbox host and use the test keys from your portal. No real money moves; responses mirror production exactly.

HOSTsandbox base URLCopy
https://sandbox.example.com

Test cards

Card numberResultCode
4111 1111 1111 1111Approved100
4000 0000 0000 0002Declined200
4000 0000 0000 9995Insufficient Funds200
4000 0000 0000 0051Partial Approval100

Use any future expiration date and any 3-digit CVC. You can also run the same scenarios live in the portal's virtual terminal.

Reference

Quick reference

Required headers

HeaderValue
AuthorizationYOUR_SECRET_KEY (no Bearer prefix)
Content-Typeapplication/json

Conventions

  • Amounts are integers in cents.
  • Every response is { "status", "msg", "data" }.

Response codes

CodeMeaning
100Approved
200Declined
201Declined — call issuer
300Gateway error
Ready to build? Start with the Quick Start or open the portal to grab your keys.

From sandbox to live with one key swap.

Grab your keys, fire a test transaction, and ship. The contract is identical in every environment.

Get your API keys Browse integrations