The pre-production release of the 2602.XX.YY versions of the SaaS are setup with a revised React-based subscription processor.
The My Profile | Subscription tab allows the user to…
- Change the plan (upgrade, downgrade)
- Update Card
- Cancel Subscription
Update Card
The update card process appears to be calling the backend, however how Stripe stores payment data and how it is rendered has changed.
Resolution
Update \stripe\MySLP_Stripe_Payments::get_customer_card_details
If Payment Method (default payment method) is set it always returns that first, but that is not where the card payment info is set when the card is changed. It has the ‘default_source’ set for the customer, which should take precedence.
On a new customer the default_source is empty, thus \stripe\MySLP_Stripe_Payments::get_customer_card_details will fall back to the payment id.
Dev Notes
Call Stack
Update Card button on React interface pulls up the Stripe independent JavaScript modal to edit the card.
Upon submit of the Stripe JS modal form it posts back to the My Profile page forcing a render…
\MySLP::render_profile_page
\MySLP_Customer_Profile::get_instance()->page_profile()
\MySLP_Customer_Profile::initialize() // from get_instance call
\MySLP_Customer_Profile::do_when_plugins_loaded
\MySLP_Customer_Profile::update_card // only runs for Stripe processor
\stripe\MySLP_Stripe_Payments::change_card
\stripe\MySLP_Stripe_Payments::change_card
- Requires $_REQUEST[‘stripToken’] to be set
- Requires $_REQUEST[‘stripeEmail’] to match the current logged-in user email
It then calls the Stripe library to update the customer information:
$stripeCustomer = $stripeCustomer->update(
$this->myslp->User->payment_customer_id,
['source' => $_REQUEST['stripeToken']]
);
\Customer_Profile_Subscription::get_subscription_data
This builds the JavaScript variables sent to React that impacts the displayed items. Those relevant to card details:
$user = $this->myslp->User;
$recurring_payments = $user->recurring_payments
Partial $recurring_payments data:
['customer_details']
[ 'default_source' ] = 'card_1T1qAGBvHKfBw2LGldu03Qw1' // matches latest history log entry
['subscription_details']
['default_payment_method'] = 'pm_1Sw3IgBvHKfBw2LGqEHop4ts'
The code is currently set to build card details from…
1. $recurring_payments[‘customer_details’][‘sources’][‘data’][0] // this is empty in newer subscriptions
2.
My Profile | History
The history tab is showing the change card operation is working via the \MySLP_User::__set calls when the recurring payment data is stored in the User meta array for persistent storage. This is fired from inside \stripe\MySLP_Stripe_Payments::change_card via $this->myslp->Recurring_Payments->add_payment_data(…).
The MySLP_User class fires this hook when recurring payment data changes:
do_action( ‘myslp_subscription_changed’, $this->subscription_status, $original_value );
This is showing the data is getting to stripe and being recorded.

Stripe test Cards
This is in the Cypress testing fixtures at SLP_SaaS/Testing/myslp-cypress/cypress/fixtures/stripe_test_cards.json
[
{
"id": "visa",
"number": "4242424242424242",
"cvc": "123",
"expiration": "0130"
},
{
"id": "mastercard",
"number": "5555555555554444",
"cvc": "456",
"expiration": "0230"
},
{
"id": "amex",
"number": "378282246310005",
"cvc": "1234",
"expiration": "0330"
},
{
"id": "discover",
"number": "6011111111111117",
"cvc": "789",
"expiration": "0430"
}
]