Skip to main content
Migo Docs

Payment Methods

Each subscription has one default payment method plus any number of additional methods on file. Scheduled charges try the default first and fall back to the other methods on failure.

Verify a card​

Before a card is attached or a subscription is created, the card is verified against an existing transaction.

POST /v1/subscriptions/verify-card requires transactionUid, processor, and cardInfo. It tokenizes the card via the processor, pre-authorizes it against the transaction, then reverts that authorization. Optionally, with shouldCreateSubscription: true (and planUid), it also creates the subscription as part of the same flow.

curl -X POST https://mw.migopayments.com/v1/subscriptions/verify-card \
-H "Authorization: Bearer <middleware-jwt>" \
-H "Content-Type: application/json" \
-d '{
"uid": "<transaction-uid>",
"processor": "<processor-slug>",
"cardInfo": { "...": "card data tokenized by the processor" },
"shouldCreateSubscription": false,
"planUid": "<plan-uid>"
}'

There is no { cardId, currency } body, no fixed $1 auth-and-void, and no valid: true response shape. The handler returns { success, message, data }.

Add a payment method​

POST /v1/subscriptions/payment-methods is normally invoked internally after verify-card. Its body nests the card data under tokenizeData:

curl -X POST https://mw.migopayments.com/v1/subscriptions/payment-methods \
-H "Authorization: Bearer <middleware-jwt>" \
-H "Content-Type: application/json" \
-d '{
"tokenizeData": {
"userId": "<userId>",
"clientId": "<clientId>",
"processorId": "<processorId>",
"cardId": "<cardId>",
"alias": "Visa ending 4242"
}
}'

The response is { success, message, data }. There are no subUid or isDefault inputs and no cardLast4 / brand / addedAt response fields.

Set a different card as default​

curl -X PUT https://mw.migopayments.com/v1/subscriptions/payment-methods/set-default \
-H "Authorization: Bearer <middleware-jwt>" \
-H "Content-Type: application/json" \
-d '{
"userId": "<userId>",
"clientId": "<clientId>",
"subscriptionId": "sub_01HAAA",
"paymentMethodId": "pm_01HBBB"
}'

All four fields (userId, clientId, subscriptionId, paymentMethodId) are required.

Remove a payment method​

DELETE /v1/subscriptions/payment-methods requires both methodId and subId query parameters (returns 400 if either is missing).

curl -X DELETE "https://mw.migopayments.com/v1/subscriptions/payment-methods?methodId=pm_01HBBB&subId=sub_01HAAA" \
-H "Authorization: Bearer <middleware-jwt>"
warning

You cannot delete the default payment method of an active subscription. Set a new default first, then delete the old one.

Failover behavior​

When a scheduled charge fails on the default method:

  1. Migo iterates the other payment methods on file (in the order returned by the payment-method store) and attempts each.
  2. First success wins; the subscription stays active.
  3. If all methods fail and retries are exhausted, the subscription becomes inactive.

Retry behavior is governed per-plan by dailyAttempts / intervalAttempt (plus optional graceDays) β€” see Scheduled charges β†’ Retry schedule.

Expiring-card notifications​

There is no Account Updater integration in this codebase. Card-expiry handling is limited to an email notification: the subscription cron emits a notifyCardExpiration event ahead of a card's expiry (the window is configured per plan via daysNotifyExpiringCard). There is no silent PAN/expiry rotation and no subscription.payment_method.updated event.