|
|
|
|
|
Sample Integration payU in django based projects |
|
|
|
Settings.py |
|
|
|
|
|
PAYU_INFO = { |
|
|
|
'merchant_key': "test merchant key", |
|
'merchant_salt': "test merchant salt", |
|
# for production environment use 'https://secure.payu.in/_payment' |
|
'payment_url': 'https://test.payu.in/_payment', |
|
'surl':'http://example.com/pay-success/', |
|
'furl':'http://example.com/failure/', |
|
'curl':'http://example.com/cancel/', |
|
} |
|
|
|
|
|
Urls.py |
|
|
|
""" Define your urls here , this urls needed for PayU transaction """ |
|
|
|
from django.conf.urls import patterns, include, url |
|
|
|
urlpatterns = patterns('', |
|
|
|
url(r'^pay-success/$','apps.billing.views.success', name='payu_success'), |
|
url(r'^failure/$', 'apps.billing.views.failure', name='failure'), |
|
url(r'^cancel/$', 'apps.billing.views.cancel', name='cancel'), |
|
url(r'^success/$','apps.buyer.views.success',name='success'), |
|
|
|
) |
|
|
|
|
|
|
|
models.py |
|
|
|
from django.db import models |
|
from uuid import uuid4 |
|
from uuid import UUID |
|
import uuid |
|
from django_extensions.db.fields import UUIDField |
|
|
|
|
|
class MyOrder(models.Model): |
|
items = models.ManyToManyField(OrderItem, null=True, blank=True) |
|
order_date = models.DateField(auto_now=True) |
|
buyer = models.ForeignKey(Buyer) |
|
|
|
txnid = models.CharField(max_length=36, primary_key=True) |
|
amount = models.FloatField(null=True, blank=True,default=0.0) |
|
hash = models.CharField(max_length=500, null=True, blank=True) |
|
billing_name = models.CharField(max_length=500, null=True, blank=True) |
|
billing_street_address = models.CharField(max_length=500, null=True, blank=True) |
|
billing_country = models.CharField(max_length=500, null=True, blank=True) |
|
billing_state = models.CharField(max_length=500, null=True, blank=True) |
|
billing_city = models.CharField(max_length=500, null=True, blank=True) |
|
billing_pincode = models.CharField(max_length=500, null=True, blank=True) |
|
billing_mobile = models.CharField(max_length=500, null=True, blank=True) |
|
billing_email = models.CharField(max_length=500, null=True, blank=True) |
|
|
|
shipping_name = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_street_address = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_country = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_state = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_city = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_pincode = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_mobile = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_rate = models.FloatField(null=False, blank=False, default=0.0) |
|
status = models.CharField(max_length=500, null=True, blank=True) |
|
shipping_email = models.CharField(max_length=500, null=True, blank=True) |
|
|
|
payment_method = models.CharField(max_length=1000,verbose_name='Payment-method') |
|
is_paid = models.BooleanField(default=False) |
|
is_delivered = models.BooleanField(default=False) |
|
is_accepted = models.BooleanField(default=False) |
|
|
|
|
|
|
|
Views.py |
|
|
|
|
|
from django.core.exceptions import ObjectDoesNotExist |
|
from django.contrib.auth.decorators import login_required |
|
import hashlib |
|
from django.conf import settings |
|
from .util import generate_hash |
|
|
|
@login_required |
|
|
|
def buy_order(request): |
|
""" funtion for save all orders and genarate order id""" |
|
items = None |
|
orderitem = None |
|
extra = False |
|
if request.user.is_authenticated() and not request.user.is_staff: |
|
user = Buyer.objects.get(id=request.user.id) // Buyer is model for Users |
|
try: |
|
cart = Cart.objects.get(buyer=request.user) // Check Any items is there in Cart Model |
|
except ObjectDoesNotExist: |
|
extra = "You dont have any item in your cart" // Intializing there is no items in cart |
|
variables = RequestContext(request, {'extra': extra}) |
|
return render_to_response('home.html', variables) // return back to home page with message (use "reverse") |
|
|
|
total_amount = OrderItem.objects.filter(buyer=request.user) // get the total amount from the OrderItem Model |
|
item_list = [] |
|
rg = rg |
|
|
|
if cart and request.POST: |
|
|
|
""" Validaing shipping address details from Post request """ |
|
if rg('shippingnme')and rg('shippingaddress') and rg('shippingemail') and rg('shippingpostel'): |
|
try: |
|
"""store all products to MyOrder model and genarate order id for the order""" |
|
myorder = MyOrder(buyer=user) |
|
myorder.buyer = user |
|
myorder.billing_name = rg('billingname') |
|
myorder.billing_street_address = rg('billingaddress') |
|
myorder.billing_pincode = rg('billingpostel') |
|
myorder.billing_city = rg('billingcity') |
|
myorder.billing_country = rg('billingcountry') |
|
myorder.billing_state = rg('billingstate') |
|
myorder.billing_mobile = rg('billingphone') |
|
myorder.billing_email = rg('billingemail') |
|
|
|
# myorder of shipping Address |
|
myorder.shipping_pincode = rg('shippingpostel') |
|
myorder.shipping_name = rg('shippingnme') |
|
myorder.shipping_street_address = rg('shippingaddress') |
|
myorder.shipping_city = rg('shippingcity') |
|
myorder.shipping_state = rg('shippingstate') |
|
myorder.shipping_mobile = rg('shippingphone') |
|
myorder.shipping_country = rg('shippingcountry') |
|
myorder.shipping_email = rg('shippingemail') |
|
|
|
""" Checking whether the payment method is COD or Online """ |
|
|
|
if rg('paymentmethod'): |
|
myorder.payment_method = rg('paymentmethod') |
|
else: |
|
myorder.payment_method = 'ON' |
|
myorder.comment = rg('prodcutmessage') |
|
myorder.txnid = str(uuid.uuid1().int >> 64) |
|
myorder.save() |
|
|
|
""" genarate an oredr id, the below loop will add all orderd product to the OrderItem Model """ |
|
|
|
for order in cart.items.all(): |
|
orderitem = OrderItem() |
|
orderitem.buyer = order.buyer |
|
orderitem.product_id = order.product.id |
|
orderitem.product_title = order.product.name |
|
orderitem.weight = order.product.weight |
|
orderitem.product_price = order.product.gross_pay()[0] |
|
orderitem.total_amount = order.total |
|
orderitem.quantity = order.quantity |
|
orderitem.save() |
|
myorder.items.add(orderitem) |
|
|
|
total_details = total_price_fu(myorder) |
|
|
|
""" After adding products to order assigning a |
|
transaction amount and shipping charge to the order """ |
|
|
|
myorder = MyOrder.objects.get(pk=myorder.txnid) |
|
myorder.amount = total_details['grand_total'] |
|
myorder.shipping_rate = total_details['shipping_rate'] |
|
|
|
""" Assigning all values for hash funtion for payu """ |
|
|
|
cleaned_data = { |
|
'key': settings.PAYU_INFO['merchant_key'],'txnid': myorder.txnid, |
|
'amount': myorder.amount,'productinfo':orderitem.product_title, |
|
'firstname': myorder.billing_name,'email': myorder.billing_email, |
|
'udf1': '', 'udf2': '', 'udf3': '', 'udf4': '', 'udf5': '', 'udf6': '', |
|
'udf7': '', 'udf8': '', 'udf9': '', 'udf10': ''} |
|
|
|
""" the generate_hash funtion is use for genarating hash |
|
value from cleaned_data """ |
|
|
|
""" generate_hash i defaine in below this code please reffer """ |
|
|
|
hash_o = generate_hash(cleaned_data) |
|
myorder.hash =hash_o |
|
myorder.save() |
|
return HttpResponse( |
|
""" |
|
<html> |
|
<head><title>Redirecting...</title></head> |
|
<body> |
|
<form action='%s' method='post' name="payu"> |
|
<input type="hidden" name="firstname" value="%s" /> |
|
<input type="hidden" name="surl" value="%s" /> |
|
<input type="hidden" name="phone" value="%s" /> |
|
<input type="hidden" name="key" value="%s" /> |
|
<input type="hidden" name="hash" value = |
|
"%s" /> |
|
<input type="hidden" name="curl" value="%s" /> |
|
<input type="hidden" name="furl" value="%s" /> |
|
<input type="hidden" name="txnid" value="%s" /> |
|
<input type="hidden" name="productinfo" value="%s" /> |
|
<input type="hidden" name="amount" value="%s" /> |
|
<input type="hidden" name="email" value="%s" /> |
|
<input type="hidden" value="submit"> |
|
</form> |
|
</body> |
|
<script language='javascript'> |
|
window.onload = function(){ |
|
document.forms['payu'].submit() |
|
} |
|
</script> |
|
</html>""" % (settings.PAYU_INFO['payment_url'], |
|
myorder.billing_name, settings.PAYU_INFO[ |
|
'surl'], |
|
myorder.billing_mobile, |
|
settings.PAYU_INFO['merchant_key'], |
|
hash_o, |
|
settings.PAYU_INFO['curl'], |
|
settings.PAYU_INFO['furl'], |
|
myorder.txnid, |
|
orderitem.product_title, |
|
myorder.amount, |
|
myorder.billing_email |
|
) |
|
) |
|
|
|
|
|
|
|
util.py |
|
|
|
|
|
from hashlib import sha512 |
|
from django.conf import settings |
|
KEYS = ('key', 'txnid', 'amount', 'productinfo', 'firstname', 'email', |
|
'udf1', 'udf2', 'udf3', 'udf4', 'udf5', 'udf6', 'udf7', 'udf8', |
|
'udf9', 'udf10') |
|
|
|
def generate_hash(data): |
|
keys = ('key', 'txnid', 'amount', 'productinfo', 'firstname', 'email', |
|
'udf1', 'udf2', 'udf3', 'udf4', 'udf5', 'udf6', 'udf7', 'udf8', |
|
'udf9', 'udf10') |
|
hash = sha512('') |
|
for key in KEYS: |
|
hash.update("%s%s" % (str(data.get(key, '')), '|')) |
|
hash.update(settings.PAYU_INFO.get('merchant_salt')) |
|
return hash.hexdigest().lower() |
|
|
|
def verify_hash(data, SALT): |
|
keys.reverse() |
|
hash = sha512(settings.PAYU_INFO.get('merchant_salt')) |
|
hash.update("%s%s" % ('|', str(data.get('status', '')))) |
|
for key in KEYS: |
|
hash.update("%s%s" % ('|', str(data.get(key, '')))) |
|
return (hash.hexdigest().lower() == data.get('hash')) |
|
|
|
|
|
After the Transaction you will get response in Json format , you can validate the amount , transaction id, |
|
item details etc , ie, whatever details we gave to Payu for transaction it will return all the data which we |
|
provided with status message ( success, failure , cancel ) |
|
|
|
Example Queryset in Json Format |
|
|
|
<QueryDict: {u'name_on_card': [u'sda'], u'net_amount_debit': [u'10'], u'payment_source': [u'payu'], u'udf10': [u''], |
|
u'issuing_bank': [u'AXIS'], u'field7': [u''], u'udf3': [u''], u'unmappedstatus': [u'captured'], |
|
u'card_type': [u'VISA'], u'PG_TYPE': [u'HDFC'], u'addedon': [u'2014-10-20 18:50:38'], u'city': [u''], |
|
u'field8': [u''], u'field9': [u'SUCCESS'], u'field2': [u'999999'], u'field3': [u'2819211501842931'], |
|
u'field1': [u'429367481506'], u'field6': [u''], u'zipcode': [u''], u'field4': [u'-1'], u'field5': [u''], |
|
u'productinfo': [u'adsdsd'], u'address1': [u''], u'discount': [u'0.00'], u'email': [u'djangorenjith@gmail.com'], |
|
u'cardhash': [u'This field is no longer supported in postback params.'], u'udf4': [u''], u'status': [u'success'], |
|
u'bank_ref_num': [u'2819211501842931'], u'error_Message': [u'No Error'], } |
|
|
|
|
|
Accodrding to Transaction Status Payu Automaticaly redirect to the provided url , you can get the Response in views |
|
using get method (request.POST.get('status')=='success' ) |
|
|
|
|
|
# Transaction Success |
|
@csrf_exempt |
|
def success(request): |
|
======================== |
|
do what functionality you need |
|
========================= |
|
# Transaction Failure |
|
@csrf_exempt |
|
def failure(request): |
|
======================== |
|
do what functionality you need |
|
========================= |
|
# Transaction Cancel |
|
@csrf_exempt |
|
def cancel(request): |
|
======================== |
|
do what functionality you need |
|
========================= |