# Payment Status Check & SMS Processing API Documentation

## Overview

This API enables automatic payment verification through SMS processing. When a user submits a top-up request, the system sets the status to `verifying_payment`. The mobile app can read SMS from the device and send it to the API, which automatically verifies and approves the payment if the amount matches.

## Table of Contents

1. [Payment Status Check API](#payment-status-check-api)
2. [SMS Processing API](#sms-processing-api)
3. [WebSocket/Broadcasting](#websocketbroadcasting)
4. [Payment Flow](#payment-flow)
5. [SMS Format Examples](#sms-format-examples)
6. [Error Handling](#error-handling)

---

## Payment Status Check API

### Endpoint
```
POST /api/payment/check-status
```

### Description
After submitting a top-up request, the UI can poll this endpoint to check the current payment status. This endpoint returns the current status and appropriate messages for each status.

### Request Headers
```
Content-Type: application/json
```

### Request Body
```json
{
    "request_id": 1,
    "user_id": 1
}
```

### Request Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `request_id` | integer | Yes | The ID of the top-up request |
| `user_id` | integer | Yes | The ID of the user who made the request |

### Response (Success - 200)

#### Status: `verifying_payment`
```json
{
    "success": true,
    "data": {
        "request_id": 1,
        "status": "verifying_payment",
        "amount": 100.00,
        "final_credited_amount": 110.00,
        "upi_details": {
            "upi_id": "example@paytm",
            "name": "Example UPI"
        },
        "created_at": "2025-12-22T10:00:00.000000Z",
        "updated_at": "2025-12-22T10:00:00.000000Z",
        "message": "Please wait, we are checking the payment status..."
    }
}
```

#### Status: `approved`
```json
{
    "success": true,
    "data": {
        "request_id": 1,
        "status": "approved",
        "amount": 100.00,
        "final_credited_amount": 110.00,
        "upi_details": {
            "upi_id": "example@paytm",
            "name": "Example UPI"
        },
        "created_at": "2025-12-22T10:00:00.000000Z",
        "updated_at": "2025-12-22T10:05:00.000000Z",
        "message": "Payment verified and approved successfully!",
        "user_new_balance": 110.00
    }
}
```

#### Status: `rejected`
```json
{
    "success": true,
    "data": {
        "request_id": 1,
        "status": "rejected",
        "amount": 100.00,
        "final_credited_amount": 110.00,
        "upi_details": {
            "upi_id": "example@paytm",
            "name": "Example UPI"
        },
        "created_at": "2025-12-22T10:00:00.000000Z",
        "updated_at": "2025-12-22T10:05:00.000000Z",
        "message": "Payment request was rejected.",
        "rejection_reason": "Payment verification failed"
    }
}
```

#### Status: `pending`
```json
{
    "success": true,
    "data": {
        "request_id": 1,
        "status": "pending",
        "amount": 100.00,
        "final_credited_amount": 110.00,
        "upi_details": {
            "upi_id": "example@paytm",
            "name": "Example UPI"
        },
        "created_at": "2025-12-22T10:00:00.000000Z",
        "updated_at": "2025-12-22T10:00:00.000000Z",
        "message": "Payment request is pending admin approval."
    }
}
```

### Response (Error - 404)
```json
{
    "success": false,
    "message": "Top-up request not found or does not belong to this user"
}
```

### Response (Error - 422)
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "request_id": ["The request id field is required."],
        "user_id": ["The user id field is required."]
    }
}
```

### Usage Example (JavaScript)
```javascript
// Poll payment status every 3 seconds
const checkPaymentStatus = async (requestId, userId) => {
    const response = await fetch('https://api.alldigtalseva.com/api/payment/check-status', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            request_id: requestId,
            user_id: userId
        })
    });
    
    const data = await response.json();
    
    if (data.success) {
        console.log('Status:', data.data.status);
        console.log('Message:', data.data.message);
        
        // Stop polling if status is approved or rejected
        if (data.data.status === 'approved' || data.data.status === 'rejected') {
            clearInterval(pollInterval);
        }
    }
};

// Start polling
const pollInterval = setInterval(() => {
    checkPaymentStatus(requestId, userId);
}, 3000);
```

---

## SMS Processing API

### Endpoint
```
POST /api/payment/process-sms
```

### Description
The mobile app reads SMS from the device and sends the SMS content to this endpoint. The system parses the SMS to extract the payment amount and UPI ID, then matches it with pending payment requests. If the amount matches, the payment is automatically approved.

### Request Headers
```
Content-Type: application/json
```

### Request Body
```json
{
    "sms_content": "Rs. 100.00 credited to account ending 1234 from UPI: example@paytm",
    "user_id": 1
}
```

### Request Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sms_content` | string | Yes | The full SMS content received from the payment gateway |
| `user_id` | integer | Yes | The ID of the user who made the payment |

### Response (Success - 200)
```json
{
    "success": true,
    "message": "Payment verified and approved successfully!",
    "data": {
        "request_id": 1,
        "status": "approved",
        "amount": 100.00,
        "final_credited_amount": 110.00,
        "user_new_balance": 110.00
    }
}
```

### Response (Error - 400 - No Match)
```json
{
    "success": false,
    "message": "Payment verification failed",
    "data": {
        "request_id": 1,
        "status": "verifying_payment",
        "reasons": [
            "Amount mismatch: Expected ₹100.00, Received ₹50.00"
        ],
        "expected_amount": 100.00,
        "received_amount": 50.00
    }
}
```

### Response (Error - 400 - Parse Failed)
```json
{
    "success": false,
    "message": "Could not parse payment information from SMS"
}
```

### Response (Error - 404)
```json
{
    "success": false,
    "message": "No pending payment request found for this user"
}
```

### Response (Error - 422)
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "sms_content": ["The sms content field is required."],
        "user_id": ["The user id field is required."]
    }
}
```

### Usage Example (Android - Kotlin)
```kotlin
// Read SMS and send to API
fun processPaymentSMS(smsContent: String, userId: Int) {
    val apiService = RetrofitClient.apiService
    
    val request = PaymentSMSRequest(
        sms_content = smsContent,
        user_id = userId
    )
    
    apiService.processSMS(request).enqueue(object : Callback<PaymentSMSResponse> {
        override fun onResponse(
            call: Call<PaymentSMSResponse>,
            response: Response<PaymentSMSResponse>
        ) {
            if (response.isSuccessful && response.body()?.success == true) {
                // Payment approved
                val data = response.body()?.data
                showSuccessMessage("Payment approved! New balance: ₹${data?.user_new_balance}")
            } else {
                // Payment verification failed
                showErrorMessage(response.body()?.message ?: "Payment verification failed")
            }
        }
        
        override fun onFailure(call: Call<PaymentSMSResponse>, t: Throwable) {
            showErrorMessage("Network error: ${t.message}")
        }
    })
}

