def get_payment_wechat_public_signing(params, nonce_str=''):
    merchant_id = 'viastelle'
    api_key = 'viastelle'

    if settings.DEBUG:
        print('Get payment wechat public keys in JSAPI signing')
        sandbox_key_params = {
            'mch_id': merchant_id,
            'nonce_str': nonce_str,
        }
        signature = utils.calculate_signature(sandbox_key_params, api_key)
        sandbox_key_params['sign'] = signature
        sandbox_key_data = utils.dict_to_xml(sandbox_key_params, signature)

        headers = {'Content-type': 'application/xml'}
        response = requests.post(url=resources.WECHAT_SANDBOX_SIGN_KEY,
                                 data=sandbox_key_data,
                                 headers=headers)
        print(response.text)

        result_dict = xmltodict.parse(response.text)['xml']
        api_key = result_dict['sandbox_signkey']

        print(api_key)

    return utils.calculate_signature(params, api_key)
def get_payment_wechat_public(order_id, total_price, product_title, nonce_str,
                              ip_addr, openid):
    wechat_app_id = 'viastelle'
    merchant_id = 'viastelle'
    api_key = 'viastelle'

    if settings.DEBUG:
        total_fee = 101
    else:
        total_fee = int((total_price * 100))

    product_split = product_title.split(' ')
    if len(product_split) >= 4:
        product_body = product_split[0] + ' ' + product_split[1]
    else:
        product_body = product_title

    notify_url = resources.get_wechat_notify_url()

    prepaid_object = {
        'appid': wechat_app_id,
        'body': product_body,
        'mch_id': merchant_id,
        'nonce_str': nonce_str,
        'notify_url': notify_url,
        'out_trade_no': order_id,
        'spbill_create_ip': ip_addr,
        'total_fee': total_fee,
        'trade_type': 'JSAPI',
        'openid': openid
    }

    print(prepaid_object)

    if settings.DEBUG:
        print('Get payment wechat public payments')
        sandbox_key_params = {
            'mch_id': merchant_id,
            'nonce_str': nonce_str,
        }
        signature = utils.calculate_signature(sandbox_key_params, api_key)
        sandbox_key_params['sign'] = signature
        sandbox_key_data = utils.dict_to_xml(sandbox_key_params, signature)

        headers = {'Content-type': 'application/xml'}
        response = requests.post(url=resources.WECHAT_SANDBOX_SIGN_KEY,
                                 data=sandbox_key_data,
                                 headers=headers)
        print(response.text)

        result_dict = xmltodict.parse(response.text)['xml']
        api_key = result_dict['sandbox_signkey']

        print(api_key)
        prepaid_object['total_fee'] = total_fee

    prepaid_signature = utils.calculate_signature(prepaid_object, api_key)
    prepaid_data = utils.dict_to_xml(prepaid_object, prepaid_signature)

    return prepaid_data
def get_payment_wechat_app(debug, order_id, total_price, product_title,
                           nonce_str):

    wechat_app_id = 'viastelle'
    merchant_id = 'viastelle'
    ip_addr = '101.132.64.37'
    api_key = 'viastelle'

    total_fee = int(round((total_price * 100), 2))

    product_split = product_title.split(' ')
    if len(product_split) >= 4:
        product_body = product_split[0] + ' ' + product_split[
            1] + ' ' + product_split[2] + '...'
    else:
        product_body = product_title
    product_name = 'Viastelle - ' + product_body

    prepaid_object = {
        'appid': wechat_app_id,
        'body': product_name.replace('\'', '`'),
        'mch_id': merchant_id,
        'nonce_str': nonce_str,
        'notify_url':
        'https://api.viastelle.com/payments/wechat/notification/',
        'out_trade_no': order_id,
        'spbill_create_ip': ip_addr,
        'total_fee': total_fee,
        'trade_type': 'APP',
    }

    prepaid_signature = utils.calculate_signature(prepaid_object, api_key)
    prepaid_data = utils.dict_to_xml(prepaid_object, prepaid_signature)

    return prepaid_data
