Commit fdad0def authored by zhengdixun's avatar zhengdixun

mock bjd

parent 50e52846
__pycache__/
.idea/
*.pyc
\ No newline at end of file
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-21 15:21'
\ No newline at end of file
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-18 15:04'
from django.views import View
import json
import base64
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from collections import OrderedDict
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as SIGN_PKCS
from django.conf import settings
from django.http import JsonResponse
import uuid
from models.offline import OLInstallment
BS = AES.block_size
PLA_PUB = RSA.importKey(settings.BJD_PLATFORM_PUBKEY)
PLA_PRI = RSA.importKey(settings.BJD_PLATFORM_PRIKEY)
MER_PUB = RSA.importKey(settings.BJD_MERCHANT_PUBKEY)
MER_PRI = RSA.importKey(settings.BJD_MERCHANT_PRIKEY)
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
class BJDBaseView(View):
def dispatch(self, request, *args, **kwargs):
print(request.POST)
# request.POST = json.loads(request.body.decode('utf8'))
# request.realDate = self.decrypt(request.POST)
request.realData = request.POST
data = super().dispatch(request, *args, **kwargs)
# request_id = uuid.uuid4().hex
# data = self._encrypt(data, request_id)
return JsonResponse(data)
def decrypt(self, data,):
content = base64.b64decode(data['data'])
encryptkey = base64.b64decode(data['encryptkey'])
decrypt = PKCS1_v1_5.new(PLA_PRI).decrypt
aes_key = b''.join(decrypt(x, object()) for x in chunks(encryptkey, 128))
unpad = lambda s: s[0:-ord(s[-1])]
real_data = unpad(AES.new(aes_key).decrypt(content).decode('utf-8'))
real_data = json.loads(real_data, object_pairs_hook=OrderedDict)
raw_sign = base64.b64decode(real_data.pop('sign'))
unsign = self._sortdata(real_data)
assert SIGN_PKCS.new(MER_PRI).verify(SHA.new(unsign.encode('utf-8')), raw_sign)
return dict(real_data)
def _encrypt(self, params, key):
params = {x: str(params[x]) for x in params}
key = key[:16]
params['sign'] = self._singer(params)
json_params = json.dumps(params).encode('utf-8')
pkcs5_pad = lambda s: s + (BS - len(s) % BS) * (chr(BS - len(s) % BS).encode())
content = AES.new(key).encrypt(pkcs5_pad(json_params))
cipher = PKCS1_v1_5.new(PLA_PUB)
encryptkey = b''.join([cipher.encrypt(x) for x in chunks(key.encode('utf-8'), 117)])
return {
'data': base64.b64encode(content),
'encryptkey': base64.b64encode(encryptkey)
}
def _sortdata(self, data):
result = ''
for k in sorted(data.keys()):
if isinstance(data[k], str):
result += data[k]
else:
result += json.dumps(data[k], separators=(',', ':'), ensure_ascii=False)
return result
def _singer(self, data):
signstr = ''.join([data[k] for k in sorted(data.keys())])
sign = SIGN_PKCS.new(MER_PRI).sign(SHA.new(signstr.encode('utf-8')))
return base64.b64encode(sign).decode()
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-18 11:57'
from django.conf.urls import url
from django.views import View
from bjd.views import Apply
from bjd.views import Confirm
from bjd.views import Detail
from bjd.views import Certificate
from bjd.views import Result
from bjd.views import Submit
urlpatterns = [
# url(r'^$', IndexView.as_view()),
# url(r'^borrower$', BorrowerInfoView.as_view()),
# url(r'^installment/(?P<loan_id>\w+)$', InstallmentInfoView.as_view()),
# url(r'^installment/$', InstallmentInfoView.as_view()),
url(r'payByInstalmentsGmConnection.do$', Apply.as_view()),
url(r'payConfirmGmConnection.do$', Confirm.as_view()),
url(r'orderDetailGmConnection.do$', Detail.as_view()),
url(r'queryCertificateGmConnection.do$', Certificate.as_view()),
url(r'stagingResultsGmConnection.do$', Result.as_view()),
url(r'orderSubmitGmConnection.do$', Submit.as_view())
]
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-18 14:34'
from django.views import View
from django.http import JsonResponse
from bjd.base import *
from models.offline import OLInstallment
from datetime import datetime, timedelta
class Apply(BJDBaseView):
def post(self, request):
order_no = int(request.realData.get('orderno'))
installment = OLInstallment.objects.get(id=order_no)
data = {
'merchantno': settings.BJD_MERCHANT_NO,
'orderno': installment.id,
'status': 'ORDER_SUCCESS',
'msg': ''
}
print(data)
return data
class Confirm(BJDBaseView):
def post(self,request):
order_no = int(request.realData.get('orderno'))
installment = OLInstallment.objects.get(id=order_no)
return {
'merchantno': settings.BJD_MERCHANT_NO,
'orderno': installment.id,
'startdate': datetime.now().strftime('%Y-%m-%d'),
'enddate': (datetime.now() + timedelta(days=30*installment.period)).strftime('%Y-%m-%d'),
'projectmoney': int(installment.amount * 0.8),
'interestmode': 'DBDX',
'periods': installment.period,
'firstrepayment': '%.2f' % (installment.amount * 0.8 / installment.period),
'repaymentdate': (datetime.now() + timedelta(days=30)).strftime('%Y-%m-%d'),
'contracturl': '',
'status': '0000',
'msg': '',
}
class Detail(BJDBaseView):
def post(self,request):
order_no = int(request.realData.get('orderno'))
installment = OLInstallment.objects.get(id=order_no)
return {
'merchantno': settings.BJD_MERCHANT_NO,
'orderno': installment.id,
'projectname': installment.item_name,
'startdate': installment.confirm_time.strftime('%Y-%m-%d'),
'enddate': (installment.confirm_time + timedelta(days=30 * installment.period)).strftime('%Y-%m-%d'),
'projectmoney': installment.allow_amount,
'costmoney': '%.2f' % (installment.allow_amount * 12 * 0.0108),
'interestmode': 'DBDX',
'periods': installment.period,
'firstrepayment': '%.2f' % (installment.allow_amount / installment.period),
'repaymentdate': (installment.confirm_time + timedelta(days=30)).strftime('%Y-%m-%d'),
'projecStatus': '1',
'repayRecords': [
{
'period': i + 1,
'principalRepayment': '%.2f' % (installment.allow_amount / installment.period),
'serviceMoney': '%.2f' % (installment.allow_amount * 0.0108),
'penalty': '0.00',
'allMoney': '%.2f' % (
installment.allow_amount / installment.period + installment.allow_amount * 0.0108),
'afterMoney': '0.00',
'intentDate': (installment.confirm_time + timedelta(days=30 * (i + 1))).strftime('%Y%m%d'),
'factDate': '',
'status': '1',
} for i in range(installment.period)
],
'status': '0000',
'msg': '',
}
class Certificate(BJDBaseView):
def post(self,request):
userid = request.realData.get('userid')
telephone = request.realData.get('telephone')
return {
'merchantno': settings.BJD_MERCHANT_NO,
'userid': userid,
'telephone': telephone,
'cerRecords': [
{
'autResult': '1',
'autType': '1001',
},
{
'autResult': '1',
'autType': '1002',
},
{
'autResult': '1',
'autType': '1004',
},
{
'autResult': '1',
'autType': '1005',
},
],
'status': '0000',
'msg': ''
}
class Result(BJDBaseView):
def post(self, request):
order_no = int(request.realData.get('orderno'))
installment = OLInstallment.objects.get(id=order_no)
return {
'merchantno': settings.BJD_MERCHANT_NO,
'orderno': installment.id,
'startdate': datetime.now().strftime('%Y-%m-%d'),
'enddate': (datetime.now() + timedelta(days=30 * installment.period)).strftime('%Y-%m-%d'),
'projectmoney': int(installment.amount * 0.8),
'interestmode': 'DBDX',
'periods': installment.period,
'remarks': '',
'firstrepayment': '%.2f' % (installment.amount * 0.8 / installment.period),
'firstservice': '%.2f' % (installment.amount * 0.8 * 0.0108),
'repaymentdate': (datetime.now() + timedelta(days=30)).strftime('%Y-%m-%d'),
'contracturl': '',
'status': '0000',
'payresoult': '2222',
'backcode': '',
'msg': '',
}
class Submit(BJDBaseView):
def post(self, request):
order_no = int(request.realData.get('orderno'))
return {
'merchantno': settings.BJD_MERCHANT_NO,
'orderno': order_no,
'status': '0000',
'msg': ''
}
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-21 15:21'
\ No newline at end of file
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-15 17:25'
from django.db import models
from django.db.models import FloatField
from django.db.models import CharField, IntegerField, DateTimeField
from gm_crypto.fields import EncryptedCharField
from gm_types.plutus.offline import ORDER
class OLInstallment(models.Model):
class Meta:
verbose_name = '分期单'
db_table = 'offline_installment'
app_label = 'installment'
borrower_id = IntegerField('借款人')
bank_id = IntegerField()
service = CharField('服务商', max_length=32, default=None)
item_name = CharField('项目名称', max_length=32, default='')
hospital_id = IntegerField()
amount = IntegerField('申请金额')
allow_amount = IntegerField('审批金额', default=None)
period = IntegerField('期数', default=0)
status = CharField('分期单状态', default=ORDER.PRE, max_length=16)
backmessage = CharField('审批结果说明', max_length=250, default=None)
reapply_id = IntegerField('继续申请分期单ID', default=None, null=True)
audit_time = DateTimeField('提交审核时间', default=None)
callback_time = DateTimeField('第三方审核回调时间', default=None)
confirm_time = DateTimeField('用户确认时间', default=None)
first_repaytime = DateTimeField('首次还款时间', default=None)
first_interest = FloatField('首次还款利息', default=0.0)
create_time = DateTimeField(auto_now_add=True)
snapshot = models.TextField(default=None, verbose_name='订单快照')
name = EncryptedCharField('下单时真实姓名', max_length=24, default=None)
phone = EncryptedCharField("下单时电话", max_length=20, unique=True, default=None)
id_card = EncryptedCharField('下单时身份证号', max_length=24, default=None)
django==2.0
git+ssh://git@git.gengmei.cc/backend/gm-types.git@master
git+ssh://git@git.gengmei.cc/backend/gm-crypto.git@dev
git+ssh://git@git.gengmei.cc/backend/gm-upload.git@master
mysqlclient==1.3.7
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-21 15:21'
\ No newline at end of file
"""
Django settings for training project.
Generated by 'django-admin startproject' using Django 2.0.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#h+b&24n%l3()37#-yd-9c4qy6_&jthms95r$ar+#y+w3fdndp'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'training.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'training.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 设置为mysql数据库
'NAME': 'plutus_test',
'USER': 'work',
'PASSWORD': 'workwork',
'HOST': 'rdsmaqevmuzj6jy.mysql.rds.aliyuncs.com',
'PORT': '',
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
"charset": "utf8mb4", # 为了支持emoji表情
},
},
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
AES_KEY = 'keycasefornonprd' # 16个字节的密钥
AES_IV = 'iv_casefornonprd' # 16个字节的初始向量
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
# #################### 博金贷相关-START #####################
BJD_MOCK = False
BJD_SERVICE = 'http://47.94.226.224:8181/hurong_proj_bj_byph/platformInterface'
BJD_MERCHANT_NO = 'SH002'
BJD_BACKURL = 'http://www.thor.test.igengmei.com/api/web/#/bjd/accreditinfo?order_id={}'
BJD_MERCHANT_PRIKEY = """-----BEGIN RSA PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM0Cz9o9g0GuZ4ap
+nxyk5gk15dxUch1GvSAnBBqKdwm76y+o9RgamGMGCvEuai9gxXKMgSMdbhV3onJ
znV3ee+8ppTa90K57mVrWgt5gJUHTTAPHqxrGvtRpbqwNAOT7oR9kII4CcPCxzpJ
+yLYNHlM/5ewpkNPQifCk4bEBaWRAgMBAAECgYAGgbBXHNytmPtwKrTofjpw+bpd
9BrEYfMZD3vkiXoKorG4qdRJSUYXEnsx6Gx8Doe6iVBNFKgn0ZHejakf0UrtYmPz
Ap0H21O2Sj8SrzF4fsH5vmDfasa6OQMlJyXSYMQ3Q35uFdIOAkcVGdap2d22dCFe
rwp3iCqzHMXrYFIuAQJBAOmkYk1EMeTsabfm7CCQS/CF4gopx2s4eWBIHT21ujNZ
LRaPKPuYJXHuZDViBCstKd6XXHsbti81X6viGbQapWUCQQDgoQpcdrM/5D7n9Xgt
GqmNnOeTZ2GYuoH5kQp1FL64Yx9QpJmylJff+WewsEvnLK+yXgnthc3JIQ4PrHwM
R8K9AkEAzN9LH4ur4Jv5e7vu1AMTw93yPo0yA2/q5qV1lpYSp1IL+lsgSbW5J/Ut
Q64mD6Izs66v9ndvQmgf8z144nf3DQJAe93x47kE8UeAtNJ0mZKpStDqFiuc8uZu
A9vKQ3PUE8N9IjASHRq5gSV72z/sKydGH3qhyNvO9YkHwvbfVLpBlQJBAMCHS7UH
RC11KvwyDDqRru3QAr7lJ3RxpIQOz3KCKvTiU3W+r2jSZ7bVal4eZbh+mvqrVH3Q
1mn2yz4MNzfVeUs=
-----END PUBLIC KEY-----
"""
BJD_PLATFORM_PUBKEY = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuWA51DrLInq8BJqkT6DF6kpub
NMoTQpnhVV3hpyi0LBrqCK6f1kQFj9ZnqOaq35DWQmvvV/2suMjNwgyvLktpkm1T
KNtB2noKAgM3xfXE9NQDXLcKSVNmTK42NC0UPsp92DZIvYaGLDw4mLzQKbQ+A1Tr
Md7y1ncR3DGTxZXCtQIDAQAB
-----END PUBLIC KEY-----
"""
BJD_MERCHANT_PUBKEY = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNAs/aPYNBrmeGqfp8cpOYJNeX
cVHIdRr0gJwQaincJu+svqPUYGphjBgrxLmovYMVyjIEjHW4Vd6Jyc51d3nvvKaU
2vdCue5la1oLeYCVB00wDx6saxr7UaW6sDQDk+6EfZCCOAnDwsc6Sfsi2DR5TP+X
sKZDT0InwpOGxAWlkQIDAQAB
-----END PUBLIC KEY-----
"""
BJD_PLATFORM_PRIKEY = """-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAK5YDnUOssierwEm
qRPoMXqSm5s0yhNCmeFVXeGnKLQsGuoIrp/WRAWP1meo5qrfkNZCa+9X/ay4yM3C
DK8uS2mSbVMo20HaegoCAzfF9cT01ANctwpJU2ZMrjY0LRQ+yn3YNki9hoYsPDiY
vNAptD4DVOsx3vLWdxHcMZPFlcK1AgMBAAECgYB+5AIpunfvQmdXLB81KPMSJjBx
BzvoRroe4fYBbZtXfx5bpdQK63T4o1bGfYzdYvhUqWVLfzxXgOpNr2Vx/vzM9rWi
oJTDMowrlalfUqIs9Dp0MBxwnPg19JWq5KxWbdg2JJ24qbaTCm95Nt/ajiFqyUhP
jp5UiLhjM/aumy5vhQJBAOCkgoh8FSMP2NTKstFIcXp/p4xKNQ9mym+1FmdRkg3G
0RVKi6ApQJVzqBpYL0h5b4cLhL/2hjB9/iNU7PR42J8CQQDGriZiaGV3IIYrT3Pc
pBjaIMpWwerSIgxguViBiTBrRmL3W2h9thSp2X/Iz7ayWsXXRHPiX672a072B7U6
WqArAkAtEHNrI9EtrnEmBt+mYiz5kQAwgXZxd4JmtGIhKdjt0JOC/OhTodLl6ESx
vD0IAexgn+vqgm7a7Xt85P1/8XorAkBbrL/JaKJo9XjzQxYTGSTegYLbxV6010Ee
4GcWXlcZKMFBocv1Na8TMGjmH/INGhVv3wYZzkzNJ3anz6av5mFBAkEAqt5LpXEL
YRTCGuY8EgB7Qgj+35ihXlFw5C6Assv9oCz6U3lHaxbmDbbrIqdSA2AwJvhuG+WH
wHluD8QR8paAog==
-----END PUBLIC KEY-----
"""
BJD_AUTHOR = [1001, 1002]
BJD_EXTRA_AUTHOR = [1004, 1005]
BJD_EXTRA_AMOUNT = 15000
# #################### 博金贷相关-END #####################
"""training URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
urlpatterns = [
url(r'mock/bjd', include('bjd.urls')),
]
# coding: utf-8
# __author__ = 'zdx'
# __date__ = '2017-12-15 17:57'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment