def get_query_form(order_id): payment = get_payment_info(order_id) if not payment: return None, None txnTime = payment.payment_time or datetime.fromtimestamp(payment.created_time).strftime('%Y%m%d%H%M%S') req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "00" req["txnSubType"] = "00" req["bizType"] = "000000" req["accessType"] = "0" req["channelType"] = "07" req["merId"] = get_payment_merchant_id() req["orderId"] = order_id req["txnTime"] = txnTime # 签名示例 req_params = AcpService.sign(req) req_url = SDKConfig().singleQueryUrl return req_params, req_url
def get_refund_form(unionpay, refund_id, refund_amount): time_now = datetime.now().strftime('%Y%m%d%H%M%S') req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "04" req["txnSubType"] = "00" req["bizType"] = "000201" req["accessType"] = "0" req["channelType"] = "07" req["backUrl"] = SDKConfig().backUrl req["merId"] = get_payment_merchant_id() req["orderId"] = refund_id req['origQryId'] = unionpay.unionpay_id req["txnTime"] = time_now req["txnAmt"] = str(refund_amount) # 签名示例 req_params = AcpService.sign(req) req_url = SDKConfig().backTransUrl return req_params, req_url
def trade(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = "01" req["txnType"] = "78" req["txnSubType"] = "00" req["bizType"] = "000301" req["channelType"] = "07" req["merId"] = "777290058110097" req["orderId"] = datetime.now().strftime('%Y%m%d%H%M%S') req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["accessType"] = "0" req["accNo"] = AcpService.encryptData("6226090000000048") req["encryptCertId"] = AcpService.getEncryptCertId() # 签名示例 req = AcpService.sign(req) url = SDKConfig().backTransUrl # post示例 resp = AcpService.post(req, url) result = "请求报文:" + map2str(req) + "<br>\n" result = result + "应答报文:" + map2str(resp) + "<br>\n" # 验签示例 result = result + "验签成功<br>\n" if AcpService.validate( resp) else "验签失败<br>\n" if "respCode" in resp: # 取应答报文里的参数的示例 result = result + "respCode=" + resp["respCode"] + "<br>\n" result = result + "respMsg=" + resp["respMsg"] + "<br>\n" # 解密示例 if "customerInfo" in resp: customerInfo = AcpService.parseCustomerInfo( resp["customerInfo"], SDKConfig().signCertPath, SDKConfig().signCertPwd) if "phoneNo" in customerInfo: result = result + "phoneNo=" + customerInfo[ "phoneNo"] + "<br>\n" return result
def demoTrade(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "95" req["txnSubType"] = "00" req["bizType"] = "000000" req["channelType"] = "07" req["accessType"] = "0" req["certType"] = "01" req["merId"] = "777290058110097" req["orderId"] = datetime.now().strftime('%Y%m%d%H%M%S') req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') # 签名示例 req = AcpService.sign(req) url = SDKConfig().backTransUrl # post示例 resp = AcpService.post(req, url) result = "请求报文:" + map2str(req) + "<br>\n" result = result + "应答报文:" + map2str(resp) + "<br>\n" # 验签示例 result = result + "验签成功<br>\n" if AcpService.validate( resp) else "验签失败<br>\n" if "respCode" in resp: # 取应答报文里的参数的示例 result = result + "respCode=" + resp["respCode"] + "<br>\n" result = result + "respMsg=" + resp["respMsg"] + "<br>\n" if resp["respCode"] == "00": resultCode = AcpService.updateEncryptCert(resp) if resultCode == 1: result += "加密公钥更新成功" + "<br>\n" elif resultCode == 0: result += "加密公钥无更新" + "<br>\n" else: result += "加密公钥更新失败" + "<br>\n" return result
def test_enCodeFileContent(self): file_content = "test_data".encode('utf-8') file_content = zlib.compress(file_content) file_content = base64.b64encode(file_content) file_content = file_content.decode('utf-8') data_dict = { "merId": "888888888888888", "batchNo": "123456", "txnTime": 1234323223, "fileName": "test.txt", "fileContent": file_content, } SDKUtil.deCodeFileContent(data_dict, SDKConfig().fileDir) encode_str = SDKUtil.enCodeFileContent(SDKConfig().fileDir + "test.txt") self.assertEqual(encode_str, "eJwrSS0uiU9JLEkEABL5A7o=")
def verifyAndGetVerifyCert(certBase64String): if certBase64String in CertUtil.__verifyCerts5_1_0: return CertUtil.__verifyCerts5_1_0[certBase64String] if SDKConfig().middleCertPath is None or SDKConfig( ).rootCertPath is None: logging.error( "rootCertPath or middleCertPath is none, exit initRootCert") return None if CertUtil.__x509Store is None: CertUtil.initRootCert(SDKConfig().middleCertPath, SDKConfig().rootCertPath) x509Cert = crypto.load_certificate(crypto.FILETYPE_PEM, certBase64String) if x509Cert.has_expired(): logging.error("signPubKeyCert has expired") return None cn = CertUtil.getIdentitiesFromCertficate(x509Cert) if cn is None: logging.error('get identities error') return None UNIONPAY_CNNAME = "中国银联股份有限公司" if SDKConfig().ifValidateCNName.lower() != "false": if UNIONPAY_CNNAME != cn: logging.error("cer owner is not CUP:" + cn) return None elif UNIONPAY_CNNAME != cn and cn != "00040000:SIGN": # 测试环境目前是00040000:SIGN logging.error("cer owner is not CUP:" + cn) return None try: x509StoreContext = crypto.X509StoreContext(CertUtil.__x509Store, x509Cert) x509StoreContext.verify_certificate() CertUtil.__verifyCerts5_1_0[certBase64String] = x509Cert return x509Cert except Exception: logging.info("validate signPubKeyCert by rootCert failed") return None
def trade(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "21" req["txnSubType"] = "03" req["bizType"] = "000401" req["accessType"] = "0" req["channelType"] = "07" req["merId"] = "777290058110097" req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["batchNo"] = "0001" req["totalQty"] = "10" req["totalAmt"] = "1000" req["fileContent"] = AcpService.enCodeFileContent("./files/bat.txt") # 签名示例 req = AcpService.sign(req) url = SDKConfig().batchTransUrl # post示例 resp = AcpService.post(req, url) result = "请求报文:" + map2str(req) + "<br>\n" result = result + "应答报文:" + map2str(resp) + "<br>\n" # 验签示例 result += ("验签成功<br>\n" if AcpService.validate(resp) else "验签失败<br>\n") if "respCode" in resp: # 取应答报文里的参数的示例 result = result + "respCode=" + resp["respCode"] + "<br>\n" result = result + "respMsg=" + resp["respMsg"] + "<br>\n" if resp["respCode"] == "00": result += "成功<br>\n" else: result += "失败<br>\n" return result
def trade(): time_now = datetime.now().strftime('%Y%m%d%H%M%S') req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "04" req["txnSubType"] = "00" req["bizType"] = "000201" req["accessType"] = "0" req["channelType"] = "07" req["backUrl"] = SDKConfig().backUrl req["orderId"] = time_now req["merId"] = "777290058110048" req["origQryId"] = "871803200930040336758" req["txnTime"] = time_now req["txnAmt"] = "100" # 签名示例 req = AcpService.sign(req) url = SDKConfig().backTransUrl # 后台自提交表单示例 resp = AcpService.post(req, url) if not AcpService.validate(resp): logging.error("回复报文验证失败") return jsonify({'status': 'error', 'error': 'not validate'}) respCode = resp['respCode'] if respCode == "00": logging.info("退款受理成功!") return jsonify({'status': 'ok', 'data': resp}) if respCode == "03" or respCode == "04" or respCode == "05": logging.warning("退款受理超时") return jsonify({'status': 'error', 'error': '退款受理超时'}) else: logging.error("退款受理失败") return jsonify({'status': 'error', 'error': '退款受理失败', 'detail': resp})
def trade(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "76" req["txnSubType"] = "01" req["bizType"] = "000000" req["accessType"] = "0" req["fileType"] = "00" req["merId"] = "700000000000001" req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["settleDate"] = "0119" # 签名示例 req = AcpService.sign(req) url = SDKConfig().fileTransUrl # post示例 resp = AcpService.post(req, url) result = "请求报文:" + map2str(req) + "<br>\n" result = result + "应答报文:" + map2str(resp) + "<br>\n" # 验签示例 result = result + ("验签成功<br>\n" if AcpService.validate(resp) else "验签失败<br>\n") if "respCode" in resp: # 取应答报文里的参数的示例 result = result + "respCode=" + resp["respCode"] + "<br>\n" result = result + "respMsg=" + resp["respMsg"] + "<br>\n" if resp["respCode"] == "00": dir = "./files/" # 先建立好文件夹哦 result += "文件保存到:" + dir + ("成功<br>\n" if AcpService.deCodeFileContent( resp, dir) else "失败<br>\n") result += analyzeFile(dir, resp["fileName"]) return result
def getVerifyCertFromPath(certId, certDir=SDKConfig().validateCertDir): if len(CertUtil.__verifyCerts) == 0: CertUtil.initVerifyCerts(certDir) if len(CertUtil.__verifyCerts) == 0: logging.info("未读取到任何证书") return None if certId in CertUtil.__verifyCerts: return CertUtil.__verifyCerts[certId].cert else: logging.info("未匹配到序列号为 " + certId + " 的证书") return None
def trade(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["txnType"] = "22" req["txnSubType"] = "03" req["bizType"] = "000401" req["accessType"] = "0" req["channelType"] = "07" req["merId"] = "777290058110097" req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["batchNo"] = "0001" # 签名示例 req = AcpService.sign(req) url = SDKConfig().batchTransUrl # post示例 resp = AcpService.post(req, url) result = "请求报文:" + map2str(req) + "<br>\n" result += "应答报文:" + map2str(resp) + "<br>\n" # 验签示例 result += ("验签成功<br>\n" if AcpService.validate(resp) else "验签失败<br>\n") if "respCode" in resp: # 取应答报文里的参数的示例 result += "respCode=" + resp["respCode"] + "<br>\n" result += "respMsg=" + resp["respMsg"] + "<br>\n" if resp["respCode"] == "00": path = "./files/" # 先建立好文件夹哦 result += "文件保存到:" \ + path + ("成功<br>\n" if AcpService.deCodeFileContent(resp, path) else "失败<br>\n") return result
def test_BuildSignature(self): req_dict = { "transType": "01", "sysReserved": "{aaa=a&bbb=b}", "merId": "888888888888888" } req_dict['signMethod'] = '01' req_dict['version'] = '5.0.0' sign_res = SDKUtil.buildSignature(req_dict, SDKConfig().signCertPath, SDKConfig().signCertPwd) check_sign = ( 'ClTZLArDgM7rE9KORsgEiCmaPo/8G4xg4SrTJAET9xcymexSSlYDjQMIfhvZ0qgtYzlI' '+fV/5/ZKbnpJD0R2qOsvhT9e+Xb2wZzJFeYJVDNBqlZZLXUcB2kU0ut2fKdHCAcWApoGA1Ks0d5s' '/CA4sp8ZdaejatHVuKnTHa8rgLallX9Gekxul538WtZoU4n4RNBEe2ythZnj5eUa' 'VFYdzzSQ6pAnlYfKzhby3p5/YFdZZHcYDbdrkQjS+ewgf6wQfFGu5X07BznqYjf6I6x25jPgidg6' 'OHE0m25uv2ksyZuEKwSM/WWUYOc0q/TF7XMhN1lpm3VZN8ePvIK5NPHPaA==') self.assertEqual(sign_res['signature'], check_sign) req_dict['signMethod'] = '01' req_dict['version'] = '5.1.0' sign_res = SDKUtil.buildSignature(req_dict, SDKConfig().signCertPath, SDKConfig().signCertPwd) check_sign = ( 'nCDm51Cju6CG0kvYNKJI0hlMMlPqKn2IftnBFWkeNftrNKxczLB2kAyASv6' 'Tr3PeOauGvgzv9KEpBBkZY1f7nhOuv/WfZVEHt4oWmxcd24TrEZ5dDtQb4t' 'amzUszl0p+TXDW4tqxzbwjjQ++acYtthLadhG44Cce0Lnno7LWIKDh1Fe6w' 'sMMAEXsJwZX7nIcskeymOTF98FopOt/RFsIHSJ4Z0UuqZ6gEOjPzSbqTgm2' 'SeAMFMmxMToUmY+doQHla5GNkI4VJox10LIZBlA8SRTwL6qt3kdHhFyP7mR' 'w2WbjzUA9kuqPtFhC7ucKJ5tFG1YmbnX5upg0Mg9h2UlofQ==') self.assertEqual(sign_res['signature'], check_sign) req_dict['signMethod'] = '11' sign_res = SDKUtil.buildSignature(req_dict, SDKConfig().signCertPath, SDKConfig().signCertPwd) check_sign = 'bda8e705fe9d67022f71e8ca14752abc402368ed142b3bc71837ac9dec99c18e' self.assertEqual(sign_res['signature'], check_sign) req_dict['signMethod'] = '12' sign_res = SDKUtil.buildSignature(req_dict, SDKConfig().signCertPath, SDKConfig().signCertPwd) check_sign = 'e3d147d4d1b835a3453c7f900acf8ad4370ebea0e750452a4a02db43c398af81' self.assertEqual(sign_res['signature'], check_sign)
def getDemoHtml(): req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["frontUrl"] = SDKConfig().frontUrl req["backUrl"] = SDKConfig().backUrl req["txnType"] = "01" req["txnSubType"] = "01" req["bizType"] = "000201" req["channelType"] = "07" req["currencyCode"] = "156" req["txnAmt"] = "1000" req["merId"] = "777290058110048" req["orderId"] = datetime.now().strftime('%Y%m%d%H%M%S') req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["accessType"] = "0" # 签名示例 req = AcpService.sign(req) url = SDKConfig().frontTransUrl # 前台自提交表单示例 resp = AcpService.createAutoFormHtml(req, url) return resp
def get_payment_form(order_id): time_now = datetime.now().strftime('%Y%m%d%H%M%S') time_out = datetime.now() + timedelta(minutes=15) time_out = time_out.strftime('%Y%m%d%H%M%S') req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["txnType"] = "01" req["txnSubType"] = "01" req["bizType"] = "000202" req["frontUrl"] = SDKConfig().frontUrl req["backUrl"] = SDKConfig().backUrl req["signMethod"] = SDKConfig().signMethod req["channelType"] = "07" req["accessType"] = "0" req["currencyCode"] = "156" req["merId"] = get_payment_merchant_id() req["orderId"] = order_id req["txnAmt"] = str(get_payment_amount(order_id)) req["txnTime"] = time_now req['payTimeout'] = time_out # 签名示例 req_params = AcpService.sign(req) req_url = SDKConfig().frontTransUrl return req_params, req_url
def setUp(self): self.certPath = SDKConfig().signCertPath self.certPassword = SDKConfig().signCertPwd self.certEncPath = SDKConfig().encryptCertPath self.certMiddlePath = SDKConfig().middleCertPath self.certRootPath = SDKConfig().rootCertPath self.certVerifyPath = SDKConfig().validateCertDir + 'verify_test.cer'
def parseCustomerInfo(customerInfostr, certPath=SDKConfig().signCertPath, certPwd=SDKConfig().signCertPwd): ''' 解析customerInfo。 为方便处理,encryptedInfo下面的信息也均转换为customerInfo子域一样方式处理, ''' customerInfostr = base64.b64decode(customerInfostr) customerInfostr = customerInfostr[1:len(customerInfostr) - 1] customerInfo = SDKUtil.parseQString(customerInfostr) if 'encryptedInfo' in customerInfo: encryptedInfoStr = customerInfo.pop("encryptedInfo") encryptedInfoStr = AcpService.decryptData(encryptedInfoStr, certPath, certPwd) encryptedInfo = SDKUtil.parseQString(encryptedInfoStr) for k, v in encryptedInfo.items(): customerInfo[k] = v return customerInfo
def _test_deCodeFileContent(self): # Generate file content file_content = "test_data".encode('utf-8') file_content = zlib.compress(file_content) file_content = base64.b64encode(file_content) file_content = file_content.decode('utf-8') data_dict = { "merId": "888888888888888", "batchNo": "123456", "txnTime": 1234323223, "fileName": "test.txt", "fileContent": file_content, } SDKUtil.deCodeFileContent(data_dict, SDKConfig().fileDir)
def initEncryptCert(certPath=SDKConfig().encryptCertPath): if certPath is None: logging.info("encryptCertPath is none, exit initEncryptCert") return None logging.info("读取加密证书 ...") with open(certPath, 'rb') as fs: c = crypto.load_certificate(crypto.FILETYPE_PEM, fs.read()) pkey = crypto.dump_publickey(crypto.FILETYPE_PEM, c.get_pubkey()) cert = Cert() cert.cert = rsa.PublicKey.load_pkcs1_openssl_pem(pkey) cert.certId = str(c.get_serial_number()) CertUtil.__encryptCert[certPath] = cert logging.info("加密证书读取成功, 序列号: " + cert.certId) return cert
def initVerifyCerts(certDir=SDKConfig().validateCertDir): logging.info("读取验签证书文件夹下所有 cer 文件 ...") cert_path = Path(certDir) cert_files = list(cert_path.glob('**/*.cer')) if len(cert_files) == 0: logging.info("请确定 " + certDir + " 路径下是否存在 cer 文件") return for file_path in cert_files: try: with open(file_path, 'rb') as fs: fCert = crypto.load_certificate(crypto.FILETYPE_PEM, fs.read()) cert = Cert() cert.certId = str(fCert.get_serial_number()) cert.cert = fCert CertUtil.__verifyCerts[cert.certId] = cert logging.info(file_path.name + " 读取成功, 序列号: " + cert.certId) except Exception as e: logging.error(file_path.name + " 读取失败, " + str(e)) continue
def getCustomerInfoWithEncrypt(customerInfo): ''' 加密时使用此方法 ''' if customerInfo is None or len(customerInfo) == 0: return "" encryptedInfo = {} for key in customerInfo.keys(): if key == 'phoneNo' or key == 'cvn2' or key == 'expired': encryptedInfo[key] = customerInfo[key] del customerInfo['phoneNo'] del customerInfo['cvn2'] del customerInfo['expired'] if len(encryptedInfo): encryptedInfo = SDKUtil.createLinkString(encryptedInfo, False, False) encryptedInfo = AcpService.encryptData(encryptedInfo, SDKConfig().encryptCertPath) customerInfo["encryptedInfo"] = encryptedInfo b64_str = "{" + SDKUtil.createLinkString(customerInfo, False, False) + "}" b64_data = base64.b64encode(b64_str.encode('utf-8')) return b64_data.decode('utf-8')
def getDemoHtml(): accNo = "6226090000000048" customerInfo = {} customerInfo['phoneNo'] = '18100000000' customerInfo['certifTp'] = '01' customerInfo['certifId'] = '510265790128303' customerInfo['customerNm'] = '张三' customerInfo['cvn2'] = '248' customerInfo['expired'] = '1912' req = {} req["version"] = SDKConfig().version req["encoding"] = SDKConfig().encoding req["signMethod"] = SDKConfig().signMethod req["frontUrl"] = SDKConfig().frontUrl req["backUrl"] = SDKConfig().backUrl req["txnType"] = "79" req["txnSubType"] = "00" req["bizType"] = "000301" req["channelType"] = "07" req["merId"] = "777290058110097" req["orderId"] = datetime.now().strftime('%Y%m%d%H%M%S') req["txnTime"] = datetime.now().strftime('%Y%m%d%H%M%S') req["accessType"] = "0" # accNo、customerInfo组装示例 req["accNo"] = AcpService.encryptData(accNo) req["customerInfo"] = AcpService.getCustomerInfoWithEncrypt(customerInfo) req["encryptCertId"] = AcpService.getEncryptCertId() # 签名示例 req = AcpService.sign(req) url = SDKConfig().frontTransUrl # 前台自提交表单示例 resp = AcpService.createAutoFormHtml(req, url) return resp
def test_getVerifyCertFromPath(self): cert = CertUtil.getVerifyCertFromPath('68759622183', SDKConfig().validateCertDir) self.assertIsNotNone(cert)
def resetEncryptCertPublicKey(certPath=SDKConfig().encryptCertPath): CertUtil.__encryptCert = {} CertUtil.initEncryptCert(certPath)
def encryptData(data, certPath=SDKConfig().encryptCertPath): return SDKUtil.encryptPub(data, certPath)
def setUp(self): self.sdk_conf = SDKConfig()
def decryptData(data, certPath=SDKConfig().signCertPath, certPwd=SDKConfig().signCertPwd): return SDKUtil.decryptPri(data, certPath, certPwd)
def sign(req, certPath=SDKConfig().signCertPath, certPwd=SDKConfig().signCertPwd): ''' 签名,证书路径和密码从配置文件读 ''' return SDKUtil.buildSignature(req, certPath, certPwd)
def getSignCertId(certPath=SDKConfig().signCertPath, certPwd=SDKConfig().signCertPwd): if certPath not in CertUtil.__signCerts: CertUtil.initSignCert(certPath, certPwd) return CertUtil.__signCerts[certPath].certId
def getEncryptKey(certPath=SDKConfig().encryptCertPath): if certPath not in CertUtil.__encryptCert: CertUtil.initEncryptCert(certPath) return CertUtil.__encryptCert[certPath].cert
def getDecryptPriKey(certPath=SDKConfig().signCertPath, certPwd=SDKConfig().signCertPwd): if certPath not in CertUtil.__signCerts: CertUtil.initSignCert(certPath, certPwd) return CertUtil.__signCerts[certPath].key