Exemple #4
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(("http://", "https://")):
            api_base_url = kwargs.pop("api_base_url", self.API_BASE_URL)
            url = "{base}{endpoint}".format(base=api_base_url, endpoint=url_or_endpoint)
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get("data", ""), dict):
            data = optionaldict(kwargs["data"])
            if "mchid" not in data:
                # F**k Tencent
                data.setdefault("mch_id", self.mch_id)
            data.setdefault("sub_mch_id", self.sub_mch_id)
            data.setdefault("nonce_str", random_string(32))
            sign = calculate_signature(data, self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode("utf-8")
            kwargs["data"] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs["cert"] = (self.mch_cert, self.mch_key)

        res = requests.request(method=method, url=url, **kwargs)
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(return_code=None, client=self, request=reqe.request, response=reqe.response)

        return self._handle_result(res)
Exemple #5
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
            url = '{base}{endpoint}'.format(base=api_base_url,
                                            endpoint=url_or_endpoint)
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get('data', ''), dict):
            data = optionaldict(kwargs['data'])
            if 'mchid' not in data:
                # F**k Tencent
                data.setdefault('mch_id', self.mch_id)
            data.setdefault('sub_mch_id', self.sub_mch_id)
            data.setdefault('nonce_str', random_string(32))
            sign = calculate_signature(data, self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode('utf-8')
            kwargs['data'] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs['cert'] = (self.mch_cert, self.mch_key)

        res = requests.request(method=method, url=url, **kwargs)
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(return_code=None,
                                     client=self,
                                     request=reqe.request,
                                     response=reqe.response)

        return self._handle_result(res)
Exemple #6
0
    def get_jsapi_params(self, prepay_id, timestamp=None, nonce_str=None, jssdk=False):
        """
        获取 JSAPI 参数

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :param jssdk: 前端调用方式,默认使用 WeixinJSBridge
                      使用 jssdk 调起支付的话,timestamp 的 s 为小写
                      使用 WeixinJSBridge 调起支付的话,timeStamp 的 S 为大写
        :return: 参数
        """
        data = {
            'appId': self.sub_appid or self.appid,
            'timeStamp': timestamp or to_text(int(time.time())),
            'nonceStr': nonce_str or random_string(32),
            'signType': 'MD5',
            'package': 'prepay_id={0}'.format(prepay_id),
        }
        sign = calculate_signature(
            data,
            self._client.api_key if not self._client.sandbox else self._client.sandbox_api_key
        )
        logger.debug('JSAPI payment parameters: data = %s, sign = %s', data, sign)
        data['paySign'] = sign
        if jssdk:
            data['timestamp'] = data.pop('timeStamp')
        return data
Exemple #7
0
    def parse_payment_result(self, xml):
        """解析微信支付结果通知"""
        try:
            data = xmltodict.parse(xml)
        except (xmltodict.ParsingInterrupted, ExpatError):
            raise InvalidSignatureException()

        if not data or "xml" not in data:
            raise InvalidSignatureException()

        data = data["xml"]
        sign = data.pop("sign", None)
        real_sign = calculate_signature(
            data, self.api_key if not self.sandbox else self.sandbox_api_key)
        if sign != real_sign:
            raise InvalidSignatureException()

        for key in (
                "total_fee",
                "settlement_total_fee",
                "cash_fee",
                "coupon_fee",
                "coupon_count",
        ):
            if key in data:
                data[key] = int(data[key])
        data["sign"] = sign
        return data
Exemple #8
0
    def get_jsapi_params(self, prepay_id, timestamp=None, nonce_str=None, jssdk=False):
        """
        获取 JSAPI 参数

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :param jssdk: 前端调用方式,默认使用 WeixinJSBridge
                      使用 jssdk 调起支付的话,timestamp 的 s 为小写
                      使用 WeixinJSBridge 调起支付的话,timeStamp 的 S 为大写
        :return: 参数
        """
        data = {
            "appId": self.sub_appid or self.appid,
            "timeStamp": timestamp or to_text(int(time.time())),
            "nonceStr": nonce_str or random_string(32),
            "signType": "MD5",
            "package": f"prepay_id={prepay_id}",
        }
        sign = calculate_signature(
            data, self._client.api_key if not self._client.sandbox else self._client.sandbox_api_key,
        )
        logger.debug("JSAPI payment parameters: data = %s, sign = %s", data, sign)
        data["paySign"] = sign
        if jssdk:
            data["timestamp"] = data.pop("timeStamp")
        return data
Exemple #9
0
 def _fetch_sandbox_api_key(self):
     nonce_str = random_string(32)
     sign = calculate_signature({"mch_id": self.mch_id, "nonce_str": nonce_str}, self.api_key)
     payload = dict_to_xml({"mch_id": self.mch_id, "nonce_str": nonce_str,}, sign=sign)
     headers = {"Content-Type": "text/xml"}
     api_url = f"{self.API_BASE_URL}sandboxnew/pay/getsignkey"
     response = self._http.post(api_url, data=payload, headers=headers)
     return xmltodict.parse(response.text)["xml"].get("sandbox_signkey")
Exemple #10
0
    def apply_signing(self, plan_id, contract_code, contract_display_account, notify_url,
                      version="1.0", clientip=None, deviceid=None, mobile=None, email=None, qq=None,
                      request_serial=None, openid=None, creid=None, outerid=None):
        """
        申请签约 api

        https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1

        :param plan_id: 模板id 协议模板id,设置路径见开发步骤。
        :param contract_code: 签约协议号 商户侧的签约协议号,由商户生成
        :param contract_display_account: 用户账户展示名称 签约用户的名称,用于页面展示,页面样例可见案例与规范
        :param notify_url: 回调通知url 用于接收签约成功消息的回调通知地址,以http或https开头。
        :param version: 版本号 固定值1.0
        :param request_serial: 可选 请求序列号 商户请求签约时的序列号,商户侧须唯一。序列号主要用于排序,不作为查询条件
        :param clientip: 可选 客户端 IP 点分IP格式(客户端IP)
        :param deviceid: 可选 设备ID android填imei的一次md5; ios填idfa的一次md5
        :param mobile: 可选 手机号 用户手机号
        :param email: 可选 邮箱地址 用户邮箱地址
        :param qq: 可选 QQ号 用户QQ号
        :param openid: 可选 微信open ID 用户微信open ID
        :param creid: 可选 身份证号 用户身份证号
        :param outerid: 可选 商户侧用户标识 用户在商户侧的标识
        :return: 返回的结果数据字典
        """
        timestamp = int(time.time())
        if request_serial is None:
            request_serial = int(time.time() * 1000)
        data = {
            "appid": self.appid,
            "mch_id": self.mch_id,
            "sub_mch_id": self.sub_mch_id,
            "plan_id": plan_id,
            "contract_code": contract_code,
            "request_serial": request_serial,
            "contract_display_account": contract_display_account,
            "notify_url": notify_url,
            "version": version,
            "timestamp": timestamp,
            "clientip": clientip,
            "deviceid": deviceid,
            "mobile": mobile,
            "email": email,
            "qq": qq,
            "openid": openid,
            "creid": creid,
            "outerid": outerid,
        }
        data = optionaldict(data)
        sign = calculate_signature(data, self._client.api_key)
        data["sign"] = sign
        return {
            "base_url": "{}papay/entrustweb".format(self._client.API_BASE_URL),
            "data": data
        }
Exemple #11
0
    def apply_signing(self, plan_id, contract_code, contract_display_account, notify_url,
                      version="1.0", clientip=None, deviceid=None, mobile=None, email=None, qq=None,
                      request_serial=None, openid=None, creid=None, outerid=None):
        """
        申请签约 api

        https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1

        :param plan_id: 模板id 协议模板id,设置路径见开发步骤。
        :param contract_code: 签约协议号 商户侧的签约协议号,由商户生成
        :param contract_display_account: 用户账户展示名称 签约用户的名称,用于页面展示,页面样例可见案例与规范
        :param notify_url: 回调通知url 用于接收签约成功消息的回调通知地址,以http或https开头。
        :param version: 版本号 固定值1.0
        :param request_serial: 可选 请求序列号 商户请求签约时的序列号,商户侧须唯一。序列号主要用于排序,不作为查询条件
        :param clientip: 可选 客户端 IP 点分IP格式(客户端IP)
        :param deviceid: 可选 设备ID android填imei的一次md5; ios填idfa的一次md5
        :param mobile: 可选 手机号 用户手机号
        :param email: 可选 邮箱地址 用户邮箱地址
        :param qq: 可选 QQ号 用户QQ号
        :param openid: 可选 微信open ID 用户微信open ID
        :param creid: 可选 身份证号 用户身份证号
        :param outerid: 可选 商户侧用户标识 用户在商户侧的标识
        :return: 返回的结果数据字典
        """
        timestamp = int(time.time())
        if request_serial is None:
            request_serial = int(time.time() * 1000)
        data = {
            "appid": self.appid,
            "mch_id": self.mch_id,
            "sub_mch_id": self.sub_mch_id,
            "plan_id": plan_id,
            "contract_code": contract_code,
            "request_serial": request_serial,
            "contract_display_account": contract_display_account,
            "notify_url": notify_url,
            "version": version,
            "timestamp": timestamp,
            "clientip": clientip,
            "deviceid": deviceid,
            "mobile": mobile,
            "email": email,
            "qq": qq,
            "openid": openid,
            "creid": creid,
            "outerid": outerid,
        }
        data = optionaldict(data)
        sign = calculate_signature(data, self._client.api_key)
        data["sign"] = sign
        return {
            "base_url": "{}papay/entrustweb".format(self._client.API_BASE_URL),
            "data": data
        }
Exemple #12
0
 def _fetch_sanbox_api_key(self):
     nonce_str = random_string(32)
     sign = calculate_signature({'mch_id': self.mch_id, 'nonce_str': nonce_str}, self.api_key)
     payload = dict_to_xml({
         'mch_id': self.mch_id,
         'nonce_str': nonce_str,
     }, sign=sign)
     headers = {'Content-Type': 'text/xml'}
     api_url = '{base}sandboxnew/pay/getsignkey'.format(base=self.API_BASE_URL)
     response = self._http.post(api_url, data=payload, headers=headers)
     return xmltodict.parse(response.text)['xml'].get('sandbox_signkey')
Exemple #13
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
            if self.sandbox:
                api_base_url = '{url}sandboxnew/'.format(url=api_base_url)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get('data', ''), dict):
            data = kwargs['data']
            if 'mchid' not in data:
                # F**k Tencent
                data.setdefault('mch_id', self.mch_id)
            data.setdefault('sub_mch_id', self.sub_mch_id)
            data.setdefault('nonce_str', random_string(32))
            data = optionaldict(data)

            if data.get('sign_type', 'MD5') == 'HMAC-SHA256':
                sign = calculate_signature_hmac(data, self.sandbox_api_key if self.sandbox else self.api_key)
            else:
                sign = calculate_signature(data, self.sandbox_api_key if self.sandbox else self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode('utf-8')
            kwargs['data'] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs['cert'] = (self.mch_cert, self.mch_key)

        kwargs['timeout'] = kwargs.get('timeout', self.timeout)
        logger.debug('Request to WeChat API: %s %s\n%s', method, url, kwargs)
        res = self._http.request(
            method=method,
            url=url,
            **kwargs
        )
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(
                return_code=None,
                client=self,
                request=reqe.request,
                response=reqe.response
            )

        return self._handle_result(res)
Exemple #14
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
            if self.sandbox:
                api_base_url = '{url}sandboxnew/'.format(url=api_base_url)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get('data', ''), dict):
            data = kwargs['data']
            if 'mchid' not in data:
                # F**k Tencent
                data.setdefault('mch_id', self.mch_id)
            data.setdefault('sub_mch_id', self.sub_mch_id)
            data.setdefault('nonce_str', random_string(32))
            data = optionaldict(data)

            if data.get('sign_type', 'MD5') == 'HMAC-SHA256':
                sign = calculate_signature_hmac(data, self.sandbox_api_key if self.sandbox else self.api_key)
            else:
                sign = calculate_signature(data, self.sandbox_api_key if self.sandbox else self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode('utf-8')
            kwargs['data'] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs['cert'] = (self.mch_cert, self.mch_key)

        kwargs['timeout'] = kwargs.get('timeout', self.timeout)
        logger.debug('Request to WeChat API: %s %s\n%s', method, url, kwargs)
        res = self._http.request(
            method=method,
            url=url,
            **kwargs
        )
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(
                return_code=None,
                client=self,
                request=reqe.request,
                response=reqe.response
            )

        return self._handle_result(res)
Exemple #15
0
    def _request(self, method, url_or_endpoint, **kwargs):
        http_client = AsyncHTTPClient()
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint

        headers = {}
        params = kwargs.pop('params', {})

        params = urlencode(dict((k, to_binary(v)) for k, v in params.items()))
        url = '{0}?{1}'.format(url, params)
        
        data = kwargs.get('data')
        if isinstance(data, dict):
            data = optionaldict(data)
            if 'mchid' not in data:
                # F**k Tencent
                data.setdefault('mch_id', self.mch_id)
            data.setdefault('sub_mch_id', self.sub_mch_id)
            data.setdefault('nonce_str', random_string(32))
            sign = calculate_signature(data, self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode('utf-8')
        else:
            body = data

        req = HTTPRequest(
            url=url,
            method=method.upper(),
            headers=headers,
            body=body
        )
        res = yield http_client.fetch(req)
        if res.error is not None:
            raise WeChatClientException(
                errcode=None,
                errmsg=None,
                client=self,
                request=req,
                response=res
            )

        result = self._handle_result(res)
        raise Return(result)
Exemple #16
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(("http://", "https://")):
            api_base_url = kwargs.pop("api_base_url", self.API_BASE_URL)
            if self.sandbox:
                api_base_url = "{url}sandboxnew/".format(url=api_base_url)
            url = "{base}{endpoint}".format(base=api_base_url,
                                            endpoint=url_or_endpoint)
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get("data", ""), dict):
            data = kwargs["data"]
            if "mchid" not in data:
                # F**k Tencent
                data.setdefault("mch_id", self.mch_id)
            data.setdefault("sub_mch_id", self.sub_mch_id)
            data.setdefault("nonce_str", random_string(32))
            data = optionaldict(data)

            if data.get("sign_type", "MD5") == "HMAC-SHA256":
                sign = calculate_signature_hmac(
                    data,
                    self.sandbox_api_key if self.sandbox else self.api_key)
            else:
                sign = calculate_signature(
                    data,
                    self.sandbox_api_key if self.sandbox else self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode("utf-8")
            kwargs["data"] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs["cert"] = (self.mch_cert, self.mch_key)

        kwargs["timeout"] = kwargs.get("timeout", self.timeout)
        logger.debug("Request to WeChat API: %s %s\n%s", method, url, kwargs)
        res = self._http.request(method=method, url=url, **kwargs)
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(
                return_code=None,
                client=self,
                request=reqe.request,
                response=reqe.response,
            )

        return self._handle_result(res)
Exemple #17
0
    def get_jsapi_signature(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 JSAPI 签名

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            'appId': self.appid,
            'timeStamp': timestamp or to_text(int(time.time())),
            'nonceStr': nonce_str or random_string(32),
            'signType': 'MD5',
            'package': 'prepay_id={0}'.format(prepay_id),
        }
        return calculate_signature(data, self._client.api_key)
Exemple #18
0
    def get_jsapi_signature(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 JSAPI 签名

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            'appId': self.appid,
            'timeStamp': timestamp or to_text(int(time.time())),
            'nonceStr': nonce_str or random_string(32),
            'signType': 'MD5',
            'package': 'prepay_id={0}'.format(prepay_id),
        }
        return calculate_signature(data, self._client.api_key)
Exemple #19
0
    def parse_payment_result(self, xml):
        """解析微信支付结果通知"""
        try:
            data = xmltodict.parse(xml)
        except (xmltodict.ParsingInterrupted, ExpatError):
            raise InvalidSignatureException()

        if not data or 'xml' not in data:
            raise InvalidSignatureException()

        data = data['xml']
        sign = data.pop('sign', None)
        real_sign = calculate_signature(data, self.api_key)
        if sign != real_sign:
            raise InvalidSignatureException()

        data['sign'] = sign
        return data
Exemple #20
0
    def parse_payment_result(self, xml):
        """解析微信支付结果通知"""
        try:
            data = xmltodict.parse(xml)
        except (xmltodict.ParsingInterrupted, ExpatError):
            raise InvalidSignatureException()

        if not data or 'xml' not in data:
            raise InvalidSignatureException()

        data = data['xml']
        sign = data.pop('sign', None)
        real_sign = calculate_signature(data, self.api_key)
        if sign != real_sign:
            raise InvalidSignatureException()

        data['sign'] = sign
        return data
def get_payment_order_app(debug, wechat_app_id, merchant_id, prepaid_id,
                          nonce_str, api_key):
    print(debug)

    timestamp = str(dateformatter.get_timestamp())
    payment_order = {
        'appid': wechat_app_id,
        'partnerid': merchant_id,
        'prepayid': prepaid_id,
        'package': 'Sign=WXPay',
        'noncestr': nonce_str,
        'timestamp': timestamp,
    }

    payment_order_sign = utils.calculate_signature(payment_order, api_key)
    payment_order['sign'] = payment_order_sign

    return payment_order
Exemple #22
0
    def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 APP 支付参数

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            "appId": self.appid,
            "package": "prepay_id={}".format(prepay_id),
            "timeStamp": timestamp or to_text(int(time.time())),
            "nonceStr": nonce_str or random_string(32),
            "signType": "MD5",
        }
        sign = calculate_signature(data, self._client.api_key)
        data["paySign"] = sign
        return data
Exemple #23
0
    def get_jsapi_signature(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 JSAPI 签名

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            "appId": self.sub_appid or self.appid,
            "timeStamp": timestamp or to_text(int(time.time())),
            "nonceStr": nonce_str or random_string(32),
            "signType": "MD5",
            "package": f"prepay_id={prepay_id}",
        }
        return calculate_signature(
            data, self._client.api_key if not self._client.sandbox else self._client.sandbox_api_key,
        )
Exemple #24
0
    def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 APP 支付参数

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            'appId': self.appid,
            'timeStamp': timestamp or to_text(int(time.time())),
            'nonceStr': nonce_str or random_string(32),
            'package': 'prepay_id=%s' % prepay_id,
            'signType': 'MD5',
         }
        sign = calculate_signature(data, self._client.api_key)
        data['paySign'] = sign
        return data
Exemple #25
0
    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint

        if isinstance(kwargs.get('data', ''), dict):
            data = optionaldict(kwargs['data'])
            if 'mchid' not in data:
                # F**k Tencent
                data.setdefault('mch_id', self.mch_id)
            data.setdefault('sub_mch_id', self.sub_mch_id)
            data.setdefault('nonce_str', random_string(32))
            sign = calculate_signature(data, self.api_key)
            body = dict_to_xml(data, sign)
            body = body.encode('utf-8')
            kwargs['data'] = body

        # 商户证书
        if self.mch_cert and self.mch_key:
            kwargs['cert'] = (self.mch_cert, self.mch_key)

        res = requests.request(
            method=method,
            url=url,
            **kwargs
        )
        try:
            res.raise_for_status()
        except requests.RequestException as reqe:
            raise WeChatPayException(
                return_code=None,
                client=self,
                request=reqe.request,
                response=reqe.response
            )

        return self._handle_result(res)
Exemple #26
0
    def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
        """
        获取 APP 支付参数

        :param prepay_id: 统一下单接口返回的 prepay_id 参数值
        :param timestamp: 可选,时间戳,默认为当前时间戳
        :param nonce_str: 可选,随机字符串,默认自动生成
        :return: 签名
        """
        data = {
            'appid': self.appid,
            'partnerid': self.mch_id,
            'prepayid': prepay_id,
            'package': 'Sign=WXPay',
            'timestamp': timestamp or to_text(int(time.time())),
            'noncestr': nonce_str or random_string(32)
        }
        sign = calculate_signature(data, self._client.api_key)
        data['sign'] = sign
        return data
