Payment Methods

Payment methods allow users to securely save tokenized card details for recurring donations. All sensitive card data is stored with Magpie and only display information is kept in the database.


The Payment Method Model

Properties

  • Name
    id
    Type
    integer
    Description

    Unique identifier for the payment method

  • Name
    user_id
    Type
    integer
    Description

    Foreign key to the user who owns this payment method

  • Name
    payment_gateway
    Type
    string
    Description

    Payment gateway: always "magpie"

  • Name
    gateway_token
    Type
    string
    Description

    Tokenized payment method from the gateway (hidden from API responses)

  • Name
    gateway_customer_id
    Type
    string | null
    Description

    Customer ID on the payment gateway (hidden from API responses)

  • Name
    card_last_four
    Type
    string
    Description

    Last 4 digits of the card for display (max 4 characters)

  • Name
    card_brand
    Type
    string | null
    Description

    Card brand: visa, mastercard, amex, etc.

  • Name
    card_exp_month
    Type
    integer
    Description

    Card expiration month (1-12)

  • Name
    card_exp_year
    Type
    integer
    Description

    Card expiration year (e.g., 2026)

  • Name
    is_default
    Type
    boolean
    Description

    Whether this is the user's default payment method

  • Name
    is_active
    Type
    boolean
    Description

    Whether the payment method is active and usable

  • Name
    created_at
    Type
    timestamp
    Description

    Record creation timestamp

  • Name
    updated_at
    Type
    timestamp
    Description

    Record last update timestamp

Relationships

  • Name
    user
    Type
    User
    Description

    The user who owns this payment method

  • Name
    subscriptions
    Type
    DonationSubscription[]
    Description

    Recurring donation subscriptions using this payment method

Computed Properties

  • Name
    card_display
    Type
    string
    Description

    Formatted display string (e.g., "Visa •••• 4242")

  • Name
    is_expired
    Type
    boolean
    Description

    Whether the card has expired based on expiration date


GET/api/v1/payment-methods

List Payment Methods

Retrieves all active payment methods for the authenticated user, sorted by default status and creation date.

Authentication: Required

Request

curl https://batchmates-v2.revlv.com/api/v1/payment-methods \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "data": [
    {
      "id": 1,
      "payment_gateway": "magpie",
      "card_last_four": "4242",
      "card_brand": "visa",
      "card_exp_month": 12,
      "card_exp_year": 2026,
      "is_default": true,
      "is_active": true,
      "created_at": "2024-01-15T10:00:00.000000Z"
    },
    {
      "id": 2,
      "payment_gateway": "magpie",
      "card_last_four": "5555",
      "card_brand": "mastercard",
      "card_exp_month": 6,
      "card_exp_year": 2025,
      "is_default": false,
      "is_active": true,
      "created_at": "2024-01-10T14:30:00.000000Z"
    }
  ]
}

POST/api/v1/payment-methods

Add Payment Method

Vaults a previously tokenized card source as a saved payment method. Card data must first be tokenized via POST /api/v1/payments/magpie/create-source — this endpoint only accepts the resulting source_id and display metadata. Raw card numbers and CVCs are never accepted here.

Authentication: Required

Request Body

  • Name
    payment_gateway
    Type
    string
    Description

    Must be "magpie"

  • Name
    source_id
    Type
    string
    Description

    Source ID returned from POST /payments/magpie/create-source (e.g. src_abc123xyz)

  • Name
    card_last_four
    Type
    string
    Description

    Last 4 digits from the source response (exactly 4 characters)

  • Name
    card_brand
    Type
    string
    Description

    Card brand from the source response

  • Name
    card_exp_month
    Type
    integer
    Description

    Expiration month from the source response (1–12)

  • Name
    card_exp_year
    Type
    integer
    Description

    Expiration year from the source response

  • Name
    set_as_default
    Type
    boolean
    Description

    Set this as the default payment method. Default: false

Request

{
  "payment_gateway": "magpie",
  "source_id": "src_abc123xyz",
  "card_last_four": "4242",
  "card_brand": "visa",
  "card_exp_month": 12,
  "card_exp_year": 2028,
  "set_as_default": true
}

