Browse Source

微信支付密钥证书

locky 4 năm trước cách đây
mục cha
commit
2aff7b8ac3

+ 23 - 0
Ansjer/file/wechatpay/apiclient_cert.pem

@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID7DCCAtSgAwIBAgIUfF0ljlOH7y//Ggpp9FV3bvBumSwwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjEwNzMwMDc1ODU5WhcNMjYwNzI5MDc1ODU5WjB+MRMwEQYDVQQDDAox
+NTA4MjA5NzQxMRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xKjAoBgNVBAsM
+IeePoOa1t+WuieWjq+S9s+eUteWtkOaciemZkOWFrOWPuDELMAkGA1UEBgwCQ04x
+ETAPBgNVBAcMCFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAy/yNuCQI8pg92b9ptotcNyrHun37o7pJN7dzxVzGXwf2DdDJfrAHsen34m6c
+dNF8foEr8k2gCAdPuHsOU7iPtmyblRXpGJj1MC1kFton4X0zd/+TykcEtfK6o9u3
+KZY1yttt6QEAlFVI+5AzsUHK5Cz0LbH/61udDQyywxqbV0bEHGoxVDq4PmsbL83v
+Y/KE+40tONGRrMvP3DzBhT1afJe8hYFTdCYGGF9hZgQHDn6pmvroicT+32BBqqYz
+tjPIU73SLs+kHB+Fj7D+GhloSJRLfASVsrAfuAsbFQHc+JVmF0RhSjZRoo4oyMmw
+FuWz6adBAGXOgNh8BX5bhkQN9QIDAQABo4GBMH8wCQYDVR0TBAIwADALBgNVHQ8E
+BAMCBPAwZQYDVR0fBF4wXDBaoFigVoZUaHR0cDovL2V2Y2EuaXRydXMuY29tLmNu
+L3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0
+NkMwMUMzRThFQkQyMA0GCSqGSIb3DQEBCwUAA4IBAQCKOhM/GTDLL6pkAmrRdwW0
+gPQAih237SHN8UaXVF/shMLcnC4TQtb74b7T7q93ZANjvJJpkCwBRFvYdTPZZLPG
+Y2+KmwIaekAMNyjE8EXU9Y+IQhAdGyLhWiZk+hYK7qwfhjVfqNa/vgu6GAf+mgad
+gaGdxJHY7F2u2tycwetOPd+fD0PTUWqLvZyL04HFrmtHmuZOxYnGvF8scNDRpDAN
+cgRzZ0oFDa/J1QdZTpY/7HAtp3i+gjlqwypVYujI/oLbpYBzB1Zwf5WX6Qt6Ok66
+m1dJWhCkgB0mAyAys6atlCcLTxAksRIFGuIjoBOqOABsi3X5xFau99PH8bshybKU
+-----END CERTIFICATE-----