Exemple #27
0
    def parse_payment_result(self, xml):
        """解析微信支付结果通知"""
        try:
            data = xmltodict.parse(xml)
        except (xmltodict.ParsingInterrupted, ExpatError):
            raise InvalidSignatureException()

        if not data or 'xml' not in data:
            raise InvalidSignatureException()

        data = data['xml']
        sign = data.pop('sign', None)
        real_sign = calculate_signature(data, self.api_key)
        if sign != real_sign:
            raise InvalidSignatureException()

        for key in ('total_fee', 'settlement_total_fee', 'cash_fee', 'coupon_fee', 'coupon_count'):
            if key in data:
                data[key] = int(data[key])
        data['sign'] = sign
        return data
    def post(self, request):
        result = ResultResponse(code.ARIES_200_SUCCESS, 'success')
        request_data = request.data
        logger_info.info(request_data)

        # Payment registration and validation check
        try:
            payment_type = request_data['payment_type']
            order_id = request_data['order_id']
        except Exception as e:
            logger_info.info(str(e))
            result = ResultResponse(code.ARIES_400_BAD_REQUEST,
                                    'Request data invalid')
            return Response(result.get_response(), result.get_code())

        # Check if the payment exists
        payment_count = Payment.objects.filter(order_id=order_id).count()

        if payment_count != 0:
            payment = Payment.objects.get(order_id=order_id)

            if payment.payment_status == 0 or payment.payment_status == 1:
                result = ResultResponse(code.ARIES_200_SUCCESS, 'success')
                return Response(result.get_response(), result.get_code())

        # Get raw data for validation
        raw_data = {}

        # Wechat app payment
        request_data['payment_raw_data'] = json.dumps(raw_data)

        try:
            wechat_serializer = WechatPaymentSerializer(data=request_data)

            if wechat_serializer.is_valid():
                wechat_serializer.save()
            else:
                logger_info.info(wechat_serializer.errors)
        except Exception as e:
            print(e)
            logger_info.info(str(e))

        if payment_type == 1:
            wechat_app_id = 'viastelle'
            merchant_id = 'viastelle'
            api_key = 'viastelle'
            nonce_str = payment_util.wechat_payment_str(order_id)
        else:
            wechat_app_id = 'viastelle'
            merchant_id = 'viastelle'
            api_key = 'viastelle'
            nonce_str = payment_util.wechat_payment_str(order_id)

        wechat_client = WeChatPay(wechat_app_id,
                                  api_key,
                                  merchant_id,
                                  sub_mch_id=None,
                                  mch_cert=None,
                                  mch_key=None)

        try:
            query_data = {
                'appid': wechat_app_id,
                'mch_id': merchant_id,
                'out_trade_no': order_id,
                'nonce_str': nonce_str
            }

            prepaid_signature = utils.calculate_signature(query_data, api_key)
            query_data_signed = utils.dict_to_xml(query_data,
                                                  prepaid_signature)

            url = get_wechat_query_url()
            headers = {'Content-Type': 'application/xml'}
            response = requests.post(url,
                                     headers=headers,
                                     data=query_data_signed)
            logger_info.info(response.text)

            response_data = response.content
            query_result = xmltodict.parse(response_data)['xml']
            query_result['order_id'] = order_id
            request_data['transaction_id'] = query_result['transaction_id']

            query_serializer = WechatQuerySerializer(data=query_result)

            if query_serializer.is_valid():
                query_serializer.save()
                query_data = query_serializer.data
            else:
                logger_info.info(query_serializer.errors)
                # Error case - refund request

        except Exception as e:
            logger_info.info(str(e))
            result = ResultResponse(
                code.ARIES_500_INTERNAL_SERVER_ERROR,
                get_msg(code.ERROR_4005_PAYMENT_SYNC_ERROR))
            result.set_error(code.ERROR_4005_PAYMENT_SYNC_ERROR)
            return Response(result.get_response(), result.get_code())

        # Set payment status
        request_data['payment_status'] = self.PAYMENT_CREATED
        payment_serializer = PaymentSerializer(data=request_data)

        # Payment object save
        if payment_serializer.is_valid():
            payment_serializer.save()
            payment = Payment.objects.get(order_id=order_id)
        else:
            logger_info.info(payment_serializer.errors)
            result = ResultResponse(code.ARIES_400_BAD_REQUEST,
                                    'Request data invalid')
            return Response(result.get_response(), result.get_code())

        # Verification payment
        if payment_type == self.WECHAT_APP_PAYMENT or payment_type == self.WECHAT_MOBILE_PAYMENT:
            if query_data['return_code'] == 'SUCCESS' and query_data[
                    'result_code'] == 'SUCCESS':
                # Payment success and check price
                # if query_data['total_fee'] == int(price_total):

                del query_result['order_id']

                if not wechat_client.check_signature(query_result):
                    payment.payment_status = 4
                else:
                    payment.payment_status = 1

                payment.save()
            else:
                payment.payment_status = 4
                payment.save()

                logger_error.error(code.ERROR_4001_PAYMENT_VALIDATION_FAILED)
                result = ResultResponse(
                    code.ARIES_500_INTERNAL_SERVER_ERROR,
                    get_msg(code.ERROR_4001_PAYMENT_VALIDATION_FAILED))
                result.set_error(code.ERROR_4001_PAYMENT_VALIDATION_FAILED)
                return Response(result.get_response(), result.get_code())
        else:
            result = ResultResponse(code.ARIES_400_BAD_REQUEST,
                                    'Request data invalid')
            return Response(result.get_response(), result.get_code())

        return Response(result.get_response(), result.get_code())
