1. 程式人生 > >python實現支付功能

python實現支付功能

#支付寶介面

import OpenSSL import json import time import urllib import base64   from django.conf import settings   def build_sign(param_map, sign_type="RSA"):     '''     Doc: https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105351&docType=1     '''     # 將篩選的引數按照第一個字元的鍵值ASCII碼遞增排序(字母升序排序),如果遇到相同字元則按照第二個字元的鍵值ASCII碼遞增排序,以此類推。     sort_param = sorted([(key, unicode(value, settings.ALIPAY_CHARSET).encode(settings.ALIPAY_CHARSET)) for key, value in param_map.iteritems()], key=lambda x: x[0])     # 將排序後的引數與其對應值,組合成“引數=引數值”的格式,並且把這些引數用&字元連線起來,此時生成的字串為待簽名字串。SDK中已封裝簽名方法,開發者可直接呼叫,詳見SDK說明。     # 如自己開發,則需將待簽名字串和私鑰放入SHA1 RSA演算法中得出簽名(sign)的值。     content = '&'.join(['='.join(x) for x in sort_param])     return base64.encodestring(OpenSSL.crypto.sign(settings.ALIPAY_APP_PRIVATE_KEY_OBJ, content, 'sha1'))   def build_params(out_trade_no, subject, body, total_amount):     '''     Doc:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.MVkRGo&treeId=193&articleId=105465&docType=1     將引數按照支付寶規定組織並簽名之後,返回     '''     params = {}     # 獲取配置檔案     params['app_id']            = settings.ALIPAY_APPID     params['method']            = settings.ALIPAY_METHOD     params['format']            = settings.ALIPAY_FORMAT     params['charset']           = settings.ALIPAY_CHARSET     params['sign_type']         = settings.ALIPAY_SIGN_TYPE     params['sign_type']         = settings.ALIPAY_SIGN_TYPE     params['timestamp']         = time.strftime('%Y-%m-%d %H:%M:%S')     params['version']           = settings.ALIPAY_VERSION     params['notify_url']        = settings.ALIPAY_NOTIFY_URL          # 業務引數     params['biz_content'] = {}     params['biz_content']['body']              = body           # 訂單描述、訂單詳細、訂單備註,顯示在支付寶收銀臺裡的“商品描述”裡     params['biz_content']['subject']           = subject        # 商品的標題/交易標題/訂單標題/訂單關鍵字等。     params['biz_content']['out_trade_no']      = out_trade_no   # 商戶網站唯一訂單號         params['biz_content']['total_amount']      = '%.2f' % (float(total_amount) / 100)   # 訂單總金額,單位為元,精確到小數點後兩位,取值範圍[0.01,100000000]         params['biz_content']['product_code']      = settings.ALIPAY_APP_PRODUCT_CODE     params['biz_content']                      = json.dumps(params['biz_content'], separators=(',', ':'))          params['sign'] = build_sign(params)          return urllib.urlencode(params)   def check_sign(message, sign):     '''Doc: https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.dDRpeK&treeId=204&articleId=105301&docType=1'''     try:         OpenSSL.crypto.verify(settings.ALIPAY_PUBLIC_KEY_OBJ, sign, message, 'SHA1')         return True     except Exception as _:         return False

# 支付寶開發者公鑰(支付寶生成) ALIPAY_PUBLIC_KEY = os.path.join(BASE_DIR, 'utils/paycenter/alipay/certs/alipay_public_key') _ALIPAY_PUBLIC_KEY_OBJ_PUB = OpenSSL.crypto.load_publickey(OpenSSL.crypto.FILETYPE_PEM, open(ALIPAY_PUBLIC_KEY).read()) _ALIPAY_PUBLIC_KEY_OBJ_X509 = OpenSSL.crypto.X509() _ALIPAY_PUBLIC_KEY_OBJ_X509.set_pubkey(_ALIPAY_PUBLIC_KEY_OBJ_PUB) ALIPAY_PUBLIC_KEY_OBJ = _ALIPAY_PUBLIC_KEY_OBJ_X509

