DevelopersPayments API

Payments API

Integrate privacy-preserving tips, wallet management, and ZK reviewer payouts into your applications.

Quick Start
Get started with the NobleID Payments API in minutes

1. Get API Key

Register at nobleid.org/developers and generate your API key

2. Install SDK

npm install @nobleid/payments-sdk
import { NobleIDPayments } from '@nobleid/payments-sdk'

const payments = new NobleIDPayments({
  apiKey: process.env.NOBLEID_API_KEY, // Server-side only - secure
  environment: 'production' // or 'sandbox'
})

// Create a tip intent
const tipIntent = await payments.createTipIntent({
  workId: 'ark:/48914/20092025/7X9K2Q',
  amount: '0.01',
  currency: 'ETH',
  message: 'Great research!'
})

API Reference

Create Tip Intent
Create a privacy-preserving tip intent for a work
POST/api/v1/payments/tip-intents

Request Body

{
  "workId": "ark:/48914/20092025/7X9K2Q",
  "amount": "0.01",
  "currency": "ETH",
  "message": "Great research!",
  "anonymous": true,
  "splitTemplate": "default"
}

Response

{
  "id": "tip_1234567890",
  "status": "pending",
  "paymentUrl": "https://pay.nobleid.org/tip_1234567890",
  "expiresAt": "2025-01-15T10:30:00Z",
  "destinationAddress": "0x742d35Cc6634C0532925a3b8D4C0532925a3b8D4",
  "amount": "0.01",
  "currency": "ETH"
}

Parameters

workId - NobleID of the work
amount - Tip amount as string
currency - ETH, USDC, or MATIC
message - Optional tip message
anonymous - Hide tipper identity

Privacy Features

Rotating destination addresses
Optional anonymous tipping
No wallet exposure
Get Tip Intent Status
GET/api/v1/payments/tip-intents/tip_1234567890
{
  "id": "tip_1234567890",
  "status": "confirmed",
  "transactionHash": "0x1234...abcd",
  "confirmedAt": "2025-01-15T10:35:00Z",
  "amount": "0.01",
  "currency": "ETH"
}
SDK Examples
Common integration patterns using the NobleID Payments SDK

React Component for Tipping

import { useState } from 'react'

export function TipButton({ workId }) {
  const [loading, setLoading] = useState(false)

  const handleTip = async () => {
    setLoading(true)
    try {
      const response = await fetch('/api/payments/create-tip', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          workId,
          amount: '0.01',
          currency: 'ETH',
          anonymous: true
        })
      })
      const intent = await response.json()
      window.open(intent.paymentUrl, '_blank')
    } catch (error) {
      console.error('Tip failed:', error)
    } finally {
      setLoading(false)
    }
  }

  return (
    <button onClick={handleTip} disabled={loading}>
      {loading ? 'Processing...' : 'Support this work'}
    </button>
  )
}

Server-side API Route

// app/api/payments/create-tip/route.ts
import { NobleIDPayments } from '@nobleid/payments-sdk'
import { useTranslation } from "@/lib/i18n"

const payments = new NobleIDPayments({
  apiKey: process.env.NOBLEID_API_KEY, // Server-side only, secure
  environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox'
})

export async function POST(request: Request) {
  try {
    const body = await request.json()
    const intent = await payments.createTipIntent(body)
    return Response.json(intent)
  } catch (error) {
    return Response.json({ error: 'Failed to create tip intent' }, { status: 500 })
  }
}

Server-side Webhook Handler

import crypto from 'crypto'

export async function POST(request) {
  const body = await request.text()
  const signature = request.headers.get('x-nobleid-signature')
  
  // Verify webhook signature
  const expectedSignature = crypto
    .createHmac('sha256', process.env.NOBLEID_WEBHOOK_SECRET)
    .update(body)
    .digest('hex')
  
  if (signature !== `sha256=${expectedSignature}`) {
    return new Response('Invalid signature', { status: 401 })
  }
  
  const event = JSON.parse(body)
  
  switch (event.event) {
    case 'tip.confirmed':
      // Handle confirmed tip
      await handleTipConfirmed(event.data)
      break
    case 'escrow.claimed':
      // Handle escrow claim
      await handleEscrowClaimed(event.data)
      break
  }
  
  return new Response('OK')
}
Authentication

API Key

Include your API key in the Authorization header:

Authorization: Bearer nid_live_1234567890abcdef

Environments

Sandbox: api-sandbox.nobleid.org
Production: api.nobleid.org
Rate Limits
Free tier: 100 requests/hour
Pro tier: 1,000 requests/hour
Enterprise: Custom limits

Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642694400
    ByNobleID