wechatpy.pay.api.order   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Test Coverage

Coverage 39.47%

Importance

Changes 0
Metric Value
eloc 80
dl 0
loc 150
rs 10
c 0
b 0
f 0
ccs 15
cts 38
cp 0.3947
wmc 9

5 Methods

Rating   Name   Duplication   Size   Complexity  
A WeChatOrder.close() 0 12 1
B WeChatOrder.create() 0 68 5
A WeChatOrder.query() 0 14 1
A WeChatOrder.reverse() 0 16 1
A WeChatOrder.get_appapi_params() 0 20 1
1
# -*- coding: utf-8 -*-
2 10
from __future__ import absolute_import, unicode_literals
3 10
import time
4 10
import random
5 10
from datetime import datetime, timedelta
6
7 10
from wechatpy.utils import timezone
8 10
from wechatpy.pay.utils import get_external_ip
9 10
from wechatpy.pay.base import BaseWeChatPayAPI
10 10
from wechatpy.utils import random_string, to_text, json
11 10
from wechatpy.pay.utils import calculate_signature
12
13
14 10
class WeChatOrder(BaseWeChatPayAPI):
15
16 10
    def create(self, trade_type, body, total_fee, notify_url, client_ip=None,
17
               user_id=None, out_trade_no=None, detail=None, attach=None,
18
               fee_type='CNY', time_start=None, time_expire=None,
19
               goods_tag=None, product_id=None, device_info=None,
20
               limit_pay=None, scene_info=None, sub_user_id=None, **kwargs):
21
        """
22
        统一下单接口
23
24
        :param trade_type: 交易类型,取值如下:JSAPI,NATIVE,APP,WAP, MWEB
25
        :param body: 商品描述
26
        :param total_fee: 总金额,单位分
27
        :param notify_url: 接收微信支付异步通知回调地址
28
        :param client_ip: 可选,APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
29
        :param user_id: 可选,用户在商户appid下的唯一标识。trade_type=JSAPI和appid已设定,此参数必传
30
        :param sub_user_id: 可选,小程序appid下的唯一标识。trade_type=JSAPI和sub_appid已设定,此参数必传
31
        :param out_trade_no: 可选,商户订单号,默认自动生成
32
        :param detail: 可选,商品详情
33
        :param attach: 可选,附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
34
        :param fee_type: 可选,符合ISO 4217标准的三位字母代码,默认人民币:CNY
35
        :param time_start: 可选,订单生成时间,默认为当前时间
36
        :param time_expire: 可选,订单失效时间,默认为订单生成时间后两小时
37
        :param goods_tag: 可选,商品标记,代金券或立减优惠功能的参数
38
        :param product_id: 可选,trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义
39
        :param device_info: 可选,终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
40
        :param limit_pay: 可选,指定支付方式,no_credit--指定不能使用信用卡支付
41
        :param scene_info: 可选,上报支付的场景信息
42
        :param kwargs: 其他未列举在上述参数中的统一下单接口调用参数,例如电子发票入口开放标识receipt
43
        :type scene_info: dict
44
        :return: 返回的结果数据
45
        """
46
        now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
47
        hours_later = now + timedelta(hours=2)
48
        if time_start is None:
49
            time_start = now
50
        if time_expire is None:
51
            time_expire = hours_later
52
        if not out_trade_no:
53
            out_trade_no = '{0}{1}{2}'.format(
54
                self.mch_id,
55
                now.strftime('%Y%m%d%H%M%S'),
56
                random.randint(1000, 10000)
57
            )
58
        if scene_info is not None:
59
            scene_info = json.dumps(scene_info, ensure_ascii=False)
60
        data = {
61
            'appid': self.appid,
62
            'sub_appid': self.sub_appid,
63
            'device_info': device_info,
64
            'body': body,
65
            'detail': detail,
66
            'attach': attach,
67
            'out_trade_no': out_trade_no,
68
            'fee_type': fee_type,
69
            'total_fee': total_fee,
70
            'spbill_create_ip': client_ip or get_external_ip(),
71
            'time_start': time_start.strftime('%Y%m%d%H%M%S'),
72
            'time_expire': time_expire.strftime('%Y%m%d%H%M%S'),
73
            'goods_tag': goods_tag,
74
            'notify_url': notify_url,
75
            'trade_type': trade_type,
76
            'limit_pay': limit_pay,
77
            'product_id': product_id,
78
            'openid': user_id,
79
            'sub_openid': sub_user_id,
80
            'scene_info': scene_info,
81
        }
82
        data.update(kwargs)
83
        return self._post('pay/unifiedorder', data=data)
84
85 10
    def query(self, transaction_id=None, out_trade_no=None):
86
        """
87
        查询订单
88
89
        :param transaction_id: 微信的订单号,优先使用
90
        :param out_trade_no: 商户系统内部的订单号,当没提供transaction_id时需要传这个。
91
        :return: 返回的结果数据
92
        """
93
        data = {
94
            'appid': self.appid,
95
            'transaction_id': transaction_id,
96
            'out_trade_no': out_trade_no,
97
        }
98
        return self._post('pay/orderquery', data=data)
99
100 10
    def close(self, out_trade_no):
101
        """
102
        关闭订单
103
104
        :param out_trade_no: 商户系统内部的订单号
105
        :return: 返回的结果数据
106
        """
107
        data = {
108
            'appid': self.appid,
109
            'out_trade_no': out_trade_no,
110
        }
111
        return self._post('pay/closeorder', data=data)
112
113 10
    def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
114
        """
115
        获取 APP 支付参数
116
117
        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
118
        :param timestamp: 可选,时间戳,默认为当前时间戳
119
        :param nonce_str: 可选,随机字符串,默认自动生成
120
        :return: 签名
121
        """
122
        data = {
123
            'appid': self.appid,
124
            'partnerid': self.mch_id,
125
            'prepayid': prepay_id,
126
            'package': 'Sign=WXPay',
127
            'timestamp': timestamp or to_text(int(time.time())),
128
            'noncestr': nonce_str or random_string(32)
129
        }
130
        sign = calculate_signature(data, self._client.api_key)
131
        data['sign'] = sign
132
        return data
133
134 10
    def reverse(self, transaction_id=None, out_trade_no=None):
135
        """
136
        撤销订单
137
138
        :param transaction_id: 可选,微信的订单号,优先使用
139
        :param out_trade_no: 可选,商户系统内部的订单号,
140
                            transaction_id、out_trade_no二选一,
141
                            如果同时存在优先级:transaction_id> out_trade_no
142
        :return: 返回的结果数据
143
        """
144
        data = {
145
            'appid': self.appid,
146
            'transaction_id': transaction_id,
147
            'out_trade_no': out_trade_no,
148
        }
149
        return self._post('secapi/pay/reverse', data=data)
150