Any Platform30 min integration

REST API Integration

Full programmatic control over crypto payment creation, settlement, and webhooks. Works with any backend language. Production-ready in under 30 minutes.

The SpacePay REST API lets you accept cryptocurrencies across 5 EVM networks on any platform, in any language, without a frontend SDK. Your backend creates a payment, the customer pays through a hosted checkout or your own UI, and your webhook endpoint receives the confirmation. Fiat settles to your bank account same-day.

The API follows standard REST conventions: JSON request and response bodies, HTTP status codes for errors, Bearer token authentication, and idempotency keys to prevent duplicate charges. If you have integrated Stripe, the patterns here will feel immediately familiar.

Base URL and Authentication

All requests go to https://api.spacepay.co.uk. A testnet is available at https://api-testnet.spacepay.co.uk for testing with simulated transactions and no real funds.

Generate your API keys in the SpacePay dashboard under Settings → API Keys. You receive a merchant secret key for server-side operations and a payment secret for customer-scoped operations. Authenticate every server-side request with:

X-SpacePay-Secret-Key: your_merchant_secret_key
Content-Type: application/json

Never expose your secret key in client-side JavaScript, mobile apps, or public repositories. Use environment variables and a secrets manager in production.

Creating a Payment

The core action is creating a payment intent. POST to /v1/payments with the amount in your settlement currency, a unique merchant reference, and a redirect URL for after the customer completes payment.

POST https://api.spacepay.co.uk/v1/external/secretkey-auth/payments
X-SpacePay-Secret-Key: your_merchant_secret_key
Content-Type: application/json
Idempotency-Key: order-8827-attempt-1

{
  "type": "payment",
  "amount": 14999,
  "currency": "USD",
  "orderId": "ORDER-8827",
  "redirectUrl": "https://yoursite.com/payment/success",
  "customMetadata": "{"customer_id":"cust_4829"}"
}

The response contains a checkout_url to redirect your customer and a payment_id to track the payment status:

{
  "id": "pay_3kJHd82nQplZ",
  "status": "pending",
  "amount": 14999,
  "currency": "USD",
  "orderId": "ORDER-8827",
  "depositAddress": {
    "type": "evm",
    "address": "0x..."
  },
  "quotes": [
    {
      "token": "USDC",
      "chainId": 137,
      "expectedAmount": "149.99",
      "exchangeRate": "1.0",
      "expiresAt": "2026-04-01T12:25:00Z"
    }
  ]
}

Redirect the customer to checkout_url. The hosted checkout handles wallet selection, QR code display, WalletConnect integration, and blockchain monitoring. You do not need to build any of this yourself.

API Endpoints Overview

MethodEndpointDescription
POST/v1/external/secretkey-auth/paymentsCreate a payment or deposit
GET/v1/external/secretkey-auth/payments/:paymentIdRetrieve a payment
GET/v1/external/secretkey-auth/paymentsList payments (paginated)
POST/v1/external/secretkey-auth/withdrawalsCreate a withdrawal
GET/v1/external/secretkey-auth/withdrawals/:withdrawalIdRetrieve a withdrawal

Webhooks

Webhooks are the primary mechanism for receiving payment status updates. Do not poll the payments endpoint — use webhooks. Register your endpoint URL in the dashboard or via the API and SpacePay will POST a signed JSON payload whenever a payment status changes.

The four event types:

Every webhook request includes an X-SpacePay-Signature header. Verify it before processing:

// Node.js webhook verification (HMAC-SHA256)
import crypto from "crypto";

