web-dev-qa-db-fra.com

Carte par défaut du client de mise à jour Stripe (PHP)

Je voudrais mettre à jour la carte par défaut pour un client utilisant Stripe.

Dans le update customer API docs on ne sait pas quoi alimenter pour le paramètre card.

En PHP, j'ai essayé de définir le card sur la base du retrieve card méthode comme celle-ci:

$customer->card=$card['id']

mais cela ne semble pas fonctionner. De même, l'utilisation du jeton comme ceci:

$customer->source=$_POST['stripe_token]

donc je suis un peu perdu. Pensées?

17
tim peterson

J'ai pu répondre à ma propre question avec le support de Stripe sur IRC #stripe channel :

Le paramètre card est spécifié par default_source comme ça:

Stripe::setApiKey($stripe_private_key);
$customer = Stripe_Customer::retrieve($stripe_cus_id);
$customer->default_source=$card['id'];
$customer->save();  
20
tim peterson

Créer une nouvelle carte et attribuer une carte comme source par défaut

Si vous souhaitez créer une nouvelle carte et définir cette nouvelle carte comme carte par défaut, essayez ceci.

* Notez que le jeton stripe doit provenir d'une requête js stripe et que l'ID client stripe proviendra probablement de l'utilisateur authentifié.

// 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();
13
Rob

1. Vue d'ensemble

La réponse de @tim peterson est complète et répond à la question posée à l'origine. Cependant, cette question Stackoverflow est l'un des premiers succès pour définir la carte par défaut pour Stripe - je voulais donc documenter mes propres découvertes un peu plus en détail.

2. Débit

Il est d'abord important de comprendre le déroulement de l'enregistrement d'une carte, et il est important de stocker en toute sécurité références sur les cartes de crédit.

En règle générale, vous allez soit ajouter une carte et la définir par défaut sur place, soit stocker l'identifiant de la carte de crédit (pas le numéro de carte de crédit!) Dans votre base de données pour effectuer des actions contre.

Notez que lors de l'ajout d'une première carte à un utilisateur, ce sera la valeur par défaut, eh bien, par défaut.

2.1. Création client

  1. Depuis votre application créez un client dans Stripe via l'API
  2. Un objet client est retourné par Stripe , y compris, customer->id
  3. Au minimum, stockez customer->id dans votre application . Ce serait généralement dans la table user ou similaire.

Un VARCHAR à 255 caractères semble approprié - cependant , après avoir discuté directement avec Stripe, ils n'ont pas de longueur de document d'identifiant dans leur système.

2.2. Création de cartes

À un stade ultérieur, vous souhaiterez ajouter une carte.

  1. Utilisez d'abord la bibliothèque Stripe JS ainsi documentée sur leur site . L'idée ici est que l'action de soumission du formulaire pointe directement sur les serveurs Stripe, donc lorsque le formulaire est soumis, les vrais détails de la carte de crédit ne parviennent jamais à votre serveur. Bien qu'il soit techniquement possible de créer des cartes sans Stripe JS, à moins qu'il n'y ait une bonne raison, je m'en tiendrai à la méthode recommandée et je laisserais faire le gros du travail.
  2. L'utilisateur est sur votre formulaire de carte de crédit et les événements suivants se produisent:
  3. Ils entrent les détails de leur carte de crédit dans votre formulaire
  4. Ils ont frappé soumettre
  5. Toutes les entrées de formulaire sont envoyées à Stripe via ajax
  6. En cas de succès Stripe JS retournera une réponse avec les données suivantes:

    • response.id
    • response.card.id
    • response.card.last4
    • response.card.brand
    • response.card.exp_month
    • response.card.exp_year
  7. Dans les exemples de Stripe, ils ajoutent au DOM un tas d'éléments de formulaire cachés, remplissent les données ci-dessus, puis "soumettent le formulaire pour realz cette fois".

  8. Votre backend, quel qu'il soit, recevra les données ci-dessus et vous pourrez les stocker comme bon vous semble.

2.3. Définition de la valeur par défaut

Revenons maintenant à la question d'origine. À un certain stade, vous pouvez avoir un utilisateur avec plusieurs cartes et devez en définir une par défaut.

Parce que vous avez stocké les données de retour du formulaire ci-dessus, vous devriez maintenant avoir une liste de cartes, identifiants de carte et ainsi de suite dans votre base de données. Il suffit donc de les parcourir en boucle, et sur la carte sur laquelle l'utilisateur clique par défaut, récupérez l'ID de la carte et mettez à jour le default_source propriété par rapport à l'objet client avec la valeur d'ID de carte.

3 exemples

Cela reflétera les trois étapes ci-dessus avec des extraits de code très lâches (en utilisant PHP mais devrait être assez facile à suivre).

Remarque Je saute la capture d'erreur et les exceptions par souci de concision. Lorsque vous effectuez une interaction avec une source externe, il est toujours recommandé de faire preuve de diligence dans la gestion des exceptions - supposez essentiellement que le service échouera.

3.1 Création de client

// 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();

3.2 Création de carte

3.2.1 Javascript

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;
})();

3.2.2 Backend

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
    ]);
}

3.3 Définition de la valeur par défaut

    Customer::retrieve($this->user->stripe_customer_id);
    $customer->default_source = $cardId;
    $customer->save();
13
Chris