Payment Links
Payment Links allow you to accept cryptocurrency payments without writing any code. Create a shareable link, send it to your customers, and get paid - it's that simple.
What are Payment Links?
Payment Links are no-code payment URLs that you create through the PayIn Admin dashboard. Share the link via email, messaging apps, or social media, and customers can pay instantly with cryptocurrency.
Key Characteristics:
- 🚫 No code required - Create links through Admin UI
- 🔗 Share anywhere - Email, WhatsApp, social media, QR code
- 💰 Flexible pricing - Fixed amount or custom amount
- 🌐 Multi-chain - Support multiple networks and tokens
- 📊 Track payments - Monitor all payments in dashboard
- 📦 Inventory control - Limit quantity for tickets/products
Payment Links vs Order API
Understanding when to use Payment Links:
| Feature | Payment Links | Order Payment API |
|---|---|---|
| Setup | No code - Admin UI only | Requires development |
| Sharing | Public URL/QR code | Programmatic integration |
| Use Case | Manual sharing, simple needs | Automated systems, e-commerce |
| Customization | Limited (via UI) | Full control (via code) |
| Payment Tracking | Dashboard only | Dashboard + Webhooks + API |
| Best For | Freelancers, small businesses | Developers, businesses with systems |
When to use Payment Links:
- Freelancer invoicing
- Event ticket sales
- Course enrollment fees
- Consulting service payments
- Donation collections
- Small business payments
- One-time product sales
Quick Start
Step 1: Create Your First Payment Link
- Log in to PayIn Admin
- Navigate to Payment Links in the sidebar
- Click Create Payment Link
- Fill in the details:
- Title: "Consulting Service - 1 Hour"
- Amount: 50 USDT
- Currency: Select USDT
- Chains: Select ethereum-sepolia, polygon-amoy
- Click Create Draft
Step 2: Customize (Optional)
- Add a Description: Explain what the payment is for
- Set Inventory: Limit to specific quantity (e.g., 10 tickets)
- Set Expiration: Auto-expire after a date
- Add Metadata: Track internal information
Step 3: Publish
- Click Publish on your payment link
- A unique URL is generated (e.g.,
payin.com/p/abc123XYZ) - Copy the link or QR code
Step 4: Share
Share your payment link via:
- 📧 Email: Copy and paste the link
- 💬 Messaging: WhatsApp, Telegram, etc.
- 📱 QR Code: Download and print
- 🌐 Website: Add link to your site
- 📱 Social Media: Share on Twitter, Facebook
Step 5: Get Paid
- Customer clicks your link
- Customer selects chain and pays
- You receive notification
- Payment appears in dashboard
Test First
Use testnet links to test the complete flow before sharing mainnet links to customers.
Creating Payment Links
Basic Payment Link
Minimum required fields:
{
"title": "Consulting Service - 1 Hour",
"amount": "50",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"is_primary": true
}
]
}What customers see:
- Title: "Consulting Service - 1 Hour"
- Price: 50 USDT
- Available chains: Ethereum Sepolia, Polygon Amoy
- Customer selects chain and pays
Payment Link with Description
{
"title": "Web Development Course",
"description": "Complete 12-week course including:\n• Frontend development\n• Backend APIs\n• Deployment guide\n• Lifetime access",
"amount": "299",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"is_primary": true
}
]
}Benefits:
- Clear explanation of what they're paying for
- Builds trust and reduces confusion
- Supports markdown formatting
Multi-Currency Payment Link
{
"title": "Premium Membership",
"amount": "99",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"is_primary": true
},
{
"currency": "USDC",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"amount": "99"
}
]
}What customers see:
- Can choose between USDT or USDC
- Same price in both currencies
- All supported chains available
Limited Inventory Payment Link
{
"title": "VIP Event Ticket",
"description": "Annual Tech Conference 2025\nDate: June 15-17\nVenue: San Francisco",
"amount": "500",
"inventoryTotal": 100,
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia"],
"is_primary": true
}
]
}Features:
- Limited to 100 tickets
- Shows "X remaining" to customers
- Automatically stops accepting payments when sold out
- Tracks reserved (pending payment) vs sold (completed)
Time-Limited Payment Link
{
"title": "Early Bird Discount",
"description": "Limited time offer - ends Dec 31, 2025",
"amount": "79",
"expiresAt": "2025-12-31T23:59:59Z",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"is_primary": true
}
]
}Features:
- Automatically expires at specified date/time
- Customers cannot pay after expiration
- Shows countdown timer on payment page
Custom Amount Payment Link
{
"title": "Donation",
"description": "Support our open source project",
"amount": "0",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum-sepolia", "polygon-amoy"],
"is_primary": true
}
]
}Features:
- Customer enters their own amount
- Useful for donations, tips, variable pricing
- Set amount to "0" for custom amount
Custom Amount Validation
Set minimum amount validation on payment page to avoid very small payments that might not cover transaction costs.
Managing Payment Links
Link States
Payment links have two states:
1. Draft (draft)
- Not publicly accessible
- Can be edited freely
- No slug/URL assigned yet
- For preparation and testing
2. Published (published)
- Publicly accessible via unique URL
- Limited editing (cannot change pricing fundamentals)
- Has unique slug (e.g.,
abc123XYZ) - Ready for customers
Publishing Workflow
Create links as drafts → Test internally → Publish when ready → Share with customers
Editing Payment Links
Can always edit:
- ✅ Title
- ✅ Description
- ✅ Inventory total (can increase or decrease)
- ✅ Expiration date
- ✅ Metadata
Cannot edit after publishing:
- ❌ Amount (create new link instead)
- ❌ Currencies
- ❌ Chain options
- ❌ Slug (auto-generated on publish)
To make major changes:
- Archive the old link
- Create a new link with updated details
- Publish and share new link
Archiving Links
Archive payment links that are no longer needed:
When to archive:
- Event is over
- Product is sold out permanently
- Promotion has ended
- Service no longer offered
Effects of archiving:
- Link becomes inaccessible
- Existing payments remain in history
- Can be restored if needed
- Helps keep your dashboard organized
Viewing Payment History
For a specific link:
- Go to Payment Links dashboard
- Click on a payment link
- View Orders tab
- See all payments for this link
Statistics shown:
- Total orders: All payment attempts
- Completed orders: Successful payments
- Pending orders: Awaiting payment/confirmation
- Expired orders: Timed out or expired
- Total revenue: Sum of completed payments
- Reserved inventory: Pending payments
- Sold inventory: Completed payments
Use Cases
Freelancer Invoice
Scenario: Web developer invoicing a client for completed work.
{
"title": "Website Development - Project Alpha",
"description": "Delivered items:\n• Homepage design\n• 5 content pages\n• Contact form\n• 2 rounds of revisions\n\nPayment due within 7 days",
"amount": "2500",
"expiresAt": "2025-02-07T23:59:59Z",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum", "polygon"],
"is_primary": true
},
{
"currency": "USDC",
"chainOptions": ["ethereum", "polygon"],
"amount": "2500"
}
],
"metadata": {
"project_id": "proj_alpha_2025",
"client_name": "Acme Corp",
"invoice_number": "INV-2025-001"
}
}Workflow:
- Create payment link for project
- Email link to client: "Pay invoice via crypto: [link]"
- Client pays using their preferred chain
- Receive notification when paid
- Mark invoice as paid in your system
Event Ticket Sales
Scenario: Tech conference selling 500 VIP tickets.
{
"title": "TechConf 2025 - VIP Pass",
"description": "Includes:\n• All conference sessions\n• VIP networking events\n• Speaker dinner\n• Conference swag bag\n\nDates: June 15-17, 2025\nVenue: San Francisco Convention Center",
"amount": "499",
"inventoryTotal": 500,
"expiresAt": "2025-06-01T00:00:00Z",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum", "polygon"],
"is_primary": true
}
],
"metadata": {
"event_id": "techconf_2025",
"ticket_type": "vip",
"venue": "SF Convention Center"
}
}Workflow:
- Create payment link for tickets
- Add link to event website
- Share on social media
- Monitor sales in dashboard
- Send ticket fulfillment emails (manual or automated)
Online Course Enrollment
Scenario: Educational platform selling course access.
{
"title": "Complete Python Bootcamp",
"description": "Learn Python from zero to hero!\n\n✓ 60 hours of video content\n✓ 200+ coding exercises\n✓ 12 real-world projects\n✓ Certificate of completion\n✓ Lifetime access\n✓ Money-back guarantee",
"amount": "149",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum", "polygon", "tron"],
"is_primary": true
},
{
"currency": "USDC",
"chainOptions": ["ethereum", "polygon"],
"amount": "149"
}
],
"metadata": {
"course_id": "python_bootcamp",
"platform": "learn.example.com",
"access_duration": "lifetime"
}
}Workflow:
- Create payment link for course
- Add to course landing page
- Customer clicks "Enroll Now" → redirects to payment link
- After payment, receive webhook (if configured)
- Auto-grant course access via webhook handler
Donation Collection
Scenario: Open source project accepting donations.
{
"title": "Support PayIn Development",
"description": "Help us build better crypto payment infrastructure!\n\nYour donation helps us:\n• Maintain and improve PayIn\n• Add support for more chains\n• Keep the service free for small businesses\n• Build developer-friendly tools\n\nEvery contribution matters. Thank you! 🙏",
"amount": "0",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum", "polygon", "tron"],
"is_primary": true
},
{
"currency": "USDC",
"chainOptions": ["ethereum", "polygon"],
}
],
"metadata": {
"campaign": "open_source_support",
"project": "payin"
}
}Features:
- Custom amount (donors choose amount)
- Multiple chain options for convenience
- Heartfelt description to encourage donations
Best Practices
Link Naming
Use clear, descriptive titles:
Good Examples:
Consulting Call - 30 Minutes
Web Design Services - Homepage Package
Conference Ticket - Early Bird Price
Python Course - Full AccessAvoid:
Payment // Too generic
Link 1 // No context
Service // Vague
Product A // UnclearDescription Guidelines
Do:
- ✅ Clearly explain what they're paying for
- ✅ List specific deliverables or features
- ✅ Include relevant dates/deadlines
- ✅ Add terms or conditions if needed
- ✅ Use bullet points for readability
Don't:
- ❌ Leave description empty
- ❌ Use overly technical jargon
- ❌ Write walls of text
- ❌ Forget important details
Pricing Strategy
Fixed Amount:
{
"amount": "99.00",
"currencies": [
{
"currency": "USDT",
"chainOptions": ["ethereum", "polygon"]
}
]
}- Use for: Products, services, tickets with fixed pricing
- Benefit: Clear expectations, no confusion
Custom Amount:
{
"amount": "0",
"currencies": [...]
}- Use for: Donations, tips, variable pricing
- Benefit: Flexibility for customers
- Warning: Set minimum amount to avoid dust payments
Multi-Chain Strategy
Offer multiple chains for convenience:
{
"currencies": [
{
"currency": "USDT",
"chainOptions": [
"ethereum", // High security
"polygon", // Low fees
"tron" // Very low fees
],
"is_primary": true
}
]
}Benefits:
- Customers choose based on their preference
- Lower fees on some chains = happier customers
- Higher conversion rates
Recommendation:
- Include at least 2 chains
- Polygon/Tron for low-value payments (< $100)
- Ethereum for high-value payments (> $1000)
Inventory Management
For limited availability:
{
"inventoryTotal": 50,
"title": "Early Bird Special - Limited to 50"
}Monitor in real-time:
- Check dashboard for available/reserved/sold counts
- Update inventory if you add more capacity
- Archive when sold out
Best practices:
- Set realistic inventory numbers
- Mention scarcity in title/description
- Update customers if sold out
Testing Links
Always test before sharing:
- Create testnet link - Use testnet environment first
- Test payment flow - Complete a test payment yourself
- Verify notifications - Check dashboard updates
- Check mobile - Test on mobile devices
- Share internally - Have team test before public launch
Test With Real Amounts
Test with realistic amounts to ensure the UX is good. Testing with $0.01 won't reveal issues with $1000 payments.
Link Sharing
Email Template:
Hi [Customer Name],
Thank you for your interest in [Product/Service]!
To complete your payment, please click the link below:
[Payment Link URL]
Or scan this QR code:
[QR Code Image]
Payment details:
• Amount: $X USDT/USDC
• Supported networks: Ethereum, Polygon
• Payment window: [if time-limited]
Questions? Reply to this email.
Best regards,
[Your Name]Social Media Post:
🎉 Now accepting crypto payments!
Get [Product/Service Name] with USDT/USDC:
[Payment Link]
✅ Instant confirmation
✅ Multiple chains supported
✅ Secure & transparent
Limited slots available! 👇Troubleshooting
"Link not found" Error
Problem: Customer gets error when accessing link.
Causes:
- Link is still in draft status (not published)
- Link has been archived
- Typo in URL
Solutions:
- Verify link status in dashboard (should be "Published")
- Check if link is archived (restore if needed)
- Copy fresh URL from dashboard
Payment Not Detected
Problem: Customer paid but payment not showing in dashboard.
Causes:
- Wrong network (paid on different chain than selected)
- Wrong token (paid ETH instead of USDT)
- Transaction still pending
- Paid to wrong address
Solutions:
- Check transaction on block explorer
- Verify correct network and token
- Wait for required confirmations
- Contact support with transaction hash
Inventory Not Updating
Problem: Inventory count not updating after payment.
Expected Behavior:
- Reserved: Increments when order created (payment pending)
- Sold: Increments when payment confirmed
- Available: Decreases when reserved
If stuck:
- Check order status (might still be pending)
- Wait for blockchain confirmations
- Refresh dashboard
Cannot Edit Published Link
Problem: Need to change amount but link is published.
Solution:
- Archive current link
- Create new link with updated amount
- Publish new link
- Share new URL with customers
- Inform existing customers of change
Keep Old Link Active
If customers already have the old link, keep it active until transition is complete. Then archive after grace period.
QR Code Not Working
Problem: Scanning QR code doesn't open payment page.
Causes:
- QR code contains wrong URL
- URL is too long for QR code
- QR code image quality too low
Solutions:
- Regenerate QR code from dashboard
- Use URL shortener if needed
- Test QR code with multiple apps
- Increase QR code size/quality
Advanced Features
Metadata for Tracking
Attach custom data to payment links:
{
"title": "Consulting Service",
"amount": "500",
"metadata": {
"client_id": "client_12345",
"project_code": "PROJ-2025-Q1",
"service_category": "consulting",
"sales_rep": "john@example.com",
"campaign": "email_blast_jan_2025"
}
}Use metadata for:
- Internal tracking and reporting
- Client/project association
- Sales attribution
- Campaign tracking
- Integration with your systems
Access metadata:
- View in payment link details
- Included in webhook events
- Searchable via API
Webhook Integration
Configure webhooks to automate fulfillment:
Event types:
paymentlink.order.completed- Payment confirmedpaymentlink.order.expired- Order expired without payment
Example webhook handler:
app.post('/webhooks/payin', async (req, res) => {
const event = req.body;
if (event.type === 'paymentlink.order.completed') {
const { paymentLinkId, buyerEmail, amount } = event.data;
// Auto-fulfill based on payment link
if (paymentLinkId === 'link_course_python') {
await grantCourseAccess(buyerEmail);
await sendWelcomeEmail(buyerEmail);
} else if (paymentLinkId === 'link_ticket_conference') {
await generateTicket(buyerEmail);
await sendTicketEmail(buyerEmail);
}
}
res.status(200).send('OK');
});API Access
Manage payment links programmatically:
Create via API:
curl -X POST https://testnet.payin.com/api/v1/payment-links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Product Name",
"amount": "99",
"currencies": [...]
}'List all links:
curl https://testnet.payin.com/api/v1/payment-links \
-H "Authorization: Bearer YOUR_API_KEY"Useful for:
- Bulk link creation
- Integration with your CMS
- Dynamic link generation
- Automated reporting
Next Steps
Enhance Your Setup
- Webhooks - Automate fulfillment
- API Integration - Programmatic control
- Security - Secure your integration
For Developers
- Order Payment Service - Full API control
- Deposit Service - Recurring payments
- Address Pool Setup - Address management
Resources
- Supported Networks - Available blockchains
- Supported Tokens - Available stablecoins
Support
Need help with Payment Links?
- 📧 Email: support@payin.com
- 💬 Discord: Join our community
- 📚 Admin Dashboard: Built-in help and tutorials