87 lines
3.6 KiB
SQL
87 lines
3.6 KiB
SQL
-- =====================================================
|
|
-- ORBIQUANT IA - PAYMENTS TABLE
|
|
-- =====================================================
|
|
-- Description: Payment transaction records
|
|
-- Schema: financial
|
|
-- =====================================================
|
|
|
|
CREATE TABLE financial.payments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Referencias
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,
|
|
subscription_id UUID REFERENCES financial.subscriptions(id) ON DELETE SET NULL,
|
|
invoice_id UUID REFERENCES financial.invoices(id) ON DELETE SET NULL,
|
|
wallet_transaction_id UUID REFERENCES financial.wallet_transactions(id) ON DELETE SET NULL,
|
|
|
|
-- Stripe integration
|
|
stripe_payment_intent_id VARCHAR(255) UNIQUE,
|
|
stripe_charge_id VARCHAR(255),
|
|
stripe_payment_method_id VARCHAR(255),
|
|
|
|
-- Payment details
|
|
amount DECIMAL(15,2) NOT NULL,
|
|
currency financial.currency_code NOT NULL,
|
|
payment_method financial.payment_method NOT NULL,
|
|
status financial.payment_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Descripción
|
|
description TEXT,
|
|
statement_descriptor VARCHAR(255), -- Lo que ve el usuario en su estado de cuenta
|
|
|
|
-- Refunds
|
|
refunded BOOLEAN DEFAULT false,
|
|
refund_amount DECIMAL(15,2),
|
|
refund_reason TEXT,
|
|
refunded_at TIMESTAMPTZ,
|
|
|
|
-- Metadata
|
|
metadata JSONB DEFAULT '{}',
|
|
|
|
-- Error handling
|
|
failure_code VARCHAR(100),
|
|
failure_message TEXT,
|
|
|
|
-- Timestamps
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
succeeded_at TIMESTAMPTZ,
|
|
failed_at TIMESTAMPTZ,
|
|
|
|
-- Constraints
|
|
CONSTRAINT positive_amount CHECK (amount > 0),
|
|
CONSTRAINT positive_refund CHECK (refund_amount IS NULL OR refund_amount > 0),
|
|
CONSTRAINT refund_lte_amount CHECK (refund_amount IS NULL OR refund_amount <= amount),
|
|
CONSTRAINT refunded_has_data CHECK (
|
|
(refunded = false AND refund_amount IS NULL AND refunded_at IS NULL) OR
|
|
(refunded = true AND refund_amount IS NOT NULL AND refunded_at IS NOT NULL)
|
|
),
|
|
CONSTRAINT succeeded_has_timestamp CHECK (
|
|
(status = 'succeeded' AND succeeded_at IS NOT NULL) OR
|
|
(status != 'succeeded')
|
|
),
|
|
CONSTRAINT failed_has_data CHECK (
|
|
(status = 'failed' AND failed_at IS NOT NULL) OR
|
|
(status != 'failed')
|
|
)
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX idx_payments_user_id ON financial.payments(user_id);
|
|
CREATE INDEX idx_payments_subscription_id ON financial.payments(subscription_id) WHERE subscription_id IS NOT NULL;
|
|
CREATE INDEX idx_payments_invoice_id ON financial.payments(invoice_id) WHERE invoice_id IS NOT NULL;
|
|
CREATE INDEX idx_payments_status ON financial.payments(status);
|
|
CREATE INDEX idx_payments_stripe_intent ON financial.payments(stripe_payment_intent_id) WHERE stripe_payment_intent_id IS NOT NULL;
|
|
CREATE INDEX idx_payments_created_at ON financial.payments(created_at DESC);
|
|
CREATE INDEX idx_payments_user_created ON financial.payments(user_id, created_at DESC);
|
|
CREATE INDEX idx_payments_payment_method ON financial.payments(payment_method);
|
|
CREATE INDEX idx_payments_refunded ON financial.payments(refunded) WHERE refunded = true;
|
|
|
|
-- Comments
|
|
COMMENT ON TABLE financial.payments IS 'Payment transaction records with Stripe integration';
|
|
COMMENT ON COLUMN financial.payments.stripe_payment_intent_id IS 'Stripe PaymentIntent ID';
|
|
COMMENT ON COLUMN financial.payments.payment_method IS 'Payment method used: card, bank_transfer, crypto, etc.';
|
|
COMMENT ON COLUMN financial.payments.statement_descriptor IS 'Text shown on customer bank statement';
|
|
COMMENT ON COLUMN financial.payments.wallet_transaction_id IS 'Related wallet transaction if payment funds a wallet';
|
|
COMMENT ON COLUMN financial.payments.metadata IS 'Additional payment metadata and context';
|