Skip to content

Organizations API

Bridge Payments supports organization-level payments with role-based access control, allowing businesses to manage payments, customers, and subscriptions at the organization level with granular permissions.

Organization Support Status

APIOrganization SupportStatusPermissions
Subscriptions✅ Full SupportCompletecanManageSubscriptions
Customers✅ Full SupportCompletecanManagePayments
Addresses✅ Full SupportNEWcanManageAddresses
Payments✅ Full SupportNEWcanManagePayments
Payment Methods✅ Full SupportNEWcanManagePaymentMethods

All APIs Now Support Organizations!

As of the latest update, all Bridge Payments APIs now have complete organization support with role-based access control.

Role-Based Access Control

Organization Roles

Bridge Payments implements a comprehensive role-based permission system:

RolePermissionsDescription
OwnerAll permissions + canDeleteOrganizationOrganization creator, full control
AdminAll permissions except deleteFull management access
BillingcanManagePayments, canManageSubscriptions, canManagePaymentMethods, canManageAddressesFinancial operations only
MemberRead-only accessCan view organization resources

Permission Matrix

PermissionOwnerAdminBillingMember
canManagePayments
canManageSubscriptions
canManagePaymentMethods
canManageAddresses
canManageMembers
canDeleteOrganization

How Organizations Work

Organization Context

When a user is authenticated, Bridge Payments automatically detects their organization from the Flowless session:

json
{
  "user": {
    "id": "user_123",
    "email": "[email protected]",
    "organizationId": "org_456789",
    "role": "billing"
  }
}

Organization-Scoped Requests

You can explicitly specify an organization ID in requests:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_org_123",
    "organization_id": "org_456789",
    "total_cents": 49999,
    "currency": "USD",
    "billing_interval": "yearly",
    "payment_method_id": "pm_org_card"
  }'

Auto-Detection

If organization_id is not provided, Bridge Payments uses the user's organization from their session:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_org_123",
    "total_cents": 49999,
    "currency": "USD",
    "billing_interval": "yearly",
    "payment_method_id": "pm_org_card"
  }'

Subscriptions (Full Support)

Create Organization Subscription

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_org_123",
    "organization_id": "org_456789",
    "total_cents": 49999,
    "currency": "USD",
    "billing_interval": "monthly",
    "payment_method_id": "pm_org_card",
    "concept": "Enterprise Plan"
  }'

Response:

json
{
  "success": true,
  "data": {
    "id": "sub_123",
    "customer_id": "cust_org_123",
    "organization_id": "org_456789",
    "user_id": null,
    "status": "active",
    "total_cents": 49999,
    "currency": "USD",
    "billing_interval": "monthly",
    "concept": "Enterprise Plan",
    "created_at": "2025-01-15T10:30:00Z"
  }
}

List Organization Subscriptions

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_abc123"

Response:

json
{
  "success": true,
  "data": [
    {
      "id": "sub_123",
      "organization_id": "org_456789",
      "status": "active",
      "total_cents": 49999,
      "billing_interval": "monthly"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 1
  }
}

Customers (Full Support)

Create Organization Customer

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/customers" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "provider_id": "stripe",
    "organization_id": "org_456789",
    "email": "[email protected]",
    "name": "Company Inc",
    "phone": "+1234567890"
  }'

Response:

json
{
  "success": true,
  "data": {
    "id": "cust_123",
    "organization_id": "org_456789",
    "user_id": null,
    "provider_id": "stripe",
    "provider_customer_id": "cus_stripe_xyz",
    "email": "[email protected]",
    "name": "Company Inc",
    "created_at": "2025-01-15T10:30:00Z"
  }
}

Access Control

Organization Access Logic

Users can access resources via:

  1. Personal Access: resource.user_id === user.id
  2. Organization Access: resource.organization_id === user.organizationId
typescript
const hasAccess = 
  subscription.user_id === userId || 
  (userOrgId && subscription.organization_id === userOrgId);

Example Access Control

