ghostguild-org/HELCIM_PAYMENT_FIX.md

149 lines
4.4 KiB
Markdown

# Helcim Payment Flow Fix
## Issue
The initial implementation had a mismatch in the payment flow:
- **Error**: "Customer ID is required" when attempting to purchase event tickets
- **Cause**: The payment initialization endpoint required a `customerId`, but event tickets are one-time purchases that don't need customer accounts
## Solution
### 1. Updated Payment Initialization (`server/api/helcim/initialize-payment.post.js`)
**Changed from:**
- Always requiring `customerId`
- Always using `verify` payment type (for card verification)
- Amount fixed at 0
**Changed to:**
- `customerId` is now optional
- Detects event ticket purchases via `metadata.type === 'event_ticket'`
- Uses `purchase` type for event tickets with amount > 0
- Uses `verify` type for subscription setup (card verification)
```javascript
// For event tickets: HelcimPay.js completes the purchase immediately
const paymentType = isEventTicket && amount > 0 ? 'purchase' : 'verify'
```
### 2. Updated Ticket Purchase Endpoint (`server/api/events/[id]/tickets/purchase.post.js`)
**Changed from:**
- Expecting `paymentToken` from client
- Calling `processHelcimPayment()` to process the payment
- Payment happens server-side after modal closes
**Changed to:**
- Expecting `transactionId` from client
- Payment already completed by HelcimPay.js modal
- Server just records the transaction
**Why?**
When using HelcimPay.js with `purchase` type, the payment is processed inside the modal and we get a completed transaction back. We don't need to make a second API call to charge the card.
### 3. Updated Frontend Component (`app/components/EventTicketPurchase.vue`)
**Changed from:**
- Getting `cardToken` from payment modal
- Sending `paymentToken` to purchase endpoint
**Changed to:**
- Getting `transactionId` from payment modal
- Sending `transactionId` to purchase endpoint
- Added validation to ensure transaction ID exists
## Payment Flow Comparison
### Old Flow (Subscriptions)
```
1. Initialize payment session (verify mode, amount: 0)
2. User enters card in modal
3. Modal returns cardToken
4. Send cardToken to server
5. Server calls Helcim API to charge card
6. Create registration
```
### New Flow (Event Tickets)
```
1. Initialize payment session (purchase mode, amount: actual price)
2. User enters card in modal
3. Helcim charges card immediately
4. Modal returns transactionId
5. Send transactionId to server
6. Server records transaction and creates registration
```
## Benefits
1. **Simpler**: One API call instead of two
2. **Faster**: Payment completes in the modal
3. **More Secure**: No need to handle card tokens server-side
4. **PCI Compliant**: Card data never touches our server
5. **Better UX**: User sees immediate payment confirmation
## Testing
### Free Member Tickets
```bash
# Should work without payment modal
1. Member logs in
2. Views event with member.isFree: true
3. Fills name/email
4. Clicks "Complete Registration"
5. ✓ Registers immediately (no payment)
```
### Paid Public Tickets
```bash
# Should trigger Helcim modal
1. Non-member views event
2. Sees public ticket price
3. Fills name/email
4. Clicks "Pay $XX.XX"
5. Helcim modal opens
6. Enters test card: 4242 4242 4242 4242
7. Payment processes
8. ✓ Modal closes with success
9. ✓ Registration created with transaction ID
```
## Environment Variables
Ensure these are set in `.env`:
```bash
# Public (client-side)
NUXT_PUBLIC_HELCIM_TOKEN=your_helcim_api_token
NUXT_PUBLIC_HELCIM_ACCOUNT_ID=your_account_id
# Private (server-side)
HELCIM_API_TOKEN=your_helcim_api_token
```
## Common Issues
### "Customer ID is required"
-**Fixed** - This error should no longer occur for event tickets
- If you still see it, check that `metadata.type: 'event_ticket'` is being passed
### "No transaction ID received"
- Check browser console for HelcimPay.js errors
- Verify Helcim credentials are correct
- Ensure test mode is enabled for testing
### Payment modal doesn't open
- Check that HelcimPay.js script loaded (see console)
- Verify `NUXT_PUBLIC_HELCIM_TOKEN` is set
- Check browser console for initialization errors
## Files Changed
1. `server/api/helcim/initialize-payment.post.js` - Smart payment type detection
2. `server/api/events/[id]/tickets/purchase.post.js` - Accept transactionId instead of token
3. `app/components/EventTicketPurchase.vue` - Pass transactionId instead of cardToken
---
**Status**: ✅ Fixed
**Date**: 2025-10-14
**Impact**: Event ticket purchases now work correctly with Helcim