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 _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)
def wechat_notify(request): wechat_pay_pay = WeChatHelper().wechatpay() data = wechat_pay_pay.parse_payment_result(request.body) print data return Response( dict_to_xml(dict(return_msg=u"OK", return_code="SUCCESS"), sign=data.get("sign")))
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)
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
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 _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")
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')
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)
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)
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)
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)
def get_payment_wechat_public_dict_to_xml(params): signature = get_payment_wechat_public_signing(params) return utils.dict_to_xml(params, signature)
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
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 payNotify(request): try: result_data = wxPay.parse_payment_result(request.body) #签名验证 #保存支付成功返回数据 res_data = dict(result_data) WxPayResult.objects.create(**res_data) #查询订单,判断是否正确 transaction_id = res_data.get('transaction_id', None) out_trade_no = res_data.get('out_trade_no', None) openid = res_data.get('openid', None) retBool = queryOrder(transaction_id, out_trade_no) #查询订单 data = { 'return_code': result_data.get('return_code'), 'return_msg': result_data.get('return_msg') } xml = dict_to_xml(data, '') if not retBool: #订单不存在 return HttpResponse(xml) else: #验证金额是否一致 if 'return_code' in res_data and 'result_code' in res_data and res_data[ 'return_code'] == 'SUCCESS' and res_data[ 'result_code'] == 'SUCCESS': if out_trade_no.startswith('M'): # 会员充值 time_end = res_data['time_end'] pay_time = datetime.strptime(time_end, "%Y%m%d%H%M%S") try: user = WxUserinfo.objects.get(openid=openid) nickname = user.nickname except WxUserinfo.DoesNotExist: nickname = '' cash_fee = res_data['cash_fee'] / 100 data = { "openid": openid, "nickname": nickname, "total_fee": res_data['total_fee'] / 100, "transaction_id": res_data['transaction_id'], "cash_fee": cash_fee, "status": 1, "pay_time": pay_time } obj, created = MemberRechargeRecord.objects.update_or_create( defaults=data, out_trade_no=out_trade_no) try: deposit = MemberDeposit.objects.get(openid=openid) if deposit.add_time != pay_time: from decimal import Decimal deposit.total_money = deposit.total_money + Decimal( cash_fee) deposit.prev_money = cash_fee deposit.add_time = pay_time deposit.save() except MemberDeposit.DoesNotExist: values = { "openid": openid, "nickname": nickname, "total_money": cash_fee, "prev_money": cash_fee, "add_time": pay_time } deposit = MemberDeposit.objects.create(**values) #更新储值卡 #判断是否是会员,不是会员更新为会员 # 产生随机密码:保存到数据库 if user and user.is_member == 0 and cash_fee >= 500: user.is_member = 1 user.save() # 发送密码给用户 resetPassword(deposit) sendChargeSuccessToUser(obj) # 发送通知 else: order = getShoppingOrder(openid, res_data['out_trade_no']) if order and order.status == 0: #更新订单 status = 1 #已支付标志 cash_fee = res_data['cash_fee'] / 100 time_end = res_data['time_end'] pay_time = datetime.strptime(time_end, "%Y%m%d%H%M%S") order.update_status_transaction_id( status, transaction_id, cash_fee, pay_time) #更新会员积分 setMemberScores(order) #发送模板消息 if openid: sendTempMessageToUser(order) return HttpResponse(xml) except InvalidSignatureException as error: pass