Résolue

Stripe Sauvegarder l'identifiant et l'adresse de livraison

# Stripe # Bases de données # Django

bonjour à tous,
je n'arrive pas à Sauvegarder l'identifiant et l'adresse de livraison dans ma base de données sur stripe.

{'after_expiration': None,
 'allow_promotion_codes': None,
 'amount_subtotal': 159,
 'amount_total': 159,
 'automatic_tax': {'enabled': True,
                   'status': 'complete'},
 'billing_address_collection': None,
 'cancel_url': 'http://127.0.0.1:8000/',
 'client_reference_id': None,
 'consent': None,
 'consent_collection': None,
 'created': 1688709289,
 'currency': 'eur',
 'currency_conversion': None,
 'custom_fields': [],
 'custom_text': {'shipping_address': None,
                 'submit': None},
 'customer': 'cus_ODYk8PU7nn7XGn',
 'customer_creation': 'always',
 'customer_details': {'address': {'city': None,
                                  'country': 'FR',
                                  'line1': None,
                                  'line2': None,
                                  'postal_code': None,
                                  'state': None},
                      'email': '[email protected]',
                      'name': 'kambila',
                      'phone': None,
                      'tax_exempt': 'none',
                      'tax_ids': []},
 'customer_email': None,
 'expires_at': 1688795688,
 'id': 'cs_test_a1CXcqtDwaxUM26SmoTD3eUlKhGccAB8WHJJzbNYMgEGI0qYL6pHlx2b7O',
 'invoice': None,
 'invoice_creation': {'enabled': False,
                      'invoice_data': {'account_tax_ids': None,
                                       'custom_fields': None,
                                       'description': None,
                                       'footer': None,
                                       'metadata': {},
                                       'rendering_options': None}},
 'livemode': False,
 'locale': None,
 'metadata': <stripeobject 0x13a775eff40="" at=""> JSON: {},
 'mode': 'payment',
 'object': 'checkout.session',
 'payment_intent': 'pi_3NR7d3CfR23yIEyo1LqEz9O8',
 'payment_link': None,
 'payment_method_collection': 'always',
 'payment_method_options': <stripeobject 0x13a77516180="" at=""> JSON: {},
 'payment_method_types': ['card',
                          'bancontact',
                          'eps',
                          'giropay',
                          'ideal',
                          'link'],
 'payment_status': 'paid',
 'phone_number_collection': {'enabled': False},
 'recovered_from': None,
 'setup_intent': None,
 'shipping_address_collection': {'allowed_countries': ['ML', 'FR']},
 'shipping_cost': None,
 'shipping_details': {'address': {'city': 'Paris',
                                  'country': 'FR',
                                  'line1': '37 Rue Lamarck',
                                  'line2': 'jjj',
                                  'postal_code': '75018',
                                  'state': ''},
                      'name': 'konimba djimiga'},
 'shipping_options': [],
 'status': 'complete',
 'submit_type': None,
 'subscription': None,
 'success_url': 'http://127.0.0.1:8000/cart/success',
 'total_details': {'amount_discount': 0,
                   'amount_shipping': 0,
                   'amount_tax': 0},
 'url': None}

   cart = request.user.cart
    # on recupère cart avec user qui est connecté grace à request
    # on va créer une liste une lise d'element à partir de ce panier
    # on va fairee une comprehention de liste en bouclant sur chaque article
    # on recupère un dict pour cheque element qui contient le le strip_id=produit et la quantite
    line_items = [{"price": Order.product.stripe_id,
                   "quantity": Order.quantity} for Order in cart.orders.all()]
    try:
        checkout_session = stripe.checkout.Session.create(
            line_items=line_items,
            customer_creation='always',
            mode='payment',
            shipping_address_collection={"allowed_countries": ["ML", "FR"]},
            success_url=request.build_absolute_uri(reverse("checkout-success")),
            cancel_url=request.build_absolute_uri(reverse("home")),
            automatic_tax={'enabled': True},
        )
    except Exception as e:
        return str(e)

    return redirect(checkout_session.url, code=303)


