Guides

Guide - Customer Payment Methods

How customers save and manage Maya payment methods in booki-api, including payment preferences and organization-level payment method validation.

Logged-in CUSTOMER users can save a Maya payment method for faster checkout. Guest users always pay one-time. The system also lets customers set a preferred payment type (maya or cash), validated against what the organization has enabled.


Architecture

Payment method fields are stored directly on the user document — no separate collection. This keeps the data model simple since payment methods are user-specific attributes and only CUSTOMER users need them.

User Model Fields

FieldTypeDescription
defaultPaymentMethodIdstring?Internal marker set when a Maya payment method is saved
hasPaymentMethodboolean?Quick flag — true if user has a saved Maya payment method
mayaCustomerIdstring?Maya customer ID, created on first Maya checkout
preferredPaymentMethod"maya" | "cash"?The customer's preferred payment type

preferredPaymentMethod is the type (cash vs Maya), not a reference to a stored card. Both can coexist: a customer can prefer Maya and also have it saved as their payment method.

All payment method endpoints are under /api/v1/users/payment-methods and require CUSTOMER role. Non-customer users receive 403 Forbidden.


Maya Payment Method Flow

Adding a payment method works as follows:

1. Frontend calls POST /api/v1/users/payment-methods/setup
        ↓
2. API sets hasPaymentMethod: true on the user document
        ↓
3. API returns a confirmation message
        ↓
4. On each booking payment, frontend calls POST /api/v1/maya/bookings/:id/checkout-session
        ↓
5. Maya creates the customer entry (mayaCustomerId) on the first checkout

There is no card tokenization or stored card number — Maya handles the checkout flow entirely.


API Endpoints

All endpoints under /api/v1/users/payment-methods.
Auth: Bearer token, CUSTOMER role only.

Setup — Save Maya Payment Method

POST /api/v1/users/payment-methods/setup
Authorization: Bearer <customer_token>

Response (200):

{
  "message": "Payment method preference updated. You will be redirected to Maya Checkout for each payment."
}

List Payment Methods

GET /api/v1/users/payment-methods
Authorization: Bearer <customer_token>

Response (200):

{
  "paymentMethods": [
    {
      "id": "maya-checkout",
      "type": "maya",
      "isDefault": true
    }
  ]
}

Returns an empty paymentMethods array if no payment method is saved.


Delete Payment Method

DELETE /api/v1/users/payment-methods/:paymentMethodId
Authorization: Bearer <customer_token>

Removes the Maya payment method from the user. Sets hasPaymentMethod to false and clears defaultPaymentMethodId.

Response (200):

{ "message": "Payment method deleted." }

Payment Preference Endpoints

Separate from saved payment methods — this manages the customer's preferred type of payment.

# Get current preference
GET /api/v1/users/payment-preference
Authorization: Bearer <customer_token>

# Update preference
PUT /api/v1/users/payment-preference
Authorization: Bearer <customer_token>
Content-Type: application/json

{ "preferredPaymentMethod": "maya" }

Valid values: "maya", "cash"


Organization Payment Method Validation

Organizations control which payment types are available via two flags:

FieldDescription
mayaConnectedEnables online Maya payments
cashConnectedEnables cash on arrival

When creating a booking, the API validates that the customer's preferredPaymentMethod is enabled for the organization. Invalid choices return an error with the list of available methods:

{
  "statusCode": 400,
  "message": "Payment method 'cash' is not available. Available methods: maya"
}

Check Available Methods (Public)

Uses tenant middleware — organizationId is resolved from the X-Tenant header or subdomain, not a URL parameter.

GET /api/v1/organizations/payments/available-methods
X-Tenant: <organization-slug>

Response (200):

{
  "availablePaymentMethods": ["maya", "cash"],
  "mayaEnabled": true,
  "cashEnabled": true
}