How to Not Charge Credit Card Again on Refresh Django

In this tutorial I'll demonstrate how to configure a new Django website from scratch to accept one-fourth dimension payments with Stripe.

Need to handle subscription payments? Cheque out Django Stripe Subscriptions.

  • Stripe Payment Options
  • Projection Setup
  • Add Stripe
  • Create a Production
  • User Flow
  • Become Publishable Central
  • Create Checkout Session
  • Redirect the User Appropriately
  • Ostend Payment with Stripe Webhooks
  • What'south Next

Stripe Payment Options

There are currently three ways to accept ane-time payments with Stripe:

  1. Charges API (legacy)
  2. Stripe Checkout (the focus of this tutorial)
  3. Payment Intents API (often coupled with Stripe Elements)

Which i should you use?

  1. Use Checkout if y'all want to get up and running fast. If you lot're familiar with the sometime modal version of Checkout, this is the way to go. Information technology provides a ton of features out-of-the-box, supports multiple languages, and includes an easy path to implementing recurring payments. Virtually importantly, Checkout manages the entire payment process for you, and then you can begin accepting payments without even having to add a single form!
  2. Use the Payment Intents API If you want a more custom experience for your cease users.

Although y'all can all the same utilise the Charges API, if you're new to Stripe do not apply it since it does non support the latest banking regulations (like SCA). Yous volition see a loftier rate of declines. For more, review the Charges vs. Payment Intents APIs page from the official Stripe docs.

Still using the Charges API? If about of your customers are based in the U.s. or Canada you don't need to drift just withal. Review the Checkout migration guide guide for more info.

Project Setup

Create a new project directory forth with a new Django projection called djangostripe:

                        $ mkdir django-stripe-checkout              &&              cd              django-stripe-checkout $ python3.x -m venv env $              source              env/bin/activate              (env)$ pip install              django              ==              3.2.9              (env)$ django-admin startproject djangostripe .                      

Feel free to swap out virtualenv and Pip for Poetry or Pipenv. For more, review Mod Python Environments.

Side by side, create a new app called payments:

                                      (env)$ python manage.py startapp payments                      

Now add together the new app to the INSTALLED_APPS configuration in settings.py:

                                      # djangostripe/settings.py              INSTALLED_APPS              =              [              'django.contrib.admin'              ,              'django.contrib.auth'              ,              'django.contrib.contenttypes'              ,              'django.contrib.sessions'              ,              'django.contrib.messages'              ,              'django.contrib.staticfiles'              ,              # Local              'payments.apps.PaymentsConfig'              ,              # new              ]                      

Update the project-level urls.py file with the payments app:

                                      # djangostripe/urls.py              from              django.contrib              import              admin              from              django.urls              import              path              ,              include              # new              urlpatterns              =              [              path              (              'admin/'              ,              admin              .              site              .              urls              ),              path              (              ''              ,              include              (              'payments.urls'              )),              # new              ]                      

Create a urls.py file within the new app, also:

                                      (env)$ bear on payments/urls.py                      

And so populate it as follows:

                                      # payments/urls.py              from              django.urls              import              path              from              .              import              views              urlpatterns              =              [              path              (              ''              ,              views              .              HomePageView              .              as_view              (),              name              =              'home'              ),              ]                      

At present add a views.py file:

                                      # payments/views.py              from              django.views.generic.base of operations              import              TemplateView              class              HomePageView              (              TemplateView              ):              template_name              =              'dwelling house.html'                      

And create a dedicated "templates" binder and file for our homepage.

                                      (env)$ mkdir templates              (env)$ touch templates/abode.html                      

Then, add the post-obit HTML:

                                      <!-- templates/home.html -->              <!DOCTYPE html>              <              html              >              <              caput              >              <              meta              charset              =              "utf-8"              >              <              meta              name              =              "viewport"              content              =              "width=device-width, initial-scale=i"              >              <              title              >Django + Stripe Checkout</              championship              >              <              link              rel              =              "stylesheet"              href              =              "https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css"              >              <              script              defer              src              =              "https://utilize.fontawesome.com/releases/v5.15.four/js/all.js"              ></              script              >              </              head              >              <              body              >              <              section              grade              =              "section"              >              <              div              grade              =              "container"              >              <              button              class              =              "push button is-chief"              id              =              "submitBtn"              >Buy!</              push              >              </              div              >              </              section              >              </              body              >              </              html              >                      

