Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main #111

Closed
wants to merge 9 commits into from
59 changes: 59 additions & 0 deletions payments/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import frappe
from frappe.utils import nowdate
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry


@frappe.whitelist(allow_guest=True)
def accept_payment(**data):
"""
headers: X-CALLBACK-TOKEN
data: {
"id": "65f675eec32d920fd76d8034",
"amount": 500000,
"status": "PAID",
"created": "2024-03-17T04:47:43.048Z",
"is_high": false,
"paid_at": "2024-03-17T04:48:32.000Z",
"updated": "2024-03-17T04:48:33.041Z",
"user_id": "65e0a60d213e0478ced4bb3e",
"currency": "IDR",
"bank_code": "MANDIRI",
"payment_id": "46913fa1-3351-47c2-aa55-3b0fde81ee36",
"description": "Invoice Demo #123",
"external_id": "invoice-1231241",
"paid_amount": 500000,
"payer_email": "[email protected]",
"merchant_name": "Sopwer",
"payment_method": "BANK_TRANSFER",
"payment_channel": "MANDIRI",
"payment_destination": "8860827838227"
}
"""

data = frappe.parse_json(data)
payment_log = frappe.get_list("Xendit Payment Log", filters={"document": data['external_id']}, fields=["name"])
if payment_log:
xpl = frappe.get_doc("Xendit Payment Log", payment_log[0].name)
token_verify = frappe.db.get_value("Xendit Settings", xpl.xendit_account, "token_verify")
if frappe.request.headers.get('X-Callback-Token') == token_verify:
pr = frappe.get_doc(xpl.doc_type, xpl.document)
pe = get_payment_entry(pr.reference_doctype, pr.reference_name)
# Ubah status payment entry menjadi "paid"
pe.reference_no = data['external_id']
pe.reference_date = data['paid_at'][:10]
pe.insert(ignore_permissions=True)
pe.submit()

# Update Xendit Payment Log
frappe.db.set_value("Xendit Payment Log", payment_log[0].name, "status", data['status'])
frappe.db.set_value("Xendit Payment Log", payment_log[0].name, "callback_payload", frappe.as_json(data))
frappe.db.commit()

return "Payment entry updated successfully"
else:
frappe.log_error("Request Payment {0} Is Invalid".format(data['id']))
return "Request Payment {0} Is Invalid".format(data['id'])

else:
frappe.log_error("Error Payment {0} Log Not Found".format(data['id']))
return "Payment log not found"
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, Frappe Technologies and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestXenditSettings(FrappeTestCase):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2024, Frappe Technologies and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Xendit Settings", {
// refresh(frm) {

// },
// });
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:title",
"creation": "2024-03-17 10:23:10.932585",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"title",
"secret_api_key",
"public_key",
"token_verify",
"use_sandbox"
],
"fields": [
{
"fieldname": "secret_api_key",
"fieldtype": "Data",
"label": "Secret Api Key"
},
{
"fieldname": "public_key",
"fieldtype": "Data",
"label": "Public Key"
},
{
"fieldname": "token_verify",
"fieldtype": "Password",
"label": "Token Verify"
},
{
"default": "0",
"fieldname": "use_sandbox",
"fieldtype": "Check",
"label": "Use Sandbox"
},
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"unique": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-03-17 15:58:18.062396",
"modified_by": "Administrator",
"module": "Payment Gateways",
"name": "Xendit Settings",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"show_title_field_in_link": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "title"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Copyright (c) 2024, Frappe Technologies and contributors
# For license information, please see license.txt

import frappe
import json
from frappe.model.document import Document
from urllib.parse import urlencode

import xendit
from xendit.apis import BalanceApi
from pprint import pprint
from xendit.apis import InvoiceApi
from xendit.invoice.model.create_invoice_request import CreateInvoiceRequest
from xendit.invoice.model import CustomerObject, AddressObject, NotificationPreference, NotificationChannel, InvoiceItem, InvoiceFee, ChannelProperties, ChannelPropertiesCards
from datetime import datetime
from frappe.utils import call_hook_method, cint, flt, get_url

from payments.utils import create_payment_gateway


def serialize_datetime(obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
raise TypeError("Type not serializable")

class XenditSettings(Document):

supported_currencies = ["IDR"]

def validate_transaction_currency(self, currency):
if currency not in self.supported_currencies:
frappe.throw(
_(
"Please select another payment method. Xendit does not support transactions in currency '{0}'"
).format(currency)
)

def on_update(self):
create_payment_gateway(
"Xendit-" + self.title,
settings="Xendit Settings",
controller=self.title,
)

def get_invoice_by_id(self, invoice_id):
xendit.set_api_key(self.secret_api_key)

api_client = xendit.ApiClient()
api_instance = InvoiceApi(api_client)
try:
# Get an invoice by ID
api_response = api_instance.get_invoice_by_id(invoice_id)
pprint(api_response)
except xendit.XenditSdkException as e:
print("Exception when calling InvoiceApi->get_invoice: %s\n" % e)


def create_request(self,doc_type, document, payload):
xendit.set_api_key(self.secret_api_key)

api_client = xendit.ApiClient()
api_instance = InvoiceApi(api_client)
create_invoice_request = CreateInvoiceRequest(
**payload
)
try:
# Create an invoice
api_response = api_instance.create_invoice(create_invoice_request)
# import pdb
# pdb.set_trace()
xpl = frappe.new_doc("Xendit Payment Log")
xpl.xendit_account = self.name
xpl.respond_payload = json.dumps(api_response.to_dict(), default=serialize_datetime, indent=4) #json.dumps(api_response.to_dict())
xpl.doc_type = doc_type
xpl.document = document
xpl.status = api_response.status
xpl.amount = api_response.amount
xpl.checkout_url = api_response.invoice_url
xpl.submit()
frappe.db.commit()
return xpl.checkout_url
# pprint(api_response)
except xendit.XenditSdkException as e:
print("Exception when calling InvoiceApi->create_invoice: %s\n" % e)


def get_payment_url(self, **kwargs):
payload = {'external_id': kwargs['reference_docname'],
'amount': kwargs['amount'],
'payer_email': kwargs['payer_email'],
'description':str(kwargs['description']),
'currency': kwargs['currency']
}
checkout_url = self.create_request("Payment Request", kwargs['reference_docname'], payload)
return get_url(checkout_url)

Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, Frappe Technologies and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestXenditPaymentLog(FrappeTestCase):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2024, Frappe Technologies and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Xendit Payment Log", {
// refresh(frm) {

// },
// });
Loading
Loading