bash
# User can access their own subscription
GET /bridge-payment/subscriptions/sub_personal_123

# User can access organization subscription
GET /bridge-payment/subscriptions/sub_org_456

# User CANNOT access other organization's subscription
GET /bridge-payment/subscriptions/sub_other_org_789  # 403 Forbidden

Guest Subscriptions for Organizations

Organizations can create guest subscriptions:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_guest_123",
    "organization_id": "org_456789",
    "total_cents": 2000,
    "currency": "USD",
    "billing_interval": "monthly",
    "payment_method_id": "pm_guest_card",
    "is_guest_subscription": true,
    "guest_data": {
      "email": "[email protected]",
      "name": "Guest User"
    }
  }'

Permission Validation

Automatic Permission Checks

Bridge Payments automatically validates permissions when creating resources:

bash
# ✅ Billing role can create payment
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments" \
  -H "X-Session-ID: session_billing_user" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "org_456789",
    "amount_cents": 10000,
    "currency": "USD"
  }'

# ❌ Member role CANNOT create payment (403 Forbidden)
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments" \
  -H "X-Session-ID: session_member_user" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "org_456789",
    "amount_cents": 10000,
    "currency": "USD"
  }'

Error Response:

json
{
  "success": false,
  "error": "Insufficient permissions to manage payments for this organization",
  "code": "INSUFFICIENT_PERMISSIONS"
}

Resource Access Control

Users can access resources via:

  1. Personal Access: resource.user_id === user.id
  2. Organization Access: User is a member of resource.organization_id with appropriate permissions
typescript
// Automatic access verification
const hasAccess =
  payment.user_id === userId ||
  (await verifyOrganizationAccess(userId, payment.organization_id, 'canManagePayments'));

Cache System

Performance Optimization

Bridge Payments uses an LRU cache for organization membership data:

  • Cache Size: 50,000 memberships
  • TTL: 5 minutes
  • Hit Rate: ~80% (typical)
  • Future: Designed for hybrid cache (Redis + LRU)

Cache Invalidation

Cache is automatically cleared when:

  • Organization membership changes
  • User roles are updated
  • Manual cache clear via admin API
bash
# Clear organization cache (admin only)
curl -X POST "https://your-instance.pubflow.com/bridge-payment/admin/cache/clear" \
  -H "X-Session-ID: session_admin" \
  -H "Content-Type: application/json" \
  -d '{
    "cache_type": "organization_membership"
  }'

Examples by Role

Owner Example

bash
# Owner can do everything
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_owner" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "org_456789",
    "customer_id": "cust_123",
    "total_cents": 49999,
    "currency": "USD",
    "billing_interval": "monthly"
  }'

Billing Role Example

bash
# Billing can manage payments and subscriptions
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payment-methods" \
  -H "X-Session-ID: session_billing" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "org_456789",
    "type": "card",
    "card_token": "tok_visa"
  }'

Member Example

bash
# Member can only read (list/get)
curl -X GET "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_member"

# Member CANNOT create (403 Forbidden)
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "X-Session-ID: session_member" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "org_456789",
    "customer_id": "cust_123",
    "total_cents": 49999
  }'

Organizations Management API

Bridge Payments provides a complete API for managing organizations, members, and permissions.

Complete Guide Available

For a comprehensive guide on using organizations, see the Organizations Guide.

Base URL

All organization management endpoints are under:

/bridge-payment/organizations

Organization CRUD Operations

Create Organization

Create a new organization. The authenticated user automatically becomes the owner.

Endpoint: POST /bridge-payment/organizations

Authentication: Required (no guests)

Request Body:

json
{
  "name": "Acme Corporation",
  "business_email": "[email protected]",
  "business_phone": "+1-555-0123",
  "tax_id": "12-3456789",
  "address": "123 Main St, San Francisco, CA 94105"
}

Response:

