Aula 94 – Django – Ecommerce – Confirmação e Processamento de Pagamento
Aula 94 – Django – Ecommerce – Confirmação e Processamento de Pagamento
Voltar para página principal do blog
Todas as aulas desse curso
Aula 93 Aula 95
Redes Sociais do Código Fluente:
Scarlett Finch
Scarlett Finch é uma influenciadora virtual criada com IA.
Ela é 🎤 cantora e 🎶compositora pop britânica.
Siga a Scarlett Finch no Instagram:
Conecte-se comigo!
LinkedIn: Fique à vontade para me adicionar no LinkedIn.
Ao conectar-se comigo, você terá acesso a atualizações regulares sobre desenvolvimento web, insights profissionais e oportunidades de networking no setor de tecnologia.
GitHub: Siga-me no GitHub para ficar por dentro dos meus projetos mais recentes, colaborar em código aberto ou simplesmente explorar os repositórios que eu contribuo, o que pode ajudar você a aprender mais sobre programação e desenvolvimento de software.
Recursos e Afiliados
Explorando os recursos abaixo, você ajuda a apoiar nosso site.
Somos parceiros afiliados das seguintes plataformas:
- https://heygen.com/ – Eleve a produção de seus vídeos com HeyGen! Com esta plataforma inovadora, você pode criar vídeos envolventes utilizando avatares personalizados, ideal para quem busca impactar e conectar com audiências em todo o mundo. HeyGen transforma a maneira como você cria conteúdo, oferecendo ferramentas fáceis de usar para produzir vídeos educativos, demonstrações de produtos e muito mais. Descubra o poder de comunicar através de avatares interativos e traga uma nova dimensão para seus projetos. Experimente HeyGen agora e revolucione sua forma de criar vídeos!
- letsrecast.ai – Redefina a maneira como você consome artigos com Recast. Esta plataforma transforma artigos longos em diálogos de áudio que são informativos, divertidos e fáceis de entender. Ideal para quem está sempre em movimento ou busca uma forma mais conveniente de se manter informado. Experimente Recast agora.
- dupdub.com – Explore o universo do marketing digital com DupDub. Esta plataforma oferece ferramentas inovadoras e soluções personalizadas para elevar a sua estratégia de marketing online. Ideal para empresas que buscam aumentar sua visibilidade e eficiência em campanhas digitais. Descubra mais sobre DupDub.
- DeepBrain AI Studios – Revolucione a criação de conteúdo com a tecnologia de inteligência artificial da DeepBrain AI Studios. Esta plataforma avançada permite que você crie vídeos interativos e apresentações utilizando avatares digitais gerados por IA, que podem simular conversas reais e interações humanas. Perfeito para educadores, criadores de conteúdo e empresas que querem inovar em suas comunicações digitais. Explore DeepBrain AI Studios.
- Audyo.ai – Transforme a maneira como você interage com conteúdo auditivo com Audyo.ai. Esta plataforma inovadora utiliza inteligência artificial para criar experiências de áudio personalizadas, melhorando a acessibilidade e a compreensão de informações através de podcasts, transcrições automáticas e síntese de voz avançada. Ideal para profissionais de mídia, educadores e qualquer pessoa que deseje acessar informações auditivas de maneira mais eficiente e envolvente. Descubra Audyo.ai e suas possibilidades.
- Acoust.io – Transforme sua produção de áudio com Acoust.io. Esta plataforma inovadora fornece uma suite completa de ferramentas para criação, edição e distribuição de áudio, ideal para artistas, produtores e empresas de mídia em busca de excelência e inovação sonora. Acoust.io simplifica o processo de levar suas ideias à realidade, oferecendo soluções de alta qualidade que elevam seus projetos de áudio. Experimente Acoust.io agora e descubra um novo patamar de possibilidades para seu conteúdo sonoro.
- Hostinger – Hospedagem web acessível e confiável. Ideal para quem busca soluções de hospedagem de sites com excelente custo-benefício e suporte ao cliente robusto. Saiba mais sobre a Hostinger.
- Digital Ocean – Infraestrutura de nuvem para desenvolvedores. Oferece uma plataforma de nuvem confiável e escalável projetada especificamente para desenvolvedores que precisam de servidores virtuais, armazenamento e networking. Explore a Digital Ocean.
- One.com – Soluções simples e poderosas para o seu site. Uma escolha ideal para quem busca registrar domínios, hospedar sites ou criar presença online com facilidade e eficiência. Visite One.com.
Educação e Networking
Amplie suas habilidades e sua rede participando de cursos gratuitos e comunidades de desenvolvedores:
- Digital Innovation One – Cursos gratuitos com certificado.
- Workover – Aprenda Python3 gratuitamente.
- Comunidades de desenvolvedores para networking:
Canais do Youtube
Explore nossos canais no YouTube para uma variedade de conteúdos educativos e de entretenimento, cada um com um foco único para enriquecer sua experiência de aprendizado e lazer.
Toti
Toti: Meu canal pessoal, onde posto clips artesanais de músicas que curto tocar, dicas de teoria musical, entre outras coisas.
Scarlett Finch
Scarlett Finch: Cantora e influenciadora criada com IA.
Lofi Music Zone Beats
Lofi Music Zone Beats: O melhor da música Lofi para estudo, trabalho e relaxamento, criando o ambiente perfeito para sua concentração.
Backing Track / Play-Along
Backing Track / Play-Along: Acompanhe faixas instrumentais para prática musical, ideal para músicos que desejam aprimorar suas habilidades.
Código Fluente
Código Fluente: Aulas gratuitas de programação, devops, IA, entre outras coisas.
Putz!
Putz!: Canal da banda Putz!, uma banda virtual, criada durante a pandemia com mais 3 amigos, Fábio, Tatá e Lula.
PIX para doações
Aula 94 – Django – Ecommerce – Confirmação e Processamento de Pagamento
Código da aula: Github
Nesta aula, vamos implementar a lógica de confirmação e processamento de pagamento no nosso projeto de e-commerce usando o Stripe.
Certifique-se que está logado no Stripe
Faça login com sua conta Stripe
stripe login
Encaminhe eventos ao seu webhook
stripe listen --forward-to localhost:4242/api/webhook
Acione eventos com a CLI
stripe trigger payment_intent.succeeded
Vamos adicionar as views de sucesso e falha de pagamento, ajustar as URLs e atualizar o JavaScript para tratar essas situações.
Boas práticas no Github
Crie a branch da aula, vou chamar a minha de: feature/payment-confirmation-and-processing
Usar feature/...
para branches no GitHub, ajuda a organizar e identificar rapidamente branches dedicadas ao desenvolvimento de novas funcionalidades.
Prefixos como feature/
, bugfix/
, hotfix/
, e release/
são amplamente aceitos como boas práticas na comunidade de desenvolvimento e ajudam a manter um fluxo de trabalho consistente e organizado.
Atualizações no código
Views de Sucesso e Falha de Pagamento
Primeiramente, vamos criar duas novas views no arquivo views.py
do billing, para renderizar as páginas de sucesso e falha de pagamento.
django_ecommerce/e_commerce/billing/views.py
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
import stripe
import json
# Configure a chave da API do Stripe
stripe.api_key = settings.STRIPE_API_KEY
# View para renderizar a página de sucesso do pagamento
def payment_success_view(request):
return render(request, 'billing/payment-success.html')
# View para renderizar a página de falha do pagamento
def payment_failed_view(request):
return render(request, 'billing/payment-failed.html')
# View para renderizar a página de método de pagamento
def payment_method_view(request):
# Adicione um log para verificar se a chave está sendo passada (opcional)
# print(f"Publish Key na view: {settings.STRIPE_PUB_KEY}")
context = {'publish_key': settings.STRIPE_PUB_KEY}
return render(request, 'billing/payment-method.html', context)
# View para criar o PaymentIntent do Stripe
@csrf_exempt
@require_POST
def create_payment_intent(request):
data = json.loads(request.body)
try:
# Calcular o valor com base nos itens enviados
# Substitua esta função pela sua lógica de cálculo de preços
amount = calculate_order_amount(data['items'])
intent = stripe.PaymentIntent.create(
amount=amount,
currency='usd',
payment_method_types=['card'],
)
return JsonResponse({'clientSecret': intent.client_secret})
except Exception as e:
return JsonResponse({'error': str(e)}, status=400)
# Função para calcular o valor do pedido
def calculate_order_amount(items):
# Substitua esta função pela sua lógica de cálculo de preços
return 1400 # preço de exemplo
Atualização das URLs
Agora vamos adicionar as novas URLs no nosso arquivo urls.py
.
e_commerce/e_commerce/urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth.views import LogoutView
from django.urls import path, include
from django.views.generic import TemplateView
from carts.views import cart_detail_api_view
from accounts.views import LoginView, RegisterView, LogoutView, guest_register_view
from addresses.views import checkout_address_create_view, checkout_address_reuse_view
from billing.views import create_payment_intent, payment_method_view, payment_success_view, payment_failed_view
from .views import (home_page,
about_page,
contact_page
)
urlpatterns = [
path('', home_page, name='home'),
path('about/', about_page, name='about'),
path('contact/', contact_page, name='contact'),
path('cart/', include("carts.urls", namespace="cart")),
path('checkout/address/create/', checkout_address_create_view, name='checkout_address_create'),
path('checkout/address/reuse/', checkout_address_reuse_view, name='checkout_address_reuse'),
path('api/cart/', cart_detail_api_view, name='api-cart'),
path('login/', LoginView.as_view(), name='login'),
path('create-payment-intent', create_payment_intent, name='create-payment-intent'),
path('billing/payment-method/', payment_method_view, name='billing-payment-method'),
path('billing/payment-success/', payment_success_view, name='payment-success'),
path('billing/payment-failed/', payment_failed_view, name='payment-failed'),
path('register/guest/', guest_register_view, name='guest_register'),
path('logout/', LogoutView.as_view(), name='logout'),
path('register/', RegisterView.as_view(), name='register'),
path('bootstrap/', TemplateView.as_view(template_name='bootstrap/example.html')),
path('search/', include("search.urls", namespace="search")),
path('products/', include("products.urls", namespace="products")),
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Atualização do JavaScript
Vamos agora atualizar o arquivo JavaScript stripe_payment.js
para redirecionar para as páginas de sucesso e falha de pagamento, dependendo do resultado do processamento do pagamento.
static_local/js/stripe_payment.js
$(document).ready(function () {
console.log("Documento pronto");
function initializeStripe() {
const stripeKeyElement = $("#stripe-key");
if (stripeKeyElement.length === 0) {
console.error("Elemento stripe-key não encontrado");
return;
}
const publishKey = stripeKeyElement.data("publishKey");
if (!publishKey) {
console.error("Chave pública do Stripe não encontrada");
return;
}
const stripe = Stripe(publishKey);
let elements,
cardElement,
clientSecret = null;
function initialize() {
$.ajax({
url: "/create-payment-intent",
method: "POST",
contentType: "application/json",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
},
data: JSON.stringify({ items: [{ id: "xl-tshirt", price: 2000 }] }),
success: function (data) {
if (data.error) {
console.error("Falha ao criar o intent de pagamento:", data.error);
return;
}
clientSecret = data.clientSecret;
elements = stripe.elements();
cardElement = elements.create("card");
cardElement.mount("#payment-element");
console.log("Elemento do cartão montado");
},
error: function (xhr, status, error) {
console.error("Erro ao inicializar os elementos do Stripe:", error);
},
});
}
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== "") {
const cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const paymentForm = $("#payment-form");
if (paymentForm.length > 0) {
paymentForm.on("submit", function (event) {
event.preventDefault();
if (!elements || !cardElement) {
showMessage(
"Elemento do cartão não inicializado corretamente.",
true
);
return;
}
setLoading(true);
stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
// Inclua os detalhes de faturamento se necessário
},
},
})
.then(function (result) {
if (result.error) {
showMessage(result.error.message, true);
setTimeout(function () {
window.location.href = "/billing/payment-failed/";
}, 3000);
} else if (
result.paymentIntent &&
result.paymentIntent.status === "succeeded"
) {
showMessage("Pagamento realizado com sucesso!", false);
setTimeout(function () {
window.location.href = "/billing/payment-success/";
}, 3000);
} else {
showMessage(
"Pagamento não foi bem-sucedido. Tente novamente.",
true
);
setTimeout(function () {
window.location.href = "/billing/payment-failed/";
}, 3000);
}
setLoading(false);
})
.catch(function (error) {
showMessage("Ocorreu um erro inesperado.", true);
setTimeout(function () {
window.location.href = "/billing/payment-failed/";
}, 3000);
setLoading(false);
});
});
} else {
console.error("Formulário de pagamento não encontrado");
}
function showMessage(messageText, isError) {
const messageContainer = $("#payment-message");
messageContainer.text(messageText).removeClass("hidden");
if (isError) {
messageContainer.addClass("error-message");
} else {
messageContainer.removeClass("error-message");
}
setTimeout(function () {
messageContainer.addClass("hidden").text("");
}, 4000);
}
function setLoading(isLoading) {
const submitButton = $("#submit");
submitButton.prop("disabled", isLoading);
$("#spinner").toggleClass("hidden", !isLoading);
$("#button-text").toggleClass("hidden", isLoading);
}
initialize();
}
// Inicializa o Stripe diretamente se o elemento estiver presente
const stripeKeyElement = $("#stripe-key");
if (stripeKeyElement.length > 0) {
initializeStripe();
}
});
Mudanças
- Adição do parâmetro
isError
na funçãoshowMessage
para distinguir entre mensagens de sucesso e erro. - Atualização das chamadas para
showMessage
para incluir o novo parâmetro false,showMessage("Pagamento realizado com sucesso!", false);
, indicando que esta é uma mensagem de sucesso e não um erro. - Simplificação do redirecionamento pós-pagamento para URLs fixas e claras, com uma redução no tempo de espera.
- Implementação de redirecionamento para a página de falha de pagamento em caso de erro durante a confirmação do pagamento.
Isso melhora a clareza, usabilidade e feedback visual para o usuário, bem como simplifica a lógica do código.
Templates de Sucesso e Falha de Pagamento
Crie os arquivos de templates para as páginas de sucesso e falha de pagamento.
Template de Sucesso (billing/templates/billing/payment-success.html
):
billing/templates/billing/payment-success.html
<!-- Começo do template -->
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>Pagamento realizado com sucesso!</h1>
<p>Seu pedido foi processado com sucesso. Obrigado por sua compra!</p>
<a href="{% url 'home' %}" class="btn btn-primary">Voltar para a página inicial</a>
</div>
{% endblock %}
<!-- Fim do template -->
Template de Falha (billing/templates/billing/payment-failed.html
):
billing/templates/billing/payment-failed.html
<!-- Começo do template -->
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>Falha no pagamento</h1>
<p>Ocorreu um problema ao processar seu pagamento. Por favor, tente novamente.</p>
<a href="{% url 'billing-payment-method' %}" class="btn btn-primary">Tentar novamente</a>
</div>
{% endblock %}
<!-- Fim do template -->
Testando
Suba o servidor
python manage.py runserver
Acesse: 127.0.0.1:8000/billing/payment-method
Nesta aula, implementamos a lógica de confirmação e processamento de pagamento no nosso projeto de e-commerce usando Django e Stripe.
Adicionamos views para sucesso e falha de pagamento, ajustamos as URLs e atualizamos o JavaScript para tratar essas situações.
Com isso, agora seu sistema de pagamento está completo e você pode testar o fluxo de pagamento no seu ambiente de desenvolvimento.
Na próxima aula, vamos aprimorar nosso sistema de pagamento implementando a lógica para calcular o valor total do pedido com base nos itens do carrinho.
Além disso, vamos criar uma API para obter os itens do carrinho em tempo real e integrar essa funcionalidade ao frontend.
Isso permitirá que o valor do pedido seja calculado dinamicamente, oferecendo uma experiência mais precisa e eficiente para os usuários.