Make certain to update the settings.py file so Django knows to look for a "templates" folder:

                                      # djangostripe/settings.py              TEMPLATES              =              [              {              'BACKEND'              :              'django.template.backends.django.DjangoTemplates'              ,              'DIRS'              :              [              'templates'              ],              # new              ...                      

Finally run migrate to sync the database and runserver to start Django's local web server.

                                      (env)$ python manage.py drift              (env)$ python manage.py runserver                      

That's it! Check out http://localhost:8000/ and y'all'll see the homepage:

Django

Add Stripe

Time for Stripe. Start by installing it:

                                      (env)$ pip install              stripe              ==              2.63.0                      

Next, register for a Stripe business relationship (if you haven't already done and so) and navigate to the dashboard. Click on "Developers":

Stripe Developers

Then in the left sidebar click on "API keys":

Stripe Developers Key

Each Stripe account has four API keys: 2 for testing and two for production. Each pair has a "secret fundamental" and a "publishable key". Practise not reveal the cloak-and-dagger key to anyone; the publishable primal volition be embedded in the JavaScript on the folio that anyone can meet.

Currently the toggle for "Viewing test data" in the upper correct indicates that we're using the test keys now. That'southward what we want.

At the bottom of your settings.py file, add the following ii lines including your ain test hugger-mugger and test publishable keys. Brand sure to include the '' characters around the actual keys.

                                      # djangostripe/settings.py              STRIPE_PUBLISHABLE_KEY              =              '<your test publishable key hither>'              STRIPE_SECRET_KEY              =              '<your test surreptitious key here>'                      

Finally, you'll demand to specify an "Account name" within your "Account settings" at https://dashboard.stripe.com/settings/business relationship:

Stripe Account Name

Create a Product

Adjacent, we need to create a product to sell.

Click "Products" and and then "Add production":

Stripe Add Product

Add a product name, enter a price, and select "Once":

Stripe Add Product

Click "Salvage production".

User Menstruation

After the user clicks the purchase button nosotros demand to do the following:

  1. Get Publishable Key

    • Transport an XHR request from the client to the server requesting the publishable central
    • Answer with the cardinal
    • Apply the key to create a new instance of Stripe.js
  2. Create Checkout Session

    • Send some other XHR request to the server requesting a new Checkout Session ID
    • Generate a new Checkout Session and ship back the ID
    • Redirect to the checkout folio for the user to terminate their purchase
  3. Redirect the User Appropriately

    • Redirect to a success page after a successful payment
    • Redirect to a cancellation page after a cancelled payment
  4. Confirm Payment with Stripe Webhooks

    • Ready the webhook endpoint
    • Test the endpoint using the Stripe CLI
    • Register the endpoint with Stripe

Get Publishable Fundamental

JavaScript Static File

Let's start by creating a new static file to agree all of our JavaScript:

                                      (env)$ mkdir static              (env)$ touch static/main.js                      

Add together a quick sanity check to the new main.js file:

                                      // static/main.js              console              .              log              (              "Sanity check!"              );                      

So update the settings.py file and then Django knows where to find static files:

                                      # djangostripe/settings.py              STATIC_URL              =              '/static/'              # for django >= 3.i              STATICFILES_DIRS              =              [              BASE_DIR              /              'static'              ]              # new              # for django < three.i              # STATICFILES_DIRS = [bone.path.join(BASE_DIR, 'static')]  # new                      

Add the static template tag along with the new script tag inside the HTML template:

                                      <!-- templates/dwelling.html -->              {% load static %}              <!-- new -->              <!DOCTYPE html>              <              html              >              <              head              >              <              meta              charset              =              "utf-8"              >              <              meta              proper noun              =              "viewport"              content              =              "width=device-width, initial-calibration=ane"              >              <              title              >Django + Stripe Checkout</              title              >              <              link              rel              =              "stylesheet"              href              =              "https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css"              >              <              script              src              =              "{% static 'main.js' %}"              ></              script              >              <!-- new -->              <              script              defer              src              =              "https://apply.fontawesome.com/releases/v5.fifteen.4/js/all.js"              ></              script              >              </              head              >              <              body              >              <              section              class              =              "section"              >              <              div              class              =              "container"              >              <              push button              class              =              "button is-primary"              id              =              "submitBtn"              >Purchase!</              button              >              </              div              >              </              section              >              </              trunk              >              </              html              >                      

Run the development server again. Navigate to http://localhost:8000/, and open the JavaScript console. You should see the sanity check:

JavaScript Sanity Check

View

Next, add a new view to payments/views.py to handle the XHR request:

                                      # payments/views.py              from              django.conf              import              settings              # new              from              django.http.response              import              JsonResponse              # new              from              django.views.decorators.csrf              import              csrf_exempt              # new              from              django.views.generic.base              import              TemplateView              class              HomePageView              (              TemplateView              ):              template_name              =              'home.html'              # new              @csrf_exempt              def              stripe_config              (              asking              ):              if              asking              .              method              ==              'Go'              :              stripe_config              =              {              'publicKey'              :              settings              .              STRIPE_PUBLISHABLE_KEY              }              return              JsonResponse              (              stripe_config              ,              rubber              =              False              )                      

Add a URL as well:

                                      # payments/urls.py              from              django.urls              import              path              from              .              import              views              urlpatterns              =              [              path              (              ''              ,              views              .              HomePageView              .              as_view              (),              name              =              'home'              ),              path              (              'config/'              ,              views              .              stripe_config              ),              # new              ]                      

XHR Asking

Adjacent, use the Fetch API to brand an XHR (XMLHttpRequest) request to the new /config/ endpoint in static/main.js:

                                      // static/main.js              console              .              log              (              "Sanity check!"              );              // new              // Get Stripe publishable primal              fetch              (              "/config/"              )              .              then              ((              result              )              =>              {              return              outcome              .              json              ();              })              .              then              ((              data              )              =>              {              // Initialize Stripe.js              const              stripe              =              Stripe              (              information              .              publicKey              );              });                      

The response from a fetch request is a ReadableStream. consequence.json() returns a promise, which nosotros resolved to a JavaScript object -- due east.g., data. Nosotros and then used dot-notation to access the publicKey in social club to obtain the publishable key.

Include Stripe.js in templates/home.html like and so:

                                      <!-- templates/home.html -->              {% load static %}              <!DOCTYPE html>              <              html              >              <              head              >              <              meta              charset              =              "utf-8"              >              <              meta              proper noun              =              "viewport"              content              =              "width=device-width, initial-scale=1"              >              <              title              >Django + Stripe Checkout</              title              >              <              link              rel              =              "stylesheet"              href              =              "https://cdn.jsdelivr.cyberspace/npm/[electronic mail protected]/css/bulma.min.css"              >              <              script              src              =              "https://js.stripe.com/v3/"              ></              script              >              <!-- new -->              <              script              src              =              "{% static 'main.js' %}"              ></              script              >              <              script              defer              src              =              "https://use.fontawesome.com/releases/v5.15.4/js/all.js"              ></              script              >              </              head              >              <              body              >              <              section              class              =              "section"              >              <              div              form              =              "container"              >              <              button              class              =              "push button is-primary"              id              =              "submitBtn"              >Purchase!</              push              >              </              div              >              </              department              >              </              body              >              </              html              >                      

Now, afterwards the page load, a call will be made to /config/, which will reply with the Stripe publishable primal. We'll so employ this key to create a new instance of Stripe.js.

Flow:

  1. Get Publishable Central

    • Send an XHR request from the customer to the server requesting the publishable key
    • Respond with the central
    • Employ the key to create a new instance of Stripe.js
  2. Create Checkout Session

    • Send another XHR request to the server requesting a new Checkout Session ID
    • Generate a new Checkout Session and send back the ID
    • Redirect to the checkout page for the user to cease their buy
  3. Redirect the User Appropriately

    • Redirect to a success page after a successful payment
    • Redirect to a cancellation folio later on a cancelled payment
  4. Confirm Payment with Stripe Webhooks

    • Set up the webhook endpoint
    • Test the endpoint using the Stripe CLI
    • Annals the endpoint with Stripe

Create Checkout Session

Moving on, we need to attach an event handler to the button's click event which will send another XHR request to the server to generate a new Checkout Session ID.

View

First, add the new view:

                                      # payments/views.py              @csrf_exempt              def              create_checkout_session              (              asking              ):              if              asking              .              method              ==              'GET'              :              domain_url              =              'http://localhost:8000/'              stripe              .              api_key              =              settings              .              STRIPE_SECRET_KEY              try              :              # Create new Checkout Session for the order              # Other optional params include:              # [billing_address_collection] - to display billing address details on the page              # [customer] - if yous have an existing Stripe Customer ID              # [payment_intent_data] - capture the payment afterward              # [customer_email] - prefill the e-mail input in the form              # For full details encounter https://stripe.com/docs/api/checkout/sessions/create              # ?session_id={CHECKOUT_SESSION_ID} means the redirect will accept the session ID fix equally a query param              checkout_session              =              stripe              .              checkout              .              Session              .              create              (              success_url              =              domain_url              +              'success?session_id=              {CHECKOUT_SESSION_ID}              '              ,              cancel_url              =              domain_url              +              'cancelled/'              ,              payment_method_types              =              [              'card'              ],              manner              =              'payment'              ,              line_items              =              [              {              'proper name'              :              'T-shirt'              ,              'quantity'              :              1              ,              'currency'              :              'usd'              ,              'amount'              :              '2000'              ,              }              ]              )              return              JsonResponse              ({              'sessionId'              :              checkout_session              [              'id'              ]})              except              Exception              as              e              :              return              JsonResponse              ({              'fault'              :              str              (              e              )})                      

Here, if the asking method is GET, we divers a domain_url, assigned the Stripe clandestine key to stripe.api_key (so information technology volition be sent automatically when we make a asking to create a new Checkout Session), created the Checkout Session, and sent the ID dorsum in the response. Take note of the success_url and cancel_url. The user will exist redirected dorsum to those URLs in the event of a successful payment or cancellation, respectively. We'll set those views up shortly.

Don't forget the import:

Add the URL:

                                      # payments/urls.py              from              django.urls              import              path              from              .              import              views              urlpatterns              =              [              path              (              ''              ,              views              .              HomePageView              .              as_view              (),              name              =              'abode'              ),              path              (              'config/'              ,              views              .              stripe_config              ),              path              (              'create-checkout-session/'              ,              views              .              create_checkout_session              ),              # new              ]                      

XHR Request

Add the result handler and subsequent XHR request to static/main.js:

                                      // static/principal.js              console              .              log              (              "Sanity check!"              );              // Get Stripe publishable key              fetch              (              "/config/"              )              .              so              ((              result              )              =>              {              return              outcome              .              json              ();              })              .              then              ((              data              )              =>              {              // Initialize Stripe.js              const              stripe              =              Stripe              (              data              .              publicKey              );              // new              // Outcome handler              document              .              querySelector              (              "#submitBtn"              ).              addEventListener              (              "click"              ,              ()              =>              {              // Get Checkout Session ID              fetch              (              "/create-checkout-session/"              )              .              then              ((              result              )              =>              {              return              result              .              json              ();              })              .              and so              ((              data              )              =>              {              console              .              log              (              data              );              // Redirect to Stripe Checkout              render              stripe              .              redirectToCheckout              ({              sessionId              :              data              .              sessionId              })              })              .              then              ((              res              )              =>              {              panel              .              log              (              res              );              });              });              });                      

Here, afterwards resolving the result.json() promise, we chosen redirectToCheckout with the Checkout Session ID from the resolved promise.

Navigate to http://localhost:8000/. On push click you should be redirected to an instance of Stripe Checkout (a Stripe-hosted page to securely collect payment data) with the T-shirt product data:

Stripe Checkout

We can test the form past using ane of the several examination carte numbers that Stripe provides. Let's use 4242 4242 4242 4242. Make sure the expiration appointment is in the future. Add whatsoever 3 numbers for the CVC and any 5 numbers for the postal lawmaking. Enter any e-mail accost and name. If all goes well, the payment should be processed, but the redirect will fail since nosotros have not prepare the /success/ URL however.

Flow:

  1. Get Publishable Central

    • Ship an XHR request from the client to the server requesting the publishable central
    • Respond with the key
    • Use the primal to create a new instance of Stripe.js
  2. Create Checkout Session

    • Ship another XHR asking to the server requesting a new Checkout Session ID
    • Generate a new Checkout Session and ship back the ID
    • Redirect to the checkout page for the user to finish their purchase
  3. Redirect the User Appropriately

    • Redirect to a success page after a successful payment
    • Redirect to a counterfoil page after a cancelled payment
  4. Confirm Payment with Stripe Webhooks

    • Set the webhook endpoint
    • Test the endpoint using the Stripe CLI
    • Annals the endpoint with Stripe

Redirect the User Appropriately

Finally, allow'southward wire up the templates, views, and URLs for handling the success and cancellation redirects.

Success template:

                                      <!-- templates/success.html -->              <!DOCTYPE html>              <              html              >              <              head              >              <              meta              charset              =              "utf-viii"              >              <              meta              proper noun              =              "viewport"              content              =              "width=device-width, initial-scale=one"              >              <              championship              >Django + Stripe Checkout</              title              >              <              link              rel              =              "stylesheet"              href              =              "https://cdn.jsdelivr.net/npm/[e-mail protected]/css/bulma.min.css"              >              <              script              defer              src              =              "https://use.fontawesome.com/releases/v5.15.4/js/all.js"              ></              script              >              </              head              >              <              trunk              >              <              section              class              =              "department"              >              <              div              form              =              "container"              >              <              p              >Your payment succeeded.</              p              >              </              div              >              </              section              >              </              trunk              >              </              html              >                      

Cancelled template:

                                      <!-- templates/cancelled.html -->              <!DOCTYPE html>              <              html              >              <              head              >              <              meta              charset              =              "utf-8"              >              <              meta              name              =              "viewport"              content              =              "width=device-width, initial-calibration=ane"              >              <              title              >Django + Stripe Checkout</              title              >              <              link              rel              =              "stylesheet"              href              =              "https://cdn.jsdelivr.net/npm/[electronic mail protected]/css/bulma.min.css"              >              <              script              defer              src              =              "https://utilise.fontawesome.com/releases/v5.15.4/js/all.js"              ></              script              >              </              head              >              <              torso              >              <              section              form              =              "section"              >              <              div              grade              =              "container"              >              <              p              >Your payment was cancelled.</              p              >              </              div              >              </              department              >              </              trunk              >              </              html              >                      

Views:

                                      # payments/views.py              class              SuccessView              (              TemplateView              ):              template_name              =              'success.html'              course              CancelledView              (              TemplateView              ):              template_name              =              'cancelled.html'                      

URLs:

                                      # payments/urls.py              from              django.urls              import              path              from              .              import              views              urlpatterns              =              [              path              (              ''              ,              views              .              HomePageView              .              as_view              (),              name              =              'home'              ),              path              (              'config/'              ,              views              .              stripe_config              ),              path              (              'create-checkout-session/'              ,              views              .              create_checkout_session              ),              path              (              'success/'              ,              views              .              SuccessView              .              as_view              ()),              # new              path              (              'cancelled/'              ,              views              .              CancelledView              .              as_view              ()),              # new              ]                      

Ok, refresh the spider web page at http://localhost:8000/. Click on the payment button and utilize the credit menu number 4242 4242 4242 4242 again along with the rest of the dummy info. Submit the payment. You should be redirected dorsum to http://localhost:8000/success/.

To ostend a charge was actually made, go back to the Stripe dashboard under "Payments":

Stripe Payments

To review, nosotros used the secret key to create a unique Checkout Session ID on the server. This ID was then used to create a Checkout case, which the end user gets redirected to after clicking the payment push button. After the charge occurred, they are and so redirected back to the success folio.

Flow:

  1. Get Publishable Key

    • Transport an XHR request from the client to the server requesting the publishable key
    • Respond with the cardinal
    • Use the central to create a new instance of Stripe.js
  2. Create Checkout Session

    • Send another XHR asking to the server requesting a new Checkout Session ID
    • Generate a new Checkout Session and send back the ID
    • Redirect to the checkout page for the user to terminate their purchase
  3. Redirect the User Appropriately

    • Redirect to a success page subsequently a successful payment
    • Redirect to a counterfoil folio after a cancelled payment
  4. Ostend Payment with Stripe Webhooks

    • Set up the webhook endpoint
    • Test the endpoint using the Stripe CLI
    • Annals the endpoint with Stripe

Confirm Payment with Stripe Webhooks

Our app works well at this point, but we still can't programmatically confirm payments and possibly run some code if a payment was successful. We already redirect the user to the success page after they bank check out, but we tin't rely on that page alone since payment confirmation happens asynchronously.

There are ii types of events in Stripe and programming in general: Synchronous events, which take an immediate event and results (e.g., creating a customer), and asynchronous events, which don't have an immediate event (e.g., confirming payments). Considering payment confirmation is done asynchronously, the user might get redirected to the success page before their payment is confirmed and before we receive their funds.

1 of the easiest ways to become notified when the payment goes through is to use a callback or so-called Stripe webhook. Nosotros'll need to create a simple endpoint in our application, which Stripe volition call whenever an event occurs (i.eastward., when a user buys a T-shirt). By using webhooks, we tin can be absolutely sure the payment went through successfully.

In guild to employ webhooks, we need to:

  1. Set upwards the webhook endpoint
  2. Test the endpoint using the Stripe CLI
  3. Register the endpoint with Stripe

This section was written by Nik Tomazic.

Endpoint

Create a new view called stripe_webhook which prints a message every time a payment goes through successfully:

                                      # payments/views.py              @csrf_exempt              def              stripe_webhook              (              request              ):              stripe              .              api_key              =              settings              .              STRIPE_SECRET_KEY              endpoint_secret              =              settings              .              STRIPE_ENDPOINT_SECRET              payload              =              request              .              trunk              sig_header              =              asking              .              META              [              'HTTP_STRIPE_SIGNATURE'              ]              outcome              =              None              attempt              :              result              =              stripe              .              Webhook              .              construct_event              (              payload              ,              sig_header              ,              endpoint_secret              )              except              ValueError              every bit              e              :              # Invalid payload              return              HttpResponse              (              status              =              400              )              except              stripe              .              error              .              SignatureVerificationError              as              eastward              :              # Invalid signature              render              HttpResponse              (              status              =              400              )              # Handle the checkout.session.completed event              if              event              [              'type'              ]              ==              'checkout.session.completed'              :              print              (              "Payment was successful."              )              # TODO: run some custom code hither              return              HttpResponse              (              status              =              200              )                      

stripe_webhook now serves as our webhook endpoint. Hither, we're only looking for checkout.session.completed events which are called whenever a checkout is successful, but y'all can employ the same pattern for other Stripe events.

Brand sure to add together the HttpResponse import to the tiptop:

                                      from              django.http.response              import              JsonResponse              ,              HttpResponse                      

The but affair left to exercise to brand the endpoint accessible is to annals it in urls.py:

                                      # payments/urls.py              from              django.urls              import              path              from              .              import              views              urlpatterns              =              [              path              (              ''              ,              views              .              HomePageView              .              as_view              (),              name              =              'home'              ),              path              (              'config/'              ,              views              .              stripe_config              ),              path              (              'create-checkout-session/'              ,              views              .              create_checkout_session              ),              path              (              'success/'              ,              views              .              SuccessView              .              as_view              ()),              path              (              'cancelled/'              ,              views              .              CancelledView              .              as_view              ()),              path              (              'webhook/'              ,              views              .              stripe_webhook              ),              # new              ]                      

Testing the webhook

We'll use the Stripe CLI to examination the webhook.

In one case downloaded and installed, run the post-obit command in a new terminal window to log in to your Stripe account:

This command should generate a pairing code:

                        Your pairing lawmaking is: peach-loves-classy-cozy This pairing code verifies your authentication with Stripe. Printing Enter to open up the browser              (^C to quit)                      

By pressing Enter, the CLI volition open up your default web browser and ask for permission to access your account information. Go alee and allow access. Back in your concluding, you should meet something similar to:

                        > Done! The Stripe CLI is configured              for              Django Test with account id acct_<ACCOUNT_ID>  Delight note: this key will elapse after              90              days, at which point you'll need to re-authenticate.                      

Next, nosotros can start listening to Stripe events and forward them to our endpoint using the following command:

                        $ stripe listen --forrad-to localhost:8000/webhook/                      

This volition also generate a webhook signing surreptitious:

                        > Ready! Your webhook signing hush-hush is whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx              (^C to quit)                      

In order to initialize the endpoint, add the hush-hush to the settings.py file:

                                      # djangostripe/settings.py              STRIPE_ENDPOINT_SECRET              =              '<your webhook signing secret here>'                      

Stripe volition now forrard events to our endpoint. To examination, run another examination payment through with 4242 4242 4242 4242. In your terminal, you should see the Payment was successful. bulletin.

In one case washed, stop the stripe listen --frontward-to localhost:8000/webhook/ process.

If you'd like to identify the user making the purchase, you tin can use the client_reference_id to attach some sort of user identifier to the Stripe session.

For instance:

                            # payments/views.py              @csrf_exempt              def              create_checkout_session              (              request              ):              if              request              .              method              ==              'Become'              :              domain_url              =              'http://localhost:8000/'              stripe              .              api_key              =              settings              .              STRIPE_SECRET_KEY              endeavor              :              checkout_session              =              stripe              .              checkout              .              Session              .              create              (              # new              client_reference_id              =              request              .              user              .              id              if              request              .              user              .              is_authenticated              else              None              ,              success_url              =              domain_url              +              'success?session_id=              {CHECKOUT_SESSION_ID}              '              ,              cancel_url              =              domain_url              +              'cancelled/'              ,              payment_method_types              =              [              'card'              ],              mode              =              'payment'              ,              line_items              =              [              {              'proper name'              :              'T-shirt'              ,              'quantity'              :              1              ,              'currency'              :              'usd'              ,              'amount'              :              '2000'              ,              }              ]              )              render              JsonResponse              ({              'sessionId'              :              checkout_session              [              'id'              ]})              except              Exception              as              east              :              return              JsonResponse              ({              'error'              :              str              (              e              )})            

Annals the endpoint

Finally, after deploying your app, you can register the endpoint in the Stripe dashboard, under Developers > Webhooks. This volition generate a webhook signing secret for use in your production app.

For example:

Django webhook

Flow:

  1. Get Publishable Key

    • Ship an XHR request from the client to the server requesting the publishable key
    • Reply with the central
    • Use the key to create a new example of Stripe.js
  2. Create Checkout Session

    • Send another XHR request to the server requesting a new Checkout Session ID
    • Generate a new Checkout Session and send back the ID
    • Redirect to the checkout page for the user to finish their purchase
  3. Redirect the User Appropriately

    • Redirect to a success page later on a successful payment
    • Redirect to a cancellation page afterward a cancelled payment
  4. Confirm Payment with Stripe Webhooks

    • Prepare upward the webhook endpoint
    • Examination the endpoint using the Stripe CLI
    • Register the endpoint with Stripe

What'southward Side by side

On a live website it's required to accept HTTPS so your connection is secure. Also while we hardcoded our API keys and webhook signing hole-and-corner for simplicity, these should really be stored in surroundings variables. You'll probably want to store the domain_url as an environment variable as well.

Take hold of the code from the django-stripe-checkout repo on GitHub.

thomasrepostity.blogspot.com

Source: https://testdriven.io/blog/django-stripe-tutorial/

0 Response to "How to Not Charge Credit Card Again on Refresh Django"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel