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

11.0 qr payments #1109

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
e7298f0
[NEW] pos_qr_scan
KolushovAlexandr Nov 8, 2017
3758069
[DOC] enhanced [REM] excessive code
KolushovAlexandr Nov 8, 2017
ca7d163
[FIX] error on second popup openning
KolushovAlexandr Nov 13, 2017
1e54b6b
[LINT] pos_qr_scan
KolushovAlexandr Nov 13, 2017
8b6f40a
[NEW] pos_wechat
KolushovAlexandr Nov 13, 2017
48f5f77
[DEV]
KolushovAlexandr Nov 20, 2017
abf0ef0
[ADD] controllers
KolushovAlexandr Nov 21, 2017
45467ee
[DEV]
KolushovAlexandr Nov 21, 2017
373ea14
[DEV] removed flask
KolushovAlexandr Nov 21, 2017
25330db
[DEV] controllers
KolushovAlexandr Nov 22, 2017
9b37a20
[DEV] with logs
KolushovAlexandr Nov 24, 2017
8b7c3a7
[FIX] old syntax prints
KolushovAlexandr Nov 24, 2017
2f80b7a
[DEV] use sha1
KolushovAlexandr Nov 24, 2017
25649a3
[REF] pos_wechat -> wechat
KolushovAlexandr Nov 24, 2017
d0d1991
[NEW] pos_payment_wechat
KolushovAlexandr Nov 24, 2017
c818438
[DEV] auth_code
KolushovAlexandr Nov 28, 2017
a1ca49f
[DEV] payment request
KolushovAlexandr Nov 29, 2017
67e5e21
[DEV] print rem & add
KolushovAlexandr Nov 29, 2017
e8f5fe5
[DEV] query API
KolushovAlexandr Nov 29, 2017
405f51a
[DEV]
KolushovAlexandr Dec 4, 2017
c675c75
[DEV] in process add signkey
KolushovAlexandr Dec 5, 2017
a183ba3
[DEV] check on dev_serv with sandboxnew
KolushovAlexandr Dec 5, 2017
c95dbea
[DEV]
KolushovAlexandr Dec 5, 2017
1d1a470
[DEV] prints for debugging
KolushovAlexandr Dec 8, 2017
f7973ce
[DOC] installable false for wechat modules
KolushovAlexandr Jun 7, 2018
c3667f2
[IMP] smal fixes
KolushovAlexandr Jun 7, 2018
93bc690
[IMP]
KolushovAlexandr Jun 7, 2018
f19b581
[DOC] index.rst about https
KolushovAlexandr Jun 8, 2018
2b45afe
[ADD] camera selection
KolushovAlexandr Jun 8, 2018
3d79569
[FIX] camera selection, [REM] excessive
KolushovAlexandr Jun 9, 2018
9dde88c
[IMP] idk
KolushovAlexandr Jun 9, 2018
2146026
[IDK] use ammend before pushing
KolushovAlexandr Jun 13, 2018
2adaa67
[REM] dev stuff
KolushovAlexandr Jun 22, 2018
1a71481
[ADD] active camera stores in the localstorage
KolushovAlexandr Jun 22, 2018
e0995ad
[DOC] detalisation
KolushovAlexandr Jun 22, 2018
d21213d
[REF] new working on the apple qr code lib
KolushovAlexandr Jun 26, 2018
f72e50c
[REM] model rep
KolushovAlexandr Jun 26, 2018
e47fe06
[DOC] version, icon
KolushovAlexandr Jun 26, 2018
0782c02
:bath: libraries to lib
KolushovAlexandr Jun 27, 2018
078ec4d
:bomb: from straight saving to db to pos.db tools
KolushovAlexandr Jun 27, 2018
a720be5
:bomb: new modules payment_wechat, pos_payment
KolushovAlexandr Jun 27, 2018
420f1a7
:bomb: closing the popup after scanning
KolushovAlexandr Jun 27, 2018
9af4a63
:rose: styles for compatibility with pos_mobile
KolushovAlexandr Jun 27, 2018
7472626
Merge remote-tracking branch 'pos-addons/11.0' into pos-addons-11.0-p…
Jul 1, 2018
c7f6401
Merge pull request #476 from yelizariev/pos-addons-11.0-pos-qr-paymen…
Jul 1, 2018
0f92fa2
:memo: doc review and cleanup
Jul 3, 2018
77fc7ab
:memo: implement "Quick Pay" directly
Jul 4, 2018
3094c62
:memo: documentation cleanup
Jul 4, 2018
bfd8037
:fire: unfinished tests
Jul 5, 2018
877c5ca
:fire: backend and tour tests for miscropay
Jul 5, 2018
8000051
:fire: use xmlrpc for micropay
Jul 5, 2018
c27ab84
:fire_engine: draft code for test_micropay_backend
Jul 6, 2018
03a7a37
:fire_engine: syntax and import errors
Jul 6, 2018
23e89cd
:fire_engine: work on test_micropay_backend
Jul 6, 2018
8c7b817
:fire: unfortunally, longpolling cannot be used with --test-enable
Jul 6, 2018
e53f099
:fire_engine: test_micropay_backend is passed
Jul 6, 2018
0c2178a
:bomb: work with POS
Jul 6, 2018
423601e
:bomb: draft js for micropay
Jul 6, 2018
59c9a22
:bomb: payment work in local sandbox mode
Jul 7, 2018
77494bd
:tv: wechat.micropay views
Jul 9, 2018
3ab2aeb
:memo: plan for payment based on unified orders
Jul 10, 2018
156d185
:memo: update notes in tests
Jul 10, 2018
bfe0bff
:fire: native payments tests
Jul 10, 2018
2ffb69d
:fire_engine: fix installation problems
Jul 10, 2018
270a04f
:fire_engine: draft code for test_native_payment
Jul 10, 2018
7ca9e88
:fire: passing result to be return via context doesn't work
Jul 10, 2018
86bf188
:fire_engine: wechat tests are passing
Jul 10, 2018
e2c9b02
:bomb:
Jul 12, 2018
26e8a69
:bomb: Support scanning via scanner
Jul 12, 2018
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
52 changes: 52 additions & 0 deletions payment_wechat/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png
:target: https://www.gnu.org/licenses/lgpl
:alt: License: LGPL-3

=================
WeChat payments
=================

Technical module to integrate WeChat payments with odoo POS, eCommerce or backend. As in WeChat QR codes are used, addional modules are required to show QR code in POS or eCommerce. Following methods are supported:

* TODO User scans QR and authorise payment
* TODO User opens eCommerce website via WeChat's browser, fills the cart and is redirected to WeChat App UI to authorise the payment

Note, that this module doesn't implement *Quick Pay* method, i.e. the one where buyer shows QR code and vendor scans.

Credits
=======

Contributors
------------
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__

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/payment_wechat/>`__.

Thank you for understanding!

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

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

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

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

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

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

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

Tested on Odoo 11.0 4d0a1330e05bd688265bea14df4ad12838f9f2d7
2 changes: 2 additions & 0 deletions payment_wechat/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import controllers
37 changes: 37 additions & 0 deletions payment_wechat/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": """WeChat payments""",
"summary": """The most popular Chinese payment method""",
"category": "Accounting",
# "live_test_url": "",
"images": [],
"version": "11.0.1.0.0",
"application": False,

"author": "IT-Projects LLC, Ivan Yelizariev",
"support": "[email protected]",
"website": "https://it-projects.info/team/yelizariev",
"license": "LGPL-3",
# "price": 9.00,
# "currency": "EUR",

"depends": [
],
"external_dependencies": {"python": [], "bin": []},
"data": [
],
"demo": [
"demo/w_p_demo.xml",
],
"qweb": [
],

"post_load": None,
"pre_init_hook": None,
"post_init_hook": None,
"uninstall_hook": None,

"auto_install": False,
"installable": True,
}
1 change: 1 addition & 0 deletions payment_wechat/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import p_w_controllers
146 changes: 146 additions & 0 deletions payment_wechat/controllers/p_w_controllers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
from __future__ import unicode_literals
import time
import random
import logging
import requests
import odoo
import json
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'json' imported but unused

from odoo.http import request

_logger = logging.getLogger(__name__)

try:
from odoo.addons.bus.controllers.main import BusController
except ImportError:
_logger.error('pos_multi_session_sync inconsisten with odoo version')
BusController = object


class Controller(BusController):

@odoo.http.route('/wechat/getsignkey', type="json", auth="public")
def getSignKey(self, message):
data = {}
data['mch_id'] = request.env['ir.config_parameter'].get_param('wechat.mchId')
wcc = request.env['wechat.config']
data['nonce_str'] = (wcc.getRandomNumberGeneration(message))[:32]
data['sign'] = (str(time.time()).replace('.', '')
+ '{0:010}'.format(random.randint(1, 9999999999))
+ '{0:010}'.format(random.randint(1, 9999999999)))[:32]
post = wcc.makeXmlPost(data)
print(post)
url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey"
r1 = requests.post(url, data=post)
print(r1)
print(r1.status_code)
print(r1.headers)
print(r1.headers['content-type'])
print(r1.iter_content)
print(len(r1.text))
print(len(r1.content))
# print(r1.mch_id)
# print(r1.sandbox_signkey)
message = {}
message['resp1'] = r1.text
return message

@odoo.http.route('/wechat/test', type="json", auth="public")
def testAccessToken(self, message):
wcc = request.env['wechat.config']
if not wcc:
wcc = wcc.create({
'token_validity': 7000,
'access_token': 'test'
})
wcc.getAccessToken()

@odoo.http.route('/wechat/payment_commence', type="json", auth="public")
def micropay(self, message):
# data = message['data']
# data['order_id'] = '{0:06}'.format(message['data']['order_id'])
# data['cashier_id'] = '{0:05}'.format(message['data']['cashier_id'])
# data['session_id'] = '{0:05}'.format(message['data']['session_id'])
data = {}
data['auth_code'] = message['data']['auth_code']
data['appid'] = request.env['ir.config_parameter'].get_param('wechat.appId')
data['mch_id'] = request.env['ir.config_parameter'].get_param('wechat.mchId')
data['body'] = message['data']['order_short']

data['out_trade_no'] = (str(time.time()).replace('.', '') \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the backslash is redundant between brackets

+ '{0:010}'.format(random.randint(1, 9999999999)) \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent
the backslash is redundant between brackets

+ '{0:010}'.format(random.randint(1, 9999999999)))[:32]
wcc = request.env['wechat.config']
if not wcc:
wcc = wcc.create({
'token_validity': 1,
'access_token': ''
})
data['total_fee'] = message['data']['total_fee']
data['spbill_create_ip'] = wcc.getIpList()[0]
print(wcc.getIpList())
# data['auth_code'] = message['data']['auth_code']
#
# device_info =
# sign_type =
# detail =
# attach =
# fee_type =
# goods_tag =
# limit_pay =
# scene_info =
#
data['nonce_str'] = (wcc.getRandomNumberGeneration(message))[:32]
data['sign'] = (wcc.getRandomNumberGeneration(message))[:32]

post = wcc.makeXmlPost(data)
print(post)
r1 = requests.post("https://api.mch.weixin.qq.com/sandboxnew/pay/micropay", data=post)
print(r1)
print(r1.status_code)
print(r1.headers)
print(r1.headers['content-type'])
print(r1.encoding)
print(len(r1.text))
print(len(r1.content))
message = {}
message['resp1'] = r1
message['resp_text1'] = r1.text
message['resp_cont1'] = r1.content
# message['encode_text1'] = r1.text.encode('iso-8859-1').decode('utf-8')
# print(r1.text.encode('utf-8'))
time.sleep(5)
# return request.redirect('/wechat/payment_query')
#
# @odoo.http.route('/wechat/payment_query', type="json", auth="public")
# def queryOrderApi(self, message):
data_qa = {}
data_qa['appid'] = data['appid']
data_qa['mch_id'] = data['mch_id']
data_qa['out_trade_no'] = data['out_trade_no']
data_qa['nonce_str'] = data['nonce_str']
data_qa['sign'] = data['sign']
if hasattr(data, 'sign_type'):
data_qa['sign_type'] = data['sign_type']

post = wcc.makeXmlPost(data_qa)
print(post)
r2 = requests.post("https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery", data=post)
print(r2)
print(r2.status_code)
print(r2.headers)
print(r2.headers['content-type'])
print(r2.encoding)
print(len(r2.text))
print(len(r2.content))
message['resp2'] = r2
message['resp_text2'] = r2.text
message['resp_cont2'] = r2.content
# message['encode_text2'] = r2.text.encode('iso-8859-1').decode('utf-8')
# with open('txt.txt', 'w+') as fil:
# fil.write(r1.text, r2.text)
# print(r2.text.encode('utf-8'))
# for each_unicode_character in r2.text.encode('utf-8').decode('utf-8'):
# print(each_unicode_character)
# print(message['encode_text1'])
# print(message['encode_text2'])
return message
11 changes: 11 additions & 0 deletions payment_wechat/demo/w_p_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--<record id="wechat_journal" model="account.journal">-->
<!--<field name="name">Wechat - Test</field>-->
<!--<field name="code">TWC</field>-->
<!--<field name="type">bank</field>-->
<!--<field name="default_debit_account_id" ref="bnk"/>-->
<!--<field name="default_credit_account_id" ref="bnk"/>-->
<!--<field name="wechat_payment">True</field>-->
<!--</record>-->
</odoo>
4 changes: 4 additions & 0 deletions payment_wechat/doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
`1.0.0`
-------

- Init version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

12 changes: 12 additions & 0 deletions payment_wechat/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
=================
WeChat payments
=================

Follow instructions of `WeChat API <https://apps.odoo.com/apps/modules/11.0/wechat/>`__.