+ 28 - 0
Ansjer/file/wechatpay/apiclient_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL/I24JAjymD3Z
+v2m2i1w3Kse6ffujukk3t3PFXMZfB/YN0Ml+sAex6ffibpx00Xx+gSvyTaAIB0+4
+ew5TuI+2bJuVFekYmPUwLWQW2ifhfTN3/5PKRwS18rqj27cpljXK223pAQCUVUj7
+kDOxQcrkLPQtsf/rW50NDLLDGptXRsQcajFUOrg+axsvze9j8oT7jS040ZGsy8/c
+PMGFPVp8l7yFgVN0JgYYX2FmBAcOfqma+uiJxP7fYEGqpjO2M8hTvdIuz6QcH4WP
+sP4aGWhIlEt8BJWysB+4CxsVAdz4lWYXRGFKNlGijijIybAW5bPpp0EAZc6A2HwF
+fluGRA31AgMBAAECggEAN2/8yAWrFNtBO/NkdILtXeTXgRyKDhYrnePSp9mt49fT
+DDApArAudzDB+JzdEnZ4Yh0S53gnPOdXyChRXXl0PTzJD7xzrAat5BkB8Z/6ZLLV
+ERC5hqjEY/qCtNOatMeo+OenuEJYePewrQWkttDNpjN9bQnKJpmwVgKUdqe9ffs2
+MK15/ZeXUMPXb4U8IER7qr8muVABydxUzefx9F0OBTogbMSQ6q9UZw1cunD91T2H
+lJaQ4erSdLqEj0WEhf6FJ/rWJjfKA7MYYxTKM0YpODr4hf4R2Qds3iHJDIp9Y3Rp
+AlskQaWXEzoJVfYNCglMmTkrlGDSQlr3juaidkjphQKBgQDuY3swj5aUA5ui5S+y
+aFqwDu4OxZC9cVotFii5FuVGQIoylGRvkswPjYYXqZAHKpW+l2muiOJOZ9t8v7D8
+uZKjei5WT6DapnbXOqGbikNEsmnX56jiwB2oAnD41SHzK7jiXEP3rSK2OsXrEQjL
+NqeXAGHYetO7Xip0Tyu9WMUKSwKBgQDbDnG3lEC5TYWh1soq6JVCh9NJY/bOT/eO
+IWimTRlOV1S754auVjOV5FMwlgJN2MtP2qxxSjxjAInEVN9XgYIumh4XofuZ0esk
+IcnfWTpMXzbuT/KpkyjIjN+jwt0cjXbgHClwZpcYtoufGIlija2uuB5JlTeZ3eL/
+E2ovQuggvwKBgDzgarUb9fgWc8hFfsiwnXgYV/KtwSifqceZwQyDLEmkcaY4/uz/
+L91I5tVkF8O8vEDPqc1IZ4JeQ064JRpkyW215d9ktk8f83lDH8H4rPT+Gsln/1jo
+dqpQ9UiWJPVUVQJ5TWISdKrUl3ZQA07hxippjpMZyrguc+j/zsurv6XBAoGBAKYb
+rd+na+0X+91dIrCm7YgltvJP+zc3LGF6tABnNmlRj89tIZPRigx/txWAqv6dBo7n
+IxxFTsVEAzP9p96TNkRgWbFSA5gAtm4PsSTMZIjFKsJLnZc5IBPzvyJPAZxFKX+H
+22SAZtM2mWlrEcLJ7Iow08a4gBENULRb5IkyExPBAoGAQ1BwOxsg4XeKt8aXPLnB
+3Crw4XZAj3rGDSHxXFWXFe4+gwycQ9mGCls4MZyKLoGoiADKNau+DaJ4CGETkpBn
+F8hZ8l4F76RQpH2X+Qhn2hEL0dreeWcpAzC2NLHuthV5bR0EhGNgXwd8NjDC0CXU
+VaSntDOpcfQSRgvp/kjPE64=
+-----END PRIVATE KEY-----

+ 27 - 0
Object/WechatPayObject.py

@@ -5,6 +5,8 @@ from urllib.parse import quote
 import requests
 import xmltodict
 
+from Ansjer.config import BASE_DIR
+
 
 class WechatPayObject:
     """配置账号信息"""
@@ -20,6 +22,7 @@ class WechatPayObject:
         self.TRADE_TYPE = 'APP'
         self.APIKEY = 'ZHansjeransjeransjer680301000000'
         self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信请求url
+        self.refund_url = 'https://api.mch.weixin.qq.com/secapi/pay/refund'   # 退款url
         self.error = None
         self.params = None
 
@@ -199,3 +202,27 @@ class WechatPayObject:
             xml += '<' + k + '>' + v + '</' + k + '>'
         xml += "</xml>"
         return xml
+
+    def refund(self, out_trade_no, out_refund_no, total_fee, refund_fee):
+        params = {
+            'appid': self.APPID,
+            'mch_id': self.MCHID,
+            'nonce_str': self.getNonceStr(),
+            'out_trade_no': out_trade_no,   # 商户订单号
+            'out_refund_no': out_refund_no,    # 商户退款单号
+            'total_fee': total_fee,     # 订单金额
+            'refund_fee': refund_fee    # 退款金额
+        }
+        # doc: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
+        string_sign = "&".join(['{}={}'.format(k, params[k]) for k in sorted(params)] + ['key={}'.format(self.APIKEY)])
+        params['sign'] = hashlib.md5(string_sign.encode('utf8')).hexdigest().upper()   # MD5签名
+        xml = "<xml>{}</xml>".format("".join(['<{k}>{v}</{k}>'.format(k=k, v=v) for k, v in params.items()]))   # 数据拼接成xml格式
+        cert = '{}/Ansjer/file/wechatpay/apiclient_cert.pem'.format(BASE_DIR)
+        key = '{}/Ansjer/file/wechatpay/apiclient_key.pem'.format(BASE_DIR)
+        r = requests.post(url=self.refund_url, headers={'Content-Type': 'text/xml'}, data=xml.encode('utf-8'),
+                          cert=(cert, key), verify=True)
+        response = xmltodict.parse(r.text)
+        if response['xml']['return_code'] == 'SUCCESS':
+            return True
+        else:
+            return False