I'd like to update the default card for a customer using Stripe.
In the update customer
API docs it is not clear what to feed in for the card
parameter.
In PHP, I've tried setting the card
based on the retrieve card
method like this:
$customer->card=$card['id']
but that doesn't appear to work. Nor does using the token like this:
$customer->source=$_POST['stripe_token]
so I'm a bit at a loss. Thoughts?
Create new card & assign card as default source If you want to create a new card & set that new card to be the default card try this. *Note the stripe token should come from a stripe js request and the stripe customer id will likely come from the authenticated user.
To update the payment information of an existing customer, you'd need to first collect the new card's information (using Checkout or your own form with Stripe. js), then send a customer update request with the new card's token in the source parameter.
Stripe works with card networks and automatically attempts to update saved card details whenever a customer receives a new card (for example, replacing an expired card or one that was reported lost or stolen).
Each fingerprint is unique to a card, so before storing additional cards for a customer, you can simply search the user's cards by fingerprint. If you're not caching the card data locally, Stripe handles duplicates for you and you don't need to do anything.
I was able to answer my own question with Stripe's support on IRC #stripe channel:
The card
parameter is specified by default_source
like this:
Stripe::setApiKey($stripe_private_key);
$customer = Stripe_Customer::retrieve($stripe_cus_id);
$customer->default_source=$card['id'];
$customer->save();
If you want to create a new card & set that new card to be the default card try this.
*Note the stripe token should come from a stripe js request and the stripe customer id will likely come from the authenticated user.
// Get the customer
$customer = Customer::retrieve("cus_9jF6ku4f2pztRo");
// Add a new card to the customer
$card = $customer->sources->create(['source' => "tok_19PmcMI94XzVK71QeIwtUJmM"]);
// Set the new card as the customers default card
$customer->default_source = $card->id;
$customer->save();
@tim peterson's answer is complete and satisfies the question originally posed. However, this Stackoverflow question is one of the first hits for setting the default card for Stripe - so I wanted to document my own findings in a bit more detail.
It's first important to understand the flow of saving a card, and it's importance for securely storing references to credit cards.
Generally you will either add a card and set it as default on the spot, or store the credit card id (not credit card number!) in your database to perform actions against.
Note that when adding a first card to a user, it will be the default by, well, default.
customer->id
customer->id
in your app. This would typically be in the user
table or similar. A VARCHAR at 255 characters seems appropriate - however, after chatting with Stripe directly, they don't have a document length of id's in their system.
At a later stage, you will want to add a card.
Upon success Stripe JS will return a response with the following data:
In Stripe's examples, they append to the DOM a bunch of hidden form elements, fill the above data, then "submit the form for realz this time".
Now back to the original question. At some stage, you may have a user with multiple cards and need to set one as default.
Because you stored the return data from the above form, you should now have a list of cards, card ids, and whatnot in your database. So simply loop over them, and which ever card the user clicks as the default, fetch the card id, and update the default_source
property against the customer object with the card id value.
This will mirror the above three steps with some very loose code snippets (using PHP but should be easy enough to follow along).
Note I am skipping over error catching and exceptions for the sake of brevity. When doing any interaction with an external source it's alway good practice to be diligent with your exception handling - basically assume that the service will fail.
// Send details to Stripe
$customer = \Stripe\Customer::create([
'email' => $this->user->email,
'description' => $this->user->name,
]);
// Then update our application
$this->user->stripe_customer_id = $customer->id;
$this->user->save();
module.exports = (function() {
function CreditCard() {
$('#payment-form').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken($form, function(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('.payment-errors').parents(".row").show();
$form.find('button').prop('disabled', false);
} else {
// token contains id, last4, and card type
var token = response.id;
var cardId = response.card.id;
var last4 = response.card.last4;
var brand = response.card.brand;
var expMonth = response.card.exp_month;
var expYear = response.card.exp_year;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
$form.append($('<input type="hidden" name="cardId" />').val(cardId));
$form.append($('<input type="hidden" name="last4" />').val(last4));
$form.append($('<input type="hidden" name="brand" />').val(brand));
$form.append($('<input type="hidden" name="expMonth" />').val(expMonth));
$form.append($('<input type="hidden" name="expYear" />').val(expYear));
// and re-submit
$form.get(0).submit();
}
});
// Prevent the form from submitting with the default action
return false;
});
}
return CreditCard;
})();
public function save(string $token, string $cardId, string $last4, string $brand, int $expMonth, int $expYear)
{
// Store in our application
$creditCard = $this->user->creditCards()->create([
'token_id' => $token,
'card_id' => $cardId,
'last4' => $last4,
'brand' => $brand,
'exp_month' => $expMonth,
'exp_year' => $expYear
]);
}
Customer::retrieve($this->user->stripe_customer_id);
$customer->default_source = $cardId;
$customer->save();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With