PayCow
JavaScript SDK
A focused Node.js client for the payment endpoints already available in PayCow: create a hosted USDT payment, retrieve its status, and verify HMAC-SHA256 webhook signatures.
@paycow/sdk
Downloadable CommonJS package with TypeScript declarations and no runtime dependencies.
Installation
Extract the downloaded archive and install the package from its local directory. The SDK uses the Fetch API and cryptography modules built into Node.js 18 and newer.
npm install ./paycow-javascript-sdk
Keep both credentials on your server. Browser bundles must never contain the API secret.
PAYCOW_API_KEY=your_api_key PAYCOW_API_SECRET=your_api_secret PAYCOW_WEBHOOK_SECRET=whsec_your_signing_secret
Create a payment
createPayment calls POST /api/payment/create. The customer or order identifier is sent as userId. The optional idempotency key is sent in both the request header and body, matching the backend replay guard.
const { PayCowClient } = require('@paycow/sdk');
const paycow = new PayCowClient({
apiKey: process.env.PAYCOW_API_KEY,
apiSecret: process.env.PAYCOW_API_SECRET
});
const payment = await paycow.createPayment({
userId: 'player-2048',
amount: '50.00',
network: 'TRC20',
addressSerialNo: 'WAL-1002',
idempotencyKey: 'topup-2048-001'
});
console.log(payment.sessionId);
console.log(payment.paymentUrl);
console.log(payment.payableAmount);
console.log(payment.depositAddress);
payableAmount as the exact amount shown to the customer. PayCow may allocate a unique micro-amount when active payments share the same destination and network.Retrieve payment status
getPaymentStatus calls the authenticated GET /api/payment/status/:sessionId endpoint.
const payment = await paycow.getPaymentStatus('66ce30d74c0c51a48f2d2903');
if (payment.status === 'PAID') {
await creditBalanceOnce(payment.userId, payment.paymentReference);
}
if (payment.status === 'CONFIRMING') {
console.log(payment.confirmations);
}
The backend can return PENDING, DETECTED, CONFIRMING, PAID, EXPIRED, or REJECTED.
Verify webhooks
Verification requires the unparsed request body, PayCow-Timestamp, PayCow-Signature, and the webhook signing secret from the merchant dashboard.
const express = require('express');
const { verifyWebhook } = require('@paycow/sdk');
const app = express();
app.post('/webhooks/paycow', express.raw({ type: 'application/json' }), async (req, res) => {
const event = verifyWebhook({
rawBody: req.body,
timestamp: req.get('PayCow-Timestamp'),
signature: req.get('PayCow-Signature'),
secret: process.env.PAYCOW_WEBHOOK_SECRET
});
if (event.type === 'payment.paid') {
await creditBalanceOnce(event.data.userId, event.data.paymentReference);
}
res.sendStatus(200);
});
The verifier checks the v1=<hex> signature with a timing-safe comparison and rejects timestamps outside the default 300-second window.
Error handling
HTTP failures raise PayCowApiError with the response status and parsed response body. Invalid local input raises PayCowValidationError.
const { PayCowApiError } = require('@paycow/sdk');
try {
await paycow.getPaymentStatus(sessionId);
} catch (error) {
if (error instanceof PayCowApiError) {
console.error(error.statusCode, error.responseBody);
}
throw error;
}
API contract
| SDK method | Backend endpoint | Required values |
|---|---|---|
createPayment | POST /api/payment/create | userId, amount, network |
getPaymentStatus | GET /api/payment/status/:id | sessionId |
verifyWebhook | Local verification | Raw body, timestamp, signature, secret |