> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gosurge.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Methods

> API reference for managing customer payment methods — cards and bank direct debit mandates.

## Overview

Payment methods are stored Paystack authorizations (cards) or direct debit mandates (bank accounts) that Surge uses to collect installment payments automatically.

<Note>
  **Who calls these endpoints?**

  Most merchant integrations do **not** call these endpoints directly. The Surge widget and the Surge consumer app handle payment method collection during checkout.

  These endpoints are relevant to you only if you are:

  * Building a **custom consumer-facing experience** (e.g. a white-label app where customers manage their Surge wallet)
  * Building the **Surge consumer app** itself

  All endpoints require a **customer JWT** (the token for the shopper, not your merchant token). Customers may only access their own payment methods.
</Note>

***

## List Payment Methods

```
GET /api/v1/payment-methods/customers/{customer_id}
Authorization: Bearer <CUSTOMER_JWT>
```

Returns all saved payment methods for the given customer.

**Response**

```json theme={null}
{
  "ok": true,
  "data": [
    {
      "id": "pm_abc123",
      "customer_id": "cust_xyz",
      "type": "card",
      "label": "Visa Card",
      "last4": "4081",
      "is_default": true,
      "created_at": "2026-03-16T10:00:00Z"
    }
  ],
  "total": 1
}
```

***

## List Supported Banks

```
GET /api/v1/payment-methods/banks
Authorization: Bearer <CUSTOMER_JWT>
```

Returns the list of Nigerian banks supported by Paystack for direct debit mandates.

**Response**

```json theme={null}
{
  "ok": true,
  "data": [
    { "name": "Access Bank", "code": "044" },
    { "name": "GTBank", "code": "058" }
  ]
}
```

***

## Add Card — Initialize (Redirect Flow)

```
POST /api/v1/payment-methods/initialize-card
Authorization: Bearer <CUSTOMER_JWT>
```

Initializes a Paystack transaction for card tokenization. Returns an `authorization_url` to redirect the customer to. On completion, Paystack redirects to `callback_url?reference=xxx` and the frontend calls `/verify-card`.

A **₦50 verification charge** (5000 kobo) is applied to confirm the card is active. This amount is refunded after successful verification.

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "callback_url": "https://yourapp.com/payment-return",
  "is_default": true
}
```

**Response**

```json theme={null}
{
  "ok": true,
  "authorization_url": "https://checkout.paystack.com/...",
  "reference": "txn_abc123"
}
```

***

## Add Card — Verify and Save

```
POST /api/v1/payment-methods/verify-card
Authorization: Bearer <CUSTOMER_JWT>
```

After the customer returns from the Paystack redirect, verify the transaction reference and save the card as a payment method.

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "reference": "txn_abc123",
  "is_default": true
}
```

**Response**

```json theme={null}
{
  "ok": true,
  "data": {
    "id": "pm_abc123",
    "customer_id": "cust_xyz",
    "type": "card",
    "label": "Visa Card",
    "last4": "4081",
    "is_default": true,
    "created_at": "2026-03-16T10:00:00Z"
  }
}
```

***

## Add Bank — Initiate Direct Debit Mandate

```
POST /api/v1/payment-methods/customers/{customer_id}/initiate-bank-mandate
Authorization: Bearer <CUSTOMER_JWT>
```

Starts the Paystack direct debit mandate flow. Paystack sends an OTP to the phone number registered to the bank account (via BVN).

**Request**

```json theme={null}
{
  "bank_code": "058",
  "account_number": "0123456789",
  "is_default": true
}
```

**Response — OTP required**

```json theme={null}
{
  "ok": true,
  "next_action": "submit_otp",
  "reference": "txn_abc123",
  "display_text": "Enter the OTP sent to your phone ending in 1234."
}
```

**Response — Web authorization required (open\_url)**

```json theme={null}
{
  "ok": true,
  "next_action": "open_url",
  "reference": "txn_abc123",
  "display_text": "Authorize in the popup window.",
  "url": "https://standard.paystack.co/..."
}
```

Possible `next_action` values: `submit_otp`, `submit_birthday`, `submit_phone`, `open_url`, `success`.

***

## Add Bank — Submit OTP

```
POST /api/v1/payment-methods/bank-mandate/submit-otp
Authorization: Bearer <CUSTOMER_JWT>
```

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "reference": "txn_abc123",
  "otp": "123456",
  "bank_code": "058",
  "bank_name": "GTBank",
  "account_number": "0123456789",
  "is_default": true
}
```

**Response — success**

```json theme={null}
{
  "ok": true,
  "next_action": "success",
  "data": { "id": "pm_abc123", "type": "bank", "label": "GTBank •••• 6789", ... }
}
```

**Response — additional step required**

```json theme={null}
{
  "ok": true,
  "next_action": "submit_birthday",
  "display_text": "Enter your date of birth to complete verification."
}
```

***

## Add Bank — Submit Birthday

```
POST /api/v1/payment-methods/bank-mandate/submit-birthday
Authorization: Bearer <CUSTOMER_JWT>
```

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "reference": "txn_abc123",
  "birthday": "1990-05-15",
  "bank_code": "058",
  "bank_name": "GTBank",
  "account_number": "0123456789",
  "is_default": true
}
```

***

## Add Bank — Submit Phone

```
POST /api/v1/payment-methods/bank-mandate/submit-phone
Authorization: Bearer <CUSTOMER_JWT>
```

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "reference": "txn_abc123",
  "phone": "08012345678",
  "bank_code": "058",
  "bank_name": "GTBank",
  "account_number": "0123456789",
  "is_default": true
}
```

***

## Add Bank — Verify Open URL Mandate

```
POST /api/v1/payment-methods/bank-mandate/verify
Authorization: Bearer <CUSTOMER_JWT>
```

Used after the customer completes the Paystack `open_url` popup flow. Verifies the transaction reference and saves the bank as a payment method.

**Request**

```json theme={null}
{
  "customer_id": "cust_xyz",
  "reference": "txn_abc123",
  "bank_code": "058",
  "bank_name": "GTBank",
  "account_number": "0123456789",
  "is_default": true
}
```

**Response**

```json theme={null}
{
  "ok": true,
  "next_action": "success",
  "data": { "id": "pm_abc123", "type": "bank", "label": "GTBank •••• 6789", ... }
}
```

***

## Set Default Payment Method

```
PUT /api/v1/payment-methods/{method_id}/default
Authorization: Bearer <CUSTOMER_JWT>
```

Marks the given method as the customer's default, clearing the default flag from all other methods.

**Response**

```json theme={null}
{ "ok": true, "message": "Default payment method updated." }
```

***

## Delete Payment Method

```
DELETE /api/v1/payment-methods/{method_id}
Authorization: Bearer <CUSTOMER_JWT>
```

Removes a saved payment method.

**Response**

```json theme={null}
{ "ok": true, "message": "Payment method removed." }
```
