Initial commit - Black Canyon Tickets whitelabel platform
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
184
supabase/migrations/005_add_fee_payment_model.sql
Normal file
184
supabase/migrations/005_add_fee_payment_model.sql
Normal file
@@ -0,0 +1,184 @@
|
||||
-- Add fee payment model options to organizations table
|
||||
-- This determines whether customers pay the platform fee on top of the ticket price
|
||||
-- or if the fee is absorbed into the ticket price
|
||||
|
||||
ALTER TABLE organizations
|
||||
ADD COLUMN platform_fee_model VARCHAR(20) DEFAULT 'customer_pays',
|
||||
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;
|
||||
|
||||
-- Update fee_structures table to include the fee model
|
||||
ALTER TABLE fee_structures
|
||||
ADD COLUMN fee_model VARCHAR(20) DEFAULT 'customer_pays',
|
||||
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;
|
||||
|
||||
-- Add comments for clarity
|
||||
COMMENT ON COLUMN organizations.platform_fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
|
||||
COMMENT ON COLUMN organizations.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';
|
||||
COMMENT ON COLUMN fee_structures.fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
|
||||
COMMENT ON COLUMN fee_structures.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';
|
||||
|
||||
-- Update existing organizations with default fee model and actual BCT rates
|
||||
UPDATE organizations
|
||||
SET
|
||||
platform_fee_model = 'customer_pays',
|
||||
absorb_fee_in_price = false,
|
||||
platform_fee_percentage = 0.025, -- 2.5% BCT platform fee
|
||||
platform_fee_fixed = 150 -- $1.50 BCT platform fee
|
||||
WHERE platform_fee_model IS NULL;
|
||||
|
||||
-- Update existing fee structure templates with actual rates
|
||||
UPDATE fee_structures
|
||||
SET
|
||||
fee_model = 'customer_pays',
|
||||
absorb_fee_in_price = false
|
||||
WHERE fee_model IS NULL;
|
||||
|
||||
-- Update the default template to reflect actual BCT rates
|
||||
UPDATE fee_structures
|
||||
SET
|
||||
fee_percentage = 0.025,
|
||||
fee_fixed = 150,
|
||||
description = 'BCT platform fee: 2.5% + $1.50 per transaction'
|
||||
WHERE name = 'Standard Platform Fee' AND is_template = true;
|
||||
|
||||
-- Add new fee structure templates with absorbed fee model and correct BCT rates
|
||||
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
|
||||
('All-Inclusive BCT Standard', 'BCT platform fee 2.5% + $1.50 included in ticket price', 'percentage_plus_fixed', 0.025, 150, 'absorbed_in_price', true, true),
|
||||
('All-Inclusive Percentage Only', '2.5% fee included in ticket price', 'percentage', 0.025, 0, 'absorbed_in_price', true, true),
|
||||
('All-Inclusive Fixed Only', '$1.50 fee included in ticket price', 'fixed', 0.0000, 150, 'absorbed_in_price', true, true),
|
||||
('Premium All-Inclusive', 'Premium 3% + $2.00 fee included in ticket price', 'percentage_plus_fixed', 0.030, 200, 'absorbed_in_price', true, true);
|
||||
|
||||
-- Add template for Stripe fee structure (for reference/calculation)
|
||||
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
|
||||
('Stripe Processing Fee', 'Stripe credit card processing: 2.99% + $0.30', 'percentage_plus_fixed', 0.0299, 30, 'customer_pays', false, true);
|
||||
|
||||
-- Add function to calculate the display price based on fee model
|
||||
CREATE OR REPLACE FUNCTION calculate_display_price(
|
||||
base_price DECIMAL,
|
||||
fee_percentage DECIMAL DEFAULT 0.03,
|
||||
fee_fixed INTEGER DEFAULT 30,
|
||||
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
||||
fee_model VARCHAR DEFAULT 'customer_pays'
|
||||
) RETURNS DECIMAL AS $$
|
||||
DECLARE
|
||||
platform_fee DECIMAL;
|
||||
display_price DECIMAL;
|
||||
BEGIN
|
||||
-- Calculate platform fee based on fee type
|
||||
CASE fee_type
|
||||
WHEN 'percentage' THEN
|
||||
platform_fee := base_price * fee_percentage;
|
||||
WHEN 'fixed' THEN
|
||||
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
||||
WHEN 'percentage_plus_fixed' THEN
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
ELSE
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
END CASE;
|
||||
|
||||
-- Calculate display price based on fee model
|
||||
CASE fee_model
|
||||
WHEN 'customer_pays' THEN
|
||||
-- Customer pays base price + platform fee
|
||||
display_price := base_price;
|
||||
WHEN 'absorbed_in_price' THEN
|
||||
-- Platform fee is absorbed into the display price
|
||||
-- To maintain the same net revenue for organizer,
|
||||
-- we need to increase the display price to cover the fee
|
||||
display_price := base_price + platform_fee;
|
||||
ELSE
|
||||
display_price := base_price;
|
||||
END CASE;
|
||||
|
||||
RETURN ROUND(display_price, 2);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Add function to calculate the total amount customer pays
|
||||
CREATE OR REPLACE FUNCTION calculate_customer_total(
|
||||
base_price DECIMAL,
|
||||
fee_percentage DECIMAL DEFAULT 0.03,
|
||||
fee_fixed INTEGER DEFAULT 30,
|
||||
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
||||
fee_model VARCHAR DEFAULT 'customer_pays'
|
||||
) RETURNS DECIMAL AS $$
|
||||
DECLARE
|
||||
platform_fee DECIMAL;
|
||||
customer_total DECIMAL;
|
||||
BEGIN
|
||||
-- Calculate platform fee based on fee type
|
||||
CASE fee_type
|
||||
WHEN 'percentage' THEN
|
||||
platform_fee := base_price * fee_percentage;
|
||||
WHEN 'fixed' THEN
|
||||
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
||||
WHEN 'percentage_plus_fixed' THEN
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
ELSE
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
END CASE;
|
||||
|
||||
-- Calculate total amount customer pays
|
||||
CASE fee_model
|
||||
WHEN 'customer_pays' THEN
|
||||
-- Customer pays base price + platform fee separately
|
||||
customer_total := base_price + platform_fee;
|
||||
WHEN 'absorbed_in_price' THEN
|
||||
-- Customer pays only the display price (fee is included)
|
||||
customer_total := base_price;
|
||||
ELSE
|
||||
customer_total := base_price + platform_fee;
|
||||
END CASE;
|
||||
|
||||
RETURN ROUND(customer_total, 2);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Add function to calculate organizer net with fee model
|
||||
CREATE OR REPLACE FUNCTION calculate_organizer_net(
|
||||
base_price DECIMAL,
|
||||
fee_percentage DECIMAL DEFAULT 0.03,
|
||||
fee_fixed INTEGER DEFAULT 30,
|
||||
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
||||
fee_model VARCHAR DEFAULT 'customer_pays'
|
||||
) RETURNS DECIMAL AS $$
|
||||
DECLARE
|
||||
platform_fee DECIMAL;
|
||||
organizer_net DECIMAL;
|
||||
BEGIN
|
||||
-- Calculate platform fee based on fee type
|
||||
CASE fee_type
|
||||
WHEN 'percentage' THEN
|
||||
platform_fee := base_price * fee_percentage;
|
||||
WHEN 'fixed' THEN
|
||||
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
||||
WHEN 'percentage_plus_fixed' THEN
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
ELSE
|
||||
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
||||
END CASE;
|
||||
|
||||
-- Calculate organizer net (what they receive)
|
||||
organizer_net := base_price - platform_fee;
|
||||
|
||||
-- Ensure organizer net is never negative
|
||||
IF organizer_net < 0 THEN
|
||||
organizer_net := 0;
|
||||
END IF;
|
||||
|
||||
RETURN ROUND(organizer_net, 2);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Add indexes for performance
|
||||
CREATE INDEX idx_organizations_platform_fee_model ON organizations(platform_fee_model);
|
||||
CREATE INDEX idx_fee_structures_fee_model ON fee_structures(fee_model);
|
||||
|
||||
-- Add check constraints to ensure valid fee models
|
||||
ALTER TABLE organizations
|
||||
ADD CONSTRAINT check_platform_fee_model
|
||||
CHECK (platform_fee_model IN ('customer_pays', 'absorbed_in_price'));
|
||||
|
||||
ALTER TABLE fee_structures
|
||||
ADD CONSTRAINT check_fee_model
|
||||
CHECK (fee_model IN ('customer_pays', 'absorbed_in_price'));
|
||||
Reference in New Issue
Block a user