> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.coinflow.cash/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server.

# Handling Failed First Payments

## Overview

When a customer attempts to subscribe to a plan, the first payment is processed immediately. If this initial payment fails, the subscription is not created. Understanding how to handle these failures is crucial for providing a smooth customer experience and maximizing successful conversions.

## How First Payment Works

### The Subscription Creation Flow

1. **Customer submits** subscription purchase
2. **First payment is processed** immediately
3. **If payment succeeds**: Subscription is created with `Active` status
4. **If payment fails**: Subscription is **not created**, and an error is returned

> **Important**: Unlike recurring payments, if the first payment fails, no subscription record is created. The customer must retry the entire subscription purchase process.

## Common Failure Reasons

### Payment Method Issues

| Error                         | Description                               | Customer Action                           |
| ----------------------------- | ----------------------------------------- | ----------------------------------------- |
| **Insufficient Funds**        | Not enough money in account               | Add funds or try different payment method |
| **Card Declined**             | Issuing bank declined the transaction     | Contact bank or use different card        |
| **Invalid Card Details**      | Incorrect card number, CVV, or expiration | Re-enter correct card information         |
| **Expired Card**              | Card has passed expiration date           | Use a different, valid card               |
| **AVS Mismatch**              | Address doesn't match card on file        | Enter correct billing address             |
| **3DS Authentication Failed** | Customer failed 3D Secure challenge       | Retry 3DS authentication                  |

### Account Issues

| Error                         | Description                    | Customer Action                         |
| ----------------------------- | ------------------------------ | --------------------------------------- |
| **Bank Account Not Verified** | ACH account needs verification | Complete account verification via Plaid |
| **Account Closed**            | Bank account has been closed   | Use different account                   |
| **ACH Not Supported**         | Bank doesn't support ACH       | Use card payment instead                |

### Technical Issues

| Error                   | Description                            | Action                             |
| ----------------------- | -------------------------------------- | ---------------------------------- |
| **Network Timeout**     | Connection to payment processor failed | Retry the subscription purchase    |
| **Invalid Session Key** | Authentication token expired           | Generate new session key and retry |
| **Plan Not Found**      | Subscription plan doesn't exist        | Verify plan code is correct        |

## Error Response Format

When first payment fails, you'll receive an error response:

```json
{
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "Payment declined: Insufficient funds",
    "details": {
      "paymentMethod": "card",
      "declineCode": "insufficient_funds",
      "canRetry": true
    }
  }
}
```

## Handling Failures in Your Application

### Using Prebuilt UI

The `CoinflowPurchase` component automatically handles errors:

```javascript
<CoinflowPurchase
  sessionKey={sessionKey}
  merchantId={merchantId}
  planCode={planCode}
  env="sandbox"
  onSuccess={(data) => {
    // Subscription created successfully
    console.log('Subscription ID:', data.subscriptionId);
    redirectToSuccessPage();
  }}
  onError={(error) => {
    // First payment failed - subscription not created
    console.error('Subscription failed:', error);

    // Display user-friendly error message
    if (error.details?.declineCode === 'insufficient_funds') {
      showError('Payment declined due to insufficient funds. Please try a different payment method.');
    } else if (error.details?.declineCode === 'card_declined') {
      showError('Your card was declined. Please contact your bank or try a different card.');
    } else {
      showError('Unable to process payment. Please try again or use a different payment method.');
    }
  }}
/>
```

### Using API Integration

Handle errors in your custom implementation:

```javascript
async function createSubscription(planCode, paymentDetails) {
  try {
    const response = await fetch(
      'https://api-sandbox.coinflow.cash/api/subscription/{merchantId}/subscribers/card',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-coinflow-auth-session-key': sessionKey
        },
        body: JSON.stringify({
          planCode,
          card: paymentDetails,
          chargebackProtectionData: [/* ... */]
        })
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw error;
    }

    const subscriptionId = await response.text();
    return { success: true, subscriptionId };

  } catch (error) {
    return {
      success: false,
      error: error.error || error,
      canRetry: error.error?.details?.canRetry !== false
    };
  }
}

// Usage
const result = await createSubscription('premium-plan', cardDetails);

if (!result.success) {
  // Handle failure
  handleSubscriptionError(result.error);
} else {
  // Success - subscription created
  showSuccessMessage(result.subscriptionId);
}
```

## User Experience Best Practices

### Provide Clear, Actionable Error Messages

Always show specific error messages that help customers understand what went wrong and how to fix it:

```javascript
function getErrorMessage(errorCode) {
  const messages = {
    insufficient_funds: {
      title: 'Insufficient Funds',
      message: 'Your payment method doesn\'t have enough funds to complete this purchase.',
      action: 'Please add funds to your account or try a different payment method.'
    },
    card_declined: {
      title: 'Card Declined',
      message: 'Your card issuer declined this transaction.',
      action: 'Please contact your bank for more information or use a different card.'
    },
    expired_card: {
      title: 'Card Expired',
      message: 'The card you entered has expired.',
      action: 'Please use a different card with a valid expiration date.'
    },
    invalid_cvv: {
      title: 'Invalid Security Code',
      message: 'The CVV/security code you entered is incorrect.',
      action: 'Please check your card and re-enter the 3-digit code on the back.'
    },
    authentication_failed: {
      title: 'Authentication Failed',
      message: 'Card authentication was not completed successfully.',
      action: 'Please try again and complete the verification with your bank.'
    },
    default: {
      title: 'Payment Failed',
      message: 'We were unable to process your payment.',
      action: 'Please try again or contact support if the problem persists.'
    }
  };

  return messages[errorCode] || messages.default;
}
```

