Resources:
simple_ecommerce/django_project/ecommerce_app/views.py
def process_payment(request):
#...
@csrf_exempt
def payment_done(request):
return render(request, 'ecommerce_app/payment_done.html')
@csrf_exempt
def payment_canceled(request):
return render(request, 'ecommerce_app/payment_cancelled.html')
def checkout(request):
if request.method == 'POST':
form = CheckoutForm(request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
#...
#...
cart.clear(request)
request.session['order_id'] = o.id
return redirect('process_payment')
else:
form = CheckoutForm()
return render(request, 'ecommerce_app/checkout.html', locals())
process_payment.html
{% block title %}Make Payment{% endblock %}
{% block content %}
Pay with PayPal
{{ form.render }}
{% endblock %}
payment_done.html
{% block content %}
Payment done.
{% endblock %}
payment_cancelled.html
{% block content %}
Payment cancelled.
{% endblock %}
simple_ecommerce/django_project/ecommerce_app/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('product///',
views.show_product, name='show_product'),
path('cart/', views.show_cart, name='show_cart'),
path('checkout/', views.checkout, name='checkout'),
path('process-payment/', views.process_payment, name='process_payment'),
path('payment-done/', views.payment_done, name='payment_done'),
path('payment-cancelled/', views.payment_canceled, name='payment_cancelled'),
]
settings.py add
PAYPAL_RECEIVER_EMAIL = '[email protected]'
PAYPAL_TEST = True
Subscription
simple_ecommerce/django_project/ecommerce_app/forms.py
class CheckoutForm(forms.ModelForm):
#...
subscription_options = [
('1-month', '1-Month subscription ($10 USD/Mon)'),
('6-month', '6-Month subscription Save $10 ($50 USD/Mon)'),
('1-year', '1-Year subscription Save $30 ($90 USD/Mon)'),
]
class SubscriptionForm(forms.Form):
plans = forms.ChoiceField(choices=subscription_options)
simple_ecommerce/django_project/ecommerce_app/views.py
@csrf_exempt
def payment_canceled(request):
return render(request, 'ecommerce_app/payment_cancelled.html')
def subscription(request):
if request.method == 'POST':
f = SubscriptionForm(request.POST)
if f.is_valid():
request.session['subscription_plan'] = request.POST.get('plans')
return redirect('process_subscription')
else:
f = SubscriptionForm()
return render(request, 'ecommerce_app/subscription_form.html', locals()
simple_ecommerce/django_project/ecommerce_app/templates/ecommerce_app/subscription_form.html
{% endblock %}
simple_ecommerce/django_project/ecommerce_app/urls.py
urlpatterns = [
#...
path('checkout/', views.checkout, name='checkout'),
path('process-payment/', views.process_payment, name='process_payment'),
path('payment-done/', views.payment_done, name='payment_done'),
path('payment-cancelled/', views.payment_canceled, name='payment_cancelled'),
path('subscribe/', views.subscription, name='subscription'),
]
simple_ecommerce/django_project/ecommerce_app/views.py
def subscription(request):
#...
def process_subscription(request):
subscription_plan = request.session.get('subscription_plan')
host = request.get_host()
if subscription_plan == '1-month':
price = "10"
billing_cycle = 1
billing_cycle_unit = "M"
elif subscription_plan == '6-month':
price = "50"
billing_cycle = 6
billing_cycle_unit = "M"
else:
price = "90"
billing_cycle = 1
billing_cycle_unit = "Y"
paypal_dict = {
"cmd": "_xclick-subscriptions",
'business': settings.PAYPAL_RECEIVER_EMAIL,
"a3": price, # monthly price
"p3": billing_cycle, # duration of each unit (depends on unit)
"t3": billing_cycle_unit, # duration unit ("M for Month")
"src": "1", # make payments recur
"sra": "1", # reattempt payment on payment error
"no_note": "1", # remove extra notes (optional)
'item_name': 'Content subscription',
'custom': 1, # custom data, pass something meaningful here
'currency_code': 'USD',
'notify_url': 'http://{}{}'.format(host,
reverse('paypal-ipn')),
'return_url': 'http://{}{}'.format(host,
reverse('payment:done')),
'cancel_return': 'http://{}{}'.format(host,
reverse('payment:canceled')),
}
form = PayPalPaymentsForm(initial=paypal_dict, button_type="subscribe")
return render(request, 'payment/process_subscription.html', locals())
simple_ecommerce/django_project/ecommerce_app/templates/ecommerce_app/process_subscription.html
Subscribe using PayPal
{{ form.render }}
{% endblock %}
simple_ecommerce/django_project/ecommerce_app/urls.py
urlpatterns = [
#...
path('subscribe/', views.subscription, name='subscription'),
path('process_subscription/', views.process_subscription, name='process_subscription'),
]
simple_ecommerce/django_project/ecommerce_app/signals.py
@receiver(valid_ipn_received)
def ipn_receiver(sender, **kwargs):
ipn_obj = sender
Check for Buy Now IPN
if ipn_obj.txn_type == 'web_accept':
if ipn_obj.payment_status == ST_PP_COMPLETED:
# payment was successful
print('great!')
order = get_object_or_404(Order, id=ipn_obj.invoice)
if order.get_total_cost() == ipn_obj.mc_gross:
# mark the order as paid
order.paid = True
order.save()
Check for subscription signup IPN
elif ipn_obj.txn_type == "subscr_signup":
# get user id and activate the account
id = ipn_obj.custom
user = User.objects.get(id=id)
user.active = True
user.save()
subject = 'Sign Up Complete'
message = 'Thanks for signing up!'
email = EmailMessage(subject,
message,
'[email protected]',
[user.email])
email.send()
Check for subscription payment IPN
elif ipn_obj.txn_type == "subscr_payment":
# get user id and extend the subscription
id = ipn_obj.custom
user = User.objects.get(id=id)
# user.extend() # extend the subscription
subject = 'Your Invoice for {} is available'.format(
datetime.strftime(datetime.now(), "%b %Y"))
message = 'Thanks for using our service. The balance was automatically ' \
'charged to your credit card.'
email = EmailMessage(subject,
message,
'[email protected]',
[user.email])
email.send()
Check for failed subscription payment IPN
elif ipn_obj.txn_type == "subscr_failed":
pass
Check for subscription cancellation IPN
elif ipn_obj.txn_type == "subscr_cancel":
pass