用Bottle的web框架,用百度云的服务。
s
app.conf
这个文件,设置route,和静态文件(不支持代码设置静态路径,bae的安全机制)
handlers:
- url : /
script: main.py
- url : /verifyReceipt
script: main.py
- url : /(.*)
script: /static/$1
- expire : .jpg modify 10 years
- expire : .swf modify 10 years
- expire : .png modify 10 years
- expire : .gif modify 10 years
- expire : .JPG modify 10 years
- expire : .ico modify 10 years
main.py
doVerifyReceipt()实现验证,别的好多是我测试代码
#!/usr/bin/env python
# coding=utf-8
from bottle import Bottle, request, static_file
import json, base64
import httplib
import dwlog, os
app = Bottle()
@app.route('/')
def index():
return '<p>Hello World</p>'
@app.route('/:filename')
def serve_static(filename):
return static_file(filename, root='./static')
#{
# "receipt-data" : "xxx",
# "productId" : "xxx"
#}
@app.post('/verifyReceipt')
def doVerifyReceipt():
# 1. 取出post的数据
receipt = request.params.get('receipt-data')
# productId = request.params.get('productId')
dwlog.logger.info('receipt-data:%s', receipt)
# 2. base64编码后构造一个json串,格式为{"receipt-data": base64Str}
receipt64 = base64.encodestring(receipt)
jsonStr = json.dumps({"receipt-data": receipt64})
dwlog.logger.info('jsonStr of receipt:%s', jsonStr)
# 3. 连接app store进行验证 ,测试时用sandbox,上线后用正式环境
#connect = httplib.HTTPSConnection("buy.itunes.apple.com")
# sandbox
connect = httplib.HTTPSConnection("sandbox.itunes.apple.com")
headers = {"Content-type": "application/json"}
connect.request("POST", "/verifyReceipt", jsonStr)
result = connect.getresponse()
respData = result.read()
dwlog.logger.info(respData)
connect.close()
# 4. 解析验证结果: status=0表示成功,并做相应操作
receipt = json.loads(respData)
status = receipt[u'status']
if status == 0:
verifyOk(receipt)
else:
verifyFail(receipt)
return respData
def verifyOk(receipt):
#分配会员权限
pass
def verifyFail(receipt):
pass
#curl -d "aa=1&bb=2" "http://localhost:8080/apii?cc=3"
@app.post('/apii')
def apii():
# data = request.forms.allitems()
# data = request.POST.allitems()
# data = request.POST.decode().allitems()
# data = request.POST.dict
# data = request.POST.values()
# data = dir(request.body)
# dwlog.logger.info(data)
#
# data = request.body.read()
# data = request.body.buf
# data = request.query.allitems()
# data = request.query_string
# data = request.url
# data = request.urlparts
# data = request.fullpath
data = request.params.allitems()
# data = request.script_name
# data = request.keys()
dwlog.logger.info(data)
jsonStr = json.dumps({"status": 0, "receipt" : "test"})
return jsonStr
if 'SERVER_SOFTWARE' in os.environ:
from bae.core.wsgi import WSGIApplication
application = WSGIApplication(app)
else:
app.run(host='localhost', port=8080)
dwlog.py
兼容bae的logging和本地环境logging
# coding=utf-8
'''
Created on 2011-8-24
主要用途:
对程序中所使用的loggong模式做一般性配置
@author: JerryKwan
'''
import os
if 'SERVER_SOFTWARE' in os.environ:
from bae.api import logging
logger = logging.getLogger()
else:
import logging
import logging.handlers
import sys
LEVELS = {'NOSET': logging.NOTSET,
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL}
# create logs file folder
logs_dir = os.path.join(os.path.curdir, "logs")
if os.path.exists(logs_dir) and os.path.isdir(logs_dir):
pass
else:
os.mkdir(logs_dir)
# define a rotating file handler
rotatingFileHandler = logging.handlers.RotatingFileHandler(filename ="./logs/log.log",
maxBytes = 1024 * 1024 * 50,
backupCount = 5)
#formatter = logging.Formatter("%(asctime)s %(name)-12s %(levelname)-8s %(message)s", "%H:%M:%S")
formatter = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s", "%H:%M:%S")
rotatingFileHandler.setFormatter(formatter)
logging.getLogger("").addHandler(rotatingFileHandler)
#define a handler whitch writes messages to sys
console = logging.StreamHandler(sys.stdout)
console.setLevel(logging.NOTSET)
#set a format which is simple for console use
#formatter = logging.Formatter("%(name)-12s: %(levelname)-8s %(message)s")
formatter = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s", "%H:%M:%S")
#tell the handler to use this format
console.setFormatter(formatter)
#add the handler to the root logger
logging.getLogger("").addHandler(console)
# set initial log level
logger = logging.getLogger("")
logger.setLevel(logging.NOTSET)
pay.html
写个页面自测一下,没问题了,再让客户端用
其中andytest.IAP是页面调用客户端的方法
IAPCallback(str)供页面回调,然后在这里验证。之所以通过javascript实现,是因为这样更灵活。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />
<script type="text/javascript" src="zepto.min.js"></script>
<title>IAP测试</title>
<script >
function pay2() {
if(andytest.IAP) {
andytest.IAP("com.andych008.iphone_50_1month");
} else {
alert("Undefined");
}
}
function IAPCallback(str) {
alert(str)
var obj = eval("(" + str + ")");
$.post("/verifyReceipt", {
"receipt-data" : obj["receipt-data"],
productId : obj["productId"]
}, function(respData) {
console.log(respData);
obj = eval("(" + respData + ")");
if(obj.status == 0)
youyuan.IAPResult(true)
else
youyuan.IAPResult(false)
});
}
function testIAPCallback() {
var str = '{ "receipt-data" : "aaa", "productId" : "bbb"} '
IAPCallback(str);
}
</script>
</head>
<body>
<a href="javascript:void(0)" οnclick="pay2()">购买50元1个月</a>
<hr />
<a href="javascript:void(0)" οnclick="testIAPCallback()">test IAPCallback</a>
</body>
</html>
s