Advertisement
Guest User

FoxyCart Django/Python3

a guest
May 22nd, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 KB | None | 0 0
  1. ## My View, I have a session variable I submit to foxy cart, that's my booking_id.
  2.  
  3. @csrf_exempt
  4. def FoxyCartIPNView(request):
  5. if request.POST and 'FoxyData' in request.POST:
  6. try:
  7. # IMPORTANT: unquote_plus is necessary for the non-ASCII binary that
  8. # FoxyCart sends.
  9. # MKR als important to set the encoding when using python3!
  10.  
  11. data = FoxyData.from_crypted_str((unquote_plus(request.POST['FoxyData'], encoding='latin-1')),
  12. FOXYCART_DATAFEED_KEY)
  13.  
  14. for transaction in data.transactions:
  15.  
  16. # get the booking id, and verify it so BMCM can see it in admin
  17. # also save foxy's xml for archive purposes, finally, we mail the customer.
  18. booking = transaction.booking_id # a custom field from foxycart
  19. booking = RetreatBooking.objects.get(pk=booking)
  20. booking.verified_transaction = True
  21. booking.foxycart_xml = data.markup
  22. booking.save()
  23.  
  24. mail_customer(request, booking, transaction)
  25. print("transaction: {}, mail customer {}\n".format(transaction.id, transaction.customer_email) )
  26.  
  27. return HttpResponse('foxy')
  28.  
  29.  
  30. except:
  31. # Something went wrong, handle the error... right? :P
  32. raise
  33.  
  34. return HttpResponseForbidden('Unauthorized request.') # No FoxyData? Not a POST? We don't speak that.
  35.  
  36.  
  37. ## my utils for the view - Python 3 compatible!
  38.  
  39. class ARC4:
  40. def __init__(self, key = None):
  41. self.state = list(range(256)) # Initialize state array with values 0 .. 255
  42. self.x = self.y = 0 # Our indexes. x, y instead of i, j
  43.  
  44. if key is not None:
  45. self.init(key)
  46.  
  47. # KSA
  48. def init(self, key):
  49. for i in list(range(256)):
  50. self.x = (ord(key[i % len(key)]) + self.state[i] + self.x) & 0xFF
  51. self.state[i], self.state[self.x] = self.state[self.x], self.state[i]
  52. self.x = 0
  53.  
  54. # PRGA
  55. def crypt(self, input):
  56. output = [None]*len(input)
  57. for i in range(len(input)):
  58. self.x = (self.x + 1) & 0xFF
  59. self.y = (self.state[self.x] + self.y) & 0xFF
  60. self.state[self.x], self.state[self.y] = self.state[self.y], self.state[self.x]
  61. r = self.state[(self.state[self.x] + self.state[self.y]) & 0xFF]
  62. output[i] = chr(ord(input[i]) ^ r)
  63. return ''.join(output)
  64.  
  65. @classmethod
  66. def from_crypted_str(self, data_str, crypt_key):
  67. a = ARC4(crypt_key)
  68. return FoxyData.from_str(a.crypt(data_str))
  69.  
  70.  
  71. class FoxyData:
  72. DateFmt = '%Y-%m-%d'
  73. DateTimeFmt = '%Y-%m-%d %H:%M:%S'
  74.  
  75. class Transaction:
  76. def __init__(self, node):
  77. def extract_kv_node(node, key_name):
  78. # print('getting node {}\n{}'.format(key_name, node))
  79. el = node.getElementsByTagName(key_name)
  80. return len(el) > 0 and el[0].firstChild.data or ''
  81.  
  82. self.id = extract_kv_node(node, 'id')
  83. self.date = datetime.strptime(
  84. extract_kv_node(node, 'transaction_date'), FoxyData.DateTimeFmt)
  85. self.customer_id = extract_kv_node(node, 'customer_id')
  86. self.customer_email = extract_kv_node(node, 'customer_email')
  87.  
  88. self.attributes = attrs = {}
  89. self.items = items = attrs['items'] = []
  90.  
  91. self.custom_fields = attrs['custom_fields'] = {}
  92. for custom_field in node.getElementsByTagName('custom_field'):
  93. self.custom_fields[extract_kv_node(custom_field, 'custom_field_name')] = \
  94. extract_kv_node(custom_field, 'custom_field_value')
  95.  
  96. # import pdb;pdb.set_trace()
  97. self.booking_id = self.custom_fields.get('booking_id')
  98.  
  99. self.transaction_details = attrs['detail'] = []
  100.  
  101.  
  102. def __init__(self, markup):
  103. self.markup = markup
  104. self.doc = parseString(self.markup)
  105. self.transactions = []
  106.  
  107. for transaction in self.doc.getElementsByTagName('transaction'):
  108. self.transactions.append(FoxyData.Transaction(transaction))
  109.  
  110.  
  111. def __str__(self):
  112. return str(self.markup)
  113.  
  114.  
  115. @classmethod
  116. def from_str(self, data_str):
  117. return FoxyData(data_str)
  118.  
  119.  
  120. """
  121. Given a string containing RC4-crypted FoxyCart datafeed XML and the
  122. cryptographic key, decrypt the contents and create a FoxyData object
  123. containing all of the Transactions in the data feed.
  124. """
  125.  
  126. @classmethod
  127. def from_crypted_str(self, data_str, crypt_key):
  128. a = ARC4(crypt_key)
  129. return FoxyData.from_str(a.crypt(data_str))
  130.  
  131.  
  132. def __len__(self):
  133. return len(self.transactions)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement