No past payments yet.
{% else %}
22 |
7 | {% if reference and doc %}
8 | {% if not doc.public_key %}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Payment Gatway is not Active.
16 |
Please contact the vendor.!
17 |
18 |
19 | Reference:
20 | {{reference}}
21 |
22 |
23 |
24 |
25 |
26 | {% elif not doc.status in ["Completed", "Processed"] and doc.order_status in ["Completed", "Closed'", "Paid"] %}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Payment Invalid
34 |
This payment link is invalid or expired!
35 |
36 |
37 | Reference:
38 | {{reference}}
39 |
40 |
41 |
42 |
43 |
44 | {% elif doc.status in ["Completed", "Processed"] or doc.order_status in ["Completed", "Closed'", "Paid"]%}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
Payment Completed/Processed
52 |
Your payment has been successfully processed. Thank you for your purchase!
53 |
54 |
55 | Reference:
56 | {{reference}}
57 |
58 |
59 |
60 |
61 |
62 | {% elif doc.status == "Failed" %}
63 |
64 |
65 |
66 |
67 |
68 |
69 |
Payment Failed
70 |
Your payment Failed!
71 |
72 |
73 | Reference:
74 | {{reference}}
75 |
76 |
77 |
78 |
79 | {% else %}
80 |
81 |
82 |
83 |
84 |
85 |
86 | Summary
87 |
88 |
89 | -
90 | Payment Reference
91 | {{ reference }}
92 |
93 | -
94 | Invoice/Order No.
95 | {{doc.order_no}}
96 |
97 | -
98 | Order Amount
99 | {{doc.order_currency}} {{doc.grand_total}}
100 |
101 | -
102 | Payment Amount
103 | {{doc.currency}} {{doc.payment_amount}}
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | {% endif %}
119 | {% else %}
120 |
121 |
122 |
123 |
124 |
125 |
126 |
Invalid Payment Reference
127 |
The payment reference could not be verified. Please check it and try again.
128 |
129 |
130 | Reference:
131 | {{reference}}
132 |
133 |
134 |
135 |
136 |
137 | {% endif %}
138 |
139 | {% endblock %}
140 |
141 | {% block script %}
142 |
143 |
144 |
145 |
149 |
150 | {% endblock %}
151 |
--------------------------------------------------------------------------------
/frappe_paystack/www/paystack-checkout/index.py:
--------------------------------------------------------------------------------
1 | import frappe, json, requests
2 |
3 | PAYMENT_LOG = "Paystack Payment Log"
4 |
5 | def get_context(context):
6 | context.title = "Paystack Checkout"
7 | reference = frappe.form_dict.reference
8 | if not reference:
9 | context.reference = None
10 | else:
11 | if frappe.db.exists(PAYMENT_LOG, {"name": reference}):
12 | doc = frappe.get_doc(PAYMENT_LOG, reference)
13 | context.doc = doc.get_data()
14 | context.reference = reference
15 | else:
16 | context.reference = None
17 |
18 | return context
19 |
20 |
21 | @frappe.whitelist(allow_guest=True)
22 | def get_payment_request(reference_doctype, reference_docname):
23 | if not (reference_doctype and reference_docname):
24 | return {'error':"Invalid payment link."}
25 | payment_request = frappe.db.get_value(
26 | reference_doctype, {
27 | "name":reference_docname,
28 | "docstatus":1,
29 | "status":["=", "Requested"],
30 | "payment_request_type": "Inward"
31 | },
32 | "*", as_dict=1
33 | )
34 | if not payment_request:
35 | return {'error':"Invalid payment link."}
36 | if payment_request.status=='Paid':
37 | return {'error':"Payment has already been made."}
38 | public_key = frappe.db.get_value(
39 | "Paystack Gateway Setting",
40 | {'enabled':1,},
41 | ["public_key"]
42 | )
43 | if not public_key:
44 | return {'error':"Payment method is unavailable at the moment, please contact us directly.."}
45 | payment_request.public_key = public_key
46 | return payment_request
47 |
48 | @frappe.whitelist(allow_guest=True)
49 | def verify_transaction():
50 | try:
51 | transaction = frappe.form_dict
52 | frappe.get_doc({
53 | 'doctype':"Paystack Log",
54 | 'message':transaction.message,
55 | 'status':transaction.status,
56 | 'reference': transaction.reference,
57 | 'transaction': transaction.transaction,
58 | }).insert(ignore_permissions=1)
59 | except Exception as e:
60 | frappe.log_error(frappe.get_traceback(), 'Verify Transaction')
61 |
62 |
63 |
64 | @frappe.whitelist(allow_guest=True)
65 | def paystack_webhook(**kwargs):
66 | """
67 | End point where payment gateway sends payment info.
68 | """
69 | try:
70 | data = frappe._dict(frappe.form_dict.data)
71 | if not (frappe.db.exists("Payment Gateway Request", {"name":data.reference})):
72 | secret_key = frappe.get_doc(
73 | "Payment Gateway Integration Settings",
74 | {'enabled':1, 'gateway':'Paystack'}
75 | ).get_secret_key()
76 | headers = {"Authorization": f"Bearer {secret_key}"}
77 | req = requests.get(
78 | f"https://api.paystack.co/transaction/verify/{data.reference}",
79 | headers=headers, timeout=10
80 | )
81 | if req.status_code in [200, 201]:
82 | response = frappe._dict(req.json())
83 | data = frappe._dict(response.data)
84 | metadata = frappe._dict(data.metadata)
85 | frappe.get_doc({
86 | 'doctype':"Payment Gateway Log",
87 | 'amount':data.amount/100,
88 | 'currency':data.currency,
89 | 'message':response.message,
90 | 'status':data.status,
91 | 'payment_gateway_request': metadata.log_id,
92 | 'reference': data.reference,
93 | 'reference_doctype': metadata.reference_doctype,
94 | 'reference_name': metadata.reference_name,
95 | 'transaction_id': data.id,
96 | 'data': response
97 | }).insert(ignore_permissions=True)
98 | else:
99 | # log error
100 | frappe.log_error(str(req.reason), 'Verify Transaction')
101 | except Exception as e:
102 | frappe.log_error(frappe.get_traceback(), 'Verify Transaction')
103 |
104 |
--------------------------------------------------------------------------------
/img/completed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mymi14s/frappe_paystack/faa7390dd85ed873ff1ff518ee36f7ee382be5b1/img/completed.png
--------------------------------------------------------------------------------
/img/gateway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mymi14s/frappe_paystack/faa7390dd85ed873ff1ff518ee36f7ee382be5b1/img/gateway.png
--------------------------------------------------------------------------------
/img/payment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mymi14s/frappe_paystack/faa7390dd85ed873ff1ff518ee36f7ee382be5b1/img/payment.png
--------------------------------------------------------------------------------
/img/payment_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mymi14s/frappe_paystack/faa7390dd85ed873ff1ff518ee36f7ee382be5b1/img/payment_button.png
--------------------------------------------------------------------------------
/img/payment_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mymi14s/frappe_paystack/faa7390dd85ed873ff1ff518ee36f7ee382be5b1/img/payment_page.png
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [year] [fullname]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "frappe_paystack"
3 | authors = [
4 | { name = "Anthony Emmanuel", email = "mymi14s@hotmail.com"}
5 | ]
6 | description = "Paystack integration for Frappe/ERPNext"
7 | requires-python = ">=3.10"
8 | readme = "README.md"
9 | dynamic = ["version"]
10 | dependencies = [
11 | # "frappe~=15.0.0" # Installed and managed by bench.
12 | ]
13 |
14 | [build-system]
15 | requires = ["flit_core >=3.4,<4"]
16 | build-backend = "flit_core.buildapi"
17 |
18 | # These dependencies are only installed when developer mode is enabled
19 | [tool.bench.dev-dependencies]
20 | # package_name = "~=1.1.0"
21 |
--------------------------------------------------------------------------------