CryptMeUp Logo

CryptMeUp

Developer Documentation

Back to CryptMeUp

This page is currently available in English only.

Merchant API: Payment Status (Signed GET)

Use this endpoint to fetch live payment status and details from your backend, signed with the same merchant webhook secret you already use for HMAC-protected checkout/webhook flows.

Endpoint Namespace

Base endpoint: GET /api/merchant-api/v1/payments/{payment_identifier}

Optional query key: include_attempts=1 (returns attempt list with tx hashes and timestamps).

Request URL

GET https://cryptmeup.com/api/merchant-api/v1/payments/{payment_identifier}?include_attempts=1

Authentication Headers

Send three headers with each request.

Signature is computed as HMAC SHA-256 over "{timestamp}.{canonical_params}" using your merchant webhook secret.

  • X-CryptMeUp-Merchant: your merchant username (lowercase)
  • X-CryptMeUp-Timestamp: unix timestamp (seconds)
  • X-CryptMeUp-Signature: sha256=<hex>

Canonical Signable Params

The API signs canonical GET parameters (RFC3986) in sorted key order.

For this endpoint, sign exactly these keys: merchant, payment_identifier, include_attempts.

Pseudo Code

merchant = "cryptmeup"
payment_identifier = "6a5467f1-5b9b-43e3-9a56-99f437a7fa24"
include_attempts = "1"

params = {
  include_attempts: include_attempts,
  merchant: merchant,
  payment_identifier: payment_identifier
}

sort params by key
payload = RFC3986_QUERY(params)
timestamp = unix_time_seconds()
signed_payload = timestamp + "." + payload
signature = "sha256=" + HMAC_SHA256_HEX(webhook_secret, signed_payload)

PHP Example

$merchant = 'cryptmeup';
$paymentIdentifier = '6a5467f1-5b9b-43e3-9a56-99f437a7fa24';
$includeAttempts = '1';

$params = [
    'include_attempts' => $includeAttempts,
    'merchant' => $merchant,
    'payment_identifier' => $paymentIdentifier,
];

ksort($params);
$payload = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
$ts = time();
$sig = 'sha256='.hash_hmac('sha256', $ts.'.'.$payload, env('CRYPT_ME_UP_WEBHOOK_SECRET'));

$url = "https://cryptmeup.com/api/merchant-api/v1/payments/{$paymentIdentifier}?include_attempts={$includeAttempts}";

$headers = [
    "X-CryptMeUp-Merchant: {$merchant}",
    "X-CryptMeUp-Timestamp: {$ts}",
    "X-CryptMeUp-Signature: {$sig}",
];

cURL Example

curl -sS -X GET \
  "https://cryptmeup.com/api/merchant-api/v1/payments/6a5467f1-5b9b-43e3-9a56-99f437a7fa24?include_attempts=1" \
  -H "X-CryptMeUp-Merchant: cryptmeup" \
  -H "X-CryptMeUp-Timestamp: 1741183200" \
  -H "X-CryptMeUp-Signature: sha256=<generated_signature>"

Security Model

This endpoint is public-accessible but cryptographically protected.

The request is accepted only when signature, timestamp window, and merchant ownership of the payment all match.

  • Replay window: 5 minutes (300 seconds).
  • Signature must match merchant webhook secret.
  • Payment must belong to the signed merchant account.
  • Request throttling is enabled on the route.

Response Shape

On success, API returns payment status plus amount, chain, wallet, and timestamps.

When include_attempts=1, it also returns attempt entries with status and tx hash.

Success Response (200)

{
  "ok": true,
  "payment": {
    "identifier": "6a5467f1-5b9b-43e3-9a56-99f437a7fa24",
    "transaction_identifier": "b10b4dfb-2e18-43ca-a6b2-64aa87ec3e7f",
    "status": "paid",
    "status_label": "PAID",
    "is_final": true,
    "is_paid": true,
    "chain": "base",
    "crypto": "ETH",
    "crypto_amount": "0.0012000000000000",
    "fiat": "USD",
    "fiat_amount_minor": 2500,
    "fiat_amount_formatted": "25.00",
    "currency_rate": "2083.240000000000",
    "latest_tx_hash": "0x...",
    "created_at": "2026-03-05T10:03:44+00:00",
    "updated_at": "2026-03-05T10:04:10+00:00",
    "expires_at": "2026-03-05T11:03:44+00:00"
  },
  "attempts": []
}

Common Error Responses

400 Missing authentication headers.
400 Invalid timestamp header.
401 Signature timestamp expired.
401 Invalid authentication credentials.
401 Invalid signature.
404 Payment not found.