json
{
  "success": true,
  "data": {
    "id": "org_abc123",
    "name": "Acme Corporation",
    "owner_user_id": "user_xyz789",
    "business_email": "[email protected]",
    "business_phone": "+1-555-0123",
    "tax_id": "12-3456789",
    "address": "123 Main St, San Francisco, CA 94105",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T10:30:00Z"
  }
}

Example:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/organizations" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corporation",
    "business_email": "[email protected]",
    "business_phone": "+1-555-0123",
    "tax_id": "12-3456789",
    "address": "123 Main St, San Francisco, CA 94105"
  }'

List Organizations

Get all organizations where the authenticated user is a member.

Endpoint: GET /bridge-payment/organizations

Authentication: Required

Query Parameters:

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items per page (max 100)

Response:

json
{
  "success": true,
  "data": [
    {
      "id": "org_abc123",
      "name": "Acme Corporation",
      "business_email": "[email protected]",
      "created_at": "2025-01-15T10:30:00Z",
      "role": "owner"
    },
    {
      "id": "org_def456",
      "name": "Tech Startup Inc",
      "business_email": "[email protected]",
      "created_at": "2025-01-10T08:15:00Z",
      "role": "billing"
    }
  ],
  "meta": {
    "pagination": {
      "total": 2,
      "page": 1,
      "pageSize": 20,
      "totalPages": 1
    }
  }
}

Example:

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/organizations?page=1&limit=20" \
  -H "X-Session-ID: session_abc123"

Get Organization

Get details of a specific organization.

Endpoint: GET /bridge-payment/organizations/:id

Authentication: Required (must be a member)

Response:

json
{
  "success": true,
  "data": {
    "id": "org_abc123",
    "name": "Acme Corporation",
    "owner_user_id": "user_xyz789",
    "business_email": "[email protected]",
    "business_phone": "+1-555-0123",
    "tax_id": "12-3456789",
    "address": "123 Main St, San Francisco, CA 94105",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T10:30:00Z",
    "your_role": "owner"
  }
}

Example:

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123" \
  -H "X-Session-ID: session_abc123"

Update Organization

Update organization details. Only the owner can update.

Endpoint: PUT /bridge-payment/organizations/:id

Authentication: Required (owner only)

Request Body:

json
{
  "name": "Acme Corporation Ltd",
  "business_email": "[email protected]",
  "business_phone": "+1-555-0199",
  "tax_id": "12-3456789",
  "address": "456 Market St, San Francisco, CA 94105"
}

Response:

json
{
  "success": true,
  "data": {
    "id": "org_abc123",
    "name": "Acme Corporation Ltd",
    "owner_user_id": "user_xyz789",
    "business_email": "[email protected]",
    "business_phone": "+1-555-0199",
    "tax_id": "12-3456789",
    "address": "456 Market St, San Francisco, CA 94105",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T11:45:00Z"
  }
}

Example:

bash
curl -X PUT "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corporation Ltd",
    "business_email": "[email protected]"
  }'

Delete Organization

Delete an organization. Only the owner can delete. This will CASCADE delete all organization members and related resources.

Endpoint: DELETE /bridge-payment/organizations/:id

Authentication: Required (owner only)

Response:

json
{
  "success": true,
  "message": "Organization deleted successfully"
}

Example:

bash
curl -X DELETE "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123" \
  -H "X-Session-ID: session_abc123"

Member Management

List Members

Get all members of an organization.

Endpoint: GET /bridge-payment/organizations/:id/members

Authentication: Required (must be a member)

Query Parameters:

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items per page (max 100)
rolestring-Filter by role (owner, admin, billing, member)

Response:

json
{
  "success": true,
  "data": [
    {
      "id": "orguser_123",
      "user_id": "user_xyz789",
      "role": "owner",
      "created_at": "2025-01-15T10:30:00Z",
      "user_name": "John",
      "user_last_name": "Doe",
      "user_email": "[email protected]",
      "user_picture": "https://example.com/avatar.jpg"
    },
    {
      "id": "orguser_456",
      "user_id": "user_abc123",
      "role": "billing",
      "created_at": "2025-01-16T14:20:00Z",
      "user_name": "Jane",
      "user_last_name": "Smith",
      "user_email": "[email protected]",
      "user_picture": null
    }
  ],
  "meta": {
    "pagination": {
      "total": 2,
      "page": 1,
      "pageSize": 20,
      "totalPages": 1
    }
  }
}

