Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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