function verifyWebhook(timestamp, rawBody, signatureHeader, secret) {
  // SpacePay signs: timestamp + "." + rawBody
  const payload = timestamp + "." + rawBody;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

app.post("/webhooks/spacepay", (req, res) => {
  const sig = req.headers["x-spacepay-signature"];
  const timestamp = req.headers["x-spacepay-timestamp"];
  if (!verifyWebhook(timestamp, req.rawBody, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send("Invalid signature");
  }

  const { event, data } = req.body;

  if (event === "payment.updated" && data.status === "completed") {
    await fulfillOrder(data.orderId);
  }

  res.status(200).send("OK");
});

Idempotency

Network timeouts can cause your server to retry a request without knowing if the first attempt succeeded. Without idempotency, you could create duplicate payments for the same order. Pass an Idempotency-Key header on every payment creation request.

If SpacePay receives two requests with the same idempotency key within 24 hours, it returns the original response instead of creating a new payment. Use a UUID generated per checkout attempt:

import { randomUUID } from "crypto";

const response = await fetch(
  "https://api.spacepay.co.uk/v1/external/secretkey-auth/payments",
  {
    method: "POST",
    headers: {
      "X-SpacePay-Secret-Key": process.env.SPACEPAY_SECRET_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": randomUUID(), // unique per checkout attempt
    },
    body: JSON.stringify({
      type: "payment",
      amount: 14999, // amount in cents
      currency: "USD",
      orderId: "ORDER-8827",
      redirectUrl: "https://yoursite.com/payment/success",
    }),
  }
);

Error Handling

The API returns standard HTTP status codes. Errors include a machine-readable code field and a human-readable message field.

StatusCodeMeaning
200Success
400invalid_requestMissing or malformed parameters
401unauthorizedInvalid or missing API key
409idempotency_conflictDifferent params for same idempotency key
422validation_errorParameters valid but rejected (e.g., amount too low)
429rate_limitedToo many requests. Back off and retry.
500server_errorSpacePay internal error. Retry with exponential backoff.

Always implement exponential backoff for 429 and 5xx responses. Do not retry 4xx errors without fixing the underlying request — they will not succeed on retry.

Integration Steps

  1. 01

    Generate API keys

    Log in to the SpacePay dashboard, go to Settings → API Keys, and generate a live keypair. Copy your secret key immediately — it is shown only once. Store it in an environment variable.

  2. 02

    Install an HTTP client

    No dedicated library is required. Use fetch (Node 18+), axios, Python requests, PHP Guzzle, or cURL. All standard HTTP clients work with the SpacePay API.

  3. 03

    Create a payment on checkout

    When your customer clicks 'Pay', your backend sends a POST to /v1/payments. Redirect the customer to the checkout_url in the response.

  4. 04

    Receive webhook confirmations

    Register your webhook URL in the dashboard. When the customer pays on-chain, SpacePay fires payment.confirmed to your endpoint. Verify the signature and fulfil the order.

  5. 05

    Receive fiat settlement

    No further action needed. SpacePay converts the crypto and settles fiat to your connected bank account same-day.

Frequently Asked Questions

Which programming languages does the SpacePay API support?

Any language that can make HTTP requests. Node.js, Python, PHP, Ruby, Go, Java, and .NET all work. Official SDKs are available for JavaScript and Python. All other languages use raw HTTP calls.

How do I authenticate with the SpacePay API?

Include your merchant secret key in the X-SpacePay-Secret-Key header on every server-side request. Keep this key server-side only — never expose it in frontend code or client-side JavaScript.

How does idempotency work?

Pass a unique Idempotency-Key header with every POST /v1/payments request. If the same key is used twice within 24 hours, SpacePay returns the original response instead of creating a duplicate payment. Use a UUID generated per checkout attempt.

How do I verify webhook authenticity?

SpacePay signs every webhook with HMAC-SHA256 using your webhook secret. The signature is in the X-SpacePay-Signature header. Compute the expected HMAC from the raw request body and compare it using a constant-time comparison before processing.

Is there a sandbox environment for testing?

Yes. Use https://api-testnet.spacepay.co.uk with testnet API keys for testing on Base Sepolia and Ethereum Sepolia. The testnet supports successful payments, underpayments, overpayments, and timeout scenarios.

Ready to integrate?

Full API reference, code samples, and a Postman collection are in the docs.

View API Docs

Other Integrations