@jpmvtv/a2u-payments
v1.3.0
Published
Portable A2U payment system for Pi Network integration in Next.js apps
Maintainers
Readme
@jpmvtv/a2u-payments
Portable A2U (App-to-User) payment system for Pi Network integration in Next.js applications
✨ Features
- ✅ Smart Setup Wizard - Auto-detects your schema, prevents breaking auth
- ✅ UID-based payments - No wallet address requests needed
- ✅ Framework-agnostic - Works with Next.js 14, 15, 16+
- ✅ React Components - Pre-built payment buttons and hooks
- ✅ Type-safe - Full TypeScript support
- ✅ Secure - Input validation, error handling, audit logging
- ✅ Flexible RLS support - Multi-tenant with any column naming convention
- ✅ Database migrations - PostgreSQL with 4 isolation strategies
- ✅ Copy-paste API routes - Ready to use endpoints
- ✅ Production-ready - Error handling, retry logic, logging
🆕 Smart Setup Wizard
No more breaking your existing auth! The wizard:
- 🔍 Scans your database to detect your Pi UID column naming
- ❓ Confirms with you before making any changes
- 📝 Generates custom migrations for your specific schema
- ⚙️ Creates configuration files for your setup
Perfect for: myPiAtlas, existing projects, custom schemas, or any production app where you can't afford to break things.
🚀 Quick Start
npm install @jpmvtv/a2u-payments
npm run setup:a2u-payments # 🧙♂️ Interactive wizard prevents breaking your auth!Understanding Pi UID
The recipientUid prop requires the Pi Network UID of the payment recipient. This is NOT a database column name - it's the actual Pi Network user identifier that you get from your authentication system or user profile.
Where to get the Pi UID:
- From your authenticated user context:
user.piUid - From your user database table:
user.pi_uidcolumn - From Pi Network API response:
user.uid
Basic Usage
import { A2UPaymentButton } from '@jpmvtv/a2u-payments/react';
import { useAuth } from '@/lib/auth'; // Your auth system
function PaymentComponent() {
const { user } = useAuth(); // Get authenticated user
return (
<A2UPaymentButton
recipientUid={user.piUid} // Use actual Pi Network UID from user
amount={3.14}
memo="Reward payment"
transactionType="customer_reward"
onSuccess={(payment) => console.log('Sent!', payment.txid)}
/>
);
}
## 🔑 Getting User Pi UID
The most common confusion is where to get the `recipientUid` value. Here's how it works:
### Data FlowYour Auth System → User Profile → Pi Network UID → Payment Component
### Common Patterns
#### Pattern 1: From Auth Context
```typescript
const { user } = useAuth(); // user.piUid contains the Pi Network UIDPattern 2: From Database
// Your users table typically has a pi_uid column
const user = await db.users.findOne({ where: { id: userId } });
// user.pi_uid is the Pi Network UIDPattern 3: From API Response
const response = await fetch('/api/user/profile');
const userData = await response.json();
// userData.piUid is the Pi Network UIDImportant Notes
- Component prop:
recipientUid(React component interface) - Database column:
uid(in a2u_payments table) - Your user table:
pi_uidorpiUid(your user management) - Source: Your authentication system or user profile database
📋 Prerequisites
- Node.js 18+
- Next.js 14+ (or 15, 16)
- PostgreSQL database
- Pi Network API credentials
- React 18+
📖 Documentation
- Installation Guide - Complete setup instructions
- API Reference - All functions, components, and hooks
- Integration Guide - Step-by-step integration examples
- Examples - Ready-to-use code examples
🎯 Use Cases
Perfect for:
- Customer rewards - Loyalty programs, cashback, bonuses
- Staff payments - Salaries, commissions, tips
- Affiliate payouts - Commission distributions
- Refunds - Customer returns and exchanges
- Platform payments - Operational and merchant payouts
🛠️ Installation
npm install @jpmvtv/a2u-paymentsQuick Setup (5 minutes)
Configure environment variables:
PI_API_KEY=your_api_key_here PI_WALLET_PRIVATE_KEY=your_wallet_private_key_here PI_API_URL=https://api.minepi.com/v2 DATABASE_URL=your_postgresql_connection_stringRun database migrations:
cp node_modules/@jpmvtv/a2u-payments/src/db/migrations/*.sql your_database/migrations/ npm run db:migrateAdd API route:
mkdir -p src/app/api/a2u-payments cp node_modules/@jpmvtv/a2u-payments/src/api/a2u-payments/route.ts src/app/api/a2u-payments/route.tsUse in components:
import { A2UPaymentButton } from '@jpmvtv/a2u-payments/react'; <A2UPaymentButton recipientUid="user-uid" amount={3.14} memo="Payment" transactionType="customer_reward" onSuccess={(payment) => alert(`Sent: ${payment.txid}`)} />
📦 Package Contents
@jpmvtv/a2u-payments/
├── dist/ # Compiled TypeScript
├── src/
│ ├── api/
│ │ └── a2u-payments/route.ts # API endpoint
│ ├── core/
│ │ ├── a2u-payment.ts # Core payment logic
│ │ ├── payment-tracker.ts # Payment tracking
│ │ └── payment-validator.ts # Input validation
│ ├── db/
│ │ ├── connection.ts # Database connection
│ │ ├── queries.ts # SQL queries
│ │ └── migrations/ # Database schemas
│ ├── react/
│ │ ├── components/
│ │ │ └── A2UPaymentButton.tsx
│ │ └── hooks/
│ │ ├── useA2UPayment.ts
│ │ └── usePaymentHistory.ts
│ └── utils/ # Utilities
└── docs/ # Full documentation🎨 Components
A2UPaymentButton
Pre-built payment button with loading states and error handling.
<A2UPaymentButton
recipientUid="user-pi-uid"
amount={3.14}
memo="Reward payment"
transactionType="customer_reward"
onSuccess={(payment) => console.log('Sent!', payment)}
onError={(error) => console.error('Failed:', error)}
loadingText="Processing..."
buttonText="Send Reward"
className="custom-button"
/>🪝 Hooks
useA2UPayment
Hook for sending A2U payments with full control.
const { sendPayment, isLoading, error } = useA2UPayment();
const result = await sendPayment({
uid: 'user-pi-uid',
amount: 3.14,
memo: 'Reward',
transaction_type: 'customer_reward'
});usePaymentHistory
Hook for retrieving payment history.
const { payments, isLoading, error, refreshHistory } = usePaymentHistory('user-pi-uid');🔧 Transaction Types
customer_reward- Customer rewards and cashbackcustomer_refund- Refunds for returnsstaff_payout- Staff salary and commissionsaffiliate_payout- Affiliate commissionsmerchant_payout- Platform payouts to merchantsplatform_payout- Platform operational payments
🗄️ Database Schema
The package uses PostgreSQL with two main tables:
a2u_payments- Payment records with full audit trailpayment_logs- Detailed transaction logs
Flexible Multi-Tenancy Support
RLS Strategies Available:
- User-based isolation - Isolate by
user_uid,piUid,user_id, etc. - Tenant-based isolation - Isolate by
tenant_id(SaaS apps) - Organization-based - Isolate by
organization_idorteam_id - Combined isolation - Both tenant + user (advanced scenarios)
Any Column Naming Convention: Customize column names to match your existing user table schema (pi_uid, piUid, user_id, etc.)
Setup: Choose your strategy in 003_enable_rls.sql and uncomment the relevant section. Supports both RLS (multi-tenant) and non-RLS (single-tenant) environments.
See Installation Guide for detailed RLS configuration.
🔒 Security
- Input validation and sanitization
- Secure database operations with parameterized queries
- Audit logging for all transactions
- Error handling without sensitive data exposure
- Environment-based configuration
🐛 Troubleshooting
Common Issues
"pi-backend not found"
npm install pi-backend"Database connection failed"
- Check
DATABASE_URLorA2U_PAYMENTS_DB_URL - Verify PostgreSQL server is running
- Ensure database user has proper permissions
"Pi Network credentials not configured"
- Verify
PI_API_KEYandPI_WALLET_PRIVATE_KEYare set - Check credentials are valid on Pi Network dashboard
For detailed troubleshooting, see INSTALL.md.
📄 License
MIT © JP Veneracion
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📞 Support
- Issues: GitHub Issues
- Email: [email protected]
🙏 Acknowledgments
Built for the Pi Network ecosystem to enable seamless A2U payment integration.
Made with ❤️ for the Pi Network community
