Skip to content

Commit

Permalink
Merge pull request #1272 from trojikman/11.0-pos_alipay
Browse files Browse the repository at this point in the history
  • Loading branch information
itpp-bot authored Jun 23, 2020
2 parents b8a751c + 2816b4f commit 36184f5
Show file tree
Hide file tree
Showing 25 changed files with 1,038 additions and 0 deletions.
94 changes: 94 additions & 0 deletions pos_alipay/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
.. image:: https://img.shields.io/badge/license-MIT-blue.svg
:target: https://opensource.org/licenses/MIT
:alt: License: MIT

========================
Alipay Payments in POS
========================

The module implements following payment workflows

Barcode Payment
---------------

* Cashier creates order and scan user's QR in user's Alipay mobile app

* scanning can be done via Mobile Phone camera (``pos_mobile`` module is recommended)
* scanning can be done via usb scanner
* scanning can be done via usb scanner attached to PosBox

* User's receives order information and authorise fund transferring
* Cashier gets payment confirmation in POS

QR Code Payment
---------------

* Cashier clicks a button to get one-time url and shows it to Buyer as a QR Code

* QR can be shown in POS
* QR can be shown in Mobile POS (``pos_mobile`` module is recommended)
* QR can be shown in Customer screen

* Buyer scans to finish the transaction.
* Cashier gets payment confirmation in POS

Debugging
=========

Scanning
--------

If you don't have camera or scanner, you can executing following code in browser console to simulate scanning::

odoo.__DEBUG__.services['web.core'].bus.trigger('qr_scanned', '28763443825664394');

Customer Screen
---------------

To emulate Customer screen do as following:

* run another odoo on a different port, say ``9069``, workers 1, extra *server wide modules*, i.e. use ``--workers=1 --load=web,hw_proxy,hw_posbox_homepage,hw_screen``
* open page at your browser: http://localhost:9069/point_of_sale/display -- you must see message ``POSBox Client display``
* at POS' Settings activate ``[x] PosBox``, activate ``[x] Customer Display`` and set **IP Address** to ``localhost:9069``
* Now just open POS

Roadmap
=======

* TODO: In sake of UX, we need to add ``alipay_order_id`` reference to ``account.bank.statement.line``

Credits
=======

Contributors
------------
* `Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>`__

Sponsors
--------
* `IT-Projects LLC <https://it-projects.info>`__

Maintainers
-----------
* `IT-Projects LLC <https://it-projects.info>`__

To get a guaranteed support you are kindly requested to purchase the module at `odoo apps store <https://apps.odoo.com/apps/modules/11.0/pos_alipay/>`__.

Thank you for understanding!

`IT-Projects Team <https://www.it-projects.info/team>`__

Further information
===================

Demo: http://runbot.it-projects.info/demo/pos_addons/11.0

HTML Description: https://apps.odoo.com/apps/modules/11.0/pos_payment_alipay/

Usage instructions: `<doc/index.rst>`_

Changelog: `<doc/changelog.rst>`_

Notifications on updates: `via Atom <https://github.com/it-projects-llc/pos-addons/commits/11.0/pos_alipay.atom>`_, `by Email <https://blogtrottr.com/?subscribe=https://github.com/it-projects-llc/pos-addons/commits/11.0/pos_alipay.atom>`_

