# Payment API Testing Guide

Complete guide for testing the Stripe payment flow with Postman and mobile apps.

---

## 📋 Table of Contents

1. [Postman Testing](#postman-testing)
2. [Mobile App Integration](#mobile-app-integration)
3. [Stripe Test Cards](#stripe-test-cards)
4. [Troubleshooting](#troubleshooting)

---

## Postman Testing

### Complete Payment Flow (4 Steps)

#### Step 1: Create Cart
```
POST /api/shop/carts/create
Headers:
  - X-Company-Hash: {{c_hash}}
  - Authorization: Bearer {{token}}
  - Content-Type: application/json

Body:
{
  "product_id": 123,
  "quantity": 1,
  "attributes": {
    "size": "M",
    "color": "red"
  }
}
```

**Response:** 
- Saves `cart_token` automatically to Postman variable
- Returns cart items with pricing

---

#### Step 2: Apply Coupon (Optional)
```
POST /api/shop/apply-coupon
Headers:
  - X-Company-Hash: {{c_hash}}
  - Authorization: Bearer {{token}}

Body:
{
  "coupon_code": "SAVE10",
  "cart_token": "{{cart_token}}"
}
```

**Response:**
- Discount amount calculated
- New total with discount shown

---

#### Step 3: Create Payment Intent
```
POST /api/shop/payment-intent
Headers:
  - X-Company-Hash: {{c_hash}}
  - Authorization: Bearer {{token}}

Query Params:
  - cart_token={{cart_token}}
```

**Response:**
- `client_secret` - For client-side Stripe.js confirmation
- `payment_intent_id` - Auto-saved to Postman ({{payment_intent_id}})
- `amount` - Total amount to charge

---

#### Step 4A: Confirm Payment (PRODUCTION - Mobile Apps)
```
POST /api/shop/payment-confirm
Headers:
  - X-Company-Hash: {{c_hash}}
  - Authorization: Bearer {{token}}

Body:
{
  "payment_intent_id": "{{payment_intent_id}}",
  "cart_token": "{{cart_token}}"
}
```

**⚠️ IMPORTANT:** This endpoint requires the payment method to be confirmed on the **client-side first** using Stripe.js, Stripe.flutter, or equivalent mobile SDK.

---

#### Step 4B: Test Confirm Payment (POSTMAN TESTING ONLY)
```
POST /api/shop/test-payment-confirm
Headers:
  - X-Company-Hash: {{c_hash}}
  - Authorization: Bearer {{token}}

Body:
{
  "payment_intent_id": "{{payment_intent_id}}",
  "cart_token": "{{cart_token}}"
}
```

**✅ This endpoint automatically:**
1. Confirms payment with Stripe test card
2. Creates the order
3. Clears the cart
4. Returns order details

**Use this for:**
- Testing complete flow in Postman
- Development/QA testing
- Integration testing

---

## Mobile App Integration

### Three-Step Payment Flow for Mobile Apps

**Step 1: Create Payment Intent (Backend)**
```javascript
// Your mobile app calls backend
const response = await fetch('{{base_url}}/api/shop/payment-intent?cart_token={{cart_token}}', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer {{token}}',
    'X-Company-Hash': '{{c_hash}}',
    'Content-Type': 'application/json'
  }
});

const data = await response.json();
const { client_secret, payment_intent_id } = data.data;
```

**Step 2: Confirm Payment with Stripe (Client-Side)**

**For Flutter:**
```dart
import 'package:flutter_stripe/flutter_stripe.dart';

final result = await Stripe.instance.confirmPaymentSheetPayment(
  clientSecret: clientSecret,
);

// On success
if (result == null) {
  // Payment confirmed on Stripe servers
  // Now confirm on backend
}
```

**For React Native:**
```javascript
import { useStripe } from '@stripe/stripe-react-native';

const { confirmPaymentSheetPayment } = useStripe();

const { error } = await confirmPaymentSheetPayment();

if (!error) {
  // Payment confirmed - proceed to backend confirmation
}
```

**For Web (Stripe.js):**
```javascript
const { paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
  payment_method: {
    card: cardElement,
    billing_details: { name: 'Customer Name' }
  }
});

if (paymentIntent.status === 'succeeded') {
  // Payment confirmed - proceed to backend confirmation
}
```

**Step 3: Confirm on Backend**
```javascript
// After client-side confirmation succeeds
const confirmResponse = await fetch('{{base_url}}/api/shop/payment-confirm', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer {{token}}',
    'X-Company-Hash': '{{c_hash}}',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    payment_intent_id: paymentIntentId,
    cart_token: cartToken
  })
});

const orderData = await confirmResponse.json();
console.log('Order created:', orderData.data.order_number);
```

---

## Stripe Test Cards

### Valid Test Cards

| Card Number | Expiry | CVC | Result |
|---|---|---|---|
| 4242 4242 4242 4242 | Any future | Any 3 | Success |
| 4000 0025 0000 3155 | Any future | Any 3 | Success (3D Secure) |
| 4000 0000 0000 0002 | Any future | Any 3 | Decline (generic) |
| 4000 0000 0000 9995 | Any future | Any 3 | Decline (insufficient funds) |
| 5555 5555 5555 4444 | Any future | Any 3 | Success (Mastercard) |

### Test Dates
- **Expiry:** Use any date in the future (e.g., 12/25, 12/99)
- **CVC:** Any 3-digit number (e.g., 123)

---

## Troubleshooting

### Error: "Payment not completed. Status: requires_source"

**Cause:** Payment method wasn't confirmed on client-side before calling backend endpoint.

**Solution:** 
1. Ensure you called Stripe.js/Flutter/React Native confirmation on **client-side first**
2. Only call `/api/shop/payment-confirm` after client-side confirmation succeeds
3. For testing, use the **test endpoint** `/api/shop/test-payment-confirm` which handles client confirmation automatically

---

### Error: "Validation failed" (422)

**Missing required fields:**

```json
{
  "payment_intent_id": "Required",
  "cart_token": "Required"
}
```

**Solution:** Include both fields in request body.

---

### Error: "Stripe credentials not configured" (400)

**Cause:** Stripe API key not configured in company settings or PaymentGatewayCredentials.

**Solution:**
1. Check company `stripe_mode` setting (live/test)
2. Check company `live_stripe_secret` or `test_stripe_secret`
3. Or configure PaymentGatewayCredentials with active status and valid keys

---

### Error: "Cart is empty" (400)

**Cause:** No items in cart or all items removed before payment.

**Solution:**
1. Create cart and add items first
2. Verify cart_token is correct
3. Check that items haven't been deleted

---

### Error: "Cart not found" (404)

**Cause:** Invalid or expired cart_token, or cart deleted.

**Solution:**
1. Verify cart_token from cart creation
2. Create new cart if expired
3. Ensure cart exists and hasn't been cleared

---

### Error: "Stripe authentication failed" (401)

**Cause:** Invalid Stripe API key or expired credentials.

**Solution:**
1. Regenerate Stripe API keys from dashboard.stripe.com
2. Update company or PaymentGatewayCredentials with new keys
3. Ensure keys match correct Stripe account

---

### Error: "Stripe connection error" (503)

**Cause:** Network connectivity issue with Stripe API.

**Solution:**
1. Check internet connection
2. Verify Stripe API endpoint is accessible
3. Retry the request after a few seconds
4. Check Stripe status page: status.stripe.com

---

## Performance Notes

- **Cart Creation:** ~100ms
- **Coupon Application:** ~150ms
- **Payment Intent Creation:** ~200-300ms (includes Stripe API call)
- **Payment Confirmation:** ~500-1000ms (includes database transaction)

---

## Security Checklist

✅ Always use HTTPS in production
✅ Store tokens securely on client (never log them)
✅ Validate cart_token and payment_intent_id
✅ Use X-Company-Hash header for company isolation
✅ Verify Bearer token is valid (Sanctum middleware)
✅ Don't expose Stripe secret keys in frontend code
✅ Test with Stripe test mode before going live
✅ Implement proper error logging and monitoring

---

## Questions?

For API documentation, see:
- [Payment API](PAYMENT_API.md) - Complete endpoint reference
- [Cart API](CART_API.md) - Shopping cart operations
- [Checkout API](CHECKOUT_API.md) - Billing/shipping info
- [Coupon API](COUPON_API.md) - Discount codes