# 支付寶開發者應用私鑰(接入方生成) ALIPAY_APP_PRIVATE_KEY = os.path.join(BASE_DIR, 'utils/paycenter/alipay/certs/alipay_app_private_key') ALIPAY_APP_PRIVATE_KEY_OBJ = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, open(ALIPAY_APP_PRIVATE_KEY).read(), None) -------------------------------------------------------------------------------------------------------------------------------------------

銀聯支付

import time import hashlib import urllib, urllib2 import base64 import OpenSSL from django.conf import settings   def build_sign(param_map, sign_type="RSA"):     '''構建簽名'''     # 將篩選的引數按照第一個字元的鍵值ASCII碼遞增排序(字母升序排序),如果遇到相同字元則按照第二個字元的鍵值ASCII碼遞增排序,以此類推。     sort_param = sorted([(key, unicode(value, settings.UNIONPAY_ENCODING).encode(settings.UNIONPAY_ENCODING)) for key, value in param_map.iteritems()], key=lambda x: x[0])     content = '&'.join(['='.join(x) for x in sort_param])     message = hashlib.sha1(content).hexdigest()     return base64.b64encode(OpenSSL.crypto.sign(settings.UNIONPAY_PRIVATE_KEY_OBJ, message, 'sha1'))   def build_params(out_trade_no, total_amount):     params = {}     # 獲取配置資訊     params['accType'] = settings.UNIONPAY_ACC_TYPE     params['accessType'] = settings.UNIONPAY_ACCESS_TYPE     params['backUrl'] = settings.UNIONPAY_BACK_URL     params['frontUrl'] = settings.UNIONPAY_FRONT_URL     params['bizType'] = settings.UNIONPAY_BIZ_TYPE     params['certId'] = settings.UNIONPAY_CERT_ID     params['channelType'] = settings.UNIONPAY_CHANNEL_TYPE     params['currencyCode'] = settings.UNIONPAY_CURRENCY_CODE     params['encoding'] = settings.UNIONPAY_ENCODING     params['merId'] = settings.UNIONPAY_MER_ID     params['signMethod'] = settings.UNIONPAY_SIGN_METHOD     params['txnType'] = settings.UNIONPAY_TXN_TYPE     params['txnSubType'] = settings.UNIONPAY_TXN_SUBTYPE     params['version'] = settings.UNIONPAY_VERSION          params['orderId'] = out_trade_no     params['txnAmt'] = '%d' % int(total_amount) # 單位為分     params['txnTime'] = time.strftime('%Y%m%d%H%M%S') #           params['signature'] = build_sign(params) #     return params     return urllib.urlencode(params)   def check_sign(message, sign):     try:         OpenSSL.crypto.verify(settings.UNIONPAY_PUBLIC_KEY_OBJ, sign, message, 'SHA1')         return True     except Exception as _:         return False  

# 商戶私鑰證書 UNIONPAY_APP_PRIVATE_KEY_CERT = os.path.join(UNIONPAY_CERTS_PATH, UNIONPAY_APP_PRIVATE_KEY_CERT_FILENAME) # PKCS12 format UNIONPAY_PRIVATE_KEYSTORE = OpenSSL.crypto.load_pkcs12(open(UNIONPAY_APP_PRIVATE_KEY_CERT).read(), UNIONPAY_APP_PRIVATE_KEY_CERT_PASSWORD) UNIONPAY_PRIVATE_KEY_OBJ = UNIONPAY_PRIVATE_KEYSTORE.get_privatekey()

# 銀聯公鑰證書 UNIONPAY_PUBLIC_KEY_CERT = os.path.join(UNIONPAY_CERTS_PATH, UNIONPAY_PUBLIC_KEY_CERT_FILENAME) UNIONPAY_PUBLIC_KEY_OBJ = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(UNIONPAY_PUBLIC_KEY_CERT).read())