API v1https://paymecheck.com/api/v1

API Reference

Integrate PayMeCheck payment links, webhooks, and on-chain settlements into your product.

Non-custodial on-chain settlement
HMAC-signed webhooks with retries
Multi-chain USDC & USDT support
Dedicated contract per merchant

Introduction

The PayMeCheck REST API lets you programmatically create payment links, query payment status, and receive real-time notifications via webhooks. All payments settle on-chain through dedicated smart contracts — Glabs Capital LLC provides the technology; funds are never held by PayMeCheck.

Each merchant account has a unique API key and dedicated proxy contracts on Ethereum, Polygon, Base, and Arbitrum. When a customer pays, the smart contract atomically splits USDC/USDT between the merchant wallet and the platform treasury.

Authentication

All API requests require a merchant API key sent as a Bearer token. Keys are issued when your merchant account is activated and can be found in the merchant dashboard (contact admin if you need a key rotated).

Header
Authorization: Bearer pmck_your_api_key

Only merchants with status active can use the API. Requests with invalid or missing keys return 401 Unauthorized.

Rate limits

API endpoints are rate-limited per IP address to protect the platform.

  • 60 requests per minute per IP for write operations (POST).
  • When exceeded, the API returns 429 Too Many Requests. Implement exponential backoff in your integration.

Errors

Errors use conventional HTTP status codes and a JSON body with an error field.

Error response
{ "error": "Invalid input" }

Common error codes

HTTPMeaning
400Invalid input or business rule violation
401Missing or invalid API key
404Resource not found
429Rate limit exceeded

Payments

Payments are indexed from on-chain PaymentProcessed events. They appear after block confirmation via the platform indexer.

GET/api/v1/payments

List payments

Returns all indexed payments for the authenticated merchant, sorted by creation date (newest first).

Response

FieldTypeRequiredDescription
data[].paymentIdstringNoUnique bytes32 payment ID used in the smart contract pay() call.
data[].chainstringNoBlockchain network where payment was confirmed.
data[].txHashstringNoOn-chain transaction hash.
data[].payerAddressstringNoWallet address that initiated the payment.
data[].amountstringNoPayment amount as a decimal string (e.g. "150.00"). Converted to token units (6 decimals) at checkout.
data[].feestringNoPlatform fee amount (token units, string).
data[].merchantAmountstringNoAmount sent to merchant wallet (token units, string).
data[].statusstringNoin-progress | completed | failed

Webhooks

Configure your webhook URL and secret in the merchant dashboard. PayMeCheck sends HTTP POST requests with JSON payloads when events occur.

  • Enable webhooks in Dashboard → Webhook. Set your endpoint URL (HTTPS recommended) and a signing secret.
  • Every delivery includes Content-Type: application/json and X-PayMeCheck-Signature for verification.
  • Failed deliveries are retried up to 3 times with delays of 1 min, 5 min, and 30 min. Monitor delivery status in the Webhook Monitor.

Event types

payment.completed

Fired when an on-chain payment is indexed and confirmed.

payment.expired

Fired when an active link passes its expiresAt without payment.

payment.completed
{
  "event": "payment.completed",
  "timestamp": "2026-06-10T14:32:01.000Z",
  "data": {
    "paymentId": "0x8f3a2b1c...",
    "linkId": "a1b2c3d4e5f678901234abcd",
    "amount": "150000000",
    "token": "USDC",
    "chain": "polygon",
    "txHash": "0xabc123...",
    "payer": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
    "merchantAmount": "148500000",
    "fee": "1500000",
    "contractAddress": "0xMerchantContract..."
  }
}
payment.expired
{
  "event": "payment.expired",
  "timestamp": "2026-06-10T18:00:00.000Z",
  "data": {
    "linkId": "a1b2c3d4e5f678901234abcd",
    "paymentId": "0x8f3a2b1c...",
    "amount": "150.00",
    "token": "USDC"
  }
}

Verify signatures

Compute HMAC-SHA256 of the raw request body using your webhook secret. Compare with the X-PayMeCheck-Signature header (format: sha256={hex}).

Node.js
const crypto = require("crypto")

function verifyWebhook(secret, rawBody, signatureHeader) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  )
}
Python
import hmac
import hashlib

def verify_webhook(secret: str, body: bytes, signature: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Checkout flow

  1. 1

    Create a payment link via API or dashboard.

  2. 2

    Redirect the customer to https://paymecheck.com/pay/{linkId}.

  3. 3

    Customer connects wallet, approves token spend, and calls pay() on the merchant contract.

  4. 4

    Indexer detects PaymentProcessed event and marks the link as paid.

  5. 5

    Webhook payment.completed is dispatched to your endpoint.

Gas fees are paid by the customer. PayMeCheck never custodies funds.

Smart contracts

Each merchant has an EIP-1167 proxy contract per chain. Key on-chain variables are publicly readable:

  • feeBps — platform fee in basis points (100–500, i.e. 1%–5%), locked at deploy
  • merchantWallet — address receiving the merchant share
  • platformTreasury — address receiving the platform fee
  • pay(bytes32 paymentId, address token, uint256 amount) — called by the payer to execute the split
PaymentProcessed event
event PaymentProcessed(
  bytes32 indexed paymentId,
  address indexed payer,
  address token,
  uint256 amount,
  uint256 fee
)

Statuses

Payment link statuses

activeAwaiting payment
paidPayment confirmed on-chain
expiredexpiresAt passed without payment
cancelledManually cancelled via API

Payment statuses

in-progressTransaction detected, awaiting finality
completedIndexed and confirmed
failedIndexing or validation failed

Networks & tokens

Supported chains and stablecoins. Token availability varies by chain.

ChainTokens
ethereumUSDC, USDT
polygonUSDC, USDT
baseUSDC
arbitrumUSDC, USDT