puffin-app/docs/TESTING_STRIPE_WEBHOOK.md

264 lines
8.1 KiB
Markdown
Raw Permalink Normal View History

Add NocoDB integration for order management with comprehensive Stripe webhook logging Features: - Complete NocoDB schema with 42 fields supporting B2B and B2C customers - Server-side NocoDB client (REST API integration) - Stripe session data mapper with automatic field mapping - Enhanced webhook handler with comprehensive logging - Automatic order creation in NocoDB after payment - Fulfillment data updates with Wren order IDs - Support for business customers (VAT/EIN, business names) - Complete billing address capture - Non-blocking error handling (webhook succeeds even if NocoDB fails) Files Added: - server/utils/nocodbClient.js - NocoDB REST API client - server/utils/nocodbMapper.js - Stripe to NocoDB data mapper - docs/NOCODB_SCHEMA.md - Complete field reference (42 columns) - docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide - docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions - docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview Files Modified: - server/routes/webhooks.js - Added NocoDB integration and enhanced logging - src/types.ts - Updated OrderRecord interface with new fields - src/api/nocodbClient.ts - Added createOrder() method - .env.example - Added NocoDB configuration template Schema includes: - Payment tracking (Stripe session/intent/customer IDs, amounts, fees) - Carbon offset details (tons, portfolio, Wren order ID) - Customer information (name, email, phone, business name) - Tax ID collection (VAT, EIN, etc.) - Complete billing address - Optional vessel/trip details for yacht calculations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
# Testing Stripe Webhook Data Collection
## Purpose
This guide explains how to test the Stripe webhook to verify all available data fields before finalizing the NocoDB schema.
## Enhanced Logging
The webhook handler now includes comprehensive logging via `logStripeSessionData()` function that displays:
- ✅ Session information (ID, payment intent, status)
- ✅ Payment amounts (total, subtotal, currency)
- ✅ Customer details (name, email, phone)
- ✅ Billing address (all fields)
- ✅ Payment method types
- ✅ Metadata (our custom fields)
- ✅ Additional fields (locale, reference IDs)
- ✅ Shipping address (if collected)
- ✅ Tax IDs (if collected)
## Testing Methods
### Method 1: Stripe CLI (Recommended for Development)
**Setup:**
```bash
# Install Stripe CLI if not already installed
# Windows: scoop install stripe
# macOS: brew install stripe/stripe-cli/stripe
# Linux: See https://stripe.com/docs/stripe-cli
# Login to Stripe
stripe login
# Forward webhooks to local server
stripe listen --forward-to localhost:3000/api/webhooks/stripe
```
**Trigger Test Payment:**
```bash
# Trigger a checkout.session.completed event
stripe trigger checkout.session.completed
```
**Expected Output:**
The server console will show:
1. The structured data log from `logStripeSessionData()` (formatted with boxes)
2. The full JSON payload
3. Payment confirmation message
4. Order fulfillment logs
### Method 2: Real Stripe Test Payment
**Setup:**
1. Ensure server is running: `npm run dev` (from `/server` directory)
2. Ensure webhook endpoint is publicly accessible (use ngrok or similar)
3. Configure webhook in Stripe Dashboard → Developers → Webhooks
4. Add webhook endpoint: `https://your-domain.com/api/webhooks/stripe`
5. Select event: `checkout.session.completed`
6. Copy webhook signing secret to `.env`: `STRIPE_WEBHOOK_SECRET=whsec_...`
**Execute Test:**
1. Navigate to your app's checkout flow
2. Use Stripe test card: `4242 4242 4242 4242`
3. Fill in test billing information
4. Complete checkout
5. Check server logs
**Test Data to Use:**
```
Card Number: 4242 4242 4242 4242
Expiry: Any future date (e.g., 12/34)
CVC: Any 3 digits (e.g., 123)
ZIP: Any 5 digits (e.g., 12345)
Name: Test User
Email: test@example.com
Phone: +1234567890 (if phone collection enabled)
Address:
Line 1: 123 Test Street
Line 2: Apt 4B
City: Test City
State: CA
ZIP: 12345
Country: US
```
### Method 3: Stripe Dashboard Test Events
**Execute:**
1. Go to Stripe Dashboard → Developers → Webhooks
2. Click on your webhook endpoint
3. Click "Send test webhook"
4. Select `checkout.session.completed`
5. Click "Send test webhook"
**Note:** This may have limited data compared to real checkout sessions.
## Reading the Logs
### Expected Log Structure
When a payment completes, you'll see logs in this order:
```
📬 Received webhook: checkout.session.completed
╔════════════════════════════════════════════════════════════════╗
║ STRIPE CHECKOUT SESSION - COMPREHENSIVE DATA ║
╚════════════════════════════════════════════════════════════════╝
📋 SESSION INFORMATION:
Session ID: cs_test_...
Payment Intent: pi_...
Payment Status: paid
Status: complete
Mode: payment
Created: 2025-11-03T...
Expires At: 2025-11-04T...
💰 PAYMENT AMOUNT:
Amount Total: 164979 cents ($1649.79)
Amount Subtotal: 164979 cents ($1649.79)
Currency: USD
👤 CUSTOMER DETAILS:
Name: Matthew Ciaccio
Email: matt@letsbe.solutions
Phone: +33612345678 (or N/A if not collected)
Tax Exempt: none
📬 BILLING ADDRESS:
Line 1: 108 Avenue du Trois Septembre
Line 2: N/A
City: Cap-d'Ail
State: N/A
Postal Code: 06320
Country: FR
🔗 CUSTOMER OBJECT:
Customer ID: cus_... (or N/A)
💳 PAYMENT METHOD:
Types: card
🏷️ METADATA (Our Custom Fields):
baseAmount: 160174
processingFee: 4805
portfolioId: 37
tons: 6.73
... (additional sections)
╔════════════════════════════════════════════════════════════════╗
║ END OF STRIPE DATA LOG ║
╚════════════════════════════════════════════════════════════════╝
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📦 Full Stripe Webhook Payload:
{
"id": "evt_...",
"object": "event",
"type": "checkout.session.completed",
"data": { ... }
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Checkout session completed: cs_test_...
💳 Payment confirmed for order: e0e976e5-...
Amount: $1649.79
🌱 Fulfilling order via Wren API...
```
## Verification Checklist
After running a test payment, verify the logs contain:
### ✅ Required Fields (Must Have Values)
- [ ] Session ID (`session.id`)
- [ ] Payment Intent (`session.payment_intent`)
- [ ] Amount Total (`session.amount_total`)
- [ ] Currency (`session.currency`)
- [ ] Customer Name (`session.customer_details.name`)
- [ ] Customer Email (`session.customer_details.email`)
- [ ] Metadata - baseAmount (`session.metadata.baseAmount`)
- [ ] Metadata - processingFee (`session.metadata.processingFee`)
- [ ] Metadata - portfolioId (`session.metadata.portfolioId`)
- [ ] Metadata - tons (`session.metadata.tons`)
### ⚠️ Optional Fields (Check if Available)
- [ ] Customer Phone (`session.customer_details.phone`)
- [ ] Billing Address Line 1 (`session.customer_details.address.line1`)
- [ ] Billing Address Line 2 (`session.customer_details.address.line2`)
- [ ] Billing City (`session.customer_details.address.city`)
- [ ] Billing State (`session.customer_details.address.state`)
- [ ] Billing Postal Code (`session.customer_details.address.postal_code`)
- [ ] Billing Country (`session.customer_details.address.country`)
### 📋 Schema Verification
Compare the logged fields against `docs/NOCODB_SCHEMA.md`:
1. Verify all required fields have values
2. Check which optional fields are actually populated
3. Identify any Stripe fields we're missing in our schema
4. Verify data types and formats
## Common Issues
### Phone Number Not Showing
**Cause:** Phone collection not enabled in checkout session creation.
**Fix:** In `server/routes/checkout.js`, ensure phone collection is enabled:
```javascript
const session = await stripe.checkout.sessions.create({
phone_number_collection: {
enabled: true
},
// ... other settings
});
```
### Address Fields Empty
**Cause:** Billing address collection not set to "required".
**Fix:** In checkout session creation:
```javascript
const session = await stripe.checkout.sessions.create({
billing_address_collection: 'required',
// ... other settings
});
```
### Metadata Missing
**Cause:** Metadata not passed when creating checkout session.
**Fix:** Ensure metadata is included in session creation:
```javascript
const session = await stripe.checkout.sessions.create({
metadata: {
baseAmount: '160174',
processingFee: '4805',
portfolioId: '37',
tons: '6.73',
// Add vessel/trip data here if available
},
// ... other settings
});
```
## Next Steps
After verifying the logged data:
1. **Document findings** - Note which fields are actually populated
2. **Update schema** - Add any missing fields to `docs/NOCODB_SCHEMA.md`
3. **Update types** - Update `OrderRecord` interface in `src/types.ts`
4. **Configure NocoDB** - Create table with verified fields
5. **Implement webhook handler** - Map Stripe data to NocoDB columns
## Reference
- [Stripe Checkout Session Object](https://stripe.com/docs/api/checkout/sessions/object)
- [Stripe Webhooks Documentation](https://stripe.com/docs/webhooks)
- [Stripe CLI Documentation](https://stripe.com/docs/stripe-cli)