def checkout_success(request):
    return render(request, 'store/success.html')


endpoint_secret = 'whsec_9d9995195841efd099f24a481a1b47ba79e69531a6404f63d57a9cfd07d11dbf'


@csrf_exempt
def webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)
    if event['type'] == 'checkout.session.completed':
        data = event['data']['object']
        try:
            user = get_object_or_404(Shopper, email=data['customer_details']['email'])
        except KeyError:
            HttpResponse('invalid user email', status=404)

        complete_order(user=user, data=data)
        save_shipping_address(user=user, data=data)
        return HttpResponse(status=200)

    return HttpResponse(status=200)


def complete_order(user, data):
    user.stripe_id = data['customer']
    user.cart.delete()
    user.cart.save()

    return HttpResponse(status=200)


def save_shipping_address(user, data):
    try:
        pprint(data)
        name = data["shipping_details"]["name"]
        city = data["address"]["city"]
        country = data["address"]["country"]
        address_1 = data["address"]["line1"]
        address_2 = data["address"]["line2"]
        zip_code = data["address"]["postal_code"]
    except KeyError:
        return HttpResponse(status=404)
    Shippingaddress.objects.get_or_create(user=user,
                                          name=name,
                                          city=city,
                                          country=country.lower(),
                                          address_1=address_1,
                                          address_2=address_2 or "",
                                          zipe_code=zip_code)
    return HttpResponse(status=200)



Hello,

as tu as un message d'erreur ?

salut,
non jai pas de message d'erreur

2023-07-08 20:32:30   --&gt; customer.created [evt_1NRfvlCfR23yIEyoC1ael59h]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_1NRfvlCfR23yIEyoC1ael59h]
2023-07-08 20:32:30   --&gt; payment_intent.created [evt_3NRfviCfR23yIEyo1TrN1E4D]
2023-07-08 20:32:30   --&gt; customer.updated [evt_1NRfvlCfR23yIEyoK6GpdECi]
2023-07-08 20:32:30   --&gt; mandate.updated [evt_1NRfvmCfR23yIEyoQ49BAD6H]
2023-07-08 20:32:30   --&gt; payment_intent.succeeded [evt_3NRfviCfR23yIEyo1R24mWll]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_3NRfviCfR23yIEyo1TrN1E4D]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_1NRfvlCfR23yIEyoK6GpdECi]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_1NRfvmCfR23yIEyoQ49BAD6H]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_3NRfviCfR23yIEyo1R24mWll]
2023-07-08 20:32:30   --&gt; charge.succeeded [evt_3NRfviCfR23yIEyo1iOy2cV9]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_3NRfviCfR23yIEyo1iOy2cV9]
2023-07-08 20:32:30   --&gt; checkout.session.completed [evt_1NRfvmCfR23yIEyobs02F9LW]
2023-07-08 20:32:30  &lt;--  [200] POST http://127.0.0.1:8000/stripe-webhook/ [evt_1NRfvmCfR23yIEyobs02F9LW]

Thibault houdon

Mentor

Salut Konimba !

Ton code semble bon, j'ai vérifié et il ne semble pas y avoir eu de changements du côté de l'API Stripe à ce sujet donc c'est bizarre.

Quand tu dis que tu n'arrives pas à sauvegarder l'adresse dans ta base de données sur Stripe, tu veux dire sauvegarder dans ta base de données Django ou Stripe ?

Dans l'exemple du cours, je sauvegarde l'adresse côté Django, et elle est également de base conservée sur Stripe. De ton côté, le customer et son adresse de shipping sont-elles bien présentes du côté de Stripe ? Mais pas du côté Django ? Juste pour être sûr que je regarde au bon endroit :)

salut Thibault ça va ?

Je souhaite sauvegarder les données fournies par le client sur Stripe dans ma base de données django.
je voudrais le faire dans la table Shippingaddress et Shopper(stripe_id).