### Implement a Smooth Retry Experience

Make it easy for customers to try again after a failed payment:

```javascript
function SubscriptionPurchaseFlow() {
  const [attempt, setAttempt] = useState(0);
  const [error, setError] = useState(null);

  const handlePurchase = async (paymentMethod) => {
    try {
      const result = await createSubscription(planCode, paymentMethod);

      if (result.success) {
        // Success!
        onSubscriptionCreated(result.subscriptionId);
      } else {
        // Failed
        setError(result.error);
        setAttempt(prev => prev + 1);
      }
    } catch (err) {
      setError(err);
    }
  };

  return (
    <div>
      {error && (
        <ErrorAlert error={error} attempt={attempt}>
          <button onClick={() => setError(null)}>Try Again</button>
          <button onClick={switchPaymentMethod}>Use Different Payment Method</button>
        </ErrorAlert>
      )}

      <PaymentForm onSubmit={handlePurchase} />
    </div>
  );
}
```

### Offer Multiple Payment Options

Give customers flexibility to choose their preferred payment method:

```javascript
function PaymentMethodSelector({ onSelect }) {
  return (
    <div>
      <h3>Choose Payment Method</h3>
      <button onClick={() => onSelect('card')}>
        Credit/Debit Card
      </button>
      <button onClick={() => onSelect('ach')}>
        Bank Account (ACH)
      </button>
      <button onClick={() => onSelect('saved')}>
        Use Saved Payment Method
      </button>
    </div>
  );
}
```

## Monitoring and Analytics

Track failed first payments to identify patterns:

```javascript
// Log failed subscription attempts
analytics.track('Subscription Purchase Failed', {
  planCode: 'premium-plan',
  paymentMethod: 'card',
  errorCode: error.code,
  declineReason: error.details?.declineCode,
  attemptNumber: attempt,
  userId: customerId,
  timestamp: new Date().toISOString()
});
```

### Key Metrics to Track

* **Failure Rate**: Percentage of first payments that fail
* **Failure Reasons**: Most common decline codes
* **Retry Success Rate**: How often customers succeed on retry
* **Payment Method Performance**: Success rate by payment type
* **Conversion After Failure**: Do customers eventually subscribe?

## Webhooks for Failed Attempts

While subscriptions aren't created for failed first payments, you can still log these attempts:

```javascript
// Your webhook handler
app.post('/webhooks/coinflow', (req, res) => {
  const event = req.body;

  if (event.event === 'subscription.payment_failed') {
    const { customerId, planCode, errorCode } = event.data;

    // Log the failed attempt
    await db.failedSubscriptions.create({
      customerId,
      planCode,
      errorCode,
      attemptedAt: new Date()
    });

    // Send follow-up email
    if (errorCode === 'insufficient_funds') {
      await sendEmail(customerId, {
        subject: 'Complete Your Subscription',
        body: 'We noticed you tried to subscribe but the payment didn\'t go through...'
      });
    }
  }

  res.sendStatus(200);
});
```

## Recovery Strategies

### Send Targeted Follow-up Emails

After a failed payment attempt, send personalized emails to help customers complete their subscription:

```javascript
async function sendRecoveryEmail(customerId, failureReason) {
  const templates = {
    insufficient_funds: {
      subject: 'Complete Your Premium Subscription',
      body: `
        Hi there,

        We noticed you tried to subscribe to our Premium plan, but the payment couldn't be processed due to insufficient funds.

        We'd love to have you as a subscriber! Here's what you can do:

        1. Add funds to your account
        2. Try a different payment method
        3. Use a credit card instead of bank account

        [Complete Your Subscription]

        If you have questions, reply to this email!
      `
    },
    card_declined: {
      subject: 'Let\'s Get Your Subscription Started',
      body: `
        Hi there,

        Your card issuer declined the subscription payment. This can happen for various reasons:

        - Daily spending limit reached
        - International transaction restrictions
        - Suspicious activity flags

        Try these solutions:

        1. Contact your bank to authorize the charge
        2. Use a different card
        3. Try again in a few hours

        [Try Again]
      `
    }
  };

  const template = templates[failureReason] || templates.card_declined;
  await sendEmail(customerId, template);
}
```

### Retargeting Campaigns

Set up retargeting for failed subscription attempts:

* Show ads reminding them of the subscription benefits
* Offer a limited-time discount
* Highlight social proof and testimonials
* Make it easy to retry with one click

## Related Resources

* [How Subscriptions Work](/guides/subscriptions/overview/how-subscriptions-work)
* [Subscription Webhooks](/guides/subscriptions/implementation-methods/api-integration#webhooks)
* [Testing Credit Card Purchases](/guides/checkout/testing/testing-credit-cards)
* [API Reference - Create Subscription](/api-reference/api-reference/subscription/create-subscription-card)