---
title: Client libraries: Node, PHP, Python, Go
description: Official Coinetic API clients for Node.js, PHP, Python and Go: one file with no external dependencies for request signing, invoices and webhook verification.
url: https://coinetic.money/docs/sdks/
lang: en
---

# Client libraries and examples

Each client is a single file with no external dependencies. Copy it into your project and you get request signing, invoice creation and retrieval, and webhook verification.

### Node.js

Node 22+. Classes `CoineticClient` and `CoineticError`, plus the `verifyWebhook` function.

    Download cryptopay.js ↓

### PHP

PHP 8.1+ with the curl and json extensions. `\Cryptopay\Client`, `\Cryptopay\verify_webhook`.

    Download Cryptopay.php ↓

### Python

Python 3.9+, standard library only. `CoineticClient`, `verify_webhook`.

    Download cryptopay.py ↓

### Go

Go 1.22+, standard library only. Package `cryptopayclient`.

    Download cryptopay.go ↓

## What's inside

| Function | Node.js | PHP | Python | Go |
| --- | --- | --- | --- | --- |
| Sign a request | `signRequest` | `sign_request` | `sign_request` | `SignRequest` |
| Create an invoice | `createInvoice` | `createInvoice` | `create_invoice` | `CreateInvoice` |
| Retrieve an invoice | `getInvoice` | `getInvoice` | `get_invoice` | `GetInvoice` |
| Verify a webhook | `verifyWebhook` | `verify_webhook` | `verify_webhook` | `VerifyWebhook` |
| Statuses safe to fulfill | `PAID_STATUSES` | `PAID_STATUSES` | `PAID_STATUSES` | `PaidStatuses` |

The technical file and class names (`cryptopay.*`, `CryptopayClient`) are legacy and won't change; Node.js and Python also provide the aliases `CoineticClient` and `CoineticError`.

## All four are tested against the same vectors

Request and webhook signatures from every client match the [test vectors](https://coinetic.money/docs/authentication/#test-vectors). Writing a client in another language? Get it to match them first: it's the fastest way to catch a signing bug.

## Minimal flow

`pseudocode`

```
invoice = client.createInvoice({order_id, price_amount: "3.00", price_currency: "USD",
                                return_url: "https://shop.example/orders/42"},
                               idempotencyKey = "order-42")
redirect(invoice.checkout_url)

on POST /webhooks/coinetic (raw body!):
    event = verifyWebhook(WEBHOOK_SECRET, headers, rawBody)   # otherwise 400/401
    if seen(event.id): return 200                             # duplicate delivery
    inv = client.getInvoice(event.data.invoice_id)            # re-check
    if inv.status in PAID_STATUSES: grantOnce(inv.order_id)
    return 200
```

## What the clients don't do

- They don't store secrets: the key and secret are passed in from environment variables or a secrets manager.
- They don't store processed `X-Webhook-Id` values; that's your database's job.
- They don't convert amounts to numbers: every amount is a string.
- They don't retry requests on their own. Retry with the same `Idempotency-Key` on `429`, `5xx` and network errors.
- They don't run in browsers or mobile apps, only on the server, where the secret lives.
