-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from Zeit-Labs/shadinaif/payfort
feat: Implement PayFort Payment Processor
- Loading branch information
Showing
40 changed files
with
2,952 additions
and
395 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../ecommerce_payfort/locale |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
""" | ||
The PayFort payment processor pluggable application for Open edX ecommerce. | ||
""" | ||
default_app_config = 'ecommerce_payfort.apps.PayFortConfig' | ||
default_app_config = 'ecommerce_payfort.apps.PayFortConfig' # pylint: disable=invalid-name | ||
|
||
|
||
__version__ = '0.1.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# edX translation file. | ||
# Copyright (C) 2024 EdX | ||
# This file is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE. | ||
# EdX Team <[email protected]>, 2024. | ||
# | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: 0.1a\n" | ||
"Report-Msgid-Bugs-To: [email protected]\n" | ||
"POT-Creation-Date: 2023-06-13 08:00+0000\n" | ||
"PO-Revision-Date: 2023-06-13 09:00+0000\n" | ||
"Last-Translator: \n" | ||
"Language-Team: openedx-translation <[email protected]>\n" | ||
"Language: en\n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: 8bit\n" | ||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||
|
||
#: ecommerce_payfort/processors.py:22 | ||
msgid "Checkout with credit card" | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/form.html:12 | ||
msgid "Redirecting to the Payment Gateway..." | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/handle_format_error.html:12 | ||
#: ecommerce_payfort/templates/payfort_payment/handle_internal_error.html:12 | ||
msgid "This is unfortunate and not expected!" | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/handle_format_error.html:14 | ||
msgid "" | ||
"The response came from the payment gateway is malformed but flagged as " | ||
"succeeded! We're are not sure if your account has been charged or not! The " | ||
"administrator has been notified and will investigate the issue shortly" | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/handle_format_error.html:16 | ||
#: ecommerce_payfort/templates/payfort_payment/handle_internal_error.html:16 | ||
msgid "" | ||
"Please do not submit a purchase again before contacting the administrator" | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/handle_format_error.html:19 | ||
#: ecommerce_payfort/templates/payfort_payment/handle_internal_error.html:18 | ||
#: ecommerce_payfort/templates/payfort_payment/wait_feedback.html:14 | ||
msgid "For your reference, the payment ID is:" | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/handle_internal_error.html:14 | ||
msgid "" | ||
"The payment has been processed successfully, but we had an unexpected error " | ||
"while submitting the payment information to the server. The administrator " | ||
"has been notified and will investigate the issue." | ||
msgstr "" | ||
|
||
#: ecommerce_payfort/templates/payfort_payment/wait_feedback.html:12 | ||
msgid "Payment succeeded. Processing enrollment.. please wait.." | ||
msgstr "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,90 @@ | ||
""" | ||
PayFort payment processor. | ||
""" | ||
|
||
"""PayFort payment processor.""" | ||
import logging | ||
from urllib.parse import urljoin | ||
|
||
from django.middleware.csrf import get_token | ||
from django.urls import reverse | ||
from django.utils.translation import ugettext_lazy as _ | ||
from oscar.apps.payment.exceptions import GatewayError | ||
from ecommerce.extensions.payment.processors import BasePaymentProcessor, HandledProcessorResponse | ||
|
||
from ecommerce.extensions.payment.processors import BasePaymentProcessor | ||
from ecommerce_payfort import utils | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def format_price(price): | ||
""" | ||
Return the price in the expected format. | ||
""" | ||
return '{:0.2f}'.format(price) | ||
|
||
|
||
class PayFortException(GatewayError): | ||
""" | ||
An umbrella exception to catch all errors from PayFort. | ||
""" | ||
pass # pylint: disable=unnecessary-pass | ||
|
||
|
||
class PayFort(BasePaymentProcessor): | ||
""" | ||
PayFort payment processor. | ||
For reference, see https://paymentservices-reference.payfort.com/docs/api/build/index.html | ||
Scroll through the page, it's a very long single-page documentation. | ||
""" | ||
|
||
NAME = 'payfort' | ||
CHECKOUT_TEXT = _("Checkout with credit card") | ||
NAME = "payfort" | ||
|
||
def __init__(self, site): | ||
"""Initialize the PayFort processor.""" | ||
super().__init__(site) | ||
self.site = site | ||
|
||
self.access_code = self.configuration.get("access_code") | ||
self.merchant_identifier = self.configuration.get("merchant_identifier") | ||
self.request_sha_phrase = self.configuration.get("request_sha_phrase") | ||
self.response_sha_phrase = self.configuration.get("response_sha_phrase") | ||
self.sha_method = self.configuration.get("sha_method") | ||
self.ecommerce_url_root = self.configuration.get("ecommerce_url_root") | ||
|
||
def get_transaction_parameters(self, basket, request=None, use_client_side_checkout=False, **kwargs): | ||
"""Return the transaction parameters needed for this processor.""" | ||
transaction_parameters = { | ||
"command": "PURCHASE", | ||
"access_code": self.access_code, | ||
"merchant_identifier": self.merchant_identifier, | ||
"language": utils.get_language(request), | ||
"merchant_reference": utils.get_merchant_reference(self.site.id, basket), | ||
"amount": utils.get_amount(basket), | ||
"currency": utils.get_currency(basket), | ||
"customer_email": utils.get_customer_email(basket), | ||
"customer_ip": utils.get_ip_address(request), | ||
"order_description": utils.get_order_description(basket), | ||
"customer_name": utils.get_customer_name(basket), | ||
"return_url": urljoin( | ||
self.ecommerce_url_root, | ||
reverse("payfort:response") | ||
), | ||
} | ||
|
||
signature = utils.get_signature( | ||
self.request_sha_phrase, | ||
self.sha_method, | ||
transaction_parameters, | ||
) | ||
transaction_parameters.update({ | ||
"signature": signature, | ||
"payment_page_url": reverse("payfort:form"), | ||
"csrfmiddlewaretoken": get_token(request), | ||
}) | ||
|
||
return transaction_parameters | ||
|
||
def handle_processor_response(self, response, basket=None): | ||
"""Handle the payment processor response and record the relevant details.""" | ||
currency = response["currency"] | ||
total = int(response["amount"]) / 100 | ||
transaction_id = utils.get_transaction_id(response) | ||
card_number = response.get("card_number") | ||
card_type = response.get("payment_option") | ||
|
||
return HandledProcessorResponse( | ||
transaction_id=transaction_id, | ||
total=total, | ||
currency=currency, | ||
card_number=card_number, | ||
card_type=card_type | ||
) | ||
|
||
def issue_credit( | ||
self, order_number, basket, reference_number, amount, currency | ||
): # pylint: disable=too-many-arguments | ||
"""Not available.""" | ||
raise NotImplementedError("PayFort processor cannot issue credits or refunds from Open edX ecommerce.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{% extends "edx/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block content %} | ||
<style> | ||
.centered-content { | ||
text-align: center; | ||
margin-top: 2em; | ||
} | ||
</style> | ||
<div class="centered-content"> | ||
<h1>{% trans "Redirecting to the Payment Gateway..." %}</h1> | ||
</div> | ||
|
||
<form action="https://sbcheckout.payfort.com/FortAPI/paymentPage" method="post" name="payment_form"> | ||
<input type="hidden" name="command" value="{{ command }}"> | ||
<input type="hidden" name="access_code" value="{{ access_code }}"> | ||
<input type="hidden" name="merchant_identifier" value="{{ merchant_identifier }}"> | ||
<input type="hidden" name="merchant_reference" value="{{ merchant_reference }}"> | ||
<input type="hidden" name="amount" value="{{ amount }}"> | ||
<input type="hidden" name="currency" value="{{ currency }}"> | ||
<input type="hidden" name="language" value="{{ language }}"> | ||
<input type="hidden" name="customer_email" value="{{ customer_email }}"> | ||
<input type="hidden" name="customer_ip" value="{{ customer_ip }}"> | ||
<input type="hidden" name="order_description" value="{{ order_description }}"> | ||
<input type="hidden" name="signature" value="{{ signature }}"> | ||
<input type="hidden" name="customer_name" value="{{ customer_name }}"> | ||
<input type="hidden" name="return_url" value="{{ return_url }}"> | ||
</form> | ||
{% endblock %} | ||
|
||
{% block javascript %} | ||
<script type="text/javascript"> | ||
window.onload = function() { | ||
document.payment_form.submit(); | ||
}; | ||
</script> | ||
{% endblock %} |
23 changes: 23 additions & 0 deletions
23
ecommerce_payfort/templates/payfort_payment/handle_format_error.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{% extends "edx/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block content %} | ||
<style> | ||
.centered-content { | ||
text-align: center; | ||
margin-top: 2em; | ||
} | ||
</style> | ||
<div class="centered-content"> | ||
<h1>{% trans "This is unfortunate and not expected!" %}</h1> | ||
|
||
<p>{% trans "The response came from the payment gateway is malformed but flagged as succeeded! We're are not sure if your account has been charged or not! The administrator has been notified and will investigate the issue shortly" %}</p> | ||
|
||
<p><strong>{% trans "Please do not submit a purchase again before contacting the administrator" %}</strong></p> | ||
|
||
{% if reference != "none" %} | ||
<p>{% trans "For your reference, the payment ID is:" %} <strong>{{ reference }}</strong></p> | ||
{% endif %} | ||
</div> | ||
|
||
{% endblock %} |
21 changes: 21 additions & 0 deletions
21
ecommerce_payfort/templates/payfort_payment/handle_internal_error.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{% extends "edx/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block content %} | ||
<style> | ||
.centered-content { | ||
text-align: center; | ||
margin-top: 2em; | ||
} | ||
</style> | ||
<div class="centered-content"> | ||
<h1>{% trans "This is unfortunate and not expected!" %}</h1> | ||
|
||
<p>{% trans "The payment has been processed successfully, but we had an unexpected error while submitting the payment information to the server. The administrator has been notified and will investigate the issue." %}</p> | ||
|
||
<p><strong>{% trans "Please do not submit a purchase again before contacting the administrator" %}</strong></p> | ||
|
||
<p>{% trans "For your reference, the payment ID is:" %} <strong>{{ merchant_reference }}</strong></p> | ||
</div> | ||
|
||
{% endblock %} |
Oops, something went wrong.