Notes
![]() ![]() Notes - notes.io |
---
### **1. Retrieve the Default Payment Method**
Update the `index` method in your `CardController` to include the `default_payment_method` from Stripe:
```php
public function index()
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
// Fetch all cards
$existingCard = $stripe->paymentMethods->all([
'customer' => Auth::user()->stripe_customer_id,
'type' => 'card',
]);
// Fetch the default payment method
$customer = $stripe->customers->retrieve(Auth::user()->stripe_customer_id);
$defaultPaymentMethod = $customer->invoice_settings->default_payment_method;
return view('cards.index', compact('existingCard', 'defaultPaymentMethod'));
}
```
---
### **2. Update the Blade File**
Modify the Blade file to check whether the card is the default card. Update the `Actions` column:
```blade
@foreach($existingCard->data as $card)
<tr style="{{ $card->id == $defaultPaymentMethod ? 'background-color: #d4edda;' : '' }}">
<td>{{ $card->card->brand }}</td>
<td>{{ $card->card->last4 }}</td>
<td>{{ $card->card->exp_month }}</td>
<td>{{ $card->card->exp_year }}</td>
<td>
@if($card->id == $defaultPaymentMethod)
<span class="badge badge-success">Default</span>
@else
<form action="{{ route('make.default.card') }}" method="POST" style="display:inline;">
@csrf
<input type="hidden" name="payment_method_id" value="{{ $card->id }}" />
<button type="submit" class="btn btn-primary" style="background-color: #007bff;">Make Default</button>
</form>
@endif
<form action="{{ route('delete.card') }}" method="POST" style="display:inline;">
@csrf
<input type="hidden" name="pay_method" value="{{ $card->id }}" />
<button type="submit" class="btn btn-danger" style="background-color: #de163d;">Delete</button>
</form>
</td>
</tr>
@endforeach
```
---
### **3. Ensure the Default Card is Set Correctly**
Make sure your `makeDefault` method updates the `default_payment_method` on Stripe correctly:
```php
public function makeDefault(Request $request)
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
try {
// Update the customer's default payment method
$stripe->customers->update(Auth::user()->stripe_customer_id, [
'invoice_settings' => [
'default_payment_method' => $request->payment_method_id,
],
]);
return redirect()->route('cards.index')->with('success', 'Default card updated successfully.');
} catch (Exception $e) {
return redirect()->route('cards.index')->with('error', 'Failed to update default card: ' . $e->getMessage());
}
}
```
---
### **4. Test the Changes**
1. Add multiple cards for the customer in Stripe.
2. Navigate to the page showing all cards.
3. The default card should be highlighted with a badge or background color, and the corresponding button should not display "Make Default".
4. Clicking "Make Default" on another card should update the default card and refresh the page.
---
### **5. Debugging Steps**
- Check the value of `$defaultPaymentMethod` in the `index` method:
```php
dd($defaultPaymentMethod);
```
Ensure it matches the `id` of one of the `existingCard->data` cards.
- Verify that the `makeDefault` method is successfully updating the `default_payment_method` in Stripe by checking the customer's `invoice_settings` directly in the Stripe Dashboard.
---
With these changes, only the card that is not the default will display the "Make Default" button, and the default card will be visually highlighted.
To implement a toggle button that dynamically reflects whether a card is set as the default (on for the default card and off for others), follow these steps:
---
### **1. Update Your Blade File**
Replace the "Make Default" button with a toggle switch. The toggle will show `checked` for the default card.
Here's how you can update the Blade file:
```blade
@foreach($existingCard->data as $card)
<tr>
<td>{{ $card->card->brand }}</td>
<td>{{ $card->card->last4 }}</td>
<td>{{ $card->card->exp_month }}</td>
<td>{{ $card->card->exp_year }}</td>
<td>
<label class="switch">
<input type="radio" name="default_card"
value="{{ $card->id }}"
onchange="updateDefaultCard('{{ $card->id }}')"
{{ $card->id == $defaultPaymentMethod ? 'checked' : '' }}>
<span class="slider round"></span>
</label>
</td>
<td>
<form action="{{ route('delete.card') }}" method="POST" style="display:inline;">
@csrf
<input type="hidden" name="pay_method" value="{{ $card->id }}" />
<button type="submit" class="btn btn-danger" style="background-color: #de163d;">Delete</button>
</form>
</td>
</tr>
@endforeach
```
### **2. Add CSS for the Toggle Button**
Include the following CSS in your Blade file to style the toggle button:
```html
<style>
.switch {
position: relative;
display: inline-block;
width: 34px;
height: 20px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: 0.4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #007bff;
}
input:checked + .slider:before {
transform: translateX(14px);
}
</style>
```
---
### **3. Add JavaScript for Updating the Default Card**
When the toggle is clicked, send an AJAX request to update the default card without reloading the page:
```html
<script>
function updateDefaultCard(paymentMethodId) {
fetch("{{ route('make.default.card') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": "{{ csrf_token() }}"
},
body: JSON.stringify({
payment_method_id: paymentMethodId
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert(data.message);
location.reload(); // Reload to reflect changes
} else {
alert(data.message);
}
})
.catch(error => {
console.error("Error:", error);
alert("Something went wrong.");
});
}
</script>
```
---
### **4. Update the `makeDefault` Method in the Controller**
Return a JSON response to handle the AJAX request:
```php
public function makeDefault(Request $request)
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
try {
// Update the customer's default payment method
$stripe->customers->update(Auth::user()->stripe_customer_id, [
'invoice_settings' => [
'default_payment_method' => $request->payment_method_id,
],
]);
return response()->json([
'success' => true,
'message' => 'Default card updated successfully.',
]);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => 'Failed to update default card: ' . $e->getMessage(),
], 500);
}
}
```
---
### **5. Add the Route**
Ensure the route for updating the default card exists in your `web.php` file:
```php
Route::post('/cards/make-default', [CardController::class, 'makeDefault'])->name('make.default.card');
```
---
### **6. Behavior**
1. The toggle is displayed for each card, with the default card toggle set to `checked`.
2. When the toggle for a non-default card is clicked:
- An AJAX request is sent to the server.
- The server updates the default payment method in Stripe.
- The page reloads (optional) to update the UI.
3. Only one toggle can be `checked` at a time.
---
With these changes, your toggle button will accurately reflect and update the default card status dynamically!
If the `exp_year` is always the same despite entering different values, the issue might be caused by:
1. **Incorrect Data Sent to Stripe**: The card expiration year and month might not be correctly passed to Stripe during the creation or update of the card.
2. **Using a Test Payment Method**: If you are using Stripe's test payment methods (e.g., `pm_card_visa`), Stripe may return predefined values for `exp_month` and `exp_year`, regardless of what you input.
3. **Incorrect Display Logic in Blade**: If the frontend (`Blade` file) is not dynamically updating the displayed values, you might see outdated or hardcoded data.
---
### **Step-by-Step Debugging and Fix**
#### **1. Check the Data Sent to Stripe**
Inspect how you are attaching the payment method in your `store` method:
```php
public function store(Request $req)
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
$paymentMethod = $req->input('payment_method_id'); // Make sure this is dynamic and valid
// Attach the payment method to the customer
$cardAdded = $stripe->paymentMethods->attach($paymentMethod, [
'customer' => Auth::user()->stripe_customer_id,
]);
return redirect()->route('cards.index')->with('success', 'Card added successfully.');
}
```
- Ensure that the `payment_method_id` corresponds to the card you are trying to attach, with the correct `exp_month` and `exp_year`.
- If you're using Stripe's test cards like `pm_card_visa`, these are predefined and won't change based on user input.
#### **2. Verify Test Card Behavior**
When using Stripe's predefined test card IDs (e.g., `pm_card_visa`), these return fixed values:
| Test Card ID | `exp_month` | `exp_year` |
|------------------|-------------|------------|
| `pm_card_visa` | 12 | 2030 |
| `pm_card_mastercard` | 12 | 2030 |
If you're testing with these IDs, the expiration dates will always default to the predefined values, regardless of what you input.
**Solution**: Use the "Setup Intent" API to collect real card details from a user for testing.
#### **3. Debug the Blade File**
Ensure that the `exp_year` displayed in your Blade file dynamically reflects the Stripe response:
```blade
<td>{{ $card->card->exp_month }}</td>
<td>{{ $card->card->exp_year }}</td>
```
If this is hardcoded or incorrectly mapped, it could show the same year for all cards.
#### **4. Fetch Data Directly from Stripe**
When displaying cards, fetch the latest data from Stripe in your `index` method to ensure accuracy:
```php
public function index()
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
// Fetch all attached cards for the customer
$existingCard = $stripe->paymentMethods->all([
'customer' => Auth::user()->stripe_customer_id,
'type' => 'card',
]);
// Fetch default payment method
$customer = $stripe->customers->retrieve(Auth::user()->stripe_customer_id);
$defaultPaymentMethod = $customer->invoice_settings->default_payment_method;
return view('cards.index', compact('existingCard', 'defaultPaymentMethod'));
}
```
#### **5. Use Real Test Cards for Validation**
If you want to test with user input, set up a form to accept actual card details using Stripe's test environment:
- Use Stripe Elements or Checkout to collect card details.
- Create a new payment method and attach it to the customer.
---
### **Example: Collecting Card Details**
1. **Frontend**: Use Stripe Elements or Checkout for user input.
2. **Backend**:
Replace `pm_card_visa` in the `store` method with the actual payment method collected from the frontend:
```php
public function store(Request $req)
{
$stripe = new StripeStripeClient(env('STRIPE_SECRET'));
$paymentMethod = $req->input('payment_method_id'); // Dynamically passed from Stripe.js
// Attach the payment method to the customer
$stripe->paymentMethods->attach($paymentMethod, [
'customer' => Auth::user()->stripe_customer_id,
]);
return redirect()->route('cards.index')->with('success', 'Card added successfully.');
}
```
---
### **Conclusion**
- If you're using predefined Stripe test cards, expiration years and months are fixed.
- Use dynamic payment method creation for user-specific values.
- Always fetch and display real-time data from Stripe when listing cards.
By following the above steps, you can resolve the issue with static `exp_year` and test dynamic data properly.
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team