feat: Square payment integration, booking flow redesign, and timezone/weekday fixes
- Add Square payment integration (mock + handlers + UI): terminal/online payments, refunds, tips, saved cards, webhooks. Build-tagged dev/prod clients. - Redesign booking flow: Step 4 conditional (deposit only), Step 5 confirmation screen with booking ID, auto-submit on transition. - Redesign schedule modal: 2x3 button grid with Pay Deposit/Pay Early logic. - Add deposit warning banner at Step 1 for users with outstanding deposits. - Fix weekday conversion bug: Go 0=Sunday vs DB 0=Monday mismatch in 6 locations. - Fix timezone bug: UTC vs London time in closing hours validation. - Fix frontend error parsing: plain text backend errors now displayed correctly. - Fix crypto.randomUUID fallback for environments without Web Crypto. - Add 7 new regression tests: closing hours, advance check, active booking limit, weekday conversion, UTC/London, deposit snapshot, exceptional hours. - Fix 3 flaky tests: dynamic dates instead of fixed, no-show timing.
This commit is contained in:
@@ -228,3 +228,78 @@ func DeleteTimeBlocker(pool *pgxpool.Pool, blockerID string) error {
|
||||
_, err := pool.Exec(ctx, "DELETE FROM time_blockers WHERE id = $1", blockerID)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateTestPayment creates a payment record for testing
|
||||
// Returns payment ID
|
||||
func CreateTestPayment(db *pgxpool.Pool, bookingID string, amount float64, method string, ptype string, status string) (string, error) {
|
||||
ctx := context.Background()
|
||||
var paymentID string
|
||||
err := db.QueryRow(ctx, `
|
||||
INSERT INTO payments (booking_id, payment_type, payment_method, status, amount, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, NOW(), NOW())
|
||||
RETURNING id
|
||||
`, bookingID, ptype, method, status, amount).Scan(&paymentID)
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create payment: %w", err)
|
||||
}
|
||||
|
||||
return paymentID, nil
|
||||
}
|
||||
|
||||
// CreateTestRefund creates a refund record for testing
|
||||
// Returns refund ID
|
||||
func CreateTestRefund(db *pgxpool.Pool, paymentID string, bookingID string, amount float64) (string, error) {
|
||||
ctx := context.Background()
|
||||
var refundID string
|
||||
err := db.QueryRow(ctx, `
|
||||
INSERT INTO refunds (payment_id, booking_id, amount, status, reason, created_at)
|
||||
VALUES ($1, $2, $3, 'completed', 'test refund', NOW())
|
||||
RETURNING id
|
||||
`, paymentID, bookingID, amount).Scan(&refundID)
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create refund: %w", err)
|
||||
}
|
||||
|
||||
return refundID, nil
|
||||
}
|
||||
|
||||
// CreateTestPaymentMethod creates a saved card for a user
|
||||
// Returns card ID
|
||||
func CreateTestPaymentMethod(db *pgxpool.Pool, userID string, squareCardID string, brand string, last4 string) (string, error) {
|
||||
ctx := context.Background()
|
||||
var cardID string
|
||||
err := db.QueryRow(ctx, `
|
||||
INSERT INTO user_saved_cards (user_id, square_card_id, brand, last_4, exp_month, exp_year, fingerprint, is_default, created_at)
|
||||
VALUES ($1, $2, $3, $4, 12, 2030, 'test_fp', false, NOW())
|
||||
RETURNING id
|
||||
`, userID, squareCardID, brand, last4).Scan(&cardID)
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create payment method: %w", err)
|
||||
}
|
||||
|
||||
return cardID, nil
|
||||
}
|
||||
|
||||
// DeletePayment deletes a payment from the database
|
||||
func DeletePayment(pool *pgxpool.Pool, paymentID string) error {
|
||||
ctx := context.Background()
|
||||
_, err := pool.Exec(ctx, "DELETE FROM payments WHERE id = $1", paymentID)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteRefund deletes a refund from the database
|
||||
func DeleteRefund(pool *pgxpool.Pool, refundID string) error {
|
||||
ctx := context.Background()
|
||||
_, err := pool.Exec(ctx, "DELETE FROM refunds WHERE id = $1", refundID)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeletePaymentMethod deletes a saved card from the database
|
||||
func DeletePaymentMethod(pool *pgxpool.Pool, cardID string) error {
|
||||
ctx := context.Background()
|
||||
_, err := pool.Exec(ctx, "DELETE FROM user_saved_cards WHERE id = $1", cardID)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user