{ "info": { "author": "Tim Allen", "author_email": "tallen@wharton.upenn.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "# Django CyberSource Hosted Checkout\n\nThis package provides utilities for using CyberSource Secure Acceptance Hosted Checkout.\n\nCyberSource Secure Acceptance Hosted Checkout is a round-trip process: you start the payment on your server, then pass off to CyberSource. At the end of the transaction, CyberSource returns to your server at a URL you configure.\n\nWe assume you have a working knowledge of the product and profiles; you can [read the CyberSource manual here](http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_WM/Secure_Acceptance_WM.pdf).\n\nThe heavy lifting it does is properly creating the `signed_date_time`, `fields_to_sign`, and `signature` fields and automatically include them in the `POST`, along with any fields you need to pass along.\n\nIf you don't feel like making your eyes bleed with that awful PDF above, here's a TL;DR.\n\n## Create Your CyberSource Profile\n\nYou'll have to do this in both the CyberSource TEST and LIVE environments. Start with TEST. The process is the same.\n\n* Log in here: https://businesscenter.cybersource.com/ebc/login/\n* Under `Tools & Settings`, click `Profiles`, then `Create New Profile`.\n* Fill in the form and click `Save`. Then click the profile name you just created to edit it further.\n* Copy your `Profile ID` from this screen into your Django settings as `CYBERSOURCE_PROFILE_ID`. You will notice there are eight sections you can modify. I will only cover the required areas here.\n * Payment Settings: enter at least one `Card Type` with at least one `Currency` associated with it.\n * Security: click `Create New Key`. Copy the `Access Key` and `Secret Key` values to your Django settings as `CYBERSOURCE_ACCESS_KEY` and `CYBERSOURCE_SECRET_KEY` respectively.\n * Customer Response Pages: for `Transaction Response Page`, select `Hosted by you`, and enter a route that you will create later in Django, such as `https://www.mysite.com/orders/payment-response/`\n* Once you have completed all of the fields, be sure to `Activate` the profile!\n\n## Install Django CyberSource Hosted Checkout\n\nFirst, `pip install django-cybersource-hosted-checkout`, and add `'cybersource_hosted_checkout'` to your `INSTALLED_APPS` list.\n\nIf you're going to be using the examples below to get started, you'll also need to `pip install django-braces`.\n\n### Settings\n\nThese settings are required to be present in Django's settings.\n\n* `CYBERSOURCE_URL`\n * For CyberSource's TEST Environment: `https://testsecureacceptance.cybersource.com/pay`\n * For CyberSource's LIVE Environment: `https://secureacceptance.cybersource.com/pay`\n* `CYBERSOURCE_PROFILE_ID` = '[Your CyberSource Profile ID]'\n* `CYBERSOURCE_ACCESS_KEY` = '[Your CyberSource Access Key]'\n* `CYBERSOURCE_SECRET_KEY` = '[Your CyberSource Secret Key]'\n\n## Code and Configuration\n\n### models.py\n\nIn this example, we will be charging a user of our Django site $19.95 in U.S. dollars to purchase a course.\n\nFirst, create a model in an app in your Django project which inherits from `AbstractCyberSourceTransaction`; the abstract model stores a unique identifier, a transaction UUID, a time stamp of when the transaction is created in Django, and another time stamp of when it is completed from CyberSource. You can add any additional fields you wish to track and store. In this example, we are adding `user` and `course`, so we can complete the transaction after payment. Then `makemigrations` and `migrate`.\n\n```python\nfrom django.db import models\nfrom cybersource_hosted_checkout.models import AbstractCyberSourceTransaction\n\nclass CyberSourceTransaction(AbstractCyberSourceTransaction):\n \"\"\"\n Stores credit card transaction receipts made with CyberSource.\n \"\"\"\n user = models.ForeignKey(User, on_delete=models.CASCADE)\n course = models.ForeignKey(Course, on_delete=models.PROTECT)\n```\n\n### views.py\n\nHere, we leverage a Django `FormView`, and in `form_valid()` we call the functions and render the template which will automatically prepare the data for CyberSource and POST it to their server. The `fields` dictionary contains CyberSource specific fields required to perform a transaction. You can see a full list in the manual; the example below is for a one-time purchase of the course for $19.95.\n\n```python\nimport datetime\nfrom uuid import uuid4\nfrom django.conf import settings\nfrom django.contrib import messages\nfrom django.contrib.messages.views import SuccessMessageMixin\nfrom django.views import View\nfrom django.views.generic import FormView\nfrom braces import LoginRequiredMixin, CsrfExemptMixin\nfrom my_app.models import CyberSourceTransaction\n\nclass AddCourseView(LoginRequiredMixin, SuccessMessageMixin, FormView):\n template_name = 'my_app/transaction.html'\n form_class = TransactionForm\n success_url = reverse_lazy('home')\n success_message = \"Your transaction has been completed.\"\n\n def form_valid(self, form, request, **kwargs):\n # Get the proverbial `course` from the database based on something in the form.\n course = Course.objects.get(course_code=form.cleaned_data['course_code'])\n\n # Create a transaction in the database before we pass to CyberSource;\n # we will update this with a timestamp on return from CyberSource\n transaction_uuid = uuid4().hex\n transaction = CyberSourceTransaction()\n transaction.transaction_uuid = transaction_uuid\n transaction.user = request.user\n transaction.course = course\n transaction.save()\n\n # Fields to pass to CyberSource - see manual for a full list\n fields = {}\n fields['profile_id'] = settings.CYBERSOURCE_PROFILE_ID\n fields['access_key'] = settings.CYBERSOURCE_ACCESS_KEY\n fields['amount'] = '19.95'\n fields['transaction_uuid'] = transaction_uuid\n fields['bill_to_forename'] = request.user.first_name\n fields['bill_to_surname'] = request.user.last_name\n fields['bill_to_email'] = request.user.email\n fields['locale'] = 'en-us'\n fields['currency'] = 'usd'\n fields['transaction_type'] = 'sale'\n fields['reference_number'] = transaction.id\n\n context = super().get_context_data(**kwargs)\n context = sign_fields_to_context(fields, context)\n\n # Render a page which POSTs to CyberSource via JavaScript.\n return render(\n request,\n 'cybersource_hosted_checkout/post_to_cybersource.html',\n context=context,\n )\n\nclass CyberSourceResponseView(CsrfExemptMixin, View):\n \"\"\"\n Recevies a POST from CyberSource and redirects to home.\n \"\"\"\n\n def post(self, request):\n if request.POST.get('decision').upper() == 'ACCEPT':\n # Success! Add the course by getting the transaction we started.\n # Check both reference number and UUID since we're not requiring\n # a login.\n transaction = CyberSourceTransaction.objects.get(\n id=request.POST.get('req_reference_number'),\n uuid=request.POST.get('req_transaction_uuid'),\n )\n transaction.return_from_cybersource = datetime.datetime.now()\n # Here is where you'll put your code in place of this dummy function.\n add_course_for_user(transaction.course, transaction.user, request)\n messages.success(\n request,\n 'Your payment was successful and the course has been added. Happy trading!',\n )\n transaction.save()\n else:\n # Uh oh, unsuccessful payment.\n messages.error(\n request,\n 'Sorry, your payment was not successful.',\n )\n\n return redirect(reverse_lazy('home'))\n```\n\nThe `AddCourseView` class will display your purchase form, and when it is valid, pass the necessary fields to CyberSource to display their checkout page.\n\nThe `CyberSourceResponseView` is the class for the view that is run after a successful checkout from CyberSource. After successfully completing a purchase, the user will then be directed back to the route you put in your CyberSource profile (in the example, `https://www.mysite.com/orders/payment-response/`), where we mark the transaction as complete by updating the timestamp `return_from_cybersource` to mark the transaction complete.\n\n### urls.py\n\nWe need to plug our views into routes that match CyberSource.\n\n```python\nfrom django.urls import path\nfrom myapp.views import MyHomeView, AddCourseView, CyberSourceResponseView\n\nurlpatterns = [\n path('', MyHomeView.as_view(), name='home'),\n path('orders/buy-course/', AddCourseView.as_view(), name='add-course'),\n path('orders/payment-response/', CyberSourceResponseView.as_view(), name='add-course-cybersource-response'),\n]\n```\n\n## Running Tests\n\n```bash\ngit clone git@github.com:wharton/django-cybersource-hosted-checkout.git\nmkvirtualenv test-cybersource\ncd django-cybersource-hosted-checkout/testproject\npip install -r requirements.txt\ncoverage run --source='..' manage.py test cybersource_hosted_checkout\ncoverage report\n```\n\n## Release Notes\n\n### 0.0.1 - 0.0.6\n\nInitial release, tests, and documentation improvements.\n\n## Contributors\n\n* Timothy Allen (https://github.com/FlipperPA)\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/wharton/django-cybersource-hosted-checkout", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "django-cybersource-hosted-checkout", "package_url": "https://pypi.org/project/django-cybersource-hosted-checkout/", "platform": "", "project_url": "https://pypi.org/project/django-cybersource-hosted-checkout/", "project_urls": { "Homepage": "https://github.com/wharton/django-cybersource-hosted-checkout" }, "release_url": "https://pypi.org/project/django-cybersource-hosted-checkout/0.0.6/", "requires_dist": [ "Django" ], "requires_python": "", "summary": "This package provides utilities for using CyberSource Secure Acceptance Hosted Checkout.", "version": "0.0.6" }, "last_serial": 4189358, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "45af06bc3e32ede602e32c8e3e6a9909", "sha256": "0f7b121317edc5bae93ed398d107d511c1eb1111664f14c1c146cd5bacf13665" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "45af06bc3e32ede602e32c8e3e6a9909", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4936, "upload_time": "2018-08-17T15:00:45", "url": "https://files.pythonhosted.org/packages/2e/61/70f4b5f5a3a598389e67139d095f4309b03cc686e6ec982e602eaa03fec8/django_cybersource_hosted_checkout-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2d954d7d8b9ebe2092f495a3a42c1682", "sha256": "f4947edb4f59f29c04dbab86e5f862d7f500146eaf5c1b9871b56e59216a8621" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.1.tar.gz", "has_sig": false, "md5_digest": "2d954d7d8b9ebe2092f495a3a42c1682", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4115, "upload_time": "2018-08-17T15:00:47", "url": "https://files.pythonhosted.org/packages/ca/97/9fe8b3107734919b958f863fe0e27a4792c0bd4a349686321bceca921017/django-cybersource-hosted-checkout-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "5bad9fb9c0ad33666c641096920ed6b3", "sha256": "86bbb685bea0cea66a886cb7ca5b0bb2cf6dca63a0fbe08226497dd16a88df4a" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "5bad9fb9c0ad33666c641096920ed6b3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6658, "upload_time": "2018-08-17T19:38:22", "url": "https://files.pythonhosted.org/packages/22/13/1043431342c23efd5011733917ab53eeab88d24a69ebf7a14dda4247c757/django_cybersource_hosted_checkout-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "afc999a08676782f2241df3f180b8b74", "sha256": "a9891c3a43463ff546062258c8961c15d255eb881cfd1e7a6a48c83ad775112d" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.2.tar.gz", "has_sig": false, "md5_digest": "afc999a08676782f2241df3f180b8b74", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6202, "upload_time": "2018-08-17T19:38:24", "url": "https://files.pythonhosted.org/packages/c6/2a/e3e299860bc7803de777375e4308b4cd9d68a5cb450dfee231ecd3e9ba11/django-cybersource-hosted-checkout-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "613a1d7a267f4946b7d554d781f09e6d", "sha256": "58c39b052bcd899cee042c21e23b684cdc4033f73a8ca796b7b2d6eb7f349b7e" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "613a1d7a267f4946b7d554d781f09e6d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6750, "upload_time": "2018-08-17T20:22:03", "url": "https://files.pythonhosted.org/packages/71/63/4b7f5ce7de8cbeaa8361ecda38cd430045d65a58b745c3682014e2ef2daf/django_cybersource_hosted_checkout-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92485eca63f9cd874cab7feea8819e39", "sha256": "6ecec52aa4104a87b7a48d4ae0521716b650f61ba54800fc19c25629ca946613" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.3.tar.gz", "has_sig": false, "md5_digest": "92485eca63f9cd874cab7feea8819e39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6315, "upload_time": "2018-08-17T20:22:04", "url": "https://files.pythonhosted.org/packages/31/1d/c33dc93ba08daac9a4e38064e7258825269b3d9317282090425c42274cc3/django-cybersource-hosted-checkout-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "5be183d88a85f920ede62466ea191a1d", "sha256": "71b15ab5fe4d2f22f9914e4128d9a9269332d1232f1d072f783c632d5a5e0c7c" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "5be183d88a85f920ede62466ea191a1d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6770, "upload_time": "2018-08-17T20:49:27", "url": "https://files.pythonhosted.org/packages/5b/9c/ebab20880dba90823f2a9526c4229406fecfd08c235f12f05da448ae7768/django_cybersource_hosted_checkout-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "df8225946c61371ed80f4cef735c4283", "sha256": "2661d2f99de4049aa80b7823ec66c694e2b56fda7cd35f4232331e1e168617dd" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.4.tar.gz", "has_sig": false, "md5_digest": "df8225946c61371ed80f4cef735c4283", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6347, "upload_time": "2018-08-17T20:49:28", "url": "https://files.pythonhosted.org/packages/63/40/27d7bf5c004fef38692b80718b17f17e690ed9298ac671bc309bfb6741a8/django-cybersource-hosted-checkout-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "74836c7d1bfe9ecc1d590ec841032875", "sha256": "0b6b606f468d7c9616666ba051a9e4d8b7493a0c5a7037bf033c9e2020a191fe" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "74836c7d1bfe9ecc1d590ec841032875", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6769, "upload_time": "2018-08-17T20:54:19", "url": "https://files.pythonhosted.org/packages/5c/94/4ef0c1c7f9a132bb50fa9c51c2e82e002afb162a4073acd508f9b925975b/django_cybersource_hosted_checkout-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db61de1f633ef76d6d199c71f615baaa", "sha256": "ed2d0006be3ce4482e3cbecf02da5491e84b128187fb095e71d2760f3dca0b39" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.5.tar.gz", "has_sig": false, "md5_digest": "db61de1f633ef76d6d199c71f615baaa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6326, "upload_time": "2018-08-17T20:54:20", "url": "https://files.pythonhosted.org/packages/f2/41/dd2439565f216d226a3c04bf0d2d927bbe0bef84ad6d9dbbe655598f0d55/django-cybersource-hosted-checkout-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "9b2f772694f085960bceafe8e74335ce", "sha256": "e3a4eb2f65e4f01ee4d1eaf534723e9616684fa821f41bc0ba06c2adddeb5108" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "9b2f772694f085960bceafe8e74335ce", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7769, "upload_time": "2018-08-20T18:16:44", "url": "https://files.pythonhosted.org/packages/23/78/61a04832f998dd1b7fad313beef0bcaf8a0ca580c344fbb47adf20d87f5c/django_cybersource_hosted_checkout-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6fc27dcd67e5eca6010673b65930ae9b", "sha256": "a51e2fd847e9b88b414fd2a735e321f0cb243cab5a05c5491c236fc63744f7ef" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.6.tar.gz", "has_sig": false, "md5_digest": "6fc27dcd67e5eca6010673b65930ae9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6862, "upload_time": "2018-08-20T18:16:46", "url": "https://files.pythonhosted.org/packages/b5/be/e289d7493fd68ab302bf867940aeba678ac3f227ed96e888e6210a689268/django-cybersource-hosted-checkout-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9b2f772694f085960bceafe8e74335ce", "sha256": "e3a4eb2f65e4f01ee4d1eaf534723e9616684fa821f41bc0ba06c2adddeb5108" }, "downloads": -1, "filename": "django_cybersource_hosted_checkout-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "9b2f772694f085960bceafe8e74335ce", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7769, "upload_time": "2018-08-20T18:16:44", "url": "https://files.pythonhosted.org/packages/23/78/61a04832f998dd1b7fad313beef0bcaf8a0ca580c344fbb47adf20d87f5c/django_cybersource_hosted_checkout-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6fc27dcd67e5eca6010673b65930ae9b", "sha256": "a51e2fd847e9b88b414fd2a735e321f0cb243cab5a05c5491c236fc63744f7ef" }, "downloads": -1, "filename": "django-cybersource-hosted-checkout-0.0.6.tar.gz", "has_sig": false, "md5_digest": "6fc27dcd67e5eca6010673b65930ae9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6862, "upload_time": "2018-08-20T18:16:46", "url": "https://files.pythonhosted.org/packages/b5/be/e289d7493fd68ab302bf867940aeba678ac3f227ed96e888e6210a689268/django-cybersource-hosted-checkout-0.0.6.tar.gz" } ] }