├── .gitignore ├── LICENSE ├── README.md ├── djstripetut ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py ├── products ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20210210_1400.py │ └── __init__.py ├── models.py ├── tests.py └── views.py ├── requirements.txt └── templates ├── cancel.html ├── landing.html └── success.html /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python template 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | staticfiles/ 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | # pyenv 63 | .python-version 64 | 65 | 66 | 67 | # Environments 68 | .venv 69 | venv/ 70 | ENV/ 71 | 72 | # Rope project settings 73 | .ropeproject 74 | 75 | # mkdocs documentation 76 | /site 77 | 78 | # mypy 79 | .mypy_cache/ 80 | 81 | 82 | ### Node template 83 | # Logs 84 | logs 85 | *.log 86 | npm-debug.log* 87 | yarn-debug.log* 88 | yarn-error.log* 89 | 90 | # Runtime data 91 | pids 92 | *.pid 93 | *.seed 94 | *.pid.lock 95 | 96 | # Directory for instrumented libs generated by jscoverage/JSCover 97 | lib-cov 98 | 99 | # Coverage directory used by tools like istanbul 100 | coverage 101 | 102 | # nyc test coverage 103 | .nyc_output 104 | 105 | # Bower dependency directory (https://bower.io/) 106 | bower_components 107 | 108 | # node-waf configuration 109 | .lock-wscript 110 | 111 | # Compiled binary addons (http://nodejs.org/api/addons.html) 112 | build/Release 113 | 114 | # Dependency directories 115 | node_modules/ 116 | jspm_packages/ 117 | 118 | # Typescript v1 declaration files 119 | typings/ 120 | 121 | # Optional npm cache directory 122 | .npm 123 | 124 | # Optional eslint cache 125 | .eslintcache 126 | 127 | # Optional REPL history 128 | .node_repl_history 129 | 130 | # Output of 'npm pack' 131 | *.tgz 132 | 133 | # Yarn Integrity file 134 | .yarn-integrity 135 | 136 | 137 | ### Linux template 138 | *~ 139 | 140 | # temporary files which can be created if a process still has a handle open of a deleted file 141 | .fuse_hidden* 142 | 143 | # KDE directory preferences 144 | .directory 145 | 146 | # Linux trash folder which might appear on any partition or disk 147 | .Trash-* 148 | 149 | # .nfs files are created when an open file is removed but is still being accessed 150 | .nfs* 151 | 152 | 153 | ### VisualStudioCode template 154 | .vscode/* 155 | !.vscode/settings.json 156 | !.vscode/tasks.json 157 | !.vscode/launch.json 158 | !.vscode/extensions.json 159 | 160 | 161 | 162 | 163 | 164 | ### Windows template 165 | # Windows thumbnail cache files 166 | Thumbs.db 167 | ehthumbs.db 168 | ehthumbs_vista.db 169 | 170 | # Dump file 171 | *.stackdump 172 | 173 | # Folder config file 174 | Desktop.ini 175 | 176 | # Recycle Bin used on file shares 177 | $RECYCLE.BIN/ 178 | 179 | # Windows Installer files 180 | *.cab 181 | *.msi 182 | *.msm 183 | *.msp 184 | 185 | # Windows shortcuts 186 | *.lnk 187 | 188 | 189 | ### macOS template 190 | # General 191 | *.DS_Store 192 | .AppleDouble 193 | .LSOverride 194 | 195 | # Icon must end with two \r 196 | Icon 197 | 198 | # Thumbnails 199 | ._* 200 | 201 | # Files that might appear in the root of a volume 202 | .DocumentRevisions-V100 203 | .fseventsd 204 | .Spotlight-V100 205 | .TemporaryItems 206 | .Trashes 207 | .VolumeIcon.icns 208 | .com.apple.timemachine.donotpresent 209 | 210 | # Directories potentially created on remote AFP share 211 | .AppleDB 212 | .AppleDesktop 213 | Network Trash Folder 214 | Temporary Items 215 | .apdisk 216 | 217 | 218 | ### SublimeText template 219 | # Cache files for Sublime Text 220 | *.tmlanguage.cache 221 | *.tmPreferences.cache 222 | *.stTheme.cache 223 | 224 | # Workspace files are user-specific 225 | *.sublime-workspace 226 | 227 | # Project files should be checked into the repository, unless a significant 228 | # proportion of contributors will probably not be using Sublime Text 229 | # *.sublime-project 230 | 231 | # SFTP configuration file 232 | sftp-config.json 233 | 234 | # Package control specific files 235 | Package Control.last-run 236 | Package Control.ca-list 237 | Package Control.ca-bundle 238 | Package Control.system-ca-bundle 239 | Package Control.cache/ 240 | Package Control.ca-certs/ 241 | Package Control.merged-ca-bundle 242 | Package Control.user-ca-bundle 243 | oscrypto-ca-bundle.crt 244 | bh_unicode_properties.cache 245 | 246 | # Sublime-github package stores a github token in this file 247 | # https://packagecontrol.io/packages/sublime-github 248 | GitHub.sublime-settings 249 | 250 | 251 | ### Vim template 252 | # Swap 253 | [._]*.s[a-v][a-z] 254 | [._]*.sw[a-p] 255 | [._]s[a-v][a-z] 256 | [._]sw[a-p] 257 | 258 | # Session 259 | Session.vim 260 | 261 | # Temporary 262 | .netrwhist 263 | 264 | # Auto-generated tag files 265 | tags 266 | 267 | ### Project template 268 | 269 | django_tutorial/media/ 270 | 271 | .pytest_cache/ 272 | 273 | .env 274 | 275 | ngrok -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | Copyright (c) 2021, JustDjango 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
8 | The Definitive Django Learning Platform. 9 |
10 | 11 | 12 | # Django Stripe Tutorial 13 | 14 | This is a tutorial on how to integrate Stripe Payments with Django. 15 | 16 | You can find the written version here: 17 | https://justdjango.com/blog/django-stripe-payments-tutorial/ 18 | 19 | Or watch it on YouTube: 20 | https://www.youtube.com/watch?v=722A27IoQnk&ab_channel=JustDjango 21 | 22 | --- 23 | 24 | 32 | -------------------------------------------------------------------------------- /djstripetut/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django-stripe-tutorial/22d2b154955418c8cfc4340c128f53d0cebe6a3a/djstripetut/__init__.py -------------------------------------------------------------------------------- /djstripetut/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for djstripetut project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djstripetut.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /djstripetut/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for djstripetut project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.1.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.1/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | 15 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 16 | BASE_DIR = Path(__file__).resolve().parent.parent 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'xy7vyv5c4tk+-d8i7-em61gm-tm0(=t0(0i%(lizeu2nhu_5ow' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'products' 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'djstripetut.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [BASE_DIR / 'templates'], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'djstripetut.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/3.1/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': BASE_DIR / 'db.sqlite3', 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/3.1/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | 111 | TIME_ZONE = 'UTC' 112 | 113 | USE_I18N = True 114 | 115 | USE_L10N = True 116 | 117 | USE_TZ = True 118 | 119 | 120 | # Static files (CSS, JavaScript, Images) 121 | # https://docs.djangoproject.com/en/3.1/howto/static-files/ 122 | 123 | STATIC_URL = '/static/' 124 | 125 | STRIPE_PUBLIC_KEY = "" 126 | STRIPE_SECRET_KEY = "" 127 | STRIPE_WEBHOOK_SECRET = "" -------------------------------------------------------------------------------- /djstripetut/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path 3 | from products.views import ( 4 | CreateCheckoutSessionView, 5 | ProductLandingPageView, 6 | SuccessView, 7 | CancelView, 8 | stripe_webhook, 9 | StripeIntentView 10 | ) 11 | 12 | urlpatterns = [ 13 | path('admin/', admin.site.urls), 14 | path('create-payment-intent/