Response

{
  "success": true,
  "data": {
    "id": 1,
    "payment_gateway": "magpie",
    "card_last_four": "4242",
    "card_brand": "visa",
    "card_exp_month": 12,
    "card_exp_year": 2028,
    "is_default": true
  },
  "message": "Payment method added successfully"
}

Error (Validation)

{
  "message": "The given data was invalid.",
  "errors": {
    "source_id": ["The source id field is required."],
    "payment_gateway": ["The selected payment gateway is invalid."]
  }
}

GET/api/v1/payment-methods/{id}

Get Payment Method

Retrieves details of a specific payment method. Users can only access their own payment methods.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The payment method ID

Request

curl https://batchmates-v2.revlv.com/api/v1/payment-methods/1 \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "data": {
    "id": 1,
    "payment_gateway": "magpie",
    "card_last_four": "4242",
    "card_brand": "visa",
    "card_exp_month": 12,
    "card_exp_year": 2026,
    "is_default": true,
    "is_active": true,
    "created_at": "2024-01-15T10:00:00.000000Z"
  }
}

Error (Unauthorized)

{
  "success": false,
  "message": "Unauthorized"
}

POST/api/v1/payment-methods/{id}/set-default

Set Default Payment Method

Sets a payment method as the user's default. This automatically unsets any existing default payment method.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The payment method ID to set as default

Request

curl -X POST https://batchmates-v2.revlv.com/api/v1/payment-methods/2/set-default \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "message": "Default payment method updated"
}

Error (Unauthorized)

{
  "success": false,
  "message": "Unauthorized"
}

DELETE/api/v1/payment-methods/{id}

Delete Payment Method

Deactivates a payment method. If the method is vaulted (has a gateway_customer_id and gateway_token), the source is detached from the Magpie customer first (best-effort — a Magpie failure does not block deletion). The record is then soft-deactivated by setting is_active to false. Payment methods with active subscriptions cannot be deleted.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The payment method ID to delete

Request

curl -X DELETE https://batchmates-v2.revlv.com/api/v1/payment-methods/2 \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "message": "Payment method removed"
}

Error (Active Subscriptions)

{
  "success": false,
  "message": "Cannot delete payment method with active subscriptions"
}

Security & Tokenization

Card saving uses a two-step tokenization flow so that raw card data never touches Batchmates servers for storage:

  1. Tokenize — Frontend calls POST /api/v1/payments/magpie/create-source with raw card fields. The backend forwards them to Magpie and returns a source_id.
  2. Vault — Frontend calls POST /api/v1/payment-methods with only the source_id and display metadata (last4, brand, expiry). No card number or CVC is accepted at this endpoint.
  3. Attach — Backend creates or reuses a Magpie customer record, attaches the source to it, and saves the PaymentMethod record.
  4. Charge later — Future charges reference the vaulted gateway_customer_id + gateway_token pair.

What's Stored

  • gateway_token — Magpie source ID (src_xxx)
  • ✅ Display info — last 4 digits, brand, expiry month/year
  • ❌ Full card number
  • ❌ CVV / CVC
  • ❌ Raw card data of any kind

Card Expiration

Payment methods automatically track card expiration:

{
  "card_exp_month": 12,
  "card_exp_year": 2026,
  "is_expired": false  // Computed property
}

The system checks if the card has expired by comparing the expiration date with the current date. Expired cards remain in the database but should prompt users to update their payment information.


Default Payment Method

Each user can have one default payment method:

  • Only one payment method can be default at a time
  • Setting a new default automatically unsets the previous one
  • Default payment methods are returned first in listings
  • Used automatically when creating new subscriptions if not specified

Error Responses

  • Name
    422 Validation Error
    Description

    Invalid input data or business rule violation

  • Name
    403 Unauthorized
    Description

    User attempting to access another user's payment method

  • Name
    404 Not Found
    Description

    Payment method not found

Validation Error

{
  "message": "The given data was invalid.",
  "errors": {
    "source_id": ["The source id field is required."],
    "payment_gateway": ["The selected payment gateway is invalid."]
  }
}

Was this page helpful?