def get_payment_wechat_signing(params):
    api_key = 'viastelle'
    return utils.calculate_signature(params, api_key)
def get_payment_wechat_mweb(debug, order_id, total_price, product_title,
                            nonce_str, scene_info, ip_addr):
    wechat_app_id = 'viastelle'
    wechat_public_app_id = 'viastelle'
    merchant_id = 'viastelle'
    merchant_id_public_account = 'viastelle'
    # ip_addr = '139.196.142.226'
    api_key = 'viastelle'
    api_key_public_account = 'viastelle'

    if debug:
        total_fee = int((total_price * 100))

        product_split = product_title.split(' ')
        if len(product_split) >= 4:
            product_body = product_split[0] + ' ' + product_split[
                1] + ' ' + product_split[2] + '...'
        else:
            product_body = product_title

        sandbox_request = {
            'mch_id': merchant_id,
            'nonce_str': nonce_str,
        }

        sandbox_request_sign = utils.calculate_signature(
            sandbox_request, api_key)
        sandbox_request['sign'] = sandbox_request_sign
        sandbox_xml = utils.dict_to_xml(sandbox_request, sandbox_request_sign)

        headers = {'Content-Type': 'application/xml'}
        response = requests.post(url=resources.WECHAT_SANDBOX_SIGN_KEY,
                                 data=sandbox_xml,
                                 headers=headers)
        response_data = response.text

        prepaid_result = xmltodict.parse(response_data)['xml']
        sandbox_api_key = prepaid_result['sandbox_signkey']
        product_name = 'Viastelle - ' + product_body

        scene_info = {'h5_info': scene_info}

        prepaid_object = {
            'appid': wechat_app_id,
            'body': product_name,
            'mch_id': merchant_id,
            'nonce_str': nonce_str,
            'notify_url':
            'http://139.196.123.42:8080/payments/wechat/notification/',
            'out_trade_no': order_id,
            'spbill_create_ip': ip_addr,
            'total_fee': total_fee,
            'trade_type': 'MWEB',
            'scene_info': json.dumps(scene_info)
        }

        prepaid_signature = utils.calculate_signature(prepaid_object,
                                                      sandbox_api_key)
        prepaid_data = utils.dict_to_xml(prepaid_object, prepaid_signature)

        return {'prepaid_data': prepaid_data, 'sandbox_key': sandbox_api_key}
    else:
        total_fee = int((total_price * 100))

        product_split = product_title.split(' ')
        if len(product_split) >= 4:
            product_body = product_split[0] + ' ' + product_split[
                1] + ' ' + product_split[2] + '...'
        else:
            product_body = product_title

        prepaid_object = {
            'appid': wechat_public_app_id,
            'body': product_body,
            'mch_id': merchant_id_public_account,
            'nonce_str': nonce_str,
            'notify_url':
            'https://api.viastelle.com/payments/wechat/notification/',
            'out_trade_no': order_id,
            'spbill_create_ip': ip_addr,
            'total_fee': total_fee,
            'trade_type': 'JSAPI',
        }

        print(prepaid_object)

        prepaid_signature = utils.calculate_signature(prepaid_object,
                                                      api_key_public_account)
        prepaid_data = utils.dict_to_xml(prepaid_object, prepaid_signature)

        return prepaid_data