Usage
=====

Following instruction covers backend usage only. For POS and eCommerce use instructions of corresponding modules.

* open menu TODO
1 change: 1 addition & 0 deletions payment_wechat/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import wechat_models
73 changes: 73 additions & 0 deletions payment_wechat/models/wechat_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from __future__ import absolute_import, unicode_literals
from odoo import fields, models, api
from odoo.http import request
import json
import hashlib
import time
import requests


class AccountJournal(models.Model):
_inherit = "account.journal"

wechat_payment = fields.Boolean(string='Allow WeChat payments', default=False,
help="Check this box if this account allows pay via WeChat")


# class PosOrder(models.Model):
# _inherit = "pos.order"
#
# auth_code = fields.Integer(string='Code obtained from customers QR or BarCode', default=0)


class WechatConfiguration(models.Model):
_name = "wechat.config"

# auth_code = fields.Integer(string='Code obtained from customers QR or BarCode', default=0)
access_token = fields.Char(string='access_token')
token_validity = fields.Float(string='validity time')

@api.multi
def getAccessToken(self):
print('inside getAccessToken!!!!!!!!!!!', self.token_validity < time.time())
if not self.token_validity:
self.createVals()
if self.token_validity < time.time():
appId = request.env['ir.config_parameter'].get_param('wechat.appId')
appSecret = request.env['ir.config_parameter'].get_param('wechat.appSecret')
url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s" % (
appId, appSecret)
response = requests.get(url)
access_token = json.loads(response.text)['access_token']
self.write({'token_validity': time.time() + 7000, 'access_token': access_token})
else:
access_token = self.access_token
return access_token

def getIpList(self):
token = self.getAccessToken()
url = "https://api.wechat.com/cgi-bin/getcallbackip?access_token=%s" % token
response = requests.get(url)
return json.loads(response.text)['ip_list']

def sortData(self, message):
arrA = []
data = message['data']
for key in data:
if data[key]:
arrA.append(str(key) + '=' + str(data[key]))
arrA.sort()
return arrA

def getRandomNumberGeneration(self, message):
data = self.sortData(message)
strA = ' & '.join(data)
return hashlib.sha256(strA.encode('utf-8')).hexdigest().upper()

def makeXmlPost(self, data):
xml_str = ['<xml>']
for key in sorted(data):
if data[key]:
xml_str.append('<' + str(key) + '>' + str(data[key]) + '</' + str(key) + '>')
xml_str.append('</xml>')
return '\n'.join(xml_str)
Binary file added payment_wechat/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions payment_wechat/views/views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_journal_form_inherited" model="ir.ui.view">
<field name="name">account.journal.form</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='type']" position="after">
<!--<field name="wechat_payment" attrs="{'invisible':[('type', '!=', 'bank')]}"/>-->
<field name="wechat_payment"/>
</xpath>
</field>
</record>

</odoo>
Loading