Tested on Odoo 11.0 ee2b9fae3519c2494f34dacf15d0a3b5bd8fbd06
3 changes: 3 additions & 0 deletions pos_alipay/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License MIT (https://opensource.org/licenses/MIT).
from . import models
from . import wizard
35 changes: 35 additions & 0 deletions pos_alipay/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# Copyright 2018 Dinar Gabbasov <https://it-projects.info/team/GabbasovDinar>
# License MIT (https://opensource.org/licenses/MIT).
{
"name": """Alipay Payments in POS""",
"summary": """Support payment by scanning user's QR""",
"category": "Point of Sale",
# "live_test_url": "",
"images": ["images/pos_alipay.png"],
"version": "11.0.1.0.0",
"application": False,
"author": "IT-Projects LLC, Kolushov Alexandr",
"support": "[email protected]",
"website": "https://it-projects.info/team/KolushovAlexandr",
"license": "LGPL-3",
# "price": 9.00,
# "currency": "EUR",
"depends": [
"alipay",
"pos_qr_scan",
"pos_qr_show",
"pos_qr_payments",
"pos_longpolling",
],
"external_dependencies": {"python": [], "bin": []},
"data": [
"views/assets.xml",
"wizard/pos_payment_views.xml",
"security/alipay_security.xml",
],
"demo": [],
"qweb": ["static/src/xml/pos.xml"],
"auto_install": False,
"installable": True,
}
4 changes: 4 additions & 0 deletions pos_alipay/doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
`1.0.0`
-------

- Init version
49 changes: 49 additions & 0 deletions pos_alipay/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
========================
Alipay Payments in POS
========================

Follow instructions of `Alipay API <https://apps.odoo.com/apps/modules/11.0/alipay/>`__ module.

Installation
============

* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way

Configuration
=============

Alipay Journals
---------------

Alipay Journals are created automatically on first opening POS session.

* In demo installation: they are availabe in POS immediatly
* In non-demo installation: add Journals to **Payment Methods** in *Point of
Sale*'s Settings, then close existing session if any and open again

Usage
=====

Scanning customer's QR
----------------------

* Start POS
* Create some Order
* Click ``[Scan QR Code]`` or use QR Scanner device attached to PosBox or the device you use (computer, tablet, phone)
* Ask customer to prepare QR in Alipay app
* Scan the QR
* Wait until customer authorise the payment in his Alipay app
* RESULT: Payment is proceeded. Use your Alipay Seller control panel to see balance update.

Refunds
-------

* Make Refund Order via backend as usual:

* Go to ``[[ Point of Sale ]] >> Orders >> Orders``
* Open product to be refuned
* Click button ``[Return Products]``

* In Refund Order click ``[Payment]``
* In **Payment Mode** specify a Alipay journal
* Specify **Alipay Order to refund**
Binary file added pos_alipay/images/pos_alipay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions pos_alipay/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from . import alipay_pos
from . import alipay_order
from . import pos_config
71 changes: 71 additions & 0 deletions pos_alipay/models/alipay_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# License MIT (https://opensource.org/licenses/MIT).
import json

from odoo import api, models

from odoo.addons.qr_payments.tools import odoo_async_call


class AlipayOrder(models.Model):
_inherit = ["alipay.order", "alipay.pos"]
_name = "alipay.order"

@api.multi
def _prepare_message(self):
self.ensure_one()
result_json = json.loads(self.result_raw)
msg = {
"event": "payment_result",
"code": result_json["code"],
"order_ref": self.order_ref,
"total_amount": self.total_amount,
"journal_id": self.journal_id.id,
}
return msg

def on_notification(self, data):
order = super(AlipayOrder, self).on_notification(data)
if order and order.pos_id:
order._send_pos_notification()
return order

@api.model
def create_qr(self, lines, **kwargs):
pos_id = kwargs.get("pos_id")
if pos_id:
if "create_vals" not in kwargs:
kwargs["create_vals"] = {}
kwargs["create_vals"]["pos_id"] = pos_id
return super(AlipayOrder, self).create_qr(lines, **kwargs)

@api.model
def _prepare_pos_create_from_qr(self, **kwargs):
create_vals = {
"pos_id": kwargs["pos_id"],
}
kwargs.update(create_vals=create_vals)
args = ()
return args, kwargs

@api.model
def pos_create_from_qr_sync(self, **kwargs):
args, kwargs = self._prepare_pos_create_from_qr(**kwargs)
record = self._create_from_qr(*args, **kwargs)
return record._prepare_message()

@api.model
def pos_create_from_qr(self, **kwargs):
"""Async method. Result is sent via longpolling"""
args, kwargs = self._prepare_pos_create_from_qr(**kwargs)
odoo_async_call(
self._create_from_qr,
args,
kwargs,
callback=self._send_pos_notification_callback,
)
return "ok"

@api.model
def _send_pos_notification_callback(self, record):
record._send_pos_notification()
20 changes: 20 additions & 0 deletions pos_alipay/models/alipay_pos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# License MIT (https://opensource.org/licenses/MIT).
from odoo import api, fields, models

CHANNEL_ALIPAY = "alipay"


class AlipayPos(models.AbstractModel):
_name = "alipay.pos"

pos_id = fields.Many2one("pos.config")

@api.multi
def _send_pos_notification(self):
self.ensure_one()
msg = self._prepare_message()
assert self.pos_id, "The record has empty value of pos_id field"
return self.env["pos.config"]._send_to_channel_by_id(
self._cr.dbname, self.pos_id.id, CHANNEL_ALIPAY, msg,
)
Loading

0 comments on commit 36184f5

Please sign in to comment.