Example:

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123/members?role=billing" \
  -H "X-Session-ID: session_abc123"

Add Member

Add a new member to the organization. Only the owner can add members.

Endpoint: POST /bridge-payment/organizations/:id/members

Authentication: Required (owner only)

Request Body:

json
{
  "email": "[email protected]",
  "role": "billing"
}

Validation:

  • Email must exist in the users table
  • User cannot already be a member
  • Role must be: admin, billing, or member (cannot add as owner)

Response:

json
{
  "success": true,
  "data": {
    "id": "orguser_789",
    "organization_id": "org_abc123",
    "user_id": "user_new123",
    "role": "billing",
    "created_at": "2025-01-17T09:00:00Z",
    "updated_at": "2025-01-17T09:00:00Z"
  },
  "message": "Member added successfully"
}

Example:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123/members" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "role": "billing"
  }'

Update Member Role

Update a member's role. Only the owner can update roles.

Endpoint: PUT /bridge-payment/organizations/:id/members/:memberId

Authentication: Required (owner only)

Request Body:

json
{
  "role": "admin"
}

Restrictions:

  • Cannot change owner role
  • Cannot change your own role
  • Role must be: admin, billing, or member

Response:

json
{
  "success": true,
  "data": {
    "id": "orguser_789",
    "organization_id": "org_abc123",
    "user_id": "user_new123",
    "role": "admin",
    "created_at": "2025-01-17T09:00:00Z",
    "updated_at": "2025-01-17T10:30:00Z"
  },
  "message": "Member role updated successfully"
}

Example:

bash
curl -X PUT "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123/members/orguser_789" \
  -H "X-Session-ID: session_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "admin"
  }'

Remove Member

Remove a member from the organization. Only the owner can remove members.

Endpoint: DELETE /bridge-payment/organizations/:id/members/:memberId

Authentication: Required (owner only)

Restrictions:

  • Cannot remove owner
  • Cannot remove yourself (use leave endpoint)

Response:

json
{
  "success": true,
  "message": "Member removed successfully"
}

Example:

bash
curl -X DELETE "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123/members/orguser_789" \
  -H "X-Session-ID: session_abc123"

Leave Organization

Leave an organization. Any member except the owner can leave.

Endpoint: POST /bridge-payment/organizations/:id/leave

Authentication: Required (cannot be owner)

Response:

json
{
  "success": true,
  "message": "You have left the organization successfully"
}

Example:

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/organizations/org_abc123/leave" \
  -H "X-Session-ID: session_abc123"

Error Responses

Common Errors

401 Unauthorized:

json
{
  "success": false,
  "error": "Authentication required"
}

403 Forbidden:

json
{
  "success": false,
  "error": "Only the organization owner can perform this action"
}

404 Not Found:

json
{
  "success": false,
  "error": "User not found with this email"
}

400 Bad Request:

json
{
  "success": false,
  "error": "User is already a member of this organization"
}

Security Features

Authentication

  • All endpoints require authentication (no guest access)
  • Session validation on every request
  • User context verification

Authorization

  • Role-based access control (RBAC)
  • Owner-only operations (update, delete, manage members)
  • Permission validation before operations
  • Resource access verification

Input Validation

  • Zod schema validation for all inputs
  • Email normalization to lowercase
  • String length limits
  • Role whitelist validation

Data Protection

  • Organization membership verification
  • Prevents cross-organization access
  • Cache invalidation after changes
  • Database transactions for atomicity

Business Logic Security

  • Cannot create multiple owners
  • Cannot remove owner
  • Cannot change owner role
  • Cannot change your own role
  • Owner cannot leave (must delete org)

Next Steps