Developer Docs

Integrate PayCow's crypto payment gateway into your platform in minutes. Accept USDT payments on ERC-20 with real-time blockchain confirmation.

Overview

PayCow provides a simple RESTful API to create and track crypto payment sessions. Your backend creates a payment session and redirects the end user to our hosted checkout page, which handles all blockchain interactions automatically.

Base URL: https://paycow.net
All API requests must be made over HTTPS.

Integration Flow

The typical integration works as follows:

1. Your server → POST /api/payment/create → receives { paymentId, checkoutUrl }
2. Redirect your user to checkoutUrl
3. PayCow monitors the blockchain and marks payment as PAID
4. Your server polls GET /payment/data/:id to check status

Authentication

All API requests require your API key and secret, passed as HTTP headers. You receive these credentials after your operator account is approved by the PayCow admin.

x-api-key: your_api_key_here
x-api-secret: your_api_secret_here
⚠️ Keep your API Secret confidential. Never expose it in client-side code, public repositories, or logs. Rotate credentials immediately if compromised via your operator dashboard.

Finding Your Credentials

Log into your operator dashboard at /dashboard.html. Your API Key and Secret are displayed in the Credentials section of your profile.

Error Handling

PayCow uses standard HTTP status codes. Error responses return a JSON body with a msg field explaining the problem.

Status Code Meaning
200 / 201Success
400Bad Request — missing or invalid parameters
401Unauthorized — invalid or missing credentials
403Forbidden — account suspended or inactive
404Not Found — resource does not exist
500Internal Server Error — try again later

Create Payment

Creates a new payment session and returns a unique payment ID and hosted checkout URL to redirect your user to.

POST /api/payment/create

Request Body

Field Type Description
amount required number Payment amount in USDT (e.g. 50.00)
userId required string Your platform's unique user identifier
network required string Blockchain network — currently only ERC20 is supported
currency optional string Currency code, default: USDT

Example Request

curl -X POST https://paycow.net/api/payment/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-api-secret: YOUR_API_SECRET" \
  -d '{
    "amount": 50.00,
    "userId": "user_123456",
    "network": "ERC20"
  }'

Success Response 200

{
  "sessionId": "648f3a...",
  "paymentUrl": "https://paycow.net/payment/648f3a...",
  "paymentReference": "a1b2c3d4e5f6a7b8",
  "depositAddress": "0xABCDEF...",
  "expiresAt": "2026-03-12T22:30:00.000Z"
}

Get Payment Status

Retrieves the current status and details of a payment session. Poll this endpoint to track the lifecycle of a payment.

GET /payment/data/:paymentId

Path Parameters

Parameter Description
paymentId required The payment ID returned from POST /api/payment/create
This endpoint does not require API credentials — it is safe to call from your frontend.

Example Request

curl https://paycow.net/payment/data/648f3a...

Success Response 200

{
  "_id": "648f3a...",
  "userId": "user_123456",
  "amountRequested": 50.00,
  "amountReceived": 50.00,
  "currencyInfo": "USDT",
  "depositAddress": "0xABCDEF...",
  "depositNetwork": "ERC20",
  "status": "PAID",
  "confirmations": 12,
  "paymentReference": "PAY-8X91KZ",
  "txHash": "0x1a2b3c...",
  "expiresAt": "2026-03-12T22:30:00.000Z",
  "createdAt": "2026-03-12T21:30:00.000Z"
}

Payment States

A payment session progresses through these states during its lifecycle:

  • PENDING Awaiting deposit from the user. The checkout page is active.
  • DETECTED An incoming transaction has been detected on-chain, awaiting confirmations.
  • CONFIRMING Transaction found, accumulating block confirmations (requires 12).
  • PAID Payment confirmed with sufficient confirmations. Credits the operator balance.
  • EXPIRED The payment window elapsed without a detected deposit.
  • REJECTED Payment manually declined by the operator.

Security & Best Practices

