| title | Quickstart |
|---|---|
| description | Accept your first payment in under five minutes. No blockchain experience required. |
This guide takes you from zero to a working payment integration. By the end, you will have created a test payment and received a webhook confirmation.
- Node.js 18 or later
- A ZendFi account (sign up here)
- Your test API key (starts with
zfi_test_)
If you already have a Next.js or Express project, the fastest path is the CLI:
npx @zendfi/cli initThis auto-detects your framework, installs the SDK, and scaffolds the necessary files. Skip to Step 3 if you go this route.
npx create-zendfi-app my-store --template nextjs-ecommerce
cd my-storenpx create-zendfi-app my-saas --template nextjs-saas
cd my-saasnpx create-zendfi-app my-api --template express-api
cd my-apiAdd your test API key to the .env file:
ZENDFI_API_KEY=zfi_test_your_key_here
ZENDFI_WEBHOOK_SECRET=your_webhook_secret_hereconst zendfi = new ZendFiClient({
apiKey: process.env.ZENDFI_API_KEY,
});
const payment = await zendfi.createPayment({
amount: 25.00,
description: 'Quickstart test payment',
customer_email: 'test@example.com',
});
console.log('Payment ID:', payment.id);
console.log('Checkout URL:', payment.payment_url);
```
The response includes a payment_url -- open it in your browser to see the hosted checkout page.
Open the checkout URL in your browser. You will see ZendFi's hosted checkout page with:
- The payment amount and description
- A QR code for Solana wallet apps
- A wallet address for direct transfers
- A countdown timer showing when the payment expires
Connect a devnet-funded wallet (like Phantom set to devnet) and complete the payment.
Need devnet SOL or USDC? Use the [Solana faucet](https://faucet.solana.com) for SOL, then swap for devnet USDC.When the payment confirms on-chain, ZendFi sends a webhook to your configured endpoint.
```typescript app/api/webhooks/zendfi/route.ts import { createNextWebhookHandler } from '@zendfi/sdk/nextjs';export const POST = createNextWebhookHandler({
secret: process.env.ZENDFI_WEBHOOK_SECRET!,
handlers: {
'payment.confirmed': async (payment) => {
console.log('Payment confirmed:', payment.id);
// Fulfill the order, send confirmation email, etc.
},
'payment.failed': async (payment) => {
console.log('Payment failed:', payment.id);
},
},
});
```
const router = express.Router();
router.post('/zendfi',
express.raw({ type: 'application/json' }),
createExpressWebhookHandler({
secret: process.env.ZENDFI_WEBHOOK_SECRET!,
handlers: {
'payment.confirmed': async (payment) => {
console.log('Payment confirmed:', payment.id);
},
'payment.failed': async (payment) => {
console.log('Payment failed:', payment.id);
},
},
})
);
export default router;
```
Use the CLI to create a tunnel and forward webhooks to your local server:
npx @zendfi/cli webhooks --port 3000This starts a local server, creates a public tunnel (via ngrok or Cloudflare), and gives you a URL to configure as your webhook endpoint in the dashboard.
graph LR
A[Create Payment] --> B[Customer Pays]
B --> C[ZendFi Verifies]
C --> D[Webhook Fires]
D --> E[You Fulfill Order]
Once you are comfortable with test mode:
- Set up webhook security to verify signatures in production.
- Switch to live mode by using a
zfi_live_API key. - Explore subscriptions, invoices, and payment links for more advanced flows.