Merchant docs
Design your Pulze integration before approval: payment links, recurring mandates, multi-token checkout, credit top-ups, agent billing, webhooks, SDK, and MCP.
Payment links
Create a link from the dashboard. Your customer opens it, connects a wallet, signs once, and Pulze records the payment or subscription against your merchant account.
Unified crypto payments
Customers can pay using bits of crypto left across supported wallets/tokens. The system routes them programmatically into one payment and settles to your preferred stablecoin.
Recurring payments
The customer signs the subscription approval once. When the billing period is due, Pulze can execute the authorized pull without asking the customer for a second approval.
Club memberships
Sports clubs, creators, alumni groups, professional associations, gaming communities, charities and other member organizations can configure recurring dues and member benefits. Your server can create a hosted checkout link automatically through the merchant API.
API keys and SDK
Build against the typed SDK interfaces for server-side subscriptions, invoices, reporting, webhooks, and checkout. Generate credentials after account approval.
MCP and agent billing
Connect approved AI agents to bounded usage reporting and saved-mandate charging. Human review modes, merchant limits, audit logs, and kill switches remain in the payment path.
Credits and usage businesses
Let customers enter a top-up amount once, save a mandate, and add credits later without repeating wallet setup. Usage businesses can meter first and bill within approved caps.
Webhooks and reconciliation
Consume signed lifecycle events for payments, subscriptions, refunds, disputes, payouts, and credit notes. Treat transaction confirmation as the source of payment truth.
Choose your integration
Club membership flow
- Choose a membership type, dues, billing interval, settlement destination and accepted customer routes.
- Optionally configure claimable per-cycle rewards and an existing club asset for display.
- Create links in the dashboard, or have your server create them when a member selects a plan.
- Member connects wallet and signs the dues authorization.
- Pulze tracks the subscription and rewards after each confirmed paid cycle.
- Members request reward claims in the Pulze portal; the club sends and verifies the transfer.
Asset details can describe an existing token or NFT, but do not mint, transfer, or grant membership rights. Rewards are tracked by Pulze and claimed by members; the club currently sends those tokens from its own wallet.
Create a club checkout from your website
Call Pulze from your server when a member chooses a plan. Return the hosted URL to your site and redirect the member there. Store the link ID against your own signup/order key so your server can reuse it after a retry. Never expose your merchant API key to the browser.
const response = await fetch(
`https://api.pulze.guru/api/v1/merchants/${process.env.PULZE_MERCHANT_ID}/payment-links`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.PULZE_API_KEY,
},
body: JSON.stringify({
amount: '10000000', // $10.00, USD 6 decimals
chain: 'base', // settlement network. Omit token to settle in the chain's USDC
period: 2592000, // monthly
title: 'Supporter membership',
customerEmail: member.email,
metadata: {
vertical: 'club-membership',
membership: {
clubType: 'sports',
membershipName: 'Supporter',
benefits: ['Member status while active'],
memberAgreement: 'Your membership terms…',
rewards: { enabled: false },
},
fanAsset: { enabled: false, delivery: 'manual' },
},
}),
},
);
if (!response.ok) throw new Error('Could not prepare checkout');
const { url, id } = await response.json();
await saveLinkForSignup(member.signupId, id); // merchant-owned idempotency
return { checkoutUrl: url };The hosted checkout is served by Pulze at the returned URL. This API call creates a payment link; your website controls its signup UX, retries, redirect, and membership records.
Connect repeat top-ups to your app
For credits or compute usage, start a short-lived checkout handoff from your server using your app's session ID. Pulze returns a one-use PKCE result after the customer selects a wallet and approves the reusable permission. Your app can then save that wallet and use the existing repeat top-up flow.
- Create a handoff for your variable credit top-up link with integrationSessionId, codeChallenge and state.
- Open checkoutUrl. Verify Pulze origin, popup source and state before forwarding the one-time code to your server.
- Exchange the code server-side with the saved verifier, then store the returned credential securely.
const handoff = await pulze.topUps.createCheckoutHandoff(
merchantId,
topUpPaymentLinkId,
{ integrationSessionId, codeChallenge, state },
);
return { checkoutUrl: handoff.checkoutUrl };
const saved = await pulze.topUps.exchangeCheckoutHandoff(merchantId, {
authorizationCode,
codeVerifier, // load only from your server-side session store
});
// Keep saved.customerTopUpAuthorization encrypted on your server.The result is bound to your merchant, link, app session, checkout-selected wallet and active Pulze permission. It works only for customer-requested top-ups; it does not authorize merchant-triggered off-cycle charges. See the Pulze SDK README for complete setup and repeat-charge examples. A top-up link must have no fixed amount: creation is refused if it has one.
Every way to create an invoice
Amounts are USD6 integer strings ($10.00 is "10000000"). chain is where you are paid; token is the settlement token's contract address (omit it for the default). An invoice is paid only after Pulze confirms the payment, never when an API call returns.
- One-time invoice: POST /merchants/{id}/payment-links with amount, title, optional customerEmail, expiresAt, maxUses and taxBehavior. Send the returned url to the customer.
- Subscription or trial: the same call with period (seconds), optional maxCycles (0 = until cancelled) and trialDays. A period needs a fixed amount.
- Credit top-up: no amount, metadata { billingIntentType: 'credit_top_up', variableAmount: true }. Customer limits default to $1 minimum, $1,000 per deposit, $2,500 per day. A fixed amount is refused.
- Metered usage link: metadata.billingIntentType 'metered_usage' with a positive initial amount; optional customer caps in metadata.authorization (maxAmountPerChargeUsd6, dailyCapUsd6).
- Split invoice: POST /merchants/{id}/payment-links/split with 2 to 12 shares. One single-use link per payer; read progress at GET /payment-links/split/{groupId}.
- Club membership: a recurring link with metadata.vertical 'club-membership' (see club token configuration below).
- Products and customer bills (dashboard session): create a product, assign it to a customer, email the checkout link, or charge a saved permission.
- Quick charge or off-cycle: bill and charge a customer who already saved a permission. Run the read-only preflight first; the settlement network must be inside their signed scope.
- Agent charge: POST /agent/customers/{payer}/charge with an agent-scoped key. requestId is required and makes retries safe.
- Signed subscription: pulze.subscriptions.create after the payer signs the EIP-712 subscription once.
Customer coins are chosen with sourceRouteMode and acceptedRoutes ({ "8453": ["USDC", "USDT"] }), separately from where you are paid. Each coin must be an executable route on its chain, and more accepted coins mean more wallet prompts for a plain wallet. API keys authenticate payment-link routes; product, customer-bill and quick-charge routes need a merchant session. Full reference: docs/INTEGRATION-INVOICES-AND-CLUB-TOKENS.md.
Club token configuration
A club link tracks dues and earned rewards. Pulze does not mint, transfer or fund tokens; the club sends rewards from its own wallet. Three token settings are separate: dues settlement (chain and token), the coins members pay with (acceptedRoutes), and the two club-token fields below.
- Reward token (membership.rewards): ERC-20 only. Needs chainId, tokenAddress, tokenDecimals (must equal the on-chain decimals), amountPerCycle in raw token units and a trigger of EVERY_PAYMENT or FIRST_PAYMENT. Requires a recurring club-membership link.
- Rewards are earned only by a confirmed recurring payment with no dispute or refund. FIRST_PAYMENT pays once per member per link and is not repeated on re-subscribe. Earned rewards stay earned if the member cancels.
- Display asset (fanAsset): an existing ERC-20, ERC-721 or ERC-1155 shown to members. Needs address and a network (defaults to the settlement chain); ERC-20 decimals are verified. It does not deliver the asset.
- Verify first: POST /merchants/{id}/payment-links/club-token-metadata with chainId, address and type returns the verified symbol and decimals, or a 400. Available networks: GET /payment-links/route-capabilities, linkSetup.assetChains.
- Claims: members request earned rewards in the Pulze portal. You list requests, send the tokens from your wallet, then fulfill with the transfer hash; Pulze checks the exact ERC-20 transfer. Or decline; the member keeps the rewards.
- The reward and display tokens may live on a different network than your settlement chain, on any network Pulze can read.
metadata: {
vertical: 'club-membership',
membership: {
clubType: 'sports',
membershipName: 'Supporter',
rewards: {
enabled: true,
trigger: 'FIRST_PAYMENT', // or 'EVERY_PAYMENT'
chainId: 8453,
tokenAddress: '0x...', // ERC-20 on that network
tokenDecimals: 18, // must match the contract
amountPerCycle: '5000000000000000000', // raw units: 5 tokens at 18 decimals
},
},
fanAsset: { enabled: true, type: 'ERC721', chainId: 8453, address: '0x...', delivery: 'manual' },
}Quick API
Prepare this server-side integration now. Add the issued key only after verification.
import { PulzeClient } from '@pulze/sdk';
const pulze = new PulzeClient({
baseUrl: 'https://api.pulze.guru/api/v1',
apiKey: process.env.PULZE_API_KEY
});
await pulze.subscriptions.create({
sub,
signature,
email: 'customer@example.com',
chain: 'base'
});TypeScript SDK
Use the typed client from your server. Keep issued credentials out of browsers, repositories, logs, prompts, and client bundles.
npm install @pulze/sdk ethers
const pulze = new PulzeClient({
baseUrl: 'https://api.pulze.guru/api/v1',
apiKey: process.env.PULZE_API_KEY
});MCP discovery
Run the MCP server without a key to inspect public payment links and route quotes. Authenticated agent tools unlock only after verification and scoped-key issuance.
PULZE_API_URL=https://api.pulze.guru \ node packages/mcp/src/server.mjs # Add PULZE_MCP_API_KEY only after approval.
API authentication and schema
Store the issued key as PULZE_API_KEY on your server and send it in X-API-Key. It is not a Bearer token. Interactive dashboard sessions use Bearer authentication separately.
POST /api/v1/merchants/{merchantId}/payment-links
X-API-Key: pk_live_...
Content-Type: application/json
{
"amount": "100000000",
"title": "Monthly plan",
"period": 2592000,
"maxCycles": 0,
"trialDays": 0,
"customerEmail": "customer@example.com",
"taxBehavior": "EXCLUSIVE"
}Amount uses six-decimal smallest units: $100.00 is 100000000. Omit period for one-time checkout. A positive period creates recurring billing; zero max cycles means the subscription remains active until cancelled.
# Python
from decimal import Decimal
import requests
usd6 = str(int(Decimal("100.00") * 1_000_000))
response = requests.post(
f"https://api.pulze.guru/api/v1/merchants/{merchant_id}/payment-links",
headers={"X-API-Key": PULZE_API_KEY},
json={"amount": usd6, "title": "Monthly plan", "period": 2592000},
timeout=20,
)
response.raise_for_status()Signed webhook contract
Register an HTTPS endpoint in merchant Settings. Pulze shows its signing secret once, supports test delivery and replay, and retries failed deliveries with backoff.
Pulze-Event: payment.confirmed
Pulze-Delivery: delivery_id
Pulze-Timestamp: 1780000000
Pulze-Signature-Version: v1
Pulze-Signature: v1=<hex hmac sha256>
signature = HMAC_SHA256(
PULZE_WEBHOOK_SECRET,
Pulze-Timestamp + "." + rawRequestBody
)
{
"id": "delivery_id",
"type": "payment.confirmed",
"createdAt": "ISO-8601 timestamp",
"data": { "paymentId": "...", "status": "CONFIRMED", "txHash": "0x..." }
}Verify against the untouched raw request body before parsing JSON. Reject stale timestamps and deduplicate by the outer delivery id. Core events are payment.confirmed, invoice.funding_confirmed, invoice.action_required, subscription.created, subscription.action_required, dispute.opened, dispute.resolved, refund.approved, refund.completed, and refund.failed.
Builder-to-launch checklist
- Complete merchant signup and payout wallet.
- Choose the API, SDK, MCP, or no-code integration pattern.
- Map payment, refund, dispute, and payout webhook handling.
- Complete Pulze account verification.
- Generate credentials and run the controlled integration test.
- Enable customer payments only after the launch review passes.