Dans le code que je te fournis au début, c'est un pprint(data), tu peux voir que le client et son adresse de livraison sont bien présents du côté de Stripe.
Cependant, dans mon interface admin, le srtipe_id du Shopper est vide, de même que l'adresse de livraison (Shippingaddress).

Thibault houdon

Mentor

Salut Konimba, ça va super, j'espère que ton début de semaine se passe bien aussi :D

Ok alors c'est bien ce que je pensais, du côté Stripe tout semble bon effectivement.

Tu as fait un peu de debug du côté de ta fonction save_shipping_address ? Tu utilises PyCharm ou VS Code (ou autre) ?

Tu peux regarder cette vidéo / formation pour les principes du debug, je pense que ça t'aideras beaucoup pour ne pas avoir à faire trop d'essais avec Stripe (vu que c'est assez long à chaque fois de passer par tout le processus de checkout) :
https://www.docstring.fr/formations/le-debogage-avec-python/le-debogage-en-pratique-avec-thonny-1225/?tab=questions

def save_shipping_address(user, data):
    try:
        pprint(data)
        name = data["shipping_details"]["name"]
        city = data["address"]["city"]
        country = data["address"]["country"]
        address_1 = data["address"]["line1"]
        address_2 = data["address"]["line2"]
        zip_code = data["address"]["postal_code"]
    except KeyError:
        return HttpResponse(status=404)

    # Ici il faudrait vérifier ce que contiennent toutes tes variables du bloc try / except (name, city, country...)
    address, created = Shippingaddress.objects.get_or_create(user=user,
                                          name=name,
                                          city=city,
                                          country=country.lower(),
                                          address_1=address_1,
                                          address_2=address_2 or "",
                                          zipe_code=zip_code)
    # Vérifie ce que te retourne ces variables (address, created)
    return HttpResponse(status=200)

Salut Thibault !

J'utilise PyCharm et j'ai regardé la vidéo sur Thonny.
Cependant, je suis toujours bloqué car toutes les ressources que j'ai trouvées sur la façon de déboguer un projet dans PyCharm sont basées sur des scripts très simples, comme l'exemple dans Thonny.
Mais ma fonction save_shipping_address est plus complexe, à mon avis.

Thibault houdon

Mentor

Salut Konimba !

Je comprends au début ça fait toujours un peu peur le déboguage.

Dans ton cas, mets un point d'arrêt (clique dans la marge) ici :
Point d'arrêt

Et lance ton projet en mode Debug plutôt que le mode normal :
Lancer en mode debug

Une fois que ton script arrivera à cet endroit il s'arrêtera et ça te donnera l'occasion d'avancer plus sereinement pas à pas avec ce bouton :
Step over

bonjour Thibault !

J'ai encore un petit problème que j'ai essayé de résoudre de mon côté, mais sans succès. J'ai mis un point d'arrêt, j'ai lancé le projet en mode débogage, mais le script ne s'arrête pas. J'ai essayé plusieurs fois en ajoutant des points d'arrêt, mais il ne se passe rien dans les threads et les variables.



et je fais clic droit , debug'views' ça donne ceci :

Thibault houdon

Mentor

Salut Konimba !

Alors tu vois je me dis que justement tu as probablement bien fait les choses, mais si ton script ne s'arrête pas là où tu as mis le point de déboguage, c'est une indication en soi : ça signifie donc que le code n'est jamais atteint.

Dans ce cas, il faut mettre ton point de debug plus haut. Si tu as mis le point de debug dans ta fonction save_shipping_address et que le script ne s'arrête pas, mets le en amont (par exemple dans ton webhook) :

@csrf_exempt
def webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)
    if event['type'] == 'checkout.session.completed':
        data = event['data']['object']
        try:
            user = get_object_or_404(Shopper, email=data['customer_details']['email'])
        except KeyError:
            HttpResponse('invalid user email', status=404)

        complete_order(user=user, data=data)
🔴      save_shipping_address(user=user, data=data)  # Met ton point de debug ici par exemple
        return HttpResponse(status=200)

    return HttpResponse(status=200)

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.