APP微信支付
- 1. 使用django生成预支付订单
* - wxpay.py
- views.py
- url.py
- cocos2d-js 拉起生成预订单
* - 封装http请求
- Weixinpay.js
- Android 拉起微信支付
* - 导入微信sdk以及阿里fastjson
- AppActivity.java
- WXPayEntryActivity.java
- AndroidManifest.xml
- 支付成功django回调
* - url.py
1. 使用django生成预支付订单
wxpay.py
import hashlib
import time
from urllib.parse import quote
import requests
import xmltodict
from pay import settings
class WeiXinPay(object):
def __init__(self):
self.APPID = settings.WX_APPID
self.MCHID = settings.WXPAY_MCHID
self.NOTIFY_URL = 'https://****/weixin_notify/'
self.TRADE_TYPE = 'APP'
self.APIKEY = settings.WXPAY_APIKEY
self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
self.error = None
self.params = None
def get_parameter(self, order_id, body, total_fee, spbill_create_ip):
self.params = {
'appid': self.APPID,
'mch_id': self.MCHID,
'nonce_str': self.getNonceStr(),
'body': body,
'out_trade_no': str(order_id),
'total_fee': str(int(total_fee)),
'spbill_create_ip': spbill_create_ip,
'trade_type': self.TRADE_TYPE,
'notify_url': self.NOTIFY_URL,
}
return self.params
def getNonceStr(self, length=32):
"""生成随机字符串"""
import random
chars = "abcdefghijklmnopqrstuvwxyz0123456789"
strs = []
for x in range(length):
strs.append(chars[random.randrange(0, len(chars))])
return "".join(strs)
def key_value_url(self, value, urlencode):
"""
将键值对转为 key1=value1&key2=value2
对参数按照key=value的格式,并按照参数名ASCII字典序排序
"""
slist = sorted(value)
buff = []
for k in slist:
v = quote(value[k]) if urlencode else value[k]
buff.append("{0}={1}".format(k, v))
return "&".join(buff)
def get_sign(self, params):
"""
生成sign
拼接API密钥
"""
stringA = self.key_value_url(params, False)
stringSignTemp = stringA + '&key=' + self.APIKEY
sign = (hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()).upper()
params['sign'] = sign
return params
def get_req_xml(self):
"""
拼接XML
"""
self.get_sign(self.params)
xml = ""
for k, v in self.params.items():
xml += ' + k + '>' + v + ' + k + '>'
xml += ""
return xml.encode("utf-8")
def get_prepay_id(self):
"""
请求获取prepay_id
"""
xml = self.get_req_xml()
respone = requests.post(self.url, xml, headers={'Content-Type': 'application/xml'})
msg = respone.text.encode('ISO-8859-1').decode('utf-8')
xmlresp = xmltodict.parse(msg)
if xmlresp['xml']['return_code'] == 'SUCCESS':
if xmlresp['xml']['result_code'] == 'SUCCESS':
prepay_id = xmlresp['xml']['prepay_id']
self.params['prepay_id'] = prepay_id
self.params['package'] = "Sign=WXPay"
self.params['timestamp'] = str(int(time.time()))
return self.params
else:
return 'failure'
else:
return 'failure'
def re_finall(self):
"""得到prepay_id后再次签名,返回给终端参数
"""
self.get_prepay_id()
if self.error:
return
sign_again_params = {
'appid': self.params['appid'],
'noncestr': self.params['nonce_str'],
'package': self.params['package'],
'partnerid': self.params['mch_id'],
'timestamp': self.params['timestamp'],
'prepayid': self.params['prepay_id']
}
self.get_sign(sign_again_params)
sign_again_params['sign'] = sign_again_params['sign']
return sign_again_params
def get_notifypay(self, data):
dictdata = dict(data)
_dictdata = dict(dictdata['xml'])
success = self.get_sign(_dictdata)
if success:
success.pop("sign", None)
success.pop("sign_type", None)
return success
else:
return None
@staticmethod
def xml_to_dict(params):
"""
拼接XML
"""
if not isinstance(params, dict):
return None
xml = ""
for k, v in params.items():
xml += ' + k + '>' + v + ' + k + '>'
xml += ""
return xml
views.py
import random
import arrow
from rest_framework.response import Response
from rest_framework.views import APIView
from pay.wxpay import WeiXinPay
class Payment(APIView):
def order_number(self):
num = random.randint(100000,999999)
order_id = str(arrow.now().timestamp) + str(num)
return order_id
def post(self,request):
total_fee = int(request.data.get('total_fee',201))
body = '支付TEST'
spbill_create_ip = '127.0.0.1'
order_id = self.order_number()
pay = WeiXinPay()
parameter_dict = pay.get_parameter(order_id, body, total_fee, spbill_create_ip)
response = pay.re_finall()
return Response(response)
url.py
path('payment/', Payment.as_view()),
cocos2d-js 拉起生成预订单
封装http请求
function httpPostTest(url, data, callback) {
var url = 'http://39.108.86.11/' + url;
var xhr = new XMLHttpRequest();
xhr.responseType = "text";
xhr.open('POST', url);
let token = jsb.reflection.callStaticMethod("com/tf/y/utils/SPUtil", "getStr", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", "token", "None");
xhr.setRequestHeader("Authorization", "Bearer" + " " + token);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(data));
xhr.onload = function(e) {};
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
var xhrRes = (new Function("return " + xhr.responseText))();
callback(xhrRes);
}
};
};
Weixinpay.js
function weixinpay() {
data = {'total_fee':201}
httpPostTest('payment/', data, function(res) {
cc.log('============pay========',JSON.stringify(res))
jsb.reflection.callStaticMethod("com/tf/y/AppActivity", "WeiXinPay", "(Ljava/lang/String;)V",JSON.stringify(res))
})
}
Android 拉起微信支付
导入微信sdk以及阿里fastjson
dependencies{
···
···
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
compile 'com.alibaba:fastjson:1.2.54'
}
AppActivity.java
package com.tf.y;
import android.util.Log;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.alibaba.fastjson.JSONObject;
import java.util.Timer;
import java.util.TimerTask;
public class AppActivity extends Cocos2dxActivity {
private static String APPID = "";
public static IWXAPI api;
···
public static void WeiXinPay(String str){
Log.d("pay","开启微信支付");
api = WXAPIFactory.createWXAPI(getActivity(),APPID,true);
PayReq request = new PayReq();
JSONObject jsonObject = JSONObject.parseObject(str);
api.registerApp(APPID);
request.appId = jsonObject.getString("appid");
request.partnerId = jsonObject.getString("partnerid");
request.prepayId= jsonObject.getString("prepayid");
request.packageValue = "Sign=WXPay";
request.nonceStr= jsonObject.getString("noncestr");
request.timeStamp= jsonObject.getString("timestamp");
request.sign= jsonObject.getString("sign");
api.sendReq(request);
}
public static void callJsWxPAy(final int value){
final String exes = "paymentResult('"+ value + "')";
TimerTask task = new TimerTask(){
public void run(){
Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxJavascriptJavaBridge.evalString("cc.log('微信调取js----java log')");
Cocos2dxJavascriptJavaBridge.evalString(exes);
}
});
}
};
Timer timer = new Timer();
timer.schedule(task, 100);
}
}
WXPayEntryActivity.java
package com.tf.y.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tf.y.AppActivity;
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI wxAPI;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wxAPI = WXAPIFactory.createWXAPI(this, "");
wxAPI.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
wxAPI.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq baseReq) {}
@Override
public void onResp(BaseResp baseRes) {
Log.i("ansen", "微信支付回调 返回错误码:"+baseRes.errCode+" 错误名称:"+baseRes.errStr);
AppActivity.callJsWxPAy(baseRes.errCode);
finish();
}
}
AndroidManifest.xml
<activity
android:name="com.tf.y.wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme=""/>
</intent-filter>
</activity>
支付成功django回调
from django.http import HttpResponse, JsonResponse
from rest_framework.views import APIView
import xml.etree.ElementTree as et
class WxpayNotify(APIView):
def post(self,request):
_xml = request.body
xml = str(_xml, encoding="utf-8")
tree = et.fromstring(xml)
return_code = tree.find("return_code").text
err_resp = ""
success_resp = ""
if return_code == 'FAIL':
return HttpResponse(err_resp, content_type='text/xml', status=200)
elif return_code == 'SUCCESS':
order_id = tree.find("out_trade_no").text
wx_order = tree.find("transaction_id").text
time_end = tree.find("time_end").text
return HttpResponse(success_resp, content_type='text/xml', status=200)
url.py
path('weixin_notify/', WxpayNotify.as_view()),
Original: https://blog.csdn.net/m0_47202787/article/details/120344310
Author: Ang-l
Title: cocos2d-js android django微信支付
相关阅读
Title: python教程:一篇文章让你理解字符串的格式化
有这样一个字符串:
sg = """
"""
如果我们希望用户输入姓名、年龄、性别和爱好,程序将以上述格式打印出来。从我们目前所了解的情况来看,我们可以使用此代码来实现:
[En]
If we want the user to enter a name, age, gender and hobby, then the program will print it out in the above format. From what we have learned so far, we can use this code to achieve:
a = "------info------"
b = "name: "
c = "age: "
d = "sex: "
e = "hobby: "
f = "-------end------"
name = input(b)
age = input(c)
sex = input(d)
hobby = input(e)
print(a)
print(b + name)
print(c + age)
print(d + sex)
print(e + hobby)
print(f)
代码运行后就是这样的:
name: alex
age: 18
sex: 男
hobby: 女
但是,虽然我们已经实现了需求,但它太繁琐了。这里可以使用格式化方法。格式化是将占位符放在需要自定义它的字符串中,然后通过向占位符提供数据来构建新的字符串。提供的数据需要与占位符对应,否则将报告错误。
[En]
But although we have achieved the demand, it is too cumbersome. The formatting method can be used here. Formatting is to put a placeholder in a string where you need to customize it, and then build a new string by providing data to the placeholder. The data provided needs to correspond to the placeholder, otherwise an error will be reported.
Python中常用的占位符有:
- %s 字符串:%s 可以填充字符串也可以填充数字(其实也可以是其他数据类型)
- %d | %i 整型:必须填充数字
- %% 转义:变成普通的 %
有了格式化的方法,上面的例子我们就可以简化成这个样子:
name = input("name: ")
age = input("age: ")
sex = input("sex: ")
hobby = input("hobby: ")
a = "哈哈啊"
msg = """
"""
print(msg % (name, int(age), sex, hobby))
在 Python 3.6 及以后的版本中引入了一个新的 f-strings 方法格式字符串,把上面的格式化方法进一步简化,具体做法为:
msg = f"""
"""
print(msg)
在字符串的引号前,用小写字母 f 声明字符串为 f-strings 格式的字符串。用大括号将需要格式化的位置标记出来,在大括号里面填入变量或者数据,构建成新的字符串。
可以通过两个大括号来进行转义,表示普通的大括号:
{{ }}
.format() 方法是另外一种字符串格式化的方法:
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
s = 'alex{}wu{}si{}r'
s1 = s.format('你好', '我好', '大家好')
print(s1)
输出的结果为:alex你好wu我好si大家好r
.format() 方法除了向上面这种按照位置格式化之外,还可以按照索引格式化:
s = 'alex{0}wu{2}si{1}r'
s1 = s.format('你好', '我好', '大家好')
print(s1)
输出的结果为:alex你好wu大家好si我好r
.format() 方法还可以按照关键字进行格式化:
s = 'alex{a}wu{c}si{b}r'
s1 = s.format(b = '你好', a = '我好', c = '大家好')
print(s1)
输出的结果为:alex我好wu大家好si你好r
Original: https://www.cnblogs.com/xxpythonxx/p/16093823.html
Author: python学习者0
Title: python教程:一篇文章让你理解字符串的格式化
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/290789/
转载文章受原作者版权保护。转载请注明原作者出处!