// SMS Receiver
class PaymentSMSReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val bundle = intent.extras
        if (bundle != null) {
            val pdus = bundle.get("pdus") as Array<*>
            for (pdu in pdus) {
                val sms = SmsMessage.createFromPdu(pdu as ByteArray)
                val messageBody = sms.messageBody
                
                // Check if SMS is from payment gateway (e.g., contains "credited" or "received")
                if (messageBody.contains("credited", ignoreCase = true) || 
                    messageBody.contains("received", ignoreCase = true)) {
                    // Get user ID from SharedPreferences or Session
                    val userId = getUserId()
                    processPaymentSMS(messageBody, userId)
                }
            }
        }
    }
}
```

### Usage Example (iOS - Swift)
```swift
// Read SMS and send to API
func processPaymentSMS(smsContent: String, userId: Int) {
    let url = URL(string: "https://api.alldigtalseva.com/api/payment/process-sms")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let body: [String: Any] = [
        "sms_content": smsContent,
        "user_id": userId
    ]
    
    request.httpBody = try? JSONSerialization.data(withJSONObject: body)
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let data = data {
            if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
                if let success = json["success"] as? Bool, success {
                    // Payment approved
                    if let data = json["data"] as? [String: Any] {
                        let newBalance = data["user_new_balance"] as? Double ?? 0
                        DispatchQueue.main.async {
                            self.showSuccessMessage("Payment approved! New balance: ₹\(newBalance)")
                        }
                    }
                } else {
                    // Payment verification failed
                    let message = json["message"] as? String ?? "Payment verification failed"
                    DispatchQueue.main.async {
                        self.showErrorMessage(message)
                    }
                }
            }
        }
    }.resume()
}
```

---

## WebSocket/Broadcasting

### Overview
When a payment is verified and approved via SMS, the system broadcasts a WebSocket event to notify the frontend in real-time. This eliminates the need for constant polling.

### Channel
```
private-payment-status.{userId}
```

### Event Name
```
payment.status.updated
```

### Event Data
```json
{
    "request_id": 1,
    "status": "approved",
    "amount": 100.00,
    "final_credited_amount": 110.00,
    "user_id": 1,
    "updated_at": "2025-12-22T10:05:00.000000Z"
}
```

### Setup

1. **Configure Broadcasting Driver** in `.env`:
```env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your_app_id
PUSHER_APP_KEY=your_app_key
PUSHER_APP_SECRET=your_app_secret
PUSHER_APP_CLUSTER=your_cluster
```

Or use Redis:
```env
BROADCAST_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
```

2. **Install Pusher Client** (for web):
```bash
npm install pusher-js
```

3. **Connect to WebSocket** (JavaScript):
```javascript
import Pusher from 'pusher-js';

// Initialize Pusher
const pusher = new Pusher('your_app_key', {
    cluster: 'your_cluster',
    authEndpoint: 'https://api.alldigtalseva.com/broadcasting/auth',
    auth: {
        headers: {
            'Authorization': 'Bearer ' + userToken // Sanctum token
        }
    }
});

// Subscribe to payment status channel
const channel = pusher.subscribe('private-payment-status.' + userId);

