Skip to content

Database schema

payments-hub creates its own tables, all prefixed {wp_prefix}paymenthub_.

Migrations are versioned and run automatically on boot via Migrator. Migration classes live in src/Core/Migrations/Versions/.

Tables

paymenthub_agreements

Stores recurring-payment agreements (mandates) with a payment provider.

Column Type Notes
id INT UNSIGNED AUTO_INCREMENT Primary key
subscription_id INT WooCommerce subscription post ID
customer_id INT WordPress user ID
ext_agreement_id VARCHAR(60) External provider agreement ID (unique)
session_id VARCHAR(100) Active session ID (cleared when agreement confirmed)
session_expires_at DATETIME Session expiry
status ENUM PENDING, ACTIVE, EXPIRED, REJECTED, CANCELED, FAILED, CANCELING
created_at DATETIME
expires_at DATETIME Provider-set expiry. For a Frisbii card, the card's expiry date
payment_link TEXT Redirect URL for agreement creation
provider VARCHAR(30) e.g. mobilepay, frisbii
gateway VARCHAR(30) Which gateway of the provider, e.g. credit_card, paypal
is_default TINYINT(1) Whether this is the subscription's default agreement

paymenthub_payments

Tracks individual payment attempts.

Column Type Notes
id INT UNSIGNED AUTO_INCREMENT Primary key
order_id INT WooCommerce order post ID
subscription_id INT WooCommerce subscription post ID (nullable)
customer_id INT WordPress user ID (nullable)
created_at DATETIME
due_at DATETIME Scheduled charge date
status ENUM AUTHORIZED, FAILED, PENDING, CANCELED, CAPTURED, REFUNDED, PROCESSING, CAPTURING, REFUNDING, CANCELING
provider VARCHAR(30)
gateway VARCHAR(30) Which gateway of the provider
amount DECIMAL(10,2)
payment_link TEXT Redirect URL for payment session
needs_processing TINYINT(1) Queued for Action Scheduler processing
ext_agreement_id VARCHAR(60) Links to provider agreement
ext_payment_id VARCHAR(60) External provider payment ID. For Frisbii the invoice handle — the id charges are addressed by
ext_transaction_id VARCHAR(60) The provider's id for the single charge attempt this row describes. Frisbii adds a transaction per attempt on the same invoice, so several rows can share ext_payment_id
session_id VARCHAR(100) Active session ID
session_expires_at DATETIME

paymenthub_webhooks

Idempotent store for incoming provider webhooks.

Column Type Notes
id BIGINT UNSIGNED AUTO_INCREMENT Primary key
provider VARCHAR(50)
external_id VARCHAR(100) Provider event ID (unique per provider)
payload LONGTEXT Raw JSON payload
status ENUM PENDING, PROCESSED, FAILED, SKIPPED
created_at DATETIME
processed_at DATETIME
last_attempt_at DATETIME

Meta tables

Each entity with meta has two tables: {entity}_meta_keys holds the key names and {entity}_meta_data the values, keyed by parent_id with a foreign key to the entity. So paymenthub_agreements_meta_keys / paymenthub_agreements_meta_data, and the same pair for paymenthub_payments.

Agreement meta is where the card import records its provenance: migrated_from, legacy_quickpay_transaction_id, card_last4 and so on. See Migrations.

ER diagram

erDiagram
    wp_posts["wp_posts (orders/subscriptions)"] {
        bigint ID PK
    }
    wp_users {
        bigint ID PK
    }
    paymenthub_agreements {
        int id PK
        int subscription_id FK
        int customer_id FK
        varchar ext_agreement_id
        varchar session_id
        enum status
        varchar provider
        varchar gateway
        tinyint is_default
    }
    paymenthub_agreements_meta_data {
        int id PK
        int parent_id FK
        int meta_key_id FK
        text meta_value
    }
    paymenthub_payments {
        int id PK
        int order_id FK
        int subscription_id FK
        int customer_id FK
        varchar ext_agreement_id
        varchar ext_payment_id
        varchar ext_transaction_id
        enum status
        varchar provider
        varchar gateway
        decimal amount
    }
    paymenthub_payments_meta_data {
        int id PK
        int parent_id FK
        int meta_key_id FK
        text meta_value
    }
    paymenthub_webhooks {
        bigint id PK
        varchar provider
        varchar external_id
        enum status
        longtext payload
    }

    wp_posts ||--o{ paymenthub_agreements : "subscription_id"
    wp_posts ||--o{ paymenthub_payments : "order_id / subscription_id"
    wp_users ||--o{ paymenthub_agreements : "customer_id"
    wp_users ||--o{ paymenthub_payments : "customer_id"
    paymenthub_agreements ||--o{ paymenthub_agreements_meta_data : "parent_id"
    paymenthub_payments ||--o{ paymenthub_payments_meta_data : "parent_id"