Ensuring the security of your integration is paramount. Follow these guidelines to protect your credentials and your users' funds.

1. API Credential Safety

Your API Secret should be treated like a password. Never include it in frontend code, mobile apps, or any client-side environment. Always execute API calls from your secure backend server.

2. Idempotency & References

Use the userId field to link payments to your internal users. Store the PayCow sessionId and paymentReference in your database to prevent duplicate processing and for audit purposes.

3. Blockchain Confirmations

PayCow requires 12 confirmations on the Ethereum blockchain for ERC20 USDT transfers before marking a payment as PAID. This protects against chain reorgs and ensures finality. While the state is CONFIRMING, you should wait for the final PAID status before delivering goods or services.

Pro Tip: You can show a "Confirming..." spinner to your users while we wait for block depth. Most users find these confirmations take 3-5 minutes on average on the Ethereum network.

4. HTTPS Only

All production traffic to paycow.net is forced over HTTPS. Ensure your local development environment also uses secure connections when communicating with our API.

Code Examples

Node.js — Create a Payment

const response = await fetch('https://paycow.net/api/payment/create', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.PAYCOW_API_KEY,
    'x-api-secret': process.env.PAYCOW_API_SECRET,
  },
  body: JSON.stringify({
    amount: 50.00,
    userId: 'user_123456',
    network: 'ERC20',
  }),
});

const { sessionId, paymentUrl } = await response.json();
res.redirect(paymentUrl);

Python — Create a Payment

import requests
import os

url = "https://paycow.net/api/payment/create"
headers = {
    "Content-Type": "application/json",
    "x-api-key": os.getenv("PAYCOW_API_KEY"),
    "x-api-secret": os.getenv("PAYCOW_API_SECRET")
}
data = {
    "amount": 50.00,
    "userId": "user_123456",
    "network": "ERC20"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()
# Redirect user to result['paymentUrl']

Go — Create a Payment

package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

func main() {
    url := "https://paycow.net/api/payment/create"
    data := map[string]interface{}{
        "amount":  50.00,
        "userId":  "user_123456",
        "network": "ERC20",
    }
    jsonData, _ := json.Marshal(data)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("x-api-key", os.Getenv("PAYCOW_API_KEY"))
    req.Header.Set("x-api-secret", os.Getenv("PAYCOW_API_SECRET"))

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
    // Parse resp.Body to get paymentUrl
}

PHP — Create a Payment

$ch = curl_init('https://paycow.net/api/payment/create');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'amount' => 50.00,
    'userId' => $user_id,
    'network' => 'ERC20'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'x-api-key: ' . getenv('PAYCOW_API_KEY'),
    'x-api-secret: ' . getenv('PAYCOW_API_SECRET'),
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode(curl_exec($ch), true);
header('Location: ' . $result['paymentUrl']);

C# — Create a Payment

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
var data = new { amount = 50.00, userId = "user_123456", network = "ERC20" };
var content = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");

client.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("PAYCOW_API_KEY"));
client.DefaultRequestHeaders.Add("x-api-secret", Environment.GetEnvironmentVariable("PAYCOW_API_SECRET"));

var response = await client.PostAsync("https://paycow.net/api/payment/create", content);
var result = await response.Content.ReadAsStringAsync();
// Parse JSON and redirect to paymentUrl

Rust — Create a Payment

use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box> {
    let client = reqwest::Client::new();
    let mut headers = HeaderMap::new();
    headers.insert("x-api-key", HeaderValue::from_str(&std::env::var("PAYCOW_API_KEY")?)?);
    headers.insert("x-api-secret", HeaderValue::from_str(&std::env::var("PAYCOW_API_SECRET")?)?);

    let data = json!({ "amount": 50.0, "userId": "user_1", "network": "ERC20" });

    let res = client.post("https://paycow.net/api/payment/create")
        .headers(headers)
        .json(&data)
        .send().await?.json::<serde_json::Value>().await?;

    println!("URL: {}", res["paymentUrl"]);
    Ok(())
}