// Listen for payment status updates
channel.bind('payment.status.updated', function(data) {
    console.log('Payment status updated:', data);
    
    if (data.status === 'approved') {
        showSuccessMessage('Payment approved! Amount: ₹' + data.final_credited_amount);
        updateWalletBalance(data.final_credited_amount);
    } else if (data.status === 'rejected') {
        showErrorMessage('Payment was rejected');
    }
});
```

### Authentication
The WebSocket channel requires authentication. Include the Sanctum token in the authorization header when connecting.

---

## Payment Flow

### Complete Flow Diagram

```
1. User submits top-up request
   ↓
2. Status set to "verifying_payment"
   ↓
3. UI shows: "Please wait, we are checking the payment status..."
   ↓
4. User makes UPI payment
   ↓
5. Payment gateway sends SMS to user's device
   ↓
6. Mobile app reads SMS automatically
   ↓
7. Mobile app sends SMS content to /api/payment/process-sms
   ↓
8. System parses SMS:
   - Extracts amount
   - Extracts UPI ID (optional)
   ↓
9. System matches with pending request:
   - Checks amount match (with tolerance)
   - Checks UPI match (if available)
   ↓
10. If match:
    - Auto-approve payment
    - Credit wallet
    - Process referral earnings
    - Broadcast WebSocket event
    ↓
11. UI receives WebSocket event OR polling detects status change
   ↓
12. UI shows success message
```

### Status Transitions

```
pending → verifying_payment → approved
                              ↓
                           rejected
```

---

## SMS Format Examples

The system can parse various SMS formats. Here are examples:

### Supported Formats

1. **Standard UPI Credit SMS:**
   ```
   Rs. 100.00 credited to account ending 1234 from UPI: example@paytm
   ```

2. **Amount with Symbol:**
   ```
   ₹100.00 received from example@ybl via UPI
   ```

3. **INR Format:**
   ```
   INR 100.00 credited to your account
   ```

4. **Detailed Format:**
   ```
   Amount: Rs. 100.00 credited to account. UPI ID: example@okaxis
   ```

5. **Simple Format:**
   ```
   100.00 credited via UPI
   ```

### Parsing Rules

- **Amount Extraction:**
  - Recognizes: `Rs.`, `₹`, `INR`
  - Supports decimal amounts: `100.00`, `100`
  - Case-insensitive matching

- **UPI ID Extraction:**
  - Email format: `example@paytm`
  - Bank-specific: `example@ybl`, `example@okaxis`, `example@okhdfcbank`, `example@okicici`
  - Case-insensitive matching

### Amount Matching

- Amounts are matched with a tolerance of ₹0.01
- Example: Expected ₹100.00 matches received ₹100.00 or ₹99.99 or ₹100.01

### UPI Matching

- UPI matching is optional but recommended
- If UPI is found in SMS, it must match the UPI used in the request
- Partial matching is supported (e.g., `example@paytm` matches `example@paytm` or `EXAMPLE@PAYTM`)

---

## Error Handling

### Common Errors

1. **SMS Parse Failure**
   - **Cause:** SMS format not recognized
   - **Solution:** Ensure SMS contains amount in recognizable format (Rs., ₹, INR)

2. **Amount Mismatch**
   - **Cause:** Amount in SMS doesn't match request amount
   - **Solution:** Verify the payment amount matches the request

3. **UPI Mismatch**
   - **Cause:** UPI in SMS doesn't match request UPI
   - **Solution:** Ensure payment is made to the correct UPI

4. **No Pending Request**
   - **Cause:** No pending or verifying payment request found
   - **Solution:** Ensure a top-up request exists and is in pending/verifying_payment status

5. **Multiple Pending Requests**
   - **Behavior:** System matches with the most recent request
   - **Recommendation:** Ensure only one pending request exists per user

---

## Best Practices

1. **Polling Interval:**
   - Poll `/api/payment/check-status` every 3-5 seconds
   - Stop polling when status is `approved` or `rejected`

2. **SMS Reading:**
   - Read SMS immediately after payment
   - Filter SMS by sender (payment gateway) if possible
   - Send SMS content as-is without modification

3. **Error Handling:**
   - Show user-friendly error messages
   - Log errors for debugging
   - Allow manual retry if SMS processing fails

4. **WebSocket:**
   - Use WebSocket for real-time updates when possible
   - Fall back to polling if WebSocket is unavailable
   - Handle connection errors gracefully

5. **Security:**
   - Always validate user_id matches the authenticated user
   - Use HTTPS for all API calls
   - Secure WebSocket connections with authentication

---

## Testing

### Test Payment Status Check
```bash
curl -X POST https://api.alldigtalseva.com/api/payment/check-status \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": 1,
    "user_id": 1
  }'
```

### Test SMS Processing
```bash
curl -X POST https://api.alldigtalseva.com/api/payment/process-sms \
  -H "Content-Type: application/json" \
  -d '{
    "sms_content": "Rs. 100.00 credited to account ending 1234 from UPI: example@paytm",
    "user_id": 1
  }'
```

---

## Support

